internal SeekableMessageNavigator(SeekableMessageNavigator nav) { this.counter = nav.counter; this.dom = nav.dom; this.location = nav.location; this.specialParent = nav.specialParent; if (this.specialParent != 0) { this.nsStack = nav.CloneNSStack(); } }
// Move this navigator to the same position as the given one internal bool MoveTo(SeekableMessageNavigator nav) { if (nav == null) { return false; } this.dom = nav.dom; this.counter = nav.counter; this.location = nav.location; this.specialParent = nav.specialParent; if (this.specialParent != NullIndex) { this.nsStack = nav.CloneNSStack(); } return true; }
// Tests whether the given navigator is positioned on the same node as this navigator internal bool IsSamePosition(SeekableMessageNavigator nav) { if (nav == null) { return false; } return this.dom == nav.dom && this.location == nav.location && this.specialParent == nav.specialParent; }
// Test whether the given navigator is positioned on a descendant of this navigator internal bool IsDescendant(SeekableMessageNavigator nav) { if (nav == null) { return false; } if (this.dom != nav.dom) { return false; } // Namespaces and attributes are not considered descendants XPathNodeType type = this.dom.nodes[nav.location].type; if (type == XPathNodeType.Namespace || type == XPathNodeType.Attribute) { return false; } // Namespaces and attributes are not parents type = this.dom.nodes[this.location].type; if (type == XPathNodeType.Namespace || type == XPathNodeType.Attribute) { return false; } // Climb up the tree looking for the current navigator's position int n = nav.location; while (n != NullIndex) { Increase(); n = this.dom.nodes[n].parent; if (n == this.location) { return true; } } return false; }
// Compare the current position to that of another navigator. internal XmlNodeOrder ComparePosition(SeekableMessageNavigator nav) { if (nav == null) { return XmlNodeOrder.Unknown; } if (this.dom != nav.dom) { return XmlNodeOrder.Unknown; } return this.dom.ComparePosition(this.specialParent, this.location, nav.specialParent, nav.location); }
internal SeekableMessageNavigator(SeekableMessageNavigator nav) { Fx.Assert(nav != null, "Navigator may not be null"); this.counter = nav.counter; this.dom = nav.dom; this.location = nav.location; this.specialParent = nav.specialParent; if (this.specialParent != NullIndex) { this.nsStack = nav.CloneNSStack(); } }
// THREAD: Synchronize this function if multiple threads can try to re-initialize an instance at the same time. Also, if you reinitialize the navigator that holds information referenced by clones, the clones will be affected as well. internal void Init(Message msg, int countMax, XmlSpace space, bool includeBody, bool atomize) { Fx.Assert(countMax > 0, "Maximum node count must be greater than zero"); this.counter = this; this.nodeCount = countMax; this.nodeCountMax = countMax; Fx.Assert(msg != null, "Message may not be null"); this.dom = this; this.location = RootIndex; this.specialParent = NullIndex; this.includeBody = includeBody; this.message = msg; this.headers = msg.Headers; this.space = space; this.atomize = false; // Will get fixed at the end of this function int minSize = msg.Headers.Count + FirstHeaderIndex + 1; if (this.nodes == null || this.nodes.Length < minSize) { this.nodes = new Node[minSize + StartSize]; } else { Array.Clear(this.nodes, 1, this.nextFreeIndex - 1); } this.bodyIndex = minSize - 1; this.nextFreeIndex = minSize; // Use the static blank DOM to create the first few nodes Array.Copy(BlankDom, this.nodes, HeaderIndex + 1); string soapNS = msg.Version.Envelope.Namespace; this.nodes[EnvelopeIndex].ns = soapNS; this.nodes[SoapNSIndex].val = soapNS; this.nodes[HeaderIndex].ns = soapNS; this.nodes[HeaderIndex].nextSibling = bodyIndex; this.nodes[HeaderIndex].firstChild = this.bodyIndex != FirstHeaderIndex ? FirstHeaderIndex : NullIndex; // Headers if (msg.Headers.Count > 0) { for (int i = FirstHeaderIndex, h = 0; h < msg.Headers.Count; ++i, ++h) { this.nodes[i].type = XPathNodeType.Element; this.nodes[i].parent = HeaderIndex; this.nodes[i].nextSibling = i + 1; this.nodes[i].prevSibling = i - 1; // Extract the header block stub data MessageHeaderInfo header = msg.Headers[h]; this.nodes[i].ns = header.Namespace; this.nodes[i].name = header.Name; this.nodes[i].firstChild = -1; } this.nodes[FirstHeaderIndex].prevSibling = NullIndex; this.nodes[this.bodyIndex - 1].nextSibling = NullIndex; } // Body this.nodes[bodyIndex].type = XPathNodeType.Element; this.nodes[bodyIndex].prefix = SoapP; this.nodes[bodyIndex].ns = soapNS; this.nodes[bodyIndex].name = BodyTag; this.nodes[bodyIndex].parent = EnvelopeIndex; this.nodes[bodyIndex].prevSibling = HeaderIndex; this.nodes[bodyIndex].firstNamespace = SoapNSIndex; this.nodes[bodyIndex].firstChild = -1; // Need to load // Atomize if (atomize) { Atomize(); } }
// Set a new count for this navigator // Set it to use itself for the counter so all clones of it will share the new counter internal void ForkNodeCount(int count) { Fx.Assert(count > 0, "Maximum node count must be greater than zero"); this.nodeCount = count; this.nodeCountMax = count; this.counter = this; }
internal bool IsDescendant(SeekableMessageNavigator nav) { if (nav != null) { if (this.dom != nav.dom) { return false; } switch (this.dom.nodes[nav.location].type) { case XPathNodeType.Namespace: case XPathNodeType.Attribute: return false; } switch (this.dom.nodes[this.location].type) { case XPathNodeType.Namespace: case XPathNodeType.Attribute: return false; } int location = nav.location; while (location != 0) { this.Increase(); location = this.dom.nodes[location].parent; if (location == this.location) { return true; } } } return false; }
internal void Init(System.ServiceModel.Channels.Message msg, int countMax, XmlSpace space, bool includeBody, bool atomize) { this.counter = this; this.nodeCount = countMax; this.nodeCountMax = countMax; this.dom = this; this.location = 1; this.specialParent = 0; this.includeBody = includeBody; this.message = msg; this.headers = msg.Headers; this.space = space; this.atomize = false; int num = (msg.Headers.Count + 6) + 1; if ((this.nodes == null) || (this.nodes.Length < num)) { this.nodes = new Node[num + 50]; } else { Array.Clear(this.nodes, 1, this.nextFreeIndex - 1); } this.bodyIndex = num - 1; this.nextFreeIndex = num; Array.Copy(BlankDom, this.nodes, 6); string str = msg.Version.Envelope.Namespace; this.nodes[2].ns = str; this.nodes[3].val = str; this.nodes[5].ns = str; this.nodes[5].nextSibling = this.bodyIndex; this.nodes[5].firstChild = (this.bodyIndex != 6) ? 6 : 0; if (msg.Headers.Count > 0) { int index = 6; for (int i = 0; i < msg.Headers.Count; i++) { this.nodes[index].type = XPathNodeType.Element; this.nodes[index].parent = 5; this.nodes[index].nextSibling = index + 1; this.nodes[index].prevSibling = index - 1; MessageHeaderInfo info = msg.Headers[i]; this.nodes[index].ns = info.Namespace; this.nodes[index].name = info.Name; this.nodes[index].firstChild = -1; index++; } this.nodes[6].prevSibling = 0; this.nodes[this.bodyIndex - 1].nextSibling = 0; } this.nodes[this.bodyIndex].type = XPathNodeType.Element; this.nodes[this.bodyIndex].prefix = "s"; this.nodes[this.bodyIndex].ns = str; this.nodes[this.bodyIndex].name = "Body"; this.nodes[this.bodyIndex].parent = 2; this.nodes[this.bodyIndex].prevSibling = 5; this.nodes[this.bodyIndex].firstNamespace = 3; this.nodes[this.bodyIndex].firstChild = -1; if (atomize) { this.Atomize(); } }
internal void ForkNodeCount(int count) { this.nodeCount = count; this.nodeCountMax = count; this.counter = this; }