Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / XmlUtils / System / Xml / Xsl / Runtime / XmlAttributeCache.cs / 1 / XmlAttributeCache.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace System.Xml.Xsl.Runtime { using System; using System.Diagnostics; using System.Xml; using System.Xml.XPath; using System.Xml.Schema; ////// This writer supports only writer methods which write attributes. Attributes are stored in a /// data structure until StartElementContent() is called, at which time the attributes are flushed /// to the wrapped writer. In the case of duplicate attributes, the last attribute's value is used. /// internal sealed class XmlAttributeCache : XmlRawWriter, IRemovableWriter { private XmlRawWriter wrapped; private OnRemoveWriter onRemove; // Event handler that is called when cached attributes are flushed to wrapped writer private AttrNameVal[] arrAttrs; // List of cached attribute names and value parts private int numEntries; // Number of attributes in the cache private int idxLastName; // The entry containing the name of the last attribute to be cached private int hashCodeUnion; // Set of hash bits that can quickly guarantee a name is not a duplicate ////// Initialize the cache. Use this method instead of a constructor in order to reuse the cache. /// public void Init(XmlRawWriter wrapped) { SetWrappedWriter(wrapped); // Clear attribute list this.numEntries = 0; this.idxLastName = 0; this.hashCodeUnion = 0; } ////// Return the number of cached attributes. /// public int Count { get { return this.numEntries; } } //----------------------------------------------- // IRemovableWriter interface //----------------------------------------------- ////// This writer will raise this event once cached attributes have been flushed in order to signal that the cache /// no longer needs to be part of the pipeline. /// public OnRemoveWriter OnRemoveWriterEvent { get { return this.onRemove; } set { this.onRemove = value; } } ////// The wrapped writer will callback on this method if it wishes to remove itself from the pipeline. /// private void SetWrappedWriter(XmlRawWriter writer) { // If new writer might remove itself from pipeline, have it callback on this method when its ready to go IRemovableWriter removable = writer as IRemovableWriter; if (removable != null) removable.OnRemoveWriterEvent = SetWrappedWriter; this.wrapped = writer; } //----------------------------------------------- // XmlWriter interface //----------------------------------------------- ////// Add an attribute to the cache. If an attribute if the same name already exists, replace it. /// public override void WriteStartAttribute(string prefix, string localName, string ns) { int hashCode; int idx = 0; Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null); // Compute hashcode based on first letter of the localName hashCode = (1 << ((int) localName[0] & 31)); // If the hashcode is not in the union, then name will not be found by a scan if ((this.hashCodeUnion & hashCode) != 0) { // The name may or may not be present, so scan for it Debug.Assert(this.numEntries != 0); do { if (this.arrAttrs[idx].IsDuplicate(localName, ns, hashCode)) break; // Next attribute name idx = this.arrAttrs[idx].NextNameIndex; } while (idx != 0); } else { // Insert hashcode into union this.hashCodeUnion |= hashCode; } // Insert new attribute; link attribute names together in a list EnsureAttributeCache(); if (this.numEntries != 0) this.arrAttrs[this.idxLastName].NextNameIndex = this.numEntries; this.idxLastName = this.numEntries++; this.arrAttrs[this.idxLastName].Init(prefix, localName, ns, hashCode); } ////// No-op. /// public override void WriteEndAttribute() { } ////// Pass through namespaces to underlying writer. If any attributes have been cached, flush them. /// internal override void WriteNamespaceDeclaration(string prefix, string ns) { FlushAttributes(); this.wrapped.WriteNamespaceDeclaration(prefix, ns); } ////// Add a block of text to the cache. This text block makes up some or all of the untyped string /// value of the current attribute. /// public override void WriteString(string text) { Debug.Assert(text != null); Debug.Assert(this.arrAttrs != null && this.numEntries != 0); EnsureAttributeCache(); this.arrAttrs[this.numEntries++].Init(text); } ////// 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) { Debug.Assert(value is XmlAtomicValue, "value should always be an XmlAtomicValue, as XmlAttributeCache is only used by XmlQueryOutput"); Debug.Assert(this.arrAttrs != null && this.numEntries != 0); EnsureAttributeCache(); this.arrAttrs[this.numEntries++].Init((XmlAtomicValue) value); } public override void WriteValue(string value) { WriteValue(value); } ////// Send cached, non-overriden attributes to the specified writer. Calling this method has /// the side effect of clearing the attribute cache. /// internal override void StartElementContent() { FlushAttributes(); // Call StartElementContent on wrapped writer this.wrapped.StartElementContent(); } public override void WriteStartElement(string prefix, string localName, string ns) { Debug.Assert(false, "Should never be called on XmlAttributeCache."); } internal override void WriteEndElement(string prefix, string localName, string ns) { Debug.Assert(false, "Should never be called on XmlAttributeCache."); } public override void WriteComment(string text) { Debug.Assert(false, "Should never be called on XmlAttributeCache."); } public override void WriteProcessingInstruction(string name, string text) { Debug.Assert(false, "Should never be called on XmlAttributeCache."); } public override void WriteEntityRef(string name) { Debug.Assert(false, "Should never be called on XmlAttributeCache."); } ////// Forward call to wrapped writer. /// public override void Close() { this.wrapped.Close(); } ////// Forward call to wrapped writer. /// public override void Flush() { this.wrapped.Flush(); } //----------------------------------------------- // Helper methods //----------------------------------------------- private void FlushAttributes() { int idx = 0, idxNext; string localName; while (idx != this.numEntries) { // Get index of next attribute's name (0 if this is the last attribute) idxNext = this.arrAttrs[idx].NextNameIndex; if (idxNext == 0) idxNext = this.numEntries; // If localName is null, then this is a duplicate attribute that has been marked as "deleted" localName = this.arrAttrs[idx].LocalName; if (localName != null) { string prefix = this.arrAttrs[idx].Prefix; string ns = this.arrAttrs[idx].Namespace; this.wrapped.WriteStartAttribute(prefix, localName, ns); // Output all of this attribute's text or typed values while (++idx != idxNext) { string text = this.arrAttrs[idx].Text; if (text != null) this.wrapped.WriteString(text); else this.wrapped.WriteValue(this.arrAttrs[idx].Value); } this.wrapped.WriteEndAttribute(); } else { // Skip over duplicate attributes idx = idxNext; } } // Notify event listener that attributes have been flushed if (this.onRemove != null) this.onRemove(this.wrapped); } private struct AttrNameVal { private string localName; private string prefix; private string namespaceName; private string text; private XmlAtomicValue value; private int hashCode; private int nextNameIndex; public string LocalName { get { return this.localName; } } public string Prefix { get { return this.prefix; } } public string Namespace { get { return this.namespaceName; } } public string Text { get { return this.text; } } public XmlAtomicValue Value { get { return this.value; } } public int NextNameIndex { get { return this.nextNameIndex; } set { this.nextNameIndex = value; } } ////// Cache an attribute's name and type. /// public void Init(string prefix, string localName, string ns, int hashCode) { this.localName = localName; this.prefix = prefix; this.namespaceName = ns; this.hashCode = hashCode; this.nextNameIndex = 0; } ////// Cache all or part of the attribute's string value. /// public void Init(string text) { this.text = text; this.value = null; } ////// Cache all or part of the attribute's typed value. /// public void Init(XmlAtomicValue value) { this.text = null; this.value = value; } ////// Returns true if this attribute has the specified name (and thus is a duplicate). /// public bool IsDuplicate(string localName, string ns, int hashCode) { // If attribute is not marked as deleted if (this.localName != null) { // And if hash codes match, if (this.hashCode == hashCode) { // And if local names match, if (this.localName.Equals(localName)) { // And if namespaces match, if (this.namespaceName.Equals(ns)) { // Then found duplicate attribute, so mark the attribute as deleted this.localName = null; return true; } } } } return false; } } #if DEBUG private const int DefaultCacheSize = 2; #else private const int DefaultCacheSize = 32; #endif ////// Ensure that attribute array has been created and is large enough for at least one /// additional entry. /// private void EnsureAttributeCache() { if (this.arrAttrs == null) { // Create caching array this.arrAttrs = new AttrNameVal[DefaultCacheSize]; } else if (this.numEntries >= this.arrAttrs.Length) { // Resize caching array Debug.Assert(this.numEntries == this.arrAttrs.Length); AttrNameVal[] arrNew = new AttrNameVal[this.numEntries * 2]; Array.Copy(this.arrAttrs, arrNew, this.numEntries); this.arrAttrs = arrNew; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace System.Xml.Xsl.Runtime { using System; using System.Diagnostics; using System.Xml; using System.Xml.XPath; using System.Xml.Schema; ////// This writer supports only writer methods which write attributes. Attributes are stored in a /// data structure until StartElementContent() is called, at which time the attributes are flushed /// to the wrapped writer. In the case of duplicate attributes, the last attribute's value is used. /// internal sealed class XmlAttributeCache : XmlRawWriter, IRemovableWriter { private XmlRawWriter wrapped; private OnRemoveWriter onRemove; // Event handler that is called when cached attributes are flushed to wrapped writer private AttrNameVal[] arrAttrs; // List of cached attribute names and value parts private int numEntries; // Number of attributes in the cache private int idxLastName; // The entry containing the name of the last attribute to be cached private int hashCodeUnion; // Set of hash bits that can quickly guarantee a name is not a duplicate ////// Initialize the cache. Use this method instead of a constructor in order to reuse the cache. /// public void Init(XmlRawWriter wrapped) { SetWrappedWriter(wrapped); // Clear attribute list this.numEntries = 0; this.idxLastName = 0; this.hashCodeUnion = 0; } ////// Return the number of cached attributes. /// public int Count { get { return this.numEntries; } } //----------------------------------------------- // IRemovableWriter interface //----------------------------------------------- ////// This writer will raise this event once cached attributes have been flushed in order to signal that the cache /// no longer needs to be part of the pipeline. /// public OnRemoveWriter OnRemoveWriterEvent { get { return this.onRemove; } set { this.onRemove = value; } } ////// The wrapped writer will callback on this method if it wishes to remove itself from the pipeline. /// private void SetWrappedWriter(XmlRawWriter writer) { // If new writer might remove itself from pipeline, have it callback on this method when its ready to go IRemovableWriter removable = writer as IRemovableWriter; if (removable != null) removable.OnRemoveWriterEvent = SetWrappedWriter; this.wrapped = writer; } //----------------------------------------------- // XmlWriter interface //----------------------------------------------- ////// Add an attribute to the cache. If an attribute if the same name already exists, replace it. /// public override void WriteStartAttribute(string prefix, string localName, string ns) { int hashCode; int idx = 0; Debug.Assert(localName != null && localName.Length != 0 && prefix != null && ns != null); // Compute hashcode based on first letter of the localName hashCode = (1 << ((int) localName[0] & 31)); // If the hashcode is not in the union, then name will not be found by a scan if ((this.hashCodeUnion & hashCode) != 0) { // The name may or may not be present, so scan for it Debug.Assert(this.numEntries != 0); do { if (this.arrAttrs[idx].IsDuplicate(localName, ns, hashCode)) break; // Next attribute name idx = this.arrAttrs[idx].NextNameIndex; } while (idx != 0); } else { // Insert hashcode into union this.hashCodeUnion |= hashCode; } // Insert new attribute; link attribute names together in a list EnsureAttributeCache(); if (this.numEntries != 0) this.arrAttrs[this.idxLastName].NextNameIndex = this.numEntries; this.idxLastName = this.numEntries++; this.arrAttrs[this.idxLastName].Init(prefix, localName, ns, hashCode); } ////// No-op. /// public override void WriteEndAttribute() { } ////// Pass through namespaces to underlying writer. If any attributes have been cached, flush them. /// internal override void WriteNamespaceDeclaration(string prefix, string ns) { FlushAttributes(); this.wrapped.WriteNamespaceDeclaration(prefix, ns); } ////// Add a block of text to the cache. This text block makes up some or all of the untyped string /// value of the current attribute. /// public override void WriteString(string text) { Debug.Assert(text != null); Debug.Assert(this.arrAttrs != null && this.numEntries != 0); EnsureAttributeCache(); this.arrAttrs[this.numEntries++].Init(text); } ////// 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) { Debug.Assert(value is XmlAtomicValue, "value should always be an XmlAtomicValue, as XmlAttributeCache is only used by XmlQueryOutput"); Debug.Assert(this.arrAttrs != null && this.numEntries != 0); EnsureAttributeCache(); this.arrAttrs[this.numEntries++].Init((XmlAtomicValue) value); } public override void WriteValue(string value) { WriteValue(value); } ////// Send cached, non-overriden attributes to the specified writer. Calling this method has /// the side effect of clearing the attribute cache. /// internal override void StartElementContent() { FlushAttributes(); // Call StartElementContent on wrapped writer this.wrapped.StartElementContent(); } public override void WriteStartElement(string prefix, string localName, string ns) { Debug.Assert(false, "Should never be called on XmlAttributeCache."); } internal override void WriteEndElement(string prefix, string localName, string ns) { Debug.Assert(false, "Should never be called on XmlAttributeCache."); } public override void WriteComment(string text) { Debug.Assert(false, "Should never be called on XmlAttributeCache."); } public override void WriteProcessingInstruction(string name, string text) { Debug.Assert(false, "Should never be called on XmlAttributeCache."); } public override void WriteEntityRef(string name) { Debug.Assert(false, "Should never be called on XmlAttributeCache."); } ////// Forward call to wrapped writer. /// public override void Close() { this.wrapped.Close(); } ////// Forward call to wrapped writer. /// public override void Flush() { this.wrapped.Flush(); } //----------------------------------------------- // Helper methods //----------------------------------------------- private void FlushAttributes() { int idx = 0, idxNext; string localName; while (idx != this.numEntries) { // Get index of next attribute's name (0 if this is the last attribute) idxNext = this.arrAttrs[idx].NextNameIndex; if (idxNext == 0) idxNext = this.numEntries; // If localName is null, then this is a duplicate attribute that has been marked as "deleted" localName = this.arrAttrs[idx].LocalName; if (localName != null) { string prefix = this.arrAttrs[idx].Prefix; string ns = this.arrAttrs[idx].Namespace; this.wrapped.WriteStartAttribute(prefix, localName, ns); // Output all of this attribute's text or typed values while (++idx != idxNext) { string text = this.arrAttrs[idx].Text; if (text != null) this.wrapped.WriteString(text); else this.wrapped.WriteValue(this.arrAttrs[idx].Value); } this.wrapped.WriteEndAttribute(); } else { // Skip over duplicate attributes idx = idxNext; } } // Notify event listener that attributes have been flushed if (this.onRemove != null) this.onRemove(this.wrapped); } private struct AttrNameVal { private string localName; private string prefix; private string namespaceName; private string text; private XmlAtomicValue value; private int hashCode; private int nextNameIndex; public string LocalName { get { return this.localName; } } public string Prefix { get { return this.prefix; } } public string Namespace { get { return this.namespaceName; } } public string Text { get { return this.text; } } public XmlAtomicValue Value { get { return this.value; } } public int NextNameIndex { get { return this.nextNameIndex; } set { this.nextNameIndex = value; } } ////// Cache an attribute's name and type. /// public void Init(string prefix, string localName, string ns, int hashCode) { this.localName = localName; this.prefix = prefix; this.namespaceName = ns; this.hashCode = hashCode; this.nextNameIndex = 0; } ////// Cache all or part of the attribute's string value. /// public void Init(string text) { this.text = text; this.value = null; } ////// Cache all or part of the attribute's typed value. /// public void Init(XmlAtomicValue value) { this.text = null; this.value = value; } ////// Returns true if this attribute has the specified name (and thus is a duplicate). /// public bool IsDuplicate(string localName, string ns, int hashCode) { // If attribute is not marked as deleted if (this.localName != null) { // And if hash codes match, if (this.hashCode == hashCode) { // And if local names match, if (this.localName.Equals(localName)) { // And if namespaces match, if (this.namespaceName.Equals(ns)) { // Then found duplicate attribute, so mark the attribute as deleted this.localName = null; return true; } } } } return false; } } #if DEBUG private const int DefaultCacheSize = 2; #else private const int DefaultCacheSize = 32; #endif ////// Ensure that attribute array has been created and is large enough for at least one /// additional entry. /// private void EnsureAttributeCache() { if (this.arrAttrs == null) { // Create caching array this.arrAttrs = new AttrNameVal[DefaultCacheSize]; } else if (this.numEntries >= this.arrAttrs.Length) { // Resize caching array Debug.Assert(this.numEntries == this.arrAttrs.Length); AttrNameVal[] arrNew = new AttrNameVal[this.numEntries * 2]; Array.Copy(this.arrAttrs, arrNew, this.numEntries); this.arrAttrs = arrNew; } } } } // 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
- ScrollViewerAutomationPeer.cs
- Native.cs
- Buffer.cs
- brushes.cs
- ConfigXmlElement.cs
- Splitter.cs
- UdpRetransmissionSettings.cs
- ReverseQueryOperator.cs
- adornercollection.cs
- WeakEventTable.cs
- NameValuePair.cs
- tooltip.cs
- PointValueSerializer.cs
- XslUrlEditor.cs
- RoleGroup.cs
- InputDevice.cs
- _SSPIWrapper.cs
- RowBinding.cs
- ExpandButtonVisibilityConverter.cs
- DBBindings.cs
- EventMap.cs
- ActivationServices.cs
- QilSortKey.cs
- ReflectEventDescriptor.cs
- InputScope.cs
- ToolBarButton.cs
- EventManager.cs
- ProcessInputEventArgs.cs
- CodeIdentifiers.cs
- Type.cs
- ListenerChannelContext.cs
- InkCanvasFeedbackAdorner.cs
- SchemaType.cs
- ActiveXMessageFormatter.cs
- ObjectParameterCollection.cs
- WebEventCodes.cs
- DetailsViewPagerRow.cs
- SymbolMethod.cs
- XPathBinder.cs
- CodeArgumentReferenceExpression.cs
- HotSpotCollectionEditor.cs
- Viewport2DVisual3D.cs
- WebBrowserHelper.cs
- MbpInfo.cs
- DbConnectionFactory.cs
- AsnEncodedData.cs
- ObjectKeyFrameCollection.cs
- autovalidator.cs
- SoapUnknownHeader.cs
- InitializationEventAttribute.cs
- PassportAuthentication.cs
- DockPanel.cs
- Encoding.cs
- ExternalCalls.cs
- GradientStopCollection.cs
- StackOverflowException.cs
- x509utils.cs
- DBDataPermissionAttribute.cs
- DataGridRowClipboardEventArgs.cs
- TraceContext.cs
- MD5HashHelper.cs
- SelectionPattern.cs
- Color.cs
- DataContractFormatAttribute.cs
- ProviderCommandInfoUtils.cs
- Win32Interop.cs
- SchemaTableColumn.cs
- DesignerActionMethodItem.cs
- MetaTableHelper.cs
- EdmItemError.cs
- CssTextWriter.cs
- ActiveXHelper.cs
- BuildDependencySet.cs
- XMLSchema.cs
- DragDrop.cs
- FileUtil.cs
- EdmToObjectNamespaceMap.cs
- ReadOnlyKeyedCollection.cs
- DataGridSortCommandEventArgs.cs
- ChannelManager.cs
- PropertyDescriptorGridEntry.cs
- SHA1.cs
- SQLResource.cs
- MouseActionConverter.cs
- TagPrefixAttribute.cs
- Matrix.cs
- ExcludePathInfo.cs
- WebPartConnectionsDisconnectVerb.cs
- Delay.cs
- ClusterRegistryConfigurationProvider.cs
- ReachVisualSerializer.cs
- TreeViewAutomationPeer.cs
- UnitySerializationHolder.cs
- TdsParserStaticMethods.cs
- OracleTimeSpan.cs
- CacheChildrenQuery.cs
- LinqTreeNodeEvaluator.cs
- DbDataReader.cs
- DBAsyncResult.cs
- NullRuntimeConfig.cs