Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAtsushi Eno <atsushieno@gmail.com>2005-03-22 10:04:18 +0300
committerAtsushi Eno <atsushieno@gmail.com>2005-03-22 10:04:18 +0300
commit15c121125e04e72d072c55656ed80545d2118ed6 (patch)
treeaba14fcede8bcc55f05cbfd02b08a75f7e5419b6 /mcs/class/System.XML/Mono.Xml.XPath
parent71fe4a042410cedd8ec11ba321b37856d3870956 (diff)
2004-03-22 Atsushi Enomoto <atsushi@ximian.com>
* DTMXPathDocumentBuilder.cs, DTMXPathDocumentWriter.cs, DTMXPathNavigator.cs, DTMXPathNode.cs : updated to be equivalent to DTMXPathNavigator2. * DTMXPathDocumentBuilder2.cs : String pool is now under index based management. For nonAtomicIndex string, don't try all the entries the pool holds. It causes significant performance loss for large documents. * DTMXPathDocument.cs, DTMXPathDocument2.cs : removed unused fields (warning elimination). svn path=/trunk/mcs/; revision=42057
Diffstat (limited to 'mcs/class/System.XML/Mono.Xml.XPath')
-rw-r--r--mcs/class/System.XML/Mono.Xml.XPath/ChangeLog13
-rw-r--r--mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument.cs44
-rwxr-xr-xmcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument2.cs37
-rw-r--r--mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder.cs128
-rwxr-xr-xmcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder2.cs65
-rwxr-xr-xmcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentWriter.cs95
-rw-r--r--mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNavigator.cs67
-rw-r--r--mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNode.cs1
8 files changed, 191 insertions, 259 deletions
diff --git a/mcs/class/System.XML/Mono.Xml.XPath/ChangeLog b/mcs/class/System.XML/Mono.Xml.XPath/ChangeLog
index 087e19444a8..d0d8a26695d 100644
--- a/mcs/class/System.XML/Mono.Xml.XPath/ChangeLog
+++ b/mcs/class/System.XML/Mono.Xml.XPath/ChangeLog
@@ -1,3 +1,16 @@
+2004-03-22 Atsushi Enomoto <atsushi@ximian.com>
+
+ * DTMXPathDocumentBuilder.cs,
+ DTMXPathDocumentWriter.cs,
+ DTMXPathNavigator.cs,
+ DTMXPathNode.cs : updated to be equivalent to DTMXPathNavigator2.
+ * DTMXPathDocumentBuilder2.cs :
+ String pool is now under index based management. For nonAtomicIndex
+ string, don't try all the entries the pool holds. It causes
+ significant performance loss for large documents.
+ * DTMXPathDocument.cs,
+ DTMXPathDocument2.cs : removed unused fields (warning elimination).
+
2004-03-16 Atsushi Enomoto <atsushi@ximian.com>
* Pattern.cs : fixed incorrect optimization.
diff --git a/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument.cs b/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument.cs
index d7b2911e1ca..4f0a80112c1 100644
--- a/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument.cs
+++ b/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument.cs
@@ -42,56 +42,26 @@ namespace Mono.Xml.XPath
class DTMXPathDocument : IXPathNavigable
{
-#region ctor.
-
public DTMXPathDocument (XmlNameTable nameTable,
DTMXPathLinkedNode [] nodes,
DTMXPathAttributeNode [] attributes,
DTMXPathNamespaceNode [] namespaces,
Hashtable idTable)
{
- this.nameTable = nameTable;
- this.nodes = nodes;
- this.attributes = attributes;
- this.namespaces = namespaces;
- this.idTable = idTable;
+ root = new DTMXPathNavigator (this,
+ nameTable,
+ nodes,
+ attributes,
+ namespaces,
+ idTable);
}
-#endregion
-
-
-#region Methods
public XPathNavigator CreateNavigator ()
{
- if (root == null) {
- root = new DTMXPathNavigator (this,
- nameTable,
- nodes,
- attributes,
- namespaces,
- idTable);
- }
return root.Clone ();
}
-#endregion
-
- XmlNameTable nameTable;
-
- // Root XPathNavigator.
- DTMXPathNavigator root;
-
-#region Immutable tree fields
-
- DTMXPathLinkedNode [] nodes = new DTMXPathLinkedNode [0];
- DTMXPathAttributeNode [] attributes = new DTMXPathAttributeNode [0];
- DTMXPathNamespaceNode [] namespaces = new DTMXPathNamespaceNode [0];
-
- // idTable [string value] -> int nodeId
- readonly Hashtable idTable;
-
-#endregion
-
+ XPathNavigator root;
}
}
diff --git a/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument2.cs b/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument2.cs
index b51e8a5a6ce..43fa3d80759 100755
--- a/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument2.cs
+++ b/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument2.cs
@@ -42,8 +42,6 @@ namespace Mono.Xml.XPath
class DTMXPathDocument2 : IXPathNavigable
{
-#region ctor.
-
public DTMXPathDocument2 (XmlNameTable nameTable,
DTMXPathLinkedNode2 [] nodes,
DTMXPathAttributeNode2 [] attributes,
@@ -52,14 +50,6 @@ namespace Mono.Xml.XPath
string [] nonAtomicStringPool,
Hashtable idTable)
{
- this.nameTable = nameTable;
- this.nodes = nodes;
- this.attributes = attributes;
- this.namespaces = namespaces;
- this.atomicStringPool = atomicStringPool;
- this.nonAtomicStringPool = nonAtomicStringPool;
- this.idTable = idTable;
-
root = new DTMXPathNavigator2 (this,
nameTable,
nodes,
@@ -70,37 +60,12 @@ namespace Mono.Xml.XPath
idTable);
}
-#endregion
-
-
-#region Methods
public XPathNavigator CreateNavigator ()
{
return root.Clone ();
}
-#endregion
-
- readonly XmlNameTable nameTable;
-
- // Root XPathNavigator.
- readonly DTMXPathNavigator2 root;
-
-#region Immutable tree fields
-
- readonly DTMXPathLinkedNode2 [] nodes;
- readonly DTMXPathAttributeNode2 [] attributes;
- readonly DTMXPathNamespaceNode2 [] namespaces;
-
- // String pool
- readonly string [] atomicStringPool;
- readonly string [] nonAtomicStringPool;
-
- // idTable [string value] -> int nodeId
- readonly Hashtable idTable;
-
-#endregion
-
+ XPathNavigator root;
}
}
diff --git a/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder.cs b/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder.cs
index 65bb3c35aae..b635a6360be 100644
--- a/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder.cs
+++ b/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder.cs
@@ -91,11 +91,12 @@ namespace Mono.Xml.XPath
this.nameTable = reader.NameTable;
nodeCapacity = defaultCapacity;
attributeCapacity = nodeCapacity;
+ nsCapacity = 10;
idTable = new Hashtable ();
nodes = new DTMXPathLinkedNode [nodeCapacity];
attributes = new DTMXPathAttributeNode [attributeCapacity];
- namespaces = new DTMXPathNamespaceNode [0];
+ namespaces = new DTMXPathNamespaceNode [nsCapacity];
Compile ();
}
@@ -105,9 +106,9 @@ namespace Mono.Xml.XPath
XmlSpace xmlSpace;
XmlNameTable nameTable;
IXmlLineInfo lineInfo;
- int nodeCapacity = 200;
- int attributeCapacity = 200;
- int nsCapacity = 10;
+ int nodeCapacity;
+ int attributeCapacity;
+ int nsCapacity;
// Linked Node
DTMXPathLinkedNode [] nodes;
@@ -124,18 +125,19 @@ namespace Mono.Xml.XPath
int nodeIndex;
int attributeIndex;
int nsIndex;
- int parentForFirstChild;
// for attribute processing; should be reset per each element.
- int firstAttributeIndex;
- int lastNsIndexInCurrent;
+ bool hasAttributes;
+ bool hasLocalNs;
int attrIndexAtStart;
int nsIndexAtStart;
- int prevSibling;
int lastNsInScope;
bool skipRead = false;
+ int [] parentStack = new int [10];
+ int parentStackIndex = 0;
+
public DTMXPathDocument CreateDocument ()
{
return new DTMXPathDocument (nameTable,
@@ -151,7 +153,7 @@ namespace Mono.Xml.XPath
// index 0 is dummy. No node (including Root) is assigned to this index
// So that we can easily compare index != 0 instead of index < 0.
// (Difference between jnz or jbe in 80x86.)
- AddNode (0, 0, 0, 0, XPathNodeType.All, "", false, "", "", "", "", "", 0, 0, 0);
+ AddNode (0, 0, 0, XPathNodeType.All, "", false, "", "", "", "", "", 0, 0, 0);
nodeIndex++;
AddAttribute (0, null, null, null, null, 0, 0);
AddNsNode (0, null, null, 0);
@@ -159,11 +161,11 @@ namespace Mono.Xml.XPath
AddNsNode (1, "xml", XmlNamespaces.XML, 0);
// add root.
- AddNode (0, 0, 0, -1, XPathNodeType.Root, xmlReader.BaseURI, false, "", "", "", "", "", 1, 0, 0);
+ AddNode (0, 0, 0, XPathNodeType.Root, xmlReader.BaseURI, false, "", "", "", "", "", 1, 0, 0);
this.nodeIndex = 1;
this.lastNsInScope = 1;
- this.parentForFirstChild = nodeIndex;
+ parentStack [0] = nodeIndex;
while (!xmlReader.EOF)
Read ();
@@ -180,15 +182,9 @@ namespace Mono.Xml.XPath
if (!xmlReader.Read ())
return;
skipRead = false;
- int parent = nodeIndex;
-
- if (nodes [nodeIndex].Depth >= xmlReader.Depth) {
- // if not, then current node is parent.
- while (xmlReader.Depth <= nodes [parent].Depth)
- parent = nodes [parent].Parent;
- }
+ int parent = parentStack [parentStackIndex];
+ int prevSibling = nodeIndex;
- prevSibling = nodeIndex;
switch (xmlReader.NodeType) {
case XmlNodeType.Element:
case XmlNodeType.CDATA:
@@ -196,17 +192,17 @@ namespace Mono.Xml.XPath
case XmlNodeType.Comment:
case XmlNodeType.Text:
case XmlNodeType.ProcessingInstruction:
- if (parentForFirstChild >= 0)
+ if (parent == nodeIndex)
prevSibling = 0;
else
- while (nodes [prevSibling].Depth != xmlReader.Depth)
+ while (nodes [prevSibling].Parent != parent)
prevSibling = nodes [prevSibling].Parent;
nodeIndex++;
if (prevSibling != 0)
nodes [prevSibling].NextSibling = nodeIndex;
- if (parentForFirstChild >= 0)
+ if (parentStack [parentStackIndex] == nodeIndex - 1)
nodes [parent].FirstChild = nodeIndex;
break;
case XmlNodeType.Whitespace:
@@ -215,33 +211,31 @@ namespace Mono.Xml.XPath
else
goto default;
case XmlNodeType.EndElement:
- parentForFirstChild = -1;
+ parentStackIndex--;
return;
default:
// No operations. Doctype, EntityReference,
return;
}
- parentForFirstChild = -1; // Might be changed in ProcessElement().
-
string value = null;
- XPathNodeType nodeType = xmlReader.NodeType == XmlNodeType.Whitespace ?
- XPathNodeType.Whitespace : XPathNodeType.Text;
+ XPathNodeType nodeType = XPathNodeType.Text;
switch (xmlReader.NodeType) {
case XmlNodeType.Element:
ProcessElement (parent, prevSibling);
break;
- case XmlNodeType.CDATA:
case XmlNodeType.SignificantWhitespace:
- case XmlNodeType.Text:
+ nodeType = XPathNodeType.SignificantWhitespace;
+ goto case XmlNodeType.Text;
case XmlNodeType.Whitespace:
- if (value == null)
- skipRead = true;
+ nodeType = XPathNodeType.Whitespace;
+ goto case XmlNodeType.Text;
+ case XmlNodeType.CDATA:
+ case XmlNodeType.Text:
AddNode (parent,
0,
prevSibling,
- xmlReader.Depth,
nodeType,
xmlReader.BaseURI,
xmlReader.IsEmptyElement,
@@ -253,10 +247,37 @@ namespace Mono.Xml.XPath
nsIndex,
lineInfo != null ? lineInfo.LineNumber : 0,
lineInfo != null ? lineInfo.LinePosition : 0);
- // this code is tricky, but after ReadString() invokation,
- // xmlReader is moved to next node!!
- if (value == null)
- nodes [nodeIndex].Value = xmlReader.ReadString ();
+ // this code is tricky, but after sequential
+ // Read() invokation, xmlReader is moved to
+ // next node.
+ if (value == null) {
+ bool loop = true;
+ value = String.Empty;
+ XPathNodeType type = XPathNodeType.Whitespace;
+ do {
+ switch (xmlReader.NodeType) {
+ case XmlNodeType.Text:
+ case XmlNodeType.CDATA:
+ type = XPathNodeType.Text;
+ goto case XmlNodeType.Whitespace;
+ case XmlNodeType.SignificantWhitespace:
+ if (type == XPathNodeType.Whitespace)
+ type = XPathNodeType.SignificantWhitespace;
+ goto case XmlNodeType.Whitespace;
+ case XmlNodeType.Whitespace:
+ if (xmlReader.NodeType != XmlNodeType.Whitespace || xmlSpace == XmlSpace.Preserve)
+ value += xmlReader.Value;
+ loop = xmlReader.Read ();
+ skipRead = true;
+ continue;
+ default:
+ loop = false;
+ break;
+ }
+ } while (loop);
+ nodes [nodeIndex].Value = value;
+ nodes [nodeIndex].NodeType = type;
+ }
break;
case XmlNodeType.Comment:
value = xmlReader.Value;
@@ -292,8 +313,8 @@ namespace Mono.Xml.XPath
private void PrepareStartElement (int previousSibling)
{
- firstAttributeIndex = 0;
- lastNsIndexInCurrent = 0;
+ hasAttributes = false;
+ hasLocalNs = false;
attrIndexAtStart = attributeIndex;
nsIndexAtStart = nsIndex;
@@ -309,7 +330,6 @@ namespace Mono.Xml.XPath
AddNode (parent,
0, // dummy:firstAttribute
previousSibling,
- xmlReader.Depth,
XPathNodeType.Element,
xmlReader.BaseURI,
xmlReader.IsEmptyElement,
@@ -330,24 +350,33 @@ namespace Mono.Xml.XPath
nodes [nodeIndex].FirstAttribute = attrIndexAtStart + 1;
if (nsIndexAtStart != nsIndex) {
nodes [nodeIndex].FirstNamespace = nsIndex;
- lastNsInScope = nsIndex;
+ if (!xmlReader.IsEmptyElement)
+ lastNsInScope = nsIndex;
}
- if (!nodes [nodeIndex].IsEmptyElement)
- parentForFirstChild = nodeIndex;
+ if (!nodes [nodeIndex].IsEmptyElement) {
+ parentStackIndex++;
+ if (parentStack.Length == parentStackIndex) {
+ int [] tmp = new int [parentStackIndex * 2];
+ Array.Copy (parentStack, tmp, parentStackIndex);
+ parentStack = tmp;
+ }
+ parentStack [parentStackIndex] = nodeIndex;
+ }
}
private void ProcessNamespace (string prefix, string ns)
{
- nsIndex++;
+ int nextTmp = hasLocalNs ?
+ nsIndex : nodes [nodeIndex].FirstNamespace;
- int nextTmp = lastNsIndexInCurrent == 0 ? nodes [nodeIndex].FirstNamespace : lastNsIndexInCurrent;
+ nsIndex++;
this.AddNsNode (nodeIndex,
prefix,
ns,
nextTmp);
- lastNsIndexInCurrent = nsIndex;
+ hasLocalNs = true;
}
private void ProcessAttribute (string prefix, string localName, string ns, string value)
@@ -361,10 +390,10 @@ namespace Mono.Xml.XPath
value,
lineInfo != null ? lineInfo.LineNumber : 0,
lineInfo != null ? lineInfo.LinePosition : 0);
- if (firstAttributeIndex == 0)
- firstAttributeIndex = attributeIndex;
- else
+ if (hasAttributes)
attributes [attributeIndex - 1].NextAttribute = attributeIndex;
+ else
+ hasAttributes = true;
// Identity infoset
if (validatingReader != null) {
@@ -403,7 +432,7 @@ namespace Mono.Xml.XPath
}
// Here followings are skipped: firstChild, nextSibling,
- public void AddNode (int parent, int firstAttribute, int previousSibling, int depth, XPathNodeType nodeType, string baseUri, bool isEmptyElement, string localName, string ns, string prefix, string value, string xmlLang, int namespaceNode, int lineNumber, int linePosition)
+ public void AddNode (int parent, int firstAttribute, int previousSibling, XPathNodeType nodeType, string baseUri, bool isEmptyElement, string localName, string ns, string prefix, string value, string xmlLang, int namespaceNode, int lineNumber, int linePosition)
{
if (nodes.Length < nodeIndex + 1) {
nodeCapacity *= 4;
@@ -418,7 +447,6 @@ namespace Mono.Xml.XPath
nodes [nodeIndex].FirstAttribute = firstAttribute;
nodes [nodeIndex].PreviousSibling = previousSibling;
nodes [nodeIndex].NextSibling = 0; // dummy
- nodes [nodeIndex].Depth = depth;
nodes [nodeIndex].NodeType = nodeType;
nodes [nodeIndex].BaseURI = baseUri;
nodes [nodeIndex].IsEmptyElement = isEmptyElement;
diff --git a/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder2.cs b/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder2.cs
index ca4266fcace..3c42eb99282 100755
--- a/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder2.cs
+++ b/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder2.cs
@@ -122,7 +122,9 @@ namespace Mono.Xml.XPath
// String pool
string [] atomicStringPool;
+ int atomicIndex;
string [] nonAtomicStringPool;
+ int nonAtomicIndex;
// idTable [string value] -> int nodeId
Hashtable idTable;
@@ -162,6 +164,7 @@ namespace Mono.Xml.XPath
atomicStringPool [1] = nonAtomicStringPool [1] = null;
atomicStringPool [2] = nonAtomicStringPool [2] = XmlNamespaces.XML;
atomicStringPool [3] = nonAtomicStringPool [3] = XmlNamespaces.XMLNS;
+ atomicIndex = nonAtomicIndex = 4;
// index 0 is dummy. No node (including Root) is assigned to this index
// So that we can easily compare index != 0 instead of index < 0.
@@ -186,21 +189,12 @@ namespace Mono.Xml.XPath
SetAttributeArrayLength (attributeIndex + 1);
SetNsArrayLength (nsIndex + 1);
- int i;
- for (i = 3; i < atomicStringPool.Length; i++) {
- if (atomicStringPool [i] == null)
- break;
- }
- string [] newArr = new string [i];
- Array.Copy (atomicStringPool, newArr, i);
+ string [] newArr = new string [atomicIndex];
+ Array.Copy (atomicStringPool, newArr, atomicIndex);
atomicStringPool = newArr;
- for (i = 3; i < nonAtomicStringPool.Length; i++) {
- if (nonAtomicStringPool [i] == null)
- break;
- }
- newArr = new string [i];
- Array.Copy (nonAtomicStringPool, newArr, i);
+ newArr = new string [nonAtomicIndex];
+ Array.Copy (nonAtomicStringPool, newArr, nonAtomicIndex);
nonAtomicStringPool = newArr;
xmlReader = null; // It is no more required.
@@ -445,20 +439,17 @@ namespace Mono.Xml.XPath
if (s == null)
return 1;
int i = 2;
- for (; i < atomicStringPool.Length; i++) {
- if (atomicStringPool [i] == null) {
- atomicStringPool [i] = s;
- return i;
- }
- else if (Object.ReferenceEquals (s,
- atomicStringPool [i]))
+ for (; i < atomicIndex; i++)
+ if (Object.ReferenceEquals (s, atomicStringPool [i]))
return i;
+
+ if (atomicIndex == atomicStringPool.Length) {
+ string [] newArr = new string [atomicIndex * 2];
+ Array.Copy (atomicStringPool, newArr, atomicIndex);
+ atomicStringPool = newArr;
}
- string [] newArr = new string [i * 2];
- Array.Copy (atomicStringPool, newArr, i);
- atomicStringPool = newArr;
- atomicStringPool [i] = s;
- return i;
+ atomicStringPool [atomicIndex] = s;
+ return atomicIndex++;
}
private int NonAtomicIndex (string s)
@@ -468,19 +459,21 @@ namespace Mono.Xml.XPath
if (s == null)
return 1;
int i = 2;
- for (; i < nonAtomicStringPool.Length; i++) {
- if (nonAtomicStringPool [i] == null) {
- nonAtomicStringPool [i] = s;
- return i;
- }
- else if (s == nonAtomicStringPool [i])
+
+ // Here we don't compare all the entries (sometimes it
+ // goes extremely slow).
+ int max = nonAtomicIndex < 100 ? nonAtomicIndex : 100;
+ for (; i < max; i++)
+ if (s == nonAtomicStringPool [i])
return i;
+
+ if (nonAtomicIndex == nonAtomicStringPool.Length) {
+ string [] newArr = new string [nonAtomicIndex * 2];
+ Array.Copy (nonAtomicStringPool, newArr, nonAtomicIndex);
+ nonAtomicStringPool = newArr;
}
- string [] newArr = new string [i * 2];
- Array.Copy (nonAtomicStringPool, newArr, i);
- nonAtomicStringPool = newArr;
- nonAtomicStringPool [i] = s;
- return i;
+ nonAtomicStringPool [nonAtomicIndex] = s;
+ return nonAtomicIndex++;
}
private void SetNodeArrayLength (int size)
diff --git a/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentWriter.cs b/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentWriter.cs
index 3688a99f555..be388f7bb98 100755
--- a/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentWriter.cs
+++ b/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentWriter.cs
@@ -48,19 +48,20 @@ namespace Mono.Xml.XPath
nameTable = nt == null ? new NameTable () : nt;
nodeCapacity = defaultCapacity;
attributeCapacity = nodeCapacity;
+ nsCapacity = 10;
idTable = new Hashtable ();
nodes = new DTMXPathLinkedNode [nodeCapacity];
attributes = new DTMXPathAttributeNode [attributeCapacity];
- namespaces = new DTMXPathNamespaceNode [0];
+ namespaces = new DTMXPathNamespaceNode [nsCapacity];
Init ();
}
XmlNameTable nameTable;
- int nodeCapacity = 200;
- int attributeCapacity = 200;
- int nsCapacity = 10;
+ int nodeCapacity;
+ int attributeCapacity;
+ int nsCapacity;
// Linked Node
DTMXPathLinkedNode [] nodes;
@@ -77,19 +78,19 @@ namespace Mono.Xml.XPath
int nodeIndex;
int attributeIndex;
int nsIndex;
- int parentForFirstChild;
+ int [] parentStack = new int [10];
+ int parentStackIndex = 0;
// for attribute processing; should be reset per each element.
- int firstAttributeIndex;
- int lastNsIndexInCurrent;
+ bool hasAttributes;
+ bool hasLocalNs;
int attrIndexAtStart;
int nsIndexAtStart;
- int prevSibling;
int lastNsInScope;
// They are only used in Writer
- int writerDepth;
+ int prevSibling;
WriteState state;
bool openNamespace;
bool isClosed;
@@ -111,7 +112,7 @@ namespace Mono.Xml.XPath
// index 0 is dummy. No node (including Root) is assigned to this index
// So that we can easily compare index != 0 instead of index < 0.
// (Difference between jnz or jbe in 80x86.)
- AddNode (0, 0, 0, 0, XPathNodeType.All, "", false, "", "", "", "", "", 0, 0, 0);
+ AddNode (0, 0, 0, XPathNodeType.All, "", false, "", "", "", "", "", 0, 0, 0);
nodeIndex++;
AddAttribute (0, null, null, null, null, 0, 0);
AddNsNode (0, null, null, 0);
@@ -119,37 +120,28 @@ namespace Mono.Xml.XPath
AddNsNode (1, "xml", XmlNamespaces.XML, 0);
// add root.
- AddNode (0, 0, 0, -1, XPathNodeType.Root, null, false, "", "", "", "", "", 1, 0, 0);
+ AddNode (0, 0, 0, XPathNodeType.Root, null, false, "", "", "", "", "", 1, 0, 0);
this.nodeIndex = 1;
this.lastNsInScope = 1;
- this.parentForFirstChild = nodeIndex;
+ parentStack [0] = nodeIndex;
state = WriteState.Content;
}
private int GetParentIndex ()
{
- if (parentForFirstChild >= 0)
- return parentForFirstChild;
-
- int parent = nodeIndex;
- if (nodes [nodeIndex].Depth >= writerDepth) {
- // if not, then current node is parent.
- while (writerDepth <= nodes [parent].Depth)
- parent = nodes [parent].Parent;
- }
- return parent;
+ return parentStack [parentStackIndex];
}
private int GetPreviousSiblingIndex ()
{
+ int parent = parentStack [parentStackIndex];
+ if (parent == nodeIndex)
+ return 0;
int prevSibling = nodeIndex;
- if (parentForFirstChild >= 0)
- prevSibling = 0;
- else
- while (nodes [prevSibling].Depth != writerDepth)
- prevSibling = nodes [prevSibling].Parent;
+ while (nodes [prevSibling].Parent != parent)
+ prevSibling = nodes [prevSibling].Parent;
return prevSibling;
}
@@ -162,10 +154,8 @@ namespace Mono.Xml.XPath
if (prevSibling != 0)
nodes [prevSibling].NextSibling = nodeIndex;
- if (parentForFirstChild >= 0)
+ if (parent == nodeIndex - 1)
nodes [parent].FirstChild = nodeIndex;
-
- parentForFirstChild = -1;
}
private void CloseStartElement ()
@@ -177,11 +167,15 @@ namespace Mono.Xml.XPath
lastNsInScope = nsIndex;
}
- if (!nodes [nodeIndex].IsEmptyElement)
- parentForFirstChild = nodeIndex;
+ parentStackIndex++;
+ if (parentStack.Length == parentStackIndex) {
+ int [] tmp = new int [parentStackIndex * 2];
+ Array.Copy (parentStack, tmp, parentStackIndex);
+ parentStack = tmp;
+ }
+ parentStack [parentStackIndex] = nodeIndex;
state = WriteState.Content;
- writerDepth++;
}
#region Adding Nodes
@@ -209,7 +203,7 @@ namespace Mono.Xml.XPath
}
// Here followings are skipped: firstChild, nextSibling,
- public void AddNode (int parent, int firstAttribute, int previousSibling, int depth, XPathNodeType nodeType, string baseUri, bool isEmptyElement, string localName, string ns, string prefix, string value, string xmlLang, int namespaceNode, int lineNumber, int linePosition)
+ public void AddNode (int parent, int firstAttribute, int previousSibling, XPathNodeType nodeType, string baseUri, bool isEmptyElement, string localName, string ns, string prefix, string value, string xmlLang, int namespaceNode, int lineNumber, int linePosition)
{
if (nodes.Length < nodeIndex + 1) {
nodeCapacity *= 4;
@@ -224,7 +218,6 @@ namespace Mono.Xml.XPath
nodes [nodeIndex].FirstAttribute = firstAttribute;
nodes [nodeIndex].PreviousSibling = previousSibling;
nodes [nodeIndex].NextSibling = 0; // dummy
- nodes [nodeIndex].Depth = depth;
nodes [nodeIndex].NodeType = nodeType;
nodes [nodeIndex].BaseURI = baseUri;
nodes [nodeIndex].IsEmptyElement = isEmptyElement;
@@ -326,12 +319,13 @@ namespace Mono.Xml.XPath
}
// When text after text, just add the value, and return.
- if (nodes [nodeIndex].Depth == writerDepth) {
+ if (nodes [nodeIndex].Parent == parentStack [parentStackIndex]) {
switch (nodes [nodeIndex].NodeType) {
case XPathNodeType.Text:
case XPathNodeType.SignificantWhitespace:
- nodes [nodeIndex].Value += data;
- if (IsWhitespace (data))
+ string value = nodes [nodeIndex].Value + data;
+ nodes [nodeIndex].Value = value;
+ if (IsWhitespace (value))
nodes [nodeIndex].NodeType = XPathNodeType.SignificantWhitespace;
else
nodes [nodeIndex].NodeType = XPathNodeType.Text;
@@ -345,7 +339,6 @@ namespace Mono.Xml.XPath
AddNode (parent,
0, // attribute
prevSibling,
- writerDepth,
XPathNodeType.Text,
null,
false,
@@ -384,7 +377,6 @@ namespace Mono.Xml.XPath
AddNode (parent,
0, // attribute
prevSibling,
- writerDepth,
XPathNodeType.Comment,
null,
false,
@@ -408,7 +400,6 @@ namespace Mono.Xml.XPath
AddNode (parent,
0, // attribute
prevSibling,
- writerDepth,
XPathNodeType.ProcessingInstruction,
null,
false,
@@ -432,7 +423,6 @@ namespace Mono.Xml.XPath
AddNode (parent,
0, // attribute
prevSibling,
- writerDepth,
XPathNodeType.Whitespace,
null,
false,
@@ -489,7 +479,6 @@ namespace Mono.Xml.XPath
AddNode (parent,
0, // dummy:firstAttribute
previousSibling,
- writerDepth,
XPathNodeType.Element,
null,
false,
@@ -505,8 +494,8 @@ namespace Mono.Xml.XPath
private void PrepareStartElement (int previousSibling)
{
- firstAttributeIndex = 0;
- lastNsIndexInCurrent = 0;
+ hasAttributes = false;
+ hasLocalNs = false;
attrIndexAtStart = attributeIndex;
nsIndexAtStart = nsIndex;
@@ -536,13 +525,11 @@ namespace Mono.Xml.XPath
default:
throw new InvalidOperationException ("Invalid state for writing EndElement: " + state);
}
- parentForFirstChild = -1;
+ parentStackIndex--;
if (nodes [nodeIndex].NodeType == XPathNodeType.Element) {
if (!full)
nodes [nodeIndex].IsEmptyElement = true;
}
-
- writerDepth--;
}
public override void WriteStartAttribute (string prefix, string localName, string ns)
@@ -559,15 +546,15 @@ namespace Mono.Xml.XPath
private void ProcessNamespace (string prefix, string ns)
{
- nsIndex++;
+ int nextTmp = hasLocalNs ? nsIndex : nodes [nodeIndex].FirstNamespace;
- int nextTmp = lastNsIndexInCurrent == 0 ? nodes [nodeIndex].FirstNamespace : lastNsIndexInCurrent;
+ nsIndex++;
this.AddNsNode (nodeIndex,
prefix,
ns,
nextTmp);
- lastNsIndexInCurrent = nsIndex;
+ hasLocalNs = true;
openNamespace = true;
}
@@ -582,10 +569,10 @@ namespace Mono.Xml.XPath
value,
0,
0);
- if (firstAttributeIndex == 0)
- firstAttributeIndex = attributeIndex;
- else
+ if (hasAttributes)
attributes [attributeIndex - 1].NextAttribute = attributeIndex;
+ else
+ hasAttributes = true;
}
public override void WriteEndAttribute ()
diff --git a/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNavigator.cs b/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNavigator.cs
index 86ddeb2ea5a..024584634e4 100644
--- a/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNavigator.cs
+++ b/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNavigator.cs
@@ -44,7 +44,6 @@ namespace Mono.Xml.XPath
class DTMXPathNavigator : XPathNavigator, IXmlLineInfo
{
-#region Copy of XPathDocument
public DTMXPathNavigator (DTMXPathDocument document,
XmlNameTable nameTable,
DTMXPathLinkedNode [] nodes,
@@ -57,7 +56,6 @@ namespace Mono.Xml.XPath
this.namespaces = namespaces;
this.idTable = idTable;
this.nameTable = nameTable;
-
this.MoveToRoot ();
this.document = document;
}
@@ -88,11 +86,6 @@ namespace Mono.Xml.XPath
// ID table
Hashtable idTable;
-// // Key table (considered xsd:keyref for XPath 2.0)
-// Hashtable keyRefTable; // [string key-name] -> idTable
-// // idTable [string value] -> int nodeId
-#endregion
-
bool currentIsNode;
bool currentIsAttr;
@@ -226,20 +219,32 @@ namespace Mono.Xml.XPath
return nodes [currentNode].Value;
}
- // Element
+ // Element - collect all content values
+ int iter = nodes [currentNode].FirstChild;
+ if (iter == 0)
+ return String.Empty;
+
if (valueBuilder == null)
valueBuilder = new StringBuilder ();
else
valueBuilder.Length = 0;
-
- int iter = nodes [currentNode].FirstChild;
- int depth = nodes [currentNode].Depth;
- while (iter < nodes.Length && nodes [iter].Depth > depth) {
+
+ int end = nodes [currentNode].NextSibling;
+ if (end == 0) {
+ int tmp = currentNode;
+ do {
+ tmp = nodes [tmp].Parent;
+ end = nodes [tmp].NextSibling;
+ } while (end == 0 && tmp != 0);
+ if (end == 0)
+ end = nodes.Length;
+ }
+
+ while (iter < end) {
switch (nodes [iter].NodeType) {
- case XPathNodeType.Comment:
- case XPathNodeType.ProcessingInstruction:
- break;
- default:
+ case XPathNodeType.Text:
+ case XPathNodeType.SignificantWhitespace:
+ case XPathNodeType.Whitespace:
valueBuilder.Append (nodes [iter].Value);
break;
}
@@ -592,37 +597,9 @@ namespace Mono.Xml.XPath
}
#endregion
-
- /*
- public string DebugDump {
- get {
- StringBuilder sb = new StringBuilder ();
-
- for (int i = 0; i < namespaces.Length; i++) {
- DTMXPathNamespaceNode n = namespaces [i];
- sb.AppendFormat ("{0}: {1},{2} {3}/{4}\n", i,
- n.DeclaredElement, n.NextNamespace,
- n.Name, n.Namespace);
- }
-
- for (int i=0; i<this.nodes.Length; i++) {
- DTMXPathLinkedNode n = nodes [i];
- sb.AppendFormat ("{0}: {1}:{2} {3} {4} {5} {6} {7}\n", new object [] {i, n.Prefix, n.LocalName, n.NamespaceURI, n.FirstNamespace, n.FirstAttribute, n.FirstChild, n.Parent});
- }
-
- for (int i=0; i<this.attributes.Length; i++) {
- DTMXPathAttributeNode n = attributes [i];
- sb.AppendFormat ("{0}: {1}:{2} {3} {4}\n", i, n.Prefix, n.LocalName, n.NamespaceURI, n.NextAttribute);
- }
-
- return sb.ToString ();
- }
- }
- */
-
}
- internal class XmlNamespaces
+ class XmlNamespaces
{
public const string XML = "http://www.w3.org/XML/1998/namespace";
public const string XMLNS = "http://www.w3.org/2000/xmlns/";
diff --git a/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNode.cs b/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNode.cs
index 9fdcf9e95a6..be368b07560 100644
--- a/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNode.cs
+++ b/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNode.cs
@@ -53,7 +53,6 @@ namespace Mono.Xml.XPath
public int NextSibling;
public int FirstAttribute;
public int FirstNamespace;
- public int Depth;
public XPathNodeType NodeType;
public string BaseURI;
public bool IsEmptyElement;