summary refs log tree commit diff stats
path: root/lib/pure
diff options
context:
space:
mode:
authordef <dennis@felsin9.de>2015-02-19 21:45:08 +0100
committerdef <dennis@felsin9.de>2015-02-27 03:10:06 +0100
commit15cc3bf67036c204ace466be4232bfed8cf76d2e (patch)
treed65fab1d5f7a0b97678acf12c8ca0089f6f1f533 /lib/pure
parentf87d663ab71f1d9513ccc7b25c453ee6b09b83aa (diff)
downloadNim-15cc3bf67036c204ace466be4232bfed8cf76d2e.tar.gz
Improve performance of parsexml
- Prevent string copies when not necessary
- Don't allocate a new XMLParser.c all the time
Diffstat (limited to 'lib/pure')
-rw-r--r--lib/pure/parsexml.nim26
1 files changed, 15 insertions, 11 deletions
diff --git a/lib/pure/parsexml.nim b/lib/pure/parsexml.nim
index b957c0cf7..6e6f6ab5d 100644
--- a/lib/pure/parsexml.nim
+++ b/lib/pure/parsexml.nim
@@ -128,6 +128,7 @@ proc open*(my: var XmlParser, input: Stream, filename: string,
   my.kind = xmlError
   my.a = ""
   my.b = ""
+  my.c = ""
   my.options = options
   
 proc close*(my: var XmlParser) {.inline.} = 
@@ -138,40 +139,40 @@ proc kind*(my: XmlParser): XmlEventKind {.inline.} =
   ## returns the current event type for the XML parser
   return my.kind
 
-proc charData*(my: XmlParser): string {.inline.} = 
+proc charData*(my: var XmlParser): var string {.inline.} = 
   ## returns the character data for the events: ``xmlCharData``, 
   ## ``xmlWhitespace``, ``xmlComment``, ``xmlCData``, ``xmlSpecial``
   assert(my.kind in {xmlCharData, xmlWhitespace, xmlComment, xmlCData, 
                      xmlSpecial})
   return my.a
 
-proc elementName*(my: XmlParser): string {.inline.} = 
+proc elementName*(my: var XmlParser): var string {.inline.} = 
   ## returns the element name for the events: ``xmlElementStart``, 
   ## ``xmlElementEnd``, ``xmlElementOpen``
   assert(my.kind in {xmlElementStart, xmlElementEnd, xmlElementOpen})
   return my.a
 
-proc entityName*(my: XmlParser): string {.inline.} = 
+proc entityName*(my: var XmlParser): var string {.inline.} = 
   ## returns the entity name for the event: ``xmlEntity``
   assert(my.kind == xmlEntity)
   return my.a
   
-proc attrKey*(my: XmlParser): string {.inline.} = 
+proc attrKey*(my: var XmlParser): var string {.inline.} = 
   ## returns the attribute key for the event ``xmlAttribute``
   assert(my.kind == xmlAttribute)
   return my.a
   
-proc attrValue*(my: XmlParser): string {.inline.} = 
+proc attrValue*(my: var XmlParser): var string {.inline.} = 
   ## returns the attribute value for the event ``xmlAttribute``
   assert(my.kind == xmlAttribute)
   return my.b
 
-proc piName*(my: XmlParser): string {.inline.} = 
+proc piName*(my: var XmlParser): var string {.inline.} = 
   ## returns the processing instruction name for the event ``xmlPI``
   assert(my.kind == xmlPI)
   return my.a
 
-proc piRest*(my: XmlParser): string {.inline.} = 
+proc piRest*(my: var XmlParser): var string {.inline.} = 
   ## returns the rest of the processing instruction for the event ``xmlPI``
   assert(my.kind == xmlPI)
   return my.b
@@ -446,13 +447,15 @@ proc parseTag(my: var XmlParser) =
     # an attribute follows:
     my.kind = xmlElementOpen
     my.state = stateAttr
-    my.c = my.a # save for later
+    # save for later:
+    my.c.setLen(my.a.len)
+    copyMem(addr my.c[0], addr my.a[0], my.a.len+1)
   else:
     my.kind = xmlElementStart
     if my.buf[my.bufpos] == '/' and my.buf[my.bufpos+1] == '>':
       inc(my.bufpos, 2)
       my.state = stateEmptyElementTag
-      my.c = nil
+      my.c.setLen(0)
     elif my.buf[my.bufpos] == '>':
       inc(my.bufpos)  
     else:
@@ -621,8 +624,9 @@ proc next*(my: var XmlParser) =
   of stateEmptyElementTag:
     my.state = stateNormal
     my.kind = xmlElementEnd
-    if not isNil(my.c):
-      my.a = my.c
+    if my.c.len > 0:
+      my.a.setLen(my.c.len)
+      copyMem(addr my.a[0], addr my.c[0], my.c.len+1)
   of stateError: 
     my.kind = xmlError
     my.state = stateNormal
e8edab39884f59d685d2608f8bd944cad27e6'>^
e80465dac ^
63ac32e6d ^
2cdfe35e7 ^

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37