Example #1
0
        /// <summary>
        /// Return a following sibling of the specified node that has the specified type.  If no such
        /// sibling exists, then do not set pageNode or idxNode and return false.
        /// </summary>
        public static bool GetContentSibling(ref XPathNode[] pageNode, ref int idxNode, XPathNodeType typ)
        {
            XPathNode[] page = pageNode;
            int         idx  = idxNode;
            int         mask = XPathNavigatorEx.GetContentKindMask(typ);

            Debug.Assert(pageNode != null && idxNode != 0, "Cannot pass null argument(s)");

            if (page[idx].NodeType != XPathNodeType.Attribute)
            {
                while (true)
                {
                    idx = page[idx].GetSibling(out page);

                    if (idx == 0)
                    {
                        break;
                    }

                    if (((1 << (int)page[idx].NodeType) & mask) != 0)
                    {
                        Debug.Assert(typ != XPathNodeType.Attribute && typ != XPathNodeType.Namespace);
                        pageNode = page;
                        idxNode  = idx;
                        return(true);
                    }
                }
            }

            return(false);
        }
Example #2
0
        /// <summary>
        /// Return the first child of the specified node that has the specified type (must be a content type).  If no such
        /// child exists, then do not set pageNode or idxNode and return false.
        /// </summary>
        public static bool GetContentChild(ref XPathNode[] pageNode, ref int idxNode, XPathNodeType typ)
        {
            XPathNode[] page = pageNode;
            int         idx  = idxNode;
            int         mask;

            Debug.Assert(pageNode != null && idxNode != 0, "Cannot pass null argument(s)");

            // Only check children if at least one content-typed child exists
            if (page[idx].HasContentChild)
            {
                mask = XPathNavigatorEx.GetContentKindMask(typ);

                GetChild(ref page, ref idx);
                do
                {
                    if (((1 << (int)page[idx].NodeType) & mask) != 0)
                    {
                        // Never return attributes, as Attribute is not a content type
                        if (typ == XPathNodeType.Attribute)
                        {
                            return(false);
                        }

                        pageNode = page;
                        idxNode  = idx;
                        return(true);
                    }

                    idx = page[idx].GetSibling(out page);
                }while (idx != 0);
            }

            return(false);
        }
Example #3
0
        /// <summary>
        /// Get the next node that:
        ///   1. Follows the current node in document order (includes descendants, unlike XPath following axis)
        ///   2. Precedes the ending node in document order (if pageEnd is null, then all following nodes in the document are considered)
        ///   3. Has the specified XPathNodeType (but Attributes and Namespaces never match)
        /// If no such node exists, then do not set pageCurrent or idxCurrent and return false.
        /// </summary>
        public static bool GetContentFollowing(ref XPathNode[] pageCurrent, ref int idxCurrent, XPathNode[] pageEnd, int idxEnd, XPathNodeType typ)
        {
            XPathNode[] page = pageCurrent;
            int         idx  = idxCurrent;
            int         mask = XPathNavigatorEx.GetContentKindMask(typ);

            Debug.Assert(pageCurrent != null && idxCurrent != 0, "Cannot pass null argument(s)");
            Debug.Assert(typ != XPathNodeType.Text, "Text should be handled by GetTextFollowing in order to take into account collapsed text.");
            Debug.Assert(page[idx].NodeType != XPathNodeType.Attribute, "Current node should never be an attribute or namespace--caller should handle this case.");

            // Since nodes are laid out in document order on pages, scan them sequentially
            // rather than following sibling/child/parent links.
            idx++;
            do
            {
                if ((object)page == (object)pageEnd && idx <= idxEnd)
                {
                    // Only scan to termination point
                    while (idx != idxEnd)
                    {
                        if (((1 << (int)page[idx].NodeType) & mask) != 0)
                        {
                            goto FoundNode;
                        }
                        idx++;
                    }
                    break;
                }
                else
                {
                    // Scan all nodes in the page
                    while (idx < page[0].PageInfo.NodeCount)
                    {
                        if (((1 << (int)page[idx].NodeType) & mask) != 0)
                        {
                            goto FoundNode;
                        }
                        idx++;
                    }
                }

                page = page[0].PageInfo.NextPage;
                idx  = 1;
            }while (page != null);

            return(false);

FoundNode:
            Debug.Assert(!page[idx].IsAttrNmsp, "GetContentFollowing should never return attributes or namespaces.");

            // Found match
            pageCurrent = page;
            idxCurrent  = idx;
            return(true);
        }
Example #4
0
 /// <summary>
 /// Return true if navigator is positioned to a node of the specified kind.  Whitespace/SignficantWhitespace/Text are
 /// all treated the same (i.e. they all match each other).
 /// </summary>
 public bool IsKindMatch(XPathNodeType typ)
 {
     return(((1 << (int)_pageCurrent[_idxCurrent].NodeType) & XPathNavigatorEx.GetKindMask(typ)) != 0);
 }