Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Xml / System / Xml / Core / XmlEventCache.cs / 1305376 / XmlEventCache.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.Xml.Schema; using System.Xml.Xsl.Runtime; namespace System.Xml { ////// Caches sequence of XmlEvents so that they can be replayed later. /// internal sealed class XmlEventCache : XmlRawWriter { private Listpages; // All event pages private XmlEvent[] pageCurr; // Page that is currently being built private int pageSize; // Number of events in pageCurr private bool hasRootNode; // True if the cached document has a root node, false if it's a fragment private StringConcat singleText; // If document consists of a single text node, cache it here rather than creating pages private string baseUri; // Base Uri of document private enum XmlEventType { Unknown = 0, DocType, StartElem, StartAttr, EndAttr, CData, Comment, PI, Whitespace, String, Raw, EntRef, CharEnt, SurrCharEnt, Base64, BinHex, XmlDecl1, XmlDecl2, StartContent, EndElem, FullEndElem, Nmsp, EndBase64, Close, Flush, Dispose, } #if DEBUG private const int InitialPageSize = 4; #else private const int InitialPageSize = 32; #endif public XmlEventCache(string baseUri, bool hasRootNode) { this.baseUri = baseUri; this.hasRootNode = hasRootNode; } public void EndEvents() { if (this.singleText.Count == 0) AddEvent(XmlEventType.Unknown); } //----------------------------------------------- // XmlEventCache methods //----------------------------------------------- /// /// Return Base Uri of the document. /// public string BaseUri { get { return this.baseUri; } } ////// Return true if the cached document has a root node, false if it's a fragment. /// public bool HasRootNode { get { return this.hasRootNode; } } ////// Replay all cached events to an XmlWriter. /// public void EventsToWriter(XmlWriter writer) { XmlEvent[] page; int idxPage, idxEvent; byte[] bytes; char[] chars; XmlRawWriter rawWriter; // Special-case single text node at the top-level if (this.singleText.Count != 0) { writer.WriteString(this.singleText.GetResult()); return; } rawWriter = writer as XmlRawWriter; // Loop over set of pages for (idxPage = 0; idxPage < this.pages.Count; idxPage++) { page = this.pages[idxPage]; // Loop over events in each page for (idxEvent = 0; idxEvent < page.Length; idxEvent++) { switch (page[idxEvent].EventType) { case XmlEventType.Unknown: // No more events Debug.Assert(idxPage + 1 == this.pages.Count); return; case XmlEventType.DocType: writer.WriteDocType(page[idxEvent].String1, page[idxEvent].String2, page[idxEvent].String3, (string) page[idxEvent].Object); break; case XmlEventType.StartElem: writer.WriteStartElement(page[idxEvent].String1, page[idxEvent].String2, page[idxEvent].String3); break; case XmlEventType.StartAttr: writer.WriteStartAttribute(page[idxEvent].String1, page[idxEvent].String2, page[idxEvent].String3); break; case XmlEventType.EndAttr: writer.WriteEndAttribute(); break; case XmlEventType.CData: writer.WriteCData(page[idxEvent].String1); break; case XmlEventType.Comment: writer.WriteComment(page[idxEvent].String1); break; case XmlEventType.PI: writer.WriteProcessingInstruction(page[idxEvent].String1, page[idxEvent].String2); break; case XmlEventType.Whitespace: writer.WriteWhitespace(page[idxEvent].String1); break; case XmlEventType.String: writer.WriteString(page[idxEvent].String1); break; case XmlEventType.Raw: writer.WriteRaw(page[idxEvent].String1); break; case XmlEventType.EntRef: writer.WriteEntityRef(page[idxEvent].String1); break; case XmlEventType.CharEnt: writer.WriteCharEntity((char) page[idxEvent].Object); break; case XmlEventType.SurrCharEnt: chars = (char[]) page[idxEvent].Object; writer.WriteSurrogateCharEntity(chars[0], chars[1]); break; case XmlEventType.Base64: bytes = (byte[]) page[idxEvent].Object; writer.WriteBase64(bytes, 0, bytes.Length); break; case XmlEventType.BinHex: bytes = (byte[]) page[idxEvent].Object; writer.WriteBinHex(bytes, 0, bytes.Length); break; case XmlEventType.XmlDecl1: if (rawWriter != null) rawWriter.WriteXmlDeclaration((XmlStandalone) page[idxEvent].Object); break; case XmlEventType.XmlDecl2: if (rawWriter != null) rawWriter.WriteXmlDeclaration(page[idxEvent].String1); break; case XmlEventType.StartContent: if (rawWriter != null) rawWriter.StartElementContent(); break; case XmlEventType.EndElem: if (rawWriter != null) rawWriter.WriteEndElement(page[idxEvent].String1, page[idxEvent].String2, page[idxEvent].String3); else writer.WriteEndElement(); break; case XmlEventType.FullEndElem: if (rawWriter != null) rawWriter.WriteFullEndElement(page[idxEvent].String1, page[idxEvent].String2, page[idxEvent].String3); else writer.WriteFullEndElement(); break; case XmlEventType.Nmsp: if (rawWriter != null) rawWriter.WriteNamespaceDeclaration(page[idxEvent].String1, page[idxEvent].String2); else writer.WriteAttributeString("xmlns", page[idxEvent].String1, XmlReservedNs.NsXmlNs, page[idxEvent].String2); break; case XmlEventType.EndBase64: if (rawWriter != null) rawWriter.WriteEndBase64(); break; case XmlEventType.Close: writer.Close(); break; case XmlEventType.Flush: writer.Flush(); break; case XmlEventType.Dispose: ((IDisposable)writer).Dispose(); break; default: Debug.Assert(false, "Unknown event: " + page[idxEvent].EventType); break; } } } Debug.Assert(false, "Unknown event should be added to end of event sequence."); } ////// Concatenate all element text and atomic value events and return the resulting string. /// public string EventsToString() { StringBuilder bldr; XmlEvent[] page; int idxPage, idxEvent; bool inAttr; // Special-case single text node at the top-level if (this.singleText.Count != 0) return this.singleText.GetResult(); bldr = new StringBuilder(); // Loop over set of pages inAttr = false; for (idxPage = 0; idxPage < this.pages.Count; idxPage++) { page = this.pages[idxPage]; // Loop over events in each page for (idxEvent = 0; idxEvent < page.Length; idxEvent++) { switch (page[idxEvent].EventType) { case XmlEventType.Unknown: // No more events Debug.Assert(idxPage + 1 == this.pages.Count); return bldr.ToString(); case XmlEventType.String: case XmlEventType.Whitespace: case XmlEventType.Raw: case XmlEventType.CData: // Append text if (!inAttr) bldr.Append(page[idxEvent].String1); break; case XmlEventType.StartAttr: // Don't append text or atomic values if they appear within attributes inAttr = true; break; case XmlEventType.EndAttr: // No longer in an attribute inAttr = false; break; } } } Debug.Assert(false, "Unknown event should be added to end of event sequence."); return string.Empty; } //----------------------------------------------- // XmlWriter interface //----------------------------------------------- public override XmlWriterSettings Settings { get { return null; } } public override void WriteDocType(string name, string pubid, string sysid, string subset) { AddEvent(XmlEventType.DocType, name, pubid, sysid, subset); } public override void WriteStartElement(string prefix, string localName, string ns) { AddEvent(XmlEventType.StartElem, prefix, localName, ns); } public override void WriteStartAttribute(string prefix, string localName, string ns) { AddEvent(XmlEventType.StartAttr, prefix, localName, ns); } public override void WriteEndAttribute() { AddEvent(XmlEventType.EndAttr); } public override void WriteCData(string text) { AddEvent(XmlEventType.CData, text); } public override void WriteComment(string text) { AddEvent(XmlEventType.Comment, text); } public override void WriteProcessingInstruction(string name, string text) { AddEvent(XmlEventType.PI, name, text); } public override void WriteWhitespace(string ws) { AddEvent(XmlEventType.Whitespace, ws); } public override void WriteString(string text) { // Special-case single text node at the top level if (this.pages == null) { this.singleText.ConcatNoDelimiter(text); } else { AddEvent(XmlEventType.String, text); } } public override void WriteChars(char[] buffer, int index, int count) { WriteString(new string(buffer, index, count)); } public override void WriteRaw(char[] buffer, int index, int count) { WriteRaw(new string(buffer, index, count)); } public override void WriteRaw(string data) { AddEvent(XmlEventType.Raw, data); } public override void WriteEntityRef(string name) { AddEvent(XmlEventType.EntRef, name); } public override void WriteCharEntity(char ch) { AddEvent(XmlEventType.CharEnt, (object) ch); } public override void WriteSurrogateCharEntity(char lowChar, char highChar) { // Save high and low characters char[] chars = {lowChar, highChar}; AddEvent(XmlEventType.SurrCharEnt, (object) chars); } public override void WriteBase64(byte[] buffer, int index, int count) { AddEvent(XmlEventType.Base64, (object) ToBytes(buffer, index, count)); } public override void WriteBinHex(byte[] buffer, int index, int count) { AddEvent(XmlEventType.BinHex, (object) ToBytes(buffer, index, count)); } public override void Close() { AddEvent(XmlEventType.Close); } public override void Flush() { AddEvent(XmlEventType.Flush); } ////// All other WriteValue methods are implemented by XmlWriter to delegate to WriteValue(object) or WriteValue(string), so /// only these two methods need to be implemented. /// public override void WriteValue(object value) { WriteString(XmlUntypedConverter.Untyped.ToString(value, this.resolver)); } public override void WriteValue(string value) { WriteString(value); } protected override void Dispose(bool disposing) { try { if (disposing) { AddEvent(XmlEventType.Dispose); } } finally { base.Dispose(disposing); } } //----------------------------------------------- // XmlRawWriter interface //----------------------------------------------- internal override void WriteXmlDeclaration(XmlStandalone standalone) { AddEvent(XmlEventType.XmlDecl1, (object) standalone); } internal override void WriteXmlDeclaration(string xmldecl) { AddEvent(XmlEventType.XmlDecl2, xmldecl); } internal override void StartElementContent() { AddEvent(XmlEventType.StartContent); } internal override void WriteEndElement(string prefix, string localName, string ns) { AddEvent(XmlEventType.EndElem, prefix, localName, ns); } internal override void WriteFullEndElement(string prefix, string localName, string ns) { AddEvent(XmlEventType.FullEndElem, prefix, localName, ns); } internal override void WriteNamespaceDeclaration(string prefix, string ns) { AddEvent(XmlEventType.Nmsp, prefix, ns); } internal override void WriteEndBase64() { AddEvent(XmlEventType.EndBase64); } //----------------------------------------------- // Helper methods //----------------------------------------------- private void AddEvent(XmlEventType eventType) { int idx = NewEvent(); this.pageCurr[idx].InitEvent(eventType); } private void AddEvent(XmlEventType eventType, string s1) { int idx = NewEvent(); this.pageCurr[idx].InitEvent(eventType, s1); } private void AddEvent(XmlEventType eventType, string s1, string s2) { int idx = NewEvent(); this.pageCurr[idx].InitEvent(eventType, s1, s2); } private void AddEvent(XmlEventType eventType, string s1, string s2, string s3) { int idx = NewEvent(); this.pageCurr[idx].InitEvent(eventType, s1, s2, s3); } private void AddEvent(XmlEventType eventType, string s1, string s2, string s3, object o) { int idx = NewEvent(); this.pageCurr[idx].InitEvent(eventType, s1, s2, s3, o); } private void AddEvent(XmlEventType eventType, object o) { int idx = NewEvent(); this.pageCurr[idx].InitEvent(eventType, o); } private int NewEvent() { if (this.pages == null) { this.pages = new List(); this.pageCurr = new XmlEvent[InitialPageSize]; this.pages.Add(this.pageCurr); if (this.singleText.Count != 0) { // Review: There is no need to concatenate the strings here this.pageCurr[0].InitEvent(XmlEventType.String, this.singleText.GetResult()); this.pageSize++; this.singleText.Clear(); } } else if (this.pageSize >= this.pageCurr.Length) { // Create new page this.pageCurr = new XmlEvent[this.pageSize * 2]; this.pages.Add(this.pageCurr); this.pageSize = 0; } return this.pageSize++; } /// /// Create a standalone buffer that doesn't need an index or count passed along with it. /// private static byte[] ToBytes(byte[] buffer, int index, int count) { if (index != 0 || count != buffer.Length) { if (buffer.Length - index > count) count = buffer.Length - index; byte[] bufferNew = new byte[count]; Array.Copy(buffer, index, bufferNew, 0, count); return bufferNew; } return buffer; } ////// Caches information for XML events like BeginElement, String, and EndAttribute so that they can be replayed later. /// private struct XmlEvent { private XmlEventType eventType; private string s1; private string s2; private string s3; private object o; public void InitEvent(XmlEventType eventType) { this.eventType = eventType; } public void InitEvent(XmlEventType eventType, string s1) { this.eventType = eventType; this.s1 = s1; } public void InitEvent(XmlEventType eventType, string s1, string s2) { this.eventType = eventType; this.s1 = s1; this.s2 = s2; } public void InitEvent(XmlEventType eventType, string s1, string s2, string s3) { this.eventType = eventType; this.s1 = s1; this.s2 = s2; this.s3 = s3; } public void InitEvent(XmlEventType eventType, string s1, string s2, string s3, object o) { this.eventType = eventType; this.s1 = s1; this.s2 = s2; this.s3 = s3; this.o = o; } public void InitEvent(XmlEventType eventType, object o) { this.eventType = eventType; this.o = o; } public XmlEventType EventType { get { return this.eventType; } } public string String1 { get { return this.s1; } } public string String2 { get { return this.s2; } } public string String3 { get { return this.s3; } } public object Object { get { return this.o; } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- BaseConfigurationRecord.cs
- ContainerParaClient.cs
- FilterableData.cs
- _ListenerAsyncResult.cs
- FixedDocumentSequencePaginator.cs
- Enum.cs
- HttpCacheVary.cs
- BoundColumn.cs
- RecordsAffectedEventArgs.cs
- CodeNamespaceImport.cs
- SafeReversePInvokeHandle.cs
- TextFormatterContext.cs
- BrushProxy.cs
- BindingExpression.cs
- IntegrationExceptionEventArgs.cs
- XmlWrappingReader.cs
- ActivityStateQuery.cs
- TextSpan.cs
- _AutoWebProxyScriptEngine.cs
- DbConnectionStringBuilder.cs
- XmlMemberMapping.cs
- ItemsChangedEventArgs.cs
- BaseDataListPage.cs
- Animatable.cs
- OracleCommandSet.cs
- Object.cs
- CombinedHttpChannel.cs
- TimelineGroup.cs
- CopyOnWriteList.cs
- JoinTreeNode.cs
- NavigationPropertyEmitter.cs
- BooleanExpr.cs
- MissingManifestResourceException.cs
- UserNameSecurityTokenProvider.cs
- TextEditorCopyPaste.cs
- BitmapImage.cs
- SqlDataSourceCommandEventArgs.cs
- LinqDataSourceStatusEventArgs.cs
- OracleConnectionString.cs
- PeerResolverBindingElement.cs
- TdsParserStaticMethods.cs
- EntityWithKeyStrategy.cs
- SqlDataSourceQuery.cs
- MarginsConverter.cs
- ProcessHostConfigUtils.cs
- GridViewHeaderRowPresenterAutomationPeer.cs
- HideDisabledControlAdapter.cs
- SafeSystemMetrics.cs
- XmlSchemaCompilationSettings.cs
- WorkflowServiceInstance.cs
- ColumnMapProcessor.cs
- IriParsingElement.cs
- TextEditorDragDrop.cs
- QueryContinueDragEvent.cs
- ThreadExceptionDialog.cs
- odbcmetadatacolumnnames.cs
- MimeTypePropertyAttribute.cs
- DataSourceHelper.cs
- XamlPoint3DCollectionSerializer.cs
- WebHeaderCollection.cs
- ClientCultureInfo.cs
- OleDbDataReader.cs
- DataControlFieldCollection.cs
- TemplateControlBuildProvider.cs
- AuthenticationModulesSection.cs
- GraphicsPath.cs
- ControlCommandSet.cs
- BamlBinaryWriter.cs
- SafeEventHandle.cs
- RouteValueDictionary.cs
- MenuCommandsChangedEventArgs.cs
- ReflectionTypeLoadException.cs
- ScriptDescriptor.cs
- XmlBoundElement.cs
- Annotation.cs
- GroupDescription.cs
- PerfCounterSection.cs
- Logging.cs
- RtfFormatStack.cs
- FigureParaClient.cs
- IndentedWriter.cs
- ObjectDataSourceMethodEventArgs.cs
- NameValueSectionHandler.cs
- MouseButton.cs
- CheckBoxFlatAdapter.cs
- FormatterServices.cs
- DynamicActionMessageFilter.cs
- OutputCacheProviderCollection.cs
- NativeMethodsCLR.cs
- BitmapPalette.cs
- ContourSegment.cs
- ExportFileRequest.cs
- ProfileServiceManager.cs
- CallbackHandler.cs
- XPathBinder.cs
- CodeMethodInvokeExpression.cs
- DataGridViewHitTestInfo.cs
- KeyToListMap.cs
- RulePatternOps.cs
- PropertyOverridesDialog.cs