Author: atsushi
Date: 2005-03-22 02:04:18 -0500 (Tue, 22 Mar 2005)
New Revision: 42057
Modified:
trunk/mcs/class/System.XML/Mono.Xml.XPath/ChangeLog
trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument.cs
trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument2.cs
trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder.cs
trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder2.cs
trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentWriter.cs
trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNavigator.cs
trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNode.cs
Log:
2004-03-22 Atsushi Enomoto <[EMAIL PROTECTED]>
* 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).
Modified: trunk/mcs/class/System.XML/Mono.Xml.XPath/ChangeLog
===================================================================
--- trunk/mcs/class/System.XML/Mono.Xml.XPath/ChangeLog 2005-03-21 20:08:12 UTC
(rev 42056)
+++ trunk/mcs/class/System.XML/Mono.Xml.XPath/ChangeLog 2005-03-22 07:04:18 UTC
(rev 42057)
@@ -1,3 +1,16 @@
+2004-03-22 Atsushi Enomoto <[EMAIL PROTECTED]>
+
+ * 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 <[EMAIL PROTECTED]>
* Pattern.cs : fixed incorrect optimization.
Modified: trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument.cs
===================================================================
--- trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument.cs
2005-03-21 20:08:12 UTC (rev 42056)
+++ trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument.cs
2005-03-22 07:04:18 UTC (rev 42057)
@@ -42,56 +42,26 @@
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;
}
}
Modified: trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument2.cs
===================================================================
--- trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument2.cs
2005-03-21 20:08:12 UTC (rev 42056)
+++ trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument2.cs
2005-03-22 07:04:18 UTC (rev 42057)
@@ -42,8 +42,6 @@
class DTMXPathDocument2 : IXPathNavigable
{
-#region ctor.
-
public DTMXPathDocument2 (XmlNameTable nameTable,
DTMXPathLinkedNode2 [] nodes,
DTMXPathAttributeNode2 [] attributes,
@@ -52,14 +50,6 @@
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 @@
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;
}
}
Modified: trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder.cs
===================================================================
--- trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder.cs
2005-03-21 20:08:12 UTC (rev 42056)
+++ trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder.cs
2005-03-22 07:04:18 UTC (rev 42057)
@@ -91,11 +91,12 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
if (!xmlReader.Read ())
return;
skipRead = false;
- int parent = nodeIndex;
+ int parent = parentStack [parentStackIndex];
+ int prevSibling = nodeIndex;
- if (nodes [nodeIndex].Depth >= xmlReader.Depth) {
- // if not, then current node is parent.
- while (xmlReader.Depth <= nodes [parent].Depth)
- parent = nodes [parent].Parent;
- }
-
- prevSibling = nodeIndex;
switch (xmlReader.NodeType) {
case XmlNodeType.Element:
case XmlNodeType.CDATA:
@@ -196,17 +192,17 @@
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 @@
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.SignificantWhitespace:
+ nodeType = XPathNodeType.SignificantWhitespace;
+ goto case XmlNodeType.Text;
+ case XmlNodeType.Whitespace:
+ nodeType = XPathNodeType.Whitespace;
+ goto case XmlNodeType.Text;
case XmlNodeType.CDATA:
- case XmlNodeType.SignificantWhitespace:
case XmlNodeType.Text:
- case XmlNodeType.Whitespace:
- if (value == null)
- skipRead = true;
AddNode (parent,
0,
prevSibling,
- xmlReader.Depth,
nodeType,
xmlReader.BaseURI,
xmlReader.IsEmptyElement,
@@ -253,10 +247,37 @@
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 @@
private void PrepareStartElement (int previousSibling)
{
- firstAttributeIndex = 0;
- lastNsIndexInCurrent = 0;
+ hasAttributes = false;
+ hasLocalNs = false;
attrIndexAtStart = attributeIndex;
nsIndexAtStart = nsIndex;
@@ -309,7 +330,6 @@
AddNode (parent,
0, // dummy:firstAttribute
previousSibling,
- xmlReader.Depth,
XPathNodeType.Element,
xmlReader.BaseURI,
xmlReader.IsEmptyElement,
@@ -330,24 +350,33 @@
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)
{
+ int nextTmp = hasLocalNs ?
+ nsIndex : nodes [nodeIndex].FirstNamespace;
+
nsIndex++;
- int nextTmp = lastNsIndexInCurrent == 0 ? nodes
[nodeIndex].FirstNamespace : lastNsIndexInCurrent;
-
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 @@
value,
lineInfo != null ? lineInfo.LineNumber : 0,
lineInfo != null ? lineInfo.LinePosition : 0);
- if (firstAttributeIndex == 0)
- firstAttributeIndex = attributeIndex;
+ if (hasAttributes)
+ attributes [attributeIndex - 1].NextAttribute =
attributeIndex;
else
- attributes [attributeIndex - 1].NextAttribute =
attributeIndex;
+ hasAttributes = true;
// Identity infoset
if (validatingReader != null) {
@@ -403,7 +432,7 @@
}
// 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 @@
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;
Modified: trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder2.cs
===================================================================
--- trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder2.cs
2005-03-21 20:08:12 UTC (rev 42056)
+++ trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder2.cs
2005-03-22 07:04:18 UTC (rev 42057)
@@ -122,7 +122,9 @@
// String pool
string [] atomicStringPool;
+ int atomicIndex;
string [] nonAtomicStringPool;
+ int nonAtomicIndex;
// idTable [string value] -> int nodeId
Hashtable idTable;
@@ -162,6 +164,7 @@
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 @@
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 @@
if (s == null)
return 1;
int i = 2;
- for (; i < atomicStringPool.Length; i++) {
- if (atomicStringPool [i] == null) {
- atomicStringPool [i] = s;
+ for (; i < atomicIndex; i++)
+ if (Object.ReferenceEquals (s, atomicStringPool
[i]))
return i;
- }
- else 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 @@
if (s == null)
return 1;
int i = 2;
- for (; i < nonAtomicStringPool.Length; i++) {
- if (nonAtomicStringPool [i] == null) {
- nonAtomicStringPool [i] = s;
+
+ // 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;
- }
- else 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)
Modified: trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentWriter.cs
===================================================================
--- trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentWriter.cs
2005-03-21 20:08:12 UTC (rev 42056)
+++ trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentWriter.cs
2005-03-22 07:04:18 UTC (rev 42057)
@@ -48,19 +48,20 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
}
// 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 @@
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 @@
}
// 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 @@
AddNode (parent,
0, // attribute
prevSibling,
- writerDepth,
XPathNodeType.Text,
null,
false,
@@ -384,7 +377,6 @@
AddNode (parent,
0, // attribute
prevSibling,
- writerDepth,
XPathNodeType.Comment,
null,
false,
@@ -408,7 +400,6 @@
AddNode (parent,
0, // attribute
prevSibling,
- writerDepth,
XPathNodeType.ProcessingInstruction,
null,
false,
@@ -432,7 +423,6 @@
AddNode (parent,
0, // attribute
prevSibling,
- writerDepth,
XPathNodeType.Whitespace,
null,
false,
@@ -489,7 +479,6 @@
AddNode (parent,
0, // dummy:firstAttribute
previousSibling,
- writerDepth,
XPathNodeType.Element,
null,
false,
@@ -505,8 +494,8 @@
private void PrepareStartElement (int previousSibling)
{
- firstAttributeIndex = 0;
- lastNsIndexInCurrent = 0;
+ hasAttributes = false;
+ hasLocalNs = false;
attrIndexAtStart = attributeIndex;
nsIndexAtStart = nsIndex;
@@ -536,13 +525,11 @@
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 @@
private void ProcessNamespace (string prefix, string ns)
{
+ int nextTmp = hasLocalNs ? nsIndex : nodes
[nodeIndex].FirstNamespace;
+
nsIndex++;
- int nextTmp = lastNsIndexInCurrent == 0 ? nodes
[nodeIndex].FirstNamespace : lastNsIndexInCurrent;
-
this.AddNsNode (nodeIndex,
prefix,
ns,
nextTmp);
- lastNsIndexInCurrent = nsIndex;
+ hasLocalNs = true;
openNamespace = true;
}
@@ -582,10 +569,10 @@
value,
0,
0);
- if (firstAttributeIndex == 0)
- firstAttributeIndex = attributeIndex;
- else
+ if (hasAttributes)
attributes [attributeIndex - 1].NextAttribute =
attributeIndex;
+ else
+ hasAttributes = true;
}
public override void WriteEndAttribute ()
Modified: trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNavigator.cs
===================================================================
--- trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNavigator.cs
2005-03-21 20:08:12 UTC (rev 42056)
+++ trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNavigator.cs
2005-03-22 07:04:18 UTC (rev 42057)
@@ -44,7 +44,6 @@
class DTMXPathNavigator : XPathNavigator, IXmlLineInfo
{
-#region Copy of XPathDocument
public DTMXPathNavigator (DTMXPathDocument document,
XmlNameTable nameTable,
DTMXPathLinkedNode [] nodes,
@@ -57,7 +56,6 @@
this.namespaces = namespaces;
this.idTable = idTable;
this.nameTable = nameTable;
-
this.MoveToRoot ();
this.document = document;
}
@@ -88,11 +86,6 @@
// 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 @@
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 @@
}
#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/";
Modified: trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNode.cs
===================================================================
--- trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNode.cs 2005-03-21
20:08:12 UTC (rev 42056)
+++ trunk/mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNode.cs 2005-03-22
07:04:18 UTC (rev 42057)
@@ -53,7 +53,6 @@
public int NextSibling;
public int FirstAttribute;
public int FirstNamespace;
- public int Depth;
public XPathNodeType NodeType;
public string BaseURI;
public bool IsEmptyElement;
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches