Skip to content

Commit 1c66d68

Browse files
committed
Many tweaks and performance improvements
1 parent ffbf29b commit 1c66d68

File tree

2 files changed

+24
-27
lines changed

2 files changed

+24
-27
lines changed

jsmn.nim

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,16 @@ type
6565
pos: int
6666
toknext: int
6767
toksuper: int
68+
autoResize: bool
6869

6970
JsmnException* = object of ValueError
7071

7172
JsmnNotEnoughTokensException* = object of JsmnException
7273
## not enough tokens, JSON string is too large
74+
7375
JsmnBadTokenException = object of JsmnException
7476
## bad token, JSON string is corrupted
77+
7578
JsmnNotEnoughJsonDataException* = object of JsmnException
7679
## JSON string is too short, expecting more JSON data
7780

@@ -85,10 +88,13 @@ proc `$`(p: JsmnParser): string =
8588

8689
{.push boundChecks: off, overflowChecks: off.}
8790

88-
proc initToken(parser: var JsmnParser, tokens: var openarray[JsmnToken], kind = JSMN_UNDEFINED, start, stop = -1): ptr JsmnToken =
91+
proc initToken(parser: var JsmnParser, tokens: var seq[JsmnToken], kind = JSMN_UNDEFINED, start, stop = -1): ptr JsmnToken =
8992
## Allocates a token and fills type and boundaries.
9093
if parser.toknext >= tokens.len:
91-
raise newException(JsmnNotEnoughTokensException, $parser)
94+
if not parser.autoResize:
95+
raise newException(JsmnNotEnoughTokensException, $parser)
96+
var newLen = int(tokens.len.float * 1.5)
97+
setLen(tokens, newLen)
9298

9399
result = addr tokens[parser.toknext]
94100
result.kind = kind
@@ -110,10 +116,10 @@ proc incSize(tokens: var openarray[JsmnToken], pos: int) {.inline.} =
110116
var parent = tokens[token.parent]
111117
echo "parent: ", parent
112118
if token.stop != -1:
113-
echo "incSize: ", JSON_STRING[token.start..<token.stop], " ", token[]
119+
echo " incSize: ", JSON_STRING[token.start..<token.stop], " ", token[]
114120
inc(token.size)
115121

116-
proc parsePrimitive(parser: var JsmnParser, tokens: var openarray[JsmnToken], json: string, length: int) =
122+
proc parsePrimitive(parser: var JsmnParser, tokens: var seq[JsmnToken], json: string, length: int) =
117123
## Fills next available token with JSON primitive.
118124
var start = parser.pos
119125
while parser.pos < length:
@@ -135,7 +141,7 @@ proc parsePrimitive(parser: var JsmnParser, tokens: var openarray[JsmnToken], js
135141
# In strict mode primitive must be followed by a comma/object/array
136142
raise newException(JsmnBadTokenException, $parser)
137143

138-
proc parseString(parser: var JsmnParser, tokens: var openarray[JsmnToken], json: string, length: int) =
144+
proc parseString(parser: var JsmnParser, tokens: var seq[JsmnToken], json: string, length: int) =
139145
## Fills next token with JSON string.
140146
let start = parser.pos
141147
inc(parser.pos)
@@ -171,7 +177,7 @@ proc parseString(parser: var JsmnParser, tokens: var openarray[JsmnToken], json:
171177
inc(parser.pos)
172178
raise newException(JsmnBadTokenException, $parser)
173179

174-
proc parse(parser: var JsmnParser, tokens: var openarray[JsmnToken], json: string, length: int): int =
180+
proc parse(parser: var JsmnParser, tokens: var seq[JsmnToken], json: string, length: int): int =
175181
## Parse JSON string and fill tokens.
176182
var
177183
token: ptr JsmnToken
@@ -266,19 +272,13 @@ proc parse(parser: var JsmnParser, tokens: var openarray[JsmnToken], json: strin
266272
var t: ptr JsmnToken = addr(tokens[parser.toksuper])
267273
if t.kind == JSMN_OBJECT or (t.kind == JSMN_STRING and t.size != 0):
268274
raise newException(JsmnBadTokenException, $parser)
269-
parsePrimitive(parser, tokens, json, length)
270-
inc(result)
271-
if parser.toksuper != -1:
272-
assert tokens[parser.toksuper].kind == JSMN_STRING or tokens[parser.toksuper].kind == JSMN_ARRAY
273-
incSize(tokens, parser.toksuper)
274275
else:
275276
raise newException(JsmnBadTokenException, $parser)
276-
else:
277-
parsePrimitive(parser, tokens, json, length)
278-
inc(result)
279-
if parser.toksuper != -1:
280-
assert tokens[parser.toksuper].kind == JSMN_STRING or tokens[parser.toksuper].kind == JSMN_ARRAY
281-
incSize(tokens, parser.toksuper)
277+
parsePrimitive(parser, tokens, json, length)
278+
inc(result)
279+
if parser.toksuper != -1:
280+
assert tokens[parser.toksuper].kind == JSMN_STRING or tokens[parser.toksuper].kind == JSMN_ARRAY
281+
incSize(tokens, parser.toksuper)
282282
inc(parser.pos)
283283

284284
var i = parser.toknext - 1
@@ -290,27 +290,24 @@ proc parse(parser: var JsmnParser, tokens: var openarray[JsmnToken], json: strin
290290

291291
{.pop.}
292292

293-
proc parseJson*(json: string, tokens: var openarray[JsmnToken]): int =
293+
proc parseJson*(json: string, tokens: var seq[JsmnToken], autoResize = false): int =
294294
## Parse a JSON data string into and array of tokens, each describing a single JSON object.
295295
when defined(verbose):
296296
JSON_STRING = json
297297
var parser: JsmnParser
298-
parser.pos = 0
299-
parser.toknext = 0
300298
parser.toksuper = -1
299+
parser.autoResize = autoResize
301300
parser.parse(tokens, json, json.len)
302301

303-
proc parseJson*(json: string): seq[JsmnToken] =
302+
proc parseJson*(json: string, initialSize = JSMN_TOKENS, autoResize = false): seq[JsmnToken] =
304303
## Parse a JSON data and returns a sequence of tokens
305304
when defined(verbose):
306305
JSON_STRING = json
307-
result = newSeq[JsmnToken](JSMN_TOKENS)
306+
result = newSeq[JsmnToken](initialSize)
308307
var ret = -1
309308
while ret < 0:
310309
try:
311-
ret = parseJson(json, result)
312-
except JsmnNotEnoughTokensException:
313-
setLen(result, result.len + JSMN_TOKENS)
310+
ret = parseJson(json, result, autoResize)
314311
except:
315312
raise getCurrentException()
316313
setLen(result, ret)

jsmn.nimble

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Package
22

3-
version = "0.1.6"
3+
version = "0.2"
44
author = "Huy Doan"
55
description = "Jsmn - a world fastest JSON parser - in pure Nim"
66
license = "MIT"
77
skipDirs = @["tests"]
88
# Dependencies
99

10-
requires "nim >= 0.13.1"
10+
requires "nim >= 0.19.4"

0 commit comments

Comments
 (0)