speed up json core module
This commit is contained in:
parent
9ca15ad369
commit
18690d4a61
1 changed files with 27 additions and 11 deletions
|
|
@ -954,9 +954,11 @@ proc newIndent(curr, indent: int, ml: bool): int =
|
||||||
proc nl(s: var string, ml: bool) =
|
proc nl(s: var string, ml: bool) =
|
||||||
if ml: s.add("\n")
|
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.
|
## Converts a string `s` to its JSON representation.
|
||||||
result = newStringOfCap(s.len + s.len shr 3)
|
## Appends to ``result``.
|
||||||
|
const
|
||||||
|
HexChars = "0123456789ABCDEF"
|
||||||
result.add("\"")
|
result.add("\"")
|
||||||
for x in runes(s):
|
for x in runes(s):
|
||||||
var r = int(x)
|
var r = int(x)
|
||||||
|
|
@ -967,10 +969,19 @@ proc escapeJson*(s: string): string =
|
||||||
of '\\': result.add("\\\\")
|
of '\\': result.add("\\\\")
|
||||||
else: result.add(c)
|
else: result.add(c)
|
||||||
else:
|
else:
|
||||||
result.add("\\u")
|
# toHex inlined for more speed (saves stupid string allocations):
|
||||||
result.add(toHex(r, 4))
|
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("\"")
|
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,
|
proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true,
|
||||||
lstArr = false, currIndent = 0) =
|
lstArr = false, currIndent = 0) =
|
||||||
case node.kind
|
case node.kind
|
||||||
|
|
@ -988,7 +999,7 @@ proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true,
|
||||||
inc i
|
inc i
|
||||||
# Need to indent more than {
|
# Need to indent more than {
|
||||||
result.indent(newIndent(currIndent, indent, ml))
|
result.indent(newIndent(currIndent, indent, ml))
|
||||||
result.add(escapeJson(key))
|
escapeJson(key, result)
|
||||||
result.add(": ")
|
result.add(": ")
|
||||||
toPretty(result, val, indent, ml, false,
|
toPretty(result, val, indent, ml, false,
|
||||||
newIndent(currIndent, indent, ml))
|
newIndent(currIndent, indent, ml))
|
||||||
|
|
@ -999,16 +1010,19 @@ proc toPretty(result: var string, node: JsonNode, indent = 2, ml = true,
|
||||||
result.add("{}")
|
result.add("{}")
|
||||||
of JString:
|
of JString:
|
||||||
if lstArr: result.indent(currIndent)
|
if lstArr: result.indent(currIndent)
|
||||||
result.add(escapeJson(node.str))
|
escapeJson(node.str, result)
|
||||||
of JInt:
|
of JInt:
|
||||||
if lstArr: result.indent(currIndent)
|
if lstArr: result.indent(currIndent)
|
||||||
result.add($node.num)
|
when defined(js): result.add($node.num)
|
||||||
|
else: result.add(node.num)
|
||||||
of JFloat:
|
of JFloat:
|
||||||
if lstArr: result.indent(currIndent)
|
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:
|
of JBool:
|
||||||
if lstArr: result.indent(currIndent)
|
if lstArr: result.indent(currIndent)
|
||||||
result.add($node.bval)
|
result.add(if node.bval: "true" else: "false")
|
||||||
of JArray:
|
of JArray:
|
||||||
if lstArr: result.indent(currIndent)
|
if lstArr: result.indent(currIndent)
|
||||||
if len(node.elems) != 0:
|
if len(node.elems) != 0:
|
||||||
|
|
@ -1057,12 +1071,12 @@ proc toUgly*(result: var string, node: JsonNode) =
|
||||||
for key, value in pairs(node.fields):
|
for key, value in pairs(node.fields):
|
||||||
if comma: result.add ","
|
if comma: result.add ","
|
||||||
else: comma = true
|
else: comma = true
|
||||||
result.add key.escapeJson()
|
key.escapeJson(result)
|
||||||
result.add ":"
|
result.add ":"
|
||||||
result.toUgly value
|
result.toUgly value
|
||||||
result.add "}"
|
result.add "}"
|
||||||
of JString:
|
of JString:
|
||||||
result.add node.str.escapeJson()
|
node.str.escapeJson(result)
|
||||||
of JInt:
|
of JInt:
|
||||||
result.add($node.num)
|
result.add($node.num)
|
||||||
of JFloat:
|
of JFloat:
|
||||||
|
|
@ -1394,4 +1408,6 @@ when isMainModule:
|
||||||
var parsed2 = parseFile("tests/testdata/jsontest2.json")
|
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(parsed2{"repository", "description"}.str=="IRC Library for Haskell", "Couldn't fetch via multiply nested key using {}")
|
||||||
|
|
||||||
|
doAssert escapeJson("\10FoobarÄ") == "\"\\u000AFoobar\\u00C4\""
|
||||||
|
|
||||||
echo("Tests succeeded!")
|
echo("Tests succeeded!")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue