Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Xml / System / Xml / Core / XmlEventCache.cs / 1 / XmlEventCache.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace System.Xml { using System; using System.Diagnostics; using System.Text; using System.IO; using System.Collections; using System.Xml.Schema; ////// Caches sequence of XmlEvents so that they can be replayed later. /// internal sealed class XmlEventCache : XmlRawWriter { private ArrayList pages; // 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 string 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 == null) 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 != null) { writer.WriteString(this.singleText); return; } rawWriter = writer as XmlRawWriter; // Loop over set of pages for (idxPage = 0; idxPage < this.pages.Count; idxPage++) { page = this.pages[idxPage] as XmlEvent[]; // 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 != null) return this.singleText; bldr = new StringBuilder(); // Loop over set of pages inAttr = false; for (idxPage = 0; idxPage < this.pages.Count; idxPage++) { page = this.pages[idxPage] as XmlEvent[]; // 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) { if (this.singleText == null) this.singleText = text; else this.singleText += 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 { 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 ArrayList(); this.pageCurr = new XmlEvent[InitialPageSize]; this.pages.Add(this.pageCurr); if (this.singleText != null) { this.pageCurr[0].InitEvent(XmlEventType.String, this.singleText); this.pageSize++; this.singleText = null; } } 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. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ValueTypeFixupInfo.cs
- BaseComponentEditor.cs
- SecurityTokenRequirement.cs
- PersistChildrenAttribute.cs
- XPathScanner.cs
- UpdateManifestForBrowserApplication.cs
- StandardToolWindows.cs
- ToolboxItemLoader.cs
- XmlBinaryWriterSession.cs
- D3DImage.cs
- MetadataArtifactLoaderXmlReaderWrapper.cs
- _NtlmClient.cs
- Registration.cs
- RegexCode.cs
- RoutedEventValueSerializer.cs
- MessageQueuePermissionEntryCollection.cs
- ObjectDataSourceView.cs
- SymmetricSecurityProtocol.cs
- DatasetMethodGenerator.cs
- SimpleMailWebEventProvider.cs
- OuterGlowBitmapEffect.cs
- EntityParameter.cs
- CommentEmitter.cs
- ManualResetEvent.cs
- HwndSourceKeyboardInputSite.cs
- DNS.cs
- DefaultSection.cs
- ItemChangedEventArgs.cs
- XmlUTF8TextWriter.cs
- SystemIPGlobalStatistics.cs
- HtmlInputSubmit.cs
- PolicyLevel.cs
- HealthMonitoringSectionHelper.cs
- InputLanguageManager.cs
- ConstraintManager.cs
- BrowserCapabilitiesCompiler.cs
- WebPartActionVerb.cs
- Point3D.cs
- CustomTrackingQuery.cs
- TableLayoutSettings.cs
- WebMessageEncoderFactory.cs
- NameValueConfigurationElement.cs
- DataSourceHelper.cs
- RelationshipEndCollection.cs
- ArrangedElement.cs
- ReadWriteSpinLock.cs
- FieldToken.cs
- OverflowException.cs
- TemplateBuilder.cs
- DataServiceKeyAttribute.cs
- AdRotator.cs
- PriorityQueue.cs
- CustomTypeDescriptor.cs
- XmlToDatasetMap.cs
- SymmetricKeyWrap.cs
- XmlEntity.cs
- XmlTextEncoder.cs
- ThumbAutomationPeer.cs
- DataTablePropertyDescriptor.cs
- Int64Converter.cs
- EncoderParameter.cs
- CodeTryCatchFinallyStatement.cs
- TimeIntervalCollection.cs
- _BaseOverlappedAsyncResult.cs
- RowToParametersTransformer.cs
- FirstMatchCodeGroup.cs
- AttributeUsageAttribute.cs
- ModuleBuilderData.cs
- DetailsViewRowCollection.cs
- EventProviderClassic.cs
- oledbmetadatacolumnnames.cs
- oledbconnectionstring.cs
- TraceContextRecord.cs
- DatatypeImplementation.cs
- HttpAsyncResult.cs
- KerberosRequestorSecurityToken.cs
- EntityDataSourceEntityTypeFilterItem.cs
- SelfIssuedSamlTokenFactory.cs
- glyphs.cs
- OpenTypeLayoutCache.cs
- WebFaultClientMessageInspector.cs
- ScriptModule.cs
- XmlSchemaObjectTable.cs
- VectorKeyFrameCollection.cs
- TraceLog.cs
- SQLConvert.cs
- SQLGuid.cs
- _CommandStream.cs
- EllipticalNodeOperations.cs
- Process.cs
- WebBrowsableAttribute.cs
- HelpProvider.cs
- ReferenceEqualityComparer.cs
- XmlAttributeCollection.cs
- FixedSOMContainer.cs
- WorkflowQueueInfo.cs
- EventMemberCodeDomSerializer.cs
- ByteFacetDescriptionElement.cs
- DebugView.cs
- __Filters.cs