summary refs log tree commit diff stats
path: root/lib/pure/json.nim
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2016-11-28 20:59:30 +0100
committerAraq <rumpf_a@web.de>2016-11-28 20:59:30 +0100
commit27723af469a937835b9679c41364d9db0090036e (patch)
treeecdd90e6287d4c172e63cae3f6b25169f4b88708 /lib/pure/json.nim
parentebaf57ea3bc17d1476e9d4bbd8d107eb6dd631a2 (diff)
parentf9c184a4932eb839a6ec4b9293e37583cd33a89a (diff)
downloadNim-27723af469a937835b9679c41364d9db0090036e.tar.gz
Merge branch 'devel' into sighashes
Diffstat (limited to 'lib/pure/json.nim')
-rw-r--r--lib/pure/json.nim44
1 files changed, 31 insertions, 13 deletions
diff --git a/lib/pure/json.nim b/lib/pure/json.nim
index 0b7908c02..5fff7352f 100644
--- a/lib/pure/json.nim
+++ b/lib/pure/json.nim
@@ -954,9 +954,11 @@ proc newIndent(curr, indent: int, ml: bool): int =
 proc nl(s: var string, ml: bool) =
   if ml: s.add("\n")
 
-proc escapeJson*(s: string): string =
+proc escapeJson*(s: string; result: var string) =
   ## Converts a string `s` to its JSON representation.
-  result = newStringOfCap(s.len + s.len shr 3)
+  ## Appends to ``result``.
+  const
+    HexChars = "0123456789ABCDEF"
   result.add("\"")
   for x in runes(s):
     var r = int(x)
@@ -967,10 +969,19 @@ proc escapeJson*(s: string): string =
       of '\\': result.add("\\\\")
       else: result.add(c)
     else:
-      result.add("\\u")
-      result.add(toHex(r, 4))
+      # toHex inlined for more speed (saves stupid string allocations):
+      result.add("\\u0000")
+      let start = result.len - 4
+      for j in countdown(3, 0):
+        result[j+start] = HexChars[r and 0xF]
+        r = r shr 4
   result.add("\"")
 
+proc escapeJson*(s: string): string =
+  ## Converts a string `s` to its JSON representation.
+  result = newStringOfCap(s.len + s.len shr 3)
+  escapeJson(s, result)
+
 proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true,
               lstArr = false, currIndent = 0) =
   case node.kind
@@ -988,7 +999,7 @@ proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true,
         inc i
         # Need to indent more than {
         result.indent(newIndent(currIndent, indent, ml))
-        result.add(escapeJson(key))
+        escapeJson(key, result)
         result.add(": ")
         toPretty(result, val, indent, ml, false,
                  newIndent(currIndent, indent, ml))
@@ -999,16 +1010,19 @@ proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true,
       result.add("{}")
   of JString:
     if lstArr: result.indent(currIndent)
-    result.add(escapeJson(node.str))
+    escapeJson(node.str, result)
   of JInt:
     if lstArr: result.indent(currIndent)
-    result.add($node.num)
+    when defined(js): result.add($node.num)
+    else: result.add(node.num)
   of JFloat:
     if lstArr: result.indent(currIndent)
-    result.add($node.fnum)
+    # Fixme: implement new system.add ops for the JS target
+    when defined(js): result.add($node.fnum)
+    else: result.add(node.fnum)
   of JBool:
     if lstArr: result.indent(currIndent)
-    result.add($node.bval)
+    result.add(if node.bval: "true" else: "false")
   of JArray:
     if lstArr: result.indent(currIndent)
     if len(node.elems) != 0:
@@ -1057,16 +1071,18 @@ proc toUgly*(result: var string, node: JsonNode) =
     for key, value in pairs(node.fields):
       if comma: result.add ","
       else:     comma = true
-      result.add key.escapeJson()
+      key.escapeJson(result)
       result.add ":"
       result.toUgly value
     result.add "}"
   of JString:
-    result.add node.str.escapeJson()
+    node.str.escapeJson(result)
   of JInt:
-    result.add($node.num)
+    when defined(js): result.add($node.num)
+    else: result.add(node.num)
   of JFloat:
-    result.add($node.fnum)
+    when defined(js): result.add($node.fnum)
+    else: result.add(node.fnum)
   of JBool:
     result.add(if node.bval: "true" else: "false")
   of JNull:
@@ -1394,4 +1410,6 @@ when isMainModule:
     var parsed2 = parseFile("tests/testdata/jsontest2.json")
     doAssert(parsed2{"repository", "description"}.str=="IRC Library for Haskell", "Couldn't fetch via multiply nested key using {}")
 
+  doAssert escapeJson("\10FoobarÄ") == "\"\\u000AFoobar\\u00C4\""
+
   echo("Tests succeeded!")