internal XmlNodeOrder ComparePosition(XPathNodePointer other)
{
RealFoliate();
other.RealFoliate();
Debug.Assert(other != null);
if (IsSamePosition(other))
return XmlNodeOrder.Same;
XmlNode curNode1 = null, curNode2 = null;
//deal with namespace node first
if (NodeType == XPathNodeType.Namespace && other.NodeType == XPathNodeType.Namespace)
{
if (_parentOfNS == other._parentOfNS)
return CompareNamespacePosition(other);
//if not from the same parent
curNode1 = _parentOfNS;
curNode2 = other._parentOfNS;
}
else if (NodeType == XPathNodeType.Namespace)
{
Debug.Assert(other.NodeType != XPathNodeType.Namespace);
if (_parentOfNS == other._node)
{
//from the same region, NS nodes come before all other nodes
if (other._column == null)
return XmlNodeOrder.After;
else
return XmlNodeOrder.Before;
}
//if not from the same region
curNode1 = _parentOfNS;
curNode2 = other._node;
}
else if (other.NodeType == XPathNodeType.Namespace)
{
Debug.Assert(NodeType != XPathNodeType.Namespace);
if (_node == other._parentOfNS)
{
//from the same region
if (_column == null)
return XmlNodeOrder.Before;
else
return XmlNodeOrder.After;
}
//if not from the same region
curNode1 = _node;
curNode2 = other._parentOfNS;
}
else
{
if (_node == other._node)
{
//compare within the same region
if (_column == other._column)
{
//one is the children of the other
Debug.Assert(_fOnValue != other._fOnValue);
if (_fOnValue)
return XmlNodeOrder.After;
else
return XmlNodeOrder.Before;
}
else
{
Debug.Assert(Row == other.Row); //in the same row
if (_column == null)
return XmlNodeOrder.Before;
else if (other._column == null)
return XmlNodeOrder.After;
else if (_column.Ordinal < other._column.Ordinal)
return XmlNodeOrder.Before;
else
return XmlNodeOrder.After;
}
}
curNode1 = _node;
curNode2 = other._node;
}
Debug.Assert(curNode1 != null);
Debug.Assert(curNode2 != null);
if (curNode1 == null || curNode2 == null)
{
return XmlNodeOrder.Unknown;
}
int depth1 = -1, depth2 = -1;
XmlNode root1 = XPathNodePointer.GetRoot(curNode1, ref depth1);
XmlNode root2 = XPathNodePointer.GetRoot(curNode2, ref depth2);
if (root1 != root2)
return XmlNodeOrder.Unknown;
if (depth1 > depth2)
{
while (curNode1 != null && depth1 > depth2)
{
curNode1 = ((curNode1.NodeType == XmlNodeType.Attribute) ? (((XmlAttribute)curNode1).OwnerElement) : (curNode1.ParentNode));
depth1--;
}
if (curNode1 == curNode2)
return XmlNodeOrder.After;
}
else if (depth2 > depth1)
{
while (curNode2 != null && depth2 > depth1)
{
curNode2 = ((curNode2.NodeType == XmlNodeType.Attribute) ? (((XmlAttribute)curNode2).OwnerElement) : (curNode2.ParentNode));
depth2--;
}
if (curNode1 == curNode2)
return XmlNodeOrder.Before;
}
XmlNode parent1 = GetParent(curNode1);
XmlNode parent2 = GetParent(curNode2);
XmlNode nextNode = null;
while (parent1 != null && parent2 != null)
{
if (parent1 == parent2)
{
while (curNode1 != null)
{
nextNode = curNode1.NextSibling;
if (nextNode == curNode2)
return XmlNodeOrder.Before;
curNode1 = nextNode;
}
return XmlNodeOrder.After;
}
curNode1 = parent1;
curNode2 = parent2;
parent1 = curNode1.ParentNode;
parent2 = curNode2.ParentNode;
}
//logically, we shouldn't reach here
Debug.Assert(false);
return XmlNodeOrder.Unknown;
}