コード例 #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 = XPathNavigator.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);
        }
コード例 #2
0
        /// <summary>
        /// Return a previous 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 GetPreviousContentSibling(ref XPathNode[] pageNode, ref int idxNode, XPathNodeType typ)
        {
            XPathNode[] page = pageNode;
            int         idx  = idxNode;
            int         mask = XPathNavigator.GetContentKindMask(typ);

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

            while (true)
            {
                if (!GetPreviousContentSibling(ref page, ref idx))
                {
                    break;
                }

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

            return(false);
        }
コード例 #3
0
        public static bool GetContentChild(ref XPathNode[] pageNode, ref int idxNode, XPathNodeType typ)
        {
            XPathNode[] nodeArray = pageNode;
            int         index     = idxNode;

            if (nodeArray[index].HasContentChild)
            {
                int contentKindMask = XPathNavigator.GetContentKindMask(typ);
                GetChild(ref nodeArray, ref index);
                do
                {
                    if (((((int)1) << nodeArray[index].NodeType) & contentKindMask) != 0)
                    {
                        if (typ == XPathNodeType.Attribute)
                        {
                            return(false);
                        }
                        pageNode = nodeArray;
                        idxNode  = index;
                        return(true);
                    }
                    index = nodeArray[index].GetSibling(out nodeArray);
                }while (index != 0);
            }
            return(false);
        }
コード例 #4
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 = XPathNavigator.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);
        }
コード例 #5
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 = XPathNavigator.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);
        }
コード例 #6
0
        public static bool GetPreviousContentSibling(ref XPathNode[] pageNode, ref int idxNode, XPathNodeType typ)
        {
            XPathNode[] nodeArray       = pageNode;
            int         index           = idxNode;
            int         contentKindMask = XPathNavigator.GetContentKindMask(typ);

            do
            {
                if (!GetPreviousContentSibling(ref nodeArray, ref index))
                {
                    return(false);
                }
            }while (((((int)1) << nodeArray[index].NodeType) & contentKindMask) == 0);
            pageNode = nodeArray;
            idxNode  = index;
            return(true);
        }
コード例 #7
0
        public static bool GetContentFollowing(ref XPathNode[] pageCurrent, ref int idxCurrent, XPathNode[] pageEnd, int idxEnd, XPathNodeType typ)
        {
            XPathNode[] nextPage        = pageCurrent;
            int         index           = idxCurrent;
            int         contentKindMask = XPathNavigator.GetContentKindMask(typ);

            index++;
Label_0012:
            if ((nextPage != pageEnd) || (index > idxEnd))
            {
                while (index < nextPage[0].PageInfo.NodeCount)
                {
                    if (((((int)1) << nextPage[index].NodeType) & contentKindMask) != 0)
                    {
                        goto Label_0081;
                    }
                    index++;
                }
                nextPage = nextPage[0].PageInfo.NextPage;
                index    = 1;
                if (nextPage != null)
                {
                    goto Label_0012;
                }
            }
            else
            {
                while (index != idxEnd)
                {
                    if (((((int)1) << nextPage[index].NodeType) & contentKindMask) != 0)
                    {
                        goto Label_0081;
                    }
                    index++;
                }
            }
            return(false);

Label_0081:
            pageCurrent = nextPage;
            idxCurrent  = index;
            return(true);
        }
コード例 #8
0
        public static bool GetContentSibling(ref XPathNode[] pageNode, ref int idxNode, XPathNodeType typ)
        {
            XPathNode[] nodeArray       = pageNode;
            int         index           = idxNode;
            int         contentKindMask = XPathNavigator.GetContentKindMask(typ);

            if (nodeArray[index].NodeType != XPathNodeType.Attribute)
            {
                do
                {
                    index = nodeArray[index].GetSibling(out nodeArray);
                    if (index == 0)
                    {
                        goto Label_004B;
                    }
                }while (((((int)1) << nodeArray[index].NodeType) & contentKindMask) == 0);
                pageNode = nodeArray;
                idxNode  = index;
                return(true);
            }
Label_004B:
            return(false);
        }
コード例 #9
0
 /// <summary>
 /// Keep only nodes with XPathNodeType = nodeType, where XPathNodeType.Text selects whitespace as well.
 /// </summary>
 private XmlNavTypeFilter(XPathNodeType nodeType)
 {
     Debug.Assert(nodeType != XPathNodeType.Attribute && nodeType != XPathNodeType.Namespace);
     this.nodeType = nodeType;
     this.mask     = XPathNavigator.GetContentKindMask(nodeType);
 }
コード例 #10
0
 public bool IsContentKindMatch(XPathNodeType typ)
 {
     return(((((int)1) << this.pageCurrent[this.idxCurrent].NodeType) & XPathNavigator.GetContentKindMask(typ)) != 0);
 }