/// <summary>Given a prefix mapping for a specific URI, this returns /// the prefix mapping previously in effect for the same URI.</summary> /// <remarks>This can be used to iterate backwards through the stack of /// prefix mappings for a given URI.</remarks> /// <param name="prefix"><see cref="ActiveMapping"/> instance for which /// we want to find the instance previously in effect with the same URI.</param> /// <returns><see cref="ActiveMapping"/> instance to look for, /// or <c>null</c> if none exists.</returns> public ActiveMapping PreviousUriMapping(ActiveMapping prefix) { string uri = prefix.Uri; // check active mapping record NamespaceMapping nsMapping = prefix.mappingsTop; if (nsMapping == null || !nsMapping.declared) { string msg = Resources.GetString(RsId.UndeclaredMapping); throw new XmlNamespacesException(String.Format(msg, prefix.Prefix)); } // find a parent scope where the same URI maps to an "active" prefix NamespaceScope scope = nsMapping.scope.parent; while (scope != null) { nsMapping = scope.FindByUri(uri); if (nsMapping != null) { ActiveMapping result = nsMapping.prefix; // result must be different from prefix, since the same prefix // cannot be "declared" with two different URIs at the same time if (result.IsDeclared) { Debug.Assert(result != prefix, Resources.GetString(RsId.InternalNsError)); return(result); } } scope = scope.parent; } return(null); }
// Returns ActiveMapping instance properly initialized for new use, // re-using old instance if possible. internal ActiveMapping NewActiveMapping(string prefix) { if (freeActiveMappings == null) { return(new ActiveMapping(prefix, this)); } else { ActiveMapping result = freeActiveMappings; freeActiveMappings = result.next; result.Init(prefix); return(result); } }
/// <summary> Indicates if a mapping for a given prefix has been added /// to this scope, even if only to "undeclare" the prefix.</summary> /// <param name="prefix"><see cref="ActiveMapping"/> instance associated with prefix.</param> /// <returns><c>true</c> if mapping has ben added, <c>false</c> otherwise.</returns> public bool InScope(ActiveMapping prefix) { NamespaceMapping nsMapping; Stack <NamespaceMapping> .Enumerator iter = nsMappings.GetEnumerator(); while (iter.MoveNext()) { nsMapping = iter.Current; if (nsMapping.prefix == prefix) { return(true); } } return(false); }
/// <summary>Releases all prefix mappings and returns them to the /// associated <see cref="XmlNamespaces"/> object for re-use.</summary> /// <remarks>Must not be called unless this instance is the most recent scope, /// that is, is the last scope in which <see cref="AddMapping"/> was called, /// otherwise the state of affected <see cref="ActiveMapping"/> instances /// will get corrupted.</remarks> protected internal void ClearMappings() { Debug.Assert(namespaces.IsLastScope(this), Resources.GetString(RsId.InternalNsError)); NamespaceMapping nsMapping; ActiveMapping activeMapping; // returns mapping records back to Namespaces for re-use while (nsMappings.Count != 0) { nsMapping = (NamespaceMapping)nsMappings.Pop(); Debug.Assert(nsMapping != null, Resources.GetString(RsId.InternalNsError)); nsMapping.prefix.PopMapping(); } // returns ActiveMapping objects back for re-use while ((activeMapping = mappings) != null) { mappings = activeMapping.next; activeMapping.Reset(); namespaces.ReturnActiveMapping(activeMapping); } }
/// <summary> Adds a namespace mapping to this scope.</summary> /// <remarks>To undeclare the namespace mapping for a given prefix, /// pass <c>null</c> as <c>uri</c> argument.</remarks> /// <param name="prefix">Prefix part of namespace mapping.</param> /// <param name="uri">URI part of namespace mapping.</param> /// <returns>The newly added <see cref="NamespaceMapping"/> instance, or <c>null</c> /// if it already exists.</returns> protected internal NamespaceMapping AddMapping(string prefix, string uri) { // find prefix mapping in use ActiveMapping activeMapping = namespaces.GetPrefixMapping(prefix); // if not in use, re-use existing instance if possible if (activeMapping == null) { activeMapping = namespaces.NewActiveMapping(prefix); // since we have acquired an unused ActiveMapping instance we need // to keep track of it so that we can give it back later for re-use activeMapping.next = mappings; mappings = activeMapping; } else if (InScope(activeMapping)) // duplicate found { return(null); } NamespaceMapping result = activeMapping.PushMapping(uri, this); nsMappings.Push(result); return(result); }
// Accepts ActiveMapping instance that is no longer needed, storing it // for re-use. Note: do not pass null argument - this is not checked. internal void ReturnActiveMapping(ActiveMapping mapping) { mapping.next = freeActiveMappings; freeActiveMappings = mapping; }
// Returns ActiveMapping instance properly initialized for new use, // re-using old instance if possible. internal ActiveMapping NewActiveMapping(string prefix) { if (freeActiveMappings == null) return new ActiveMapping(prefix, this); else { ActiveMapping result = freeActiveMappings; freeActiveMappings = result.next; result.Init(prefix); return result; } }
/// <summary>Given a prefix mapping for a specific URI, this returns /// the prefix mapping previously in effect for the same URI.</summary> /// <remarks>This can be used to iterate backwards through the stack of /// prefix mappings for a given URI.</remarks> /// <param name="prefix"><see cref="ActiveMapping"/> instance for which /// we want to find the instance previously in effect with the same URI.</param> /// <returns><see cref="ActiveMapping"/> instance to look for, /// or <c>null</c> if none exists.</returns> public ActiveMapping PreviousUriMapping(ActiveMapping prefix) { string uri = prefix.Uri; // check active mapping record NamespaceMapping nsMapping = prefix.mappingsTop; if (nsMapping == null || !nsMapping.declared) { string msg = Resources.GetString(RsId.UndeclaredMapping); throw new XmlNamespacesException(String.Format(msg, prefix.Prefix)); } // find a parent scope where the same URI maps to an "active" prefix NamespaceScope scope = nsMapping.scope.parent; while (scope != null) { nsMapping = scope.FindByUri(uri); if (nsMapping != null) { ActiveMapping result = nsMapping.prefix; // result must be different from prefix, since the same prefix // cannot be "declared" with two different URIs at the same time if (result.IsDeclared) { Debug.Assert(result != prefix, Resources.GetString(RsId.InternalNsError)); return result; } } scope = scope.parent; } return null; }
/// <summary> Adds a namespace mapping to this scope.</summary> /// <remarks>To undeclare the namespace mapping for a given prefix, /// pass <c>null</c> as <c>uri</c> argument.</remarks> /// <param name="prefix">Prefix part of namespace mapping.</param> /// <param name="uri">URI part of namespace mapping.</param> /// <returns>The newly added <see cref="NamespaceMapping"/> instance, or <c>null</c> /// if it already exists.</returns> protected internal NamespaceMapping AddMapping(string prefix, string uri) { // find prefix mapping in use ActiveMapping activeMapping = namespaces.GetPrefixMapping(prefix); // if not in use, re-use existing instance if possible if (activeMapping == null) { activeMapping = namespaces.NewActiveMapping(prefix); // since we have acquired an unused ActiveMapping instance we need // to keep track of it so that we can give it back later for re-use activeMapping.next = mappings; mappings = activeMapping; } else if (InScope(activeMapping)) // duplicate found return null; NamespaceMapping result = activeMapping.PushMapping(uri, this); nsMappings.Push(result); return result; }
/// <summary> Indicates if a mapping for a given prefix has been added /// to this scope, even if only to "undeclare" the prefix.</summary> /// <param name="prefix"><see cref="ActiveMapping"/> instance associated with prefix.</param> /// <returns><c>true</c> if mapping has ben added, <c>false</c> otherwise.</returns> public bool InScope(ActiveMapping prefix) { NamespaceMapping nsMapping; Stack<NamespaceMapping>.Enumerator iter = nsMappings.GetEnumerator(); while (iter.MoveNext()) { nsMapping = iter.Current; if (nsMapping.prefix == prefix) return true; } return false; }
/// <summary>Initializes <see cref="ActiveMapping"/> instance for re-use /// with a different prefix.</summary> /// <param name="prefix">Prefix to be associated with this instance.</param> protected internal void Init(string prefix) { this.prefix = prefix; next = null; }