summary refs log tree commit diff stats
path: root/lib/pure
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2011-05-08 17:38:34 +0200
committerAraq <rumpf_a@web.de>2011-05-08 17:38:34 +0200
commitd2e2d71d05b9a8381bf7fef7bb23da029e576c2a (patch)
tree137e4494aa119f8477204f8f974e4391f9ef1b2c /lib/pure
parent1893f4101a59497d9c5713068ad396efdddb8574 (diff)
downloadNim-d2e2d71d05b9a8381bf7fef7bb23da029e576c2a.tar.gz
newStringOfCap implemented and used to optimize some procs
Diffstat (limited to 'lib/pure')
-rwxr-xr-xlib/pure/cgi.nim19
-rwxr-xr-xlib/pure/json.nim3
-rwxr-xr-xlib/pure/strutils.nim20
3 files changed, 28 insertions, 14 deletions
diff --git a/lib/pure/cgi.nim b/lib/pure/cgi.nim
index af222caba..ae05d5734 100755
--- a/lib/pure/cgi.nim
+++ b/lib/pure/cgi.nim
@@ -36,7 +36,7 @@ proc URLencode*(s: string): string =
   ## ``{'A'..'Z', 'a'..'z', '0'..'9', '_'}`` are carried over to the result,
   ## a space is converted to ``'+'`` and every other character is encoded as
   ## ``'%xx'`` where ``xx`` denotes its hexadecimal value. 
-  result = ""
+  result = newStringOfCap(s.len + s.len shr 2) # assume 12% non-alnum-chars
   for i in 0..s.len-1:
     case s[i]
     of 'a'..'z', 'A'..'Z', '0'..'9', '_': add(result, s[i])
@@ -57,8 +57,9 @@ proc URLdecode*(s: string): string =
   ## is converted to a space, ``'%xx'`` (where ``xx`` denotes a hexadecimal
   ## value) is converted to the character with ordinal number ``xx``, and  
   ## and every other character is carried over. 
-  result = ""
+  result = newString(s.len)
   var i = 0
+  var j = 0
   while i < s.len:
     case s[i]
     of '%': 
@@ -66,10 +67,12 @@ proc URLdecode*(s: string): string =
       handleHexChar(s[i+1], x)
       handleHexChar(s[i+2], x)
       inc(i, 2)
-      add(result, chr(x))
-    of '+': add(result, ' ')
-    else: add(result, s[i])
+      result[j] = chr(x)
+    of '+': result[j] = ' '
+    else: result[j] = s[i]
     inc(i)
+    inc(j)
+  setLen(result, j)
 
 proc addXmlChar(dest: var string, c: Char) {.inline.} = 
   case c
@@ -86,7 +89,7 @@ proc XMLencode*(s: string): string =
   ## * ``>`` is replaced by ``&gt;``
   ## * ``&`` is replaced by ``&amp;``
   ## * every other character is carried over.
-  result = ""
+  result = newStringOfCap(s.len + s.len shr 2)
   for i in 0..len(s)-1: addXmlChar(result, s[i])
 
 type
@@ -367,4 +370,8 @@ proc existsCookie*(name: string): bool =
   if gcookies == nil: gcookies = parseCookies(getHttpCookie())
   result = hasKey(gcookies, name)
 
+when isMainModule:
+  const test1 = "abc\L+def xyz"
+  assert UrlEncode(test1) == "abc%0A%2Bdef+xyz"
+  assert UrlDecode(UrlEncode(test1)) == test1
 
diff --git a/lib/pure/json.nim b/lib/pure/json.nim
index 75958a55f..efadf030c 100755
--- a/lib/pure/json.nim
+++ b/lib/pure/json.nim
@@ -620,7 +620,8 @@ proc nl(s: var string, ml: bool) =
 
 proc escapeJson*(s: string): string = 
   ## Converts a string `s` to its JSON representation.
-  result = "\""
+  result = newStringOfCap(s.len + s.len shr 3)
+  result.add("\"")
   for x in runes(s):
     var r = int(x)
     if r >= 32 and r <= 127:
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim
index 382eece7b..f13910dbf 100755
--- a/lib/pure/strutils.nim
+++ b/lib/pure/strutils.nim
@@ -89,12 +89,16 @@ proc normalize*(s: string): string {.noSideEffect, procvar,
   rtl, extern: "nsuNormalize".} =

   ## Normalizes the string `s`. That means to convert it to lower case and

   ## remove any '_'. This is needed for Nimrod identifiers for example.

-  result = ""

+  result = newString(s.len)
+  var j = 0

   for i in 0..len(s) - 1:

     if s[i] in {'A'..'Z'}:

-      add result, Chr(Ord(s[i]) + (Ord('a') - Ord('A')))

+      result[j] = Chr(Ord(s[i]) + (Ord('a') - Ord('A')))
+      inc j

     elif s[i] != '_':

-      add result, s[i]

+      result[j] = s[i]
+      inc j
+  if j != s.len: setLen(result, j)

 

 proc cmpIgnoreCase*(a, b: string): int {.noSideEffect,

   rtl, extern: "nsuCmpIgnoreCase", procvar.} =

@@ -226,13 +230,14 @@ proc `%` *(formatstr: string, a: openarray[string]): string {.noSideEffect,
   ##

   ## The variables are compared with `cmpIgnoreStyle`. `EInvalidValue` is

   ## raised if an ill-formed format string has been passed to the `%` operator.

-  result = ""

+  result = newStringOfCap(formatstr.len + a.len shl 4)

   addf(result, formatstr, a)

 

 proc `%` *(formatstr, a: string): string {.noSideEffect, 

   rtl, extern: "nsuFormatSingleElem".} =

   ## This is the same as ``formatstr % [a]``.

-  return formatstr % [a]

+  result = newStringOfCap(formatstr.len + a.len)

+  addf(result, formatstr, [a])

 

 proc strip*(s: string, leading = true, trailing = true): string {.noSideEffect,

   rtl, extern: "nsuStrip".} =

@@ -510,7 +515,7 @@ proc wordWrap*(s: string, maxLineWidth = 80,
                newLine = "\n"): string {.

                noSideEffect, rtl, extern: "nsuWordWrap".} = 

   ## word wraps `s`.

-  result = ""

+  result = newStringOfCap(s.len + s.len shr 6)

   var SpaceLeft = maxLineWidth

   for word, isSep in tokenize(s, seps):

     if len(word) > SpaceLeft:

@@ -804,7 +809,8 @@ proc escape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect,
   ## The procedure has been designed so that its output is usable for many

   ## different common syntaxes. The resulting string is prefixed with

   ## `prefix` and suffixed with `suffix`. Both may be empty strings.

-  result = prefix

+  result = newStringOfCap(s.len + s.len shr 2)
+  result.add(prefix)

   for c in items(s):

     case c

     of '\0'..'\31', '\128'..'\255':