diff --git a/src/jsonpak/dollar.nim b/src/jsonpak/dollar.nim index 2be5c9d..58c8f85 100644 --- a/src/jsonpak/dollar.nim +++ b/src/jsonpak/dollar.nim @@ -1,5 +1,29 @@ -from std/json import escapeJsonUnquoted, escapeJson import private/[bitabs, jsonnode, jsontree], std/importutils +from std/strutils import toHex + +proc escapeJsonUnquoted*(s: string; result: var string) = + ## Converts a string `s` to its JSON representation without quotes. + ## Appends to `result`. + for c in s: + case c + of '\L': result.add("\\n") + of '\b': result.add("\\b") + of '\f': result.add("\\f") + of '\t': result.add("\\t") + of '\v': result.add("\\u000b") + of '\r': result.add("\\r") + of '"': result.add("\\\"") + of '\0'..'\7': result.add("\\u000" & $ord(c)) + of '\14'..'\31': result.add("\\u00" & toHex(ord(c), 2)) + of '\\': result.add("\\\\") + else: result.add(c) + +proc escapeJson*(s: string; result: var string) = + ## Converts a string `s` to its JSON representation with quotes. + ## Appends to `result`. + result.add("\"") + escapeJsonUnquoted(s, result) + result.add("\"") type JsonIter = object diff --git a/src/jsonpak/private/bitabs.nim b/src/jsonpak/private/bitabs.nim index 36de5ad..adb9983 100644 --- a/src/jsonpak/private/bitabs.nim +++ b/src/jsonpak/private/bitabs.nim @@ -2,6 +2,7 @@ ## of (Table[LitId, Val], Table[Val, LitId]). import std/[hashes, assertions] +from std/math import nextPowerOfTwo const defaultInitialSize = 64 @@ -15,6 +16,13 @@ type vals: seq[T] # indexed by LitId keys: seq[Key] # indexed by hash(val) +proc slotsNeeded(count: Natural): int {.inline.} = + # Make sure to synchronize with `mustRehash` + result = nextPowerOfTwo(count * 3 div 2 + 4) + +proc initBiTable*[T](initialSize = defaultInitialSize): BiTable[T] = + BiTable[T](vals: @[], keys: newSeq[Key](slotsNeeded(initialSize))) + proc nextTry(h, maxHash: Hash): Hash {.inline.} = result = (h + 1) and maxHash