]> git.proxmox.com Git - ceph.git/blame - ceph/src/jaegertracing/thrift/lib/erl/src/thrift_json_parser.erl
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / jaegertracing / thrift / lib / erl / src / thrift_json_parser.erl
CommitLineData
f67539c2
TL
1%% Licensed to the Apache Software Foundation (ASF) under one
2%% or more contributor license agreements. See the NOTICE file
3%% distributed with this work for additional information
4%% regarding copyright ownership. The ASF licenses this file
5%% to you under the Apache License, Version 2.0 (the
6%% "License"); you may not use this file except in compliance
7%% with the License. You may obtain a copy of the License at
8%%
9%% http://www.apache.org/licenses/LICENSE-2.0
10%%
11%% Unless required by applicable law or agreed to in writing,
12%% software distributed under the License is distributed on an
13%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14%% KIND, either express or implied. See the License for the
15%% specific language governing permissions and limitations
16%% under the License.
17%%
18%% The json parser implementation was created by
19%% alisdair sullivan <alisdair@hartbrake.com> based on
20%% the jsx json library
21
22-module(thrift_json_parser).
23-export([parser/0, handle_event/2]).
24
25
26-record(config, {strict_utf8 = false :: boolean()}).
27
28
29parser() -> fun(JSON) -> start(JSON, {?MODULE, []}, [], #config{}) end.
30
31
32handle_event(Event, {Handler, State}, _Config) -> {Handler, Handler:handle_event(Event, State)}.
33
34handle_event(end_json, State) -> lists:reverse([end_json] ++ State);
35handle_event(Event, State) -> [Event] ++ State.
36
37
38%% whitespace
39-define(space, 16#20).
40-define(tab, 16#09).
41-define(cr, 16#0D).
42-define(newline, 16#0A).
43
44%% object delimiters
45-define(start_object, 16#7B).
46-define(end_object, 16#7D).
47
48%% array delimiters
49-define(start_array, 16#5B).
50-define(end_array, 16#5D).
51
52%% kv seperator
53-define(comma, 16#2C).
54-define(doublequote, 16#22).
55-define(singlequote, 16#27).
56-define(colon, 16#3A).
57
58%% string escape sequences
59-define(rsolidus, 16#5C).
60-define(solidus, 16#2F).
61
62%% math
63-define(zero, 16#30).
64-define(decimalpoint, 16#2E).
65-define(negative, 16#2D).
66-define(positive, 16#2B).
67
68%% comments
69-define(star, 16#2A).
70
71
72%% some useful guards
73-define(is_hex(Symbol),
74 (Symbol >= $a andalso Symbol =< $f) orelse
75 (Symbol >= $A andalso Symbol =< $F) orelse
76 (Symbol >= $0 andalso Symbol =< $9)
77).
78
79-define(is_nonzero(Symbol),
80 Symbol >= $1 andalso Symbol =< $9
81).
82
83-define(is_whitespace(Symbol),
84 Symbol =:= ?space; Symbol =:= ?tab; Symbol =:= ?cr; Symbol =:= ?newline
85).
86
87
88%% lists are benchmarked to be faster (tho higher in memory usage) than binaries
89new_seq() -> [].
90new_seq(C) -> [C].
91
92acc_seq(Seq, C) when is_list(C) -> lists:reverse(C) ++ Seq;
93acc_seq(Seq, C) -> [C] ++ Seq.
94
95end_seq(Seq) -> unicode:characters_to_binary(lists:reverse(Seq)).
96
97end_seq(Seq, _) -> end_seq(Seq).
98
99
100start(<<16#ef, 16#bb, 16#bf, Rest/binary>>, Handler, Stack, Config) ->
101 value(Rest, Handler, Stack, Config);
102start(Bin, Handler, Stack, Config) ->
103 value(Bin, Handler, Stack, Config).
104
105
106value(<<?doublequote, Rest/binary>>, Handler, Stack, Config) ->
107 string(Rest, Handler, new_seq(), Stack, Config);
108value(<<$t, Rest/binary>>, Handler, Stack, Config) ->
109 true(Rest, Handler, Stack, Config);
110value(<<$f, Rest/binary>>, Handler, Stack, Config) ->
111 false(Rest, Handler, Stack, Config);
112value(<<$n, Rest/binary>>, Handler, Stack, Config) ->
113 null(Rest, Handler, Stack, Config);
114value(<<?negative, Rest/binary>>, Handler, Stack, Config) ->
115 negative(Rest, Handler, new_seq($-), Stack, Config);
116value(<<?zero, Rest/binary>>, Handler, Stack, Config) ->
117 zero(Rest, Handler, new_seq($0), Stack, Config);
118value(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_nonzero(S) ->
119 integer(Rest, Handler, new_seq(S), Stack, Config);
120value(<<?start_object, Rest/binary>>, Handler, Stack, Config) ->
121 object(Rest, handle_event(start_object, Handler, Config), [key|Stack], Config);
122value(<<?start_array, Rest/binary>>, Handler, Stack, Config) ->
123 array(Rest, handle_event(start_array, Handler, Config), [array|Stack], Config);
124value(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_whitespace(S) ->
125 value(Rest, Handler, Stack, Config);
126value(_Bin, _Handler, _Stack, _Config) ->
127 erlang:error(badarg).
128
129
130object(<<?doublequote, Rest/binary>>, Handler, Stack, Config) ->
131 string(Rest, Handler, new_seq(), Stack, Config);
132object(<<?end_object, Rest/binary>>, Handler, [key|Stack], Config) ->
133 maybe_done(Rest, handle_event(end_object, Handler, Config), Stack, Config);
134object(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_whitespace(S) ->
135 object(Rest, Handler, Stack, Config);
136object(_Bin, _Handler, _Stack, _Config) ->
137 erlang:error(badarg).
138
139
140array(<<?end_array, Rest/binary>>, Handler, [array|Stack], Config) ->
141 maybe_done(Rest, handle_event(end_array, Handler, Config), Stack, Config);
142array(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_whitespace(S) ->
143 array(Rest, Handler, Stack, Config);
144array(Bin, Handler, Stack, Config) ->
145 value(Bin, Handler, Stack, Config).
146
147
148colon(<<?colon, Rest/binary>>, Handler, [key|Stack], Config) ->
149 value(Rest, Handler, [object|Stack], Config);
150colon(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_whitespace(S) ->
151 colon(Rest, Handler, Stack, Config);
152colon(_Bin, _Handler, _Stack, _Config) ->
153 erlang:error(badarg).
154
155
156key(<<?doublequote, Rest/binary>>, Handler, Stack, Config) ->
157 string(Rest, Handler, new_seq(), Stack, Config);
158key(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_whitespace(S) ->
159 key(Rest, Handler, Stack, Config);
160key(_Bin, _Handler, _Stack, _Config) ->
161 erlang:error(badarg).
162
163
164%% note that if you encounter an error from string and you can't find the clause that
165%% caused it here, it might be in unescape below
166string(<<?doublequote, Rest/binary>>, Handler, Acc, Stack, Config) ->
167 doublequote(Rest, Handler, Acc, Stack, Config);
168string(<<?solidus, Rest/binary>>, Handler, Acc, Stack, Config) ->
169 string(Rest, Handler, acc_seq(Acc, ?solidus), Stack, Config);
170string(<<?rsolidus/utf8, Rest/binary>>, Handler, Acc, Stack, Config) ->
171 unescape(Rest, Handler, Acc, Stack, Config);
172string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#20, X < 16#2028 ->
173 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
174string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X == 16#2028; X == 16#2029 ->
175 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
176string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X > 16#2029, X < 16#d800 ->
177 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
178string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X > 16#dfff, X < 16#fdd0 ->
179 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
180string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X > 16#fdef, X < 16#fffe ->
181 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
182string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#10000, X < 16#1fffe ->
183 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
184string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#20000, X < 16#2fffe ->
185 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
186string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#30000, X < 16#3fffe ->
187 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
188string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#40000, X < 16#4fffe ->
189 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
190string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#50000, X < 16#5fffe ->
191 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
192string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#60000, X < 16#6fffe ->
193 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
194string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#70000, X < 16#7fffe ->
195 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
196string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#80000, X < 16#8fffe ->
197 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
198string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#90000, X < 16#9fffe ->
199 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
200string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#a0000, X < 16#afffe ->
201 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
202string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#b0000, X < 16#bfffe ->
203 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
204string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#c0000, X < 16#cfffe ->
205 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
206string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#d0000, X < 16#dfffe ->
207 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
208string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#e0000, X < 16#efffe ->
209 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
210string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#f0000, X < 16#ffffe ->
211 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
212string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#100000, X < 16#10fffe ->
213 string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
214%% surrogates
215string(<<237, X, _, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false})
216 when X >= 160 ->
217 string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config);
218%% u+xfffe, u+xffff, control codes and other noncharacters
219string(<<_/utf8, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false}) ->
220 string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config);
221%% u+fffe and u+ffff for R14BXX (subsequent runtimes will happily match the
222%% preceding clause
223string(<<239, 191, X, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false})
224 when X == 190; X == 191 ->
225 string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config);
226%% overlong encodings and missing continuations of a 2 byte sequence
227string(<<X, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false})
228 when X >= 192, X =< 223 ->
229 strip_continuations(Rest, Handler, Acc, Stack, Config, 1);
230%% overlong encodings and missing continuations of a 3 byte sequence
231string(<<X, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false})
232 when X >= 224, X =< 239 ->
233 strip_continuations(Rest, Handler, Acc, Stack, Config, 2);
234%% overlong encodings and missing continuations of a 4 byte sequence
235string(<<X, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false})
236 when X >= 240, X =< 247 ->
237 strip_continuations(Rest, Handler, Acc, Stack, Config, 3);
238%% incompletes and unexpected bytes, including orphan continuations
239string(<<_, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false}) ->
240 string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config);
241string(_Bin, _Handler, _Acc, _Stack, _Config) ->
242 erlang:error(badarg).
243
244
245doublequote(Rest, Handler, Acc, [key|_] = Stack, Config) ->
246 colon(Rest, handle_event({key, end_seq(Acc, Config)}, Handler, Config), Stack, Config);
247doublequote(Rest, Handler, Acc, Stack, Config) ->
248 maybe_done(Rest, handle_event({string, end_seq(Acc, Config)}, Handler, Config), Stack, Config).
249
250
251%% strips continuation bytes after bad utf bytes, guards against both too short
252%% and overlong sequences. N is the maximum number of bytes to strip
253strip_continuations(<<Rest/binary>>, Handler, Acc, Stack, Config, 0) ->
254 string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config);
255strip_continuations(<<X, Rest/binary>>, Handler, Acc, Stack, Config, N) when X >= 128, X =< 191 ->
256 strip_continuations(Rest, Handler, Acc, Stack, Config, N - 1);
257%% not a continuation byte, insert a replacement character for sequence thus
258%% far and dispatch back to string
259strip_continuations(<<Rest/binary>>, Handler, Acc, Stack, Config, _) ->
260 string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config).
261
262
263%% this all gets really gross and should probably eventually be folded into
264%% but for now it fakes being part of string on incompletes and errors
265unescape(<<$b, Rest/binary>>, Handler, Acc, Stack, Config) ->
266 string(Rest, Handler, acc_seq(Acc, $\b), Stack, Config);
267unescape(<<$f, Rest/binary>>, Handler, Acc, Stack, Config) ->
268 string(Rest, Handler, acc_seq(Acc, $\f), Stack, Config);
269unescape(<<$n, Rest/binary>>, Handler, Acc, Stack, Config) ->
270 string(Rest, Handler, acc_seq(Acc, $\n), Stack, Config);
271unescape(<<$r, Rest/binary>>, Handler, Acc, Stack, Config) ->
272 string(Rest, Handler, acc_seq(Acc, $\r), Stack, Config);
273unescape(<<$t, Rest/binary>>, Handler, Acc, Stack, Config) ->
274 string(Rest, Handler, acc_seq(Acc, $\t), Stack, Config);
275unescape(<<?doublequote, Rest/binary>>, Handler, Acc, Stack, Config) ->
276 string(Rest, Handler, acc_seq(Acc, $\"), Stack, Config);
277unescape(<<?rsolidus, Rest/binary>>, Handler, Acc, Stack, Config) ->
278 string(Rest, Handler, acc_seq(Acc, $\\), Stack, Config);
279unescape(<<?solidus, Rest/binary>>, Handler, Acc, Stack, Config) ->
280 string(Rest, Handler, acc_seq(Acc, $/), Stack, Config);
281unescape(<<$u, $d, A, B, C, ?rsolidus, $u, $d, X, Y, Z, Rest/binary>>, Handler, Acc, Stack, Config)
282 when (A == $8 orelse A == $9 orelse A == $a orelse A == $b),
283 (X == $c orelse X == $d orelse X == $e orelse X == $f),
284 ?is_hex(B), ?is_hex(C), ?is_hex(Y), ?is_hex(Z)
285 ->
286 High = erlang:list_to_integer([$d, A, B, C], 16),
287 Low = erlang:list_to_integer([$d, X, Y, Z], 16),
288 Codepoint = (High - 16#d800) * 16#400 + (Low - 16#dc00) + 16#10000,
289 string(Rest, Handler, acc_seq(Acc, Codepoint), Stack, Config);
290unescape(<<$u, $d, A, B, C, ?rsolidus, $u, W, X, Y, Z, Rest/binary>>, Handler, Acc, Stack, Config)
291 when (A == $8 orelse A == $9 orelse A == $a orelse A == $b),
292 ?is_hex(B), ?is_hex(C), ?is_hex(W), ?is_hex(X), ?is_hex(Y), ?is_hex(Z)
293 ->
294 string(Rest, Handler, acc_seq(Acc, [16#fffd, 16#fffd]), Stack, Config);
295unescape(<<$u, A, B, C, D, Rest/binary>>, Handler, Acc, Stack, Config)
296 when ?is_hex(A), ?is_hex(B), ?is_hex(C), ?is_hex(D) ->
297 case erlang:list_to_integer([A, B, C, D], 16) of
298 Codepoint when Codepoint < 16#d800; Codepoint > 16#dfff ->
299 string(Rest, Handler, acc_seq(Acc, Codepoint), Stack, Config);
300 _ ->
301 string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config)
302 end;
303unescape(_Bin, _Handler, _Acc, _Stack, _Config) ->
304 erlang:error(badarg).
305
306
307%% like in strings, there's some pseudo states in here that will never
308%% show up in errors or incompletes. some show up in value, some show
309%% up in integer, decimal or exp
310negative(<<$0, Rest/binary>>, Handler, Acc, Stack, Config) ->
311 zero(Rest, Handler, acc_seq(Acc, $0), Stack, Config);
312negative(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when ?is_nonzero(S) ->
313 integer(Rest, Handler, acc_seq(Acc, S), Stack, Config);
314negative(_Bin, _Handler, _Acc, _Stack, _Config) ->
315 erlang:error(badarg).
316
317
318zero(<<?decimalpoint, Rest/binary>>, Handler, Acc, Stack, Config) ->
319 decimal(Rest, Handler, acc_seq(Acc, ?decimalpoint), Stack, Config);
320zero(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= $e; S =:= $E ->
321 e(Rest, Handler, acc_seq(Acc, ".0e"), Stack, Config);
322zero(Bin, Handler, Acc, Stack, Config) ->
323 finish_number(Bin, Handler, {zero, Acc}, Stack, Config).
324
325
326integer(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) ->
327 integer(Rest, Handler, acc_seq(Acc, S), Stack, Config);
328integer(<<?decimalpoint, Rest/binary>>, Handler, Acc, Stack, Config) ->
329 initialdecimal(Rest, Handler, acc_seq(Acc, ?decimalpoint), Stack, Config);
330integer(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= $e; S =:= $E ->
331 e(Rest, Handler, acc_seq(Acc, ".0e"), Stack, Config);
332integer(Bin, Handler, Acc, Stack, Config) ->
333 finish_number(Bin, Handler, {integer, Acc}, Stack, Config).
334
335
336initialdecimal(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) ->
337 decimal(Rest, Handler, acc_seq(Acc, S), Stack, Config);
338initialdecimal(_Bin, _Handler, _Acc, _Stack, _Config) ->
339 erlang:error(badarg).
340
341
342decimal(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) ->
343 decimal(Rest, Handler, acc_seq(Acc, S), Stack, Config);
344decimal(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= $e; S =:= $E ->
345 e(Rest, Handler, acc_seq(Acc, $e), Stack, Config);
346decimal(Bin, Handler, Acc, Stack, Config) ->
347 finish_number(Bin, Handler, {decimal, Acc}, Stack, Config).
348
349
350e(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) ->
351 exp(Rest, Handler, acc_seq(Acc, S), Stack, Config);
352e(<<Sign, Rest/binary>>, Handler, Acc, Stack, Config) when Sign =:= ?positive; Sign =:= ?negative ->
353 ex(Rest, Handler, acc_seq(Acc, Sign), Stack, Config);
354e(_Bin, _Handler, _Acc, _Stack, _Config) ->
355 erlang:error(badarg).
356
357
358ex(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) ->
359 exp(Rest, Handler, acc_seq(Acc, S), Stack, Config);
360ex(_Bin, _Handler, _Acc, _Stack, _Config) ->
361 erlang:error(badarg).
362
363
364exp(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) ->
365 exp(Rest, Handler, acc_seq(Acc, S), Stack, Config);
366exp(Bin, Handler, Acc, Stack, Config) ->
367 finish_number(Bin, Handler, {exp, Acc}, Stack, Config).
368
369
370finish_number(Rest, Handler, Acc, [], Config) ->
371 maybe_done(Rest, handle_event(format_number(Acc), Handler, Config), [], Config);
372finish_number(Rest, Handler, Acc, Stack, Config) ->
373 maybe_done(Rest, handle_event(format_number(Acc), Handler, Config), Stack, Config).
374
375
376format_number({zero, Acc}) -> {integer, list_to_integer(lists:reverse(Acc))};
377format_number({integer, Acc}) -> {integer, list_to_integer(lists:reverse(Acc))};
378format_number({decimal, Acc}) -> {float, list_to_float(lists:reverse(Acc))};
379format_number({exp, Acc}) -> {float, list_to_float(lists:reverse(Acc))}.
380
381
382true(<<$r, $u, $e, Rest/binary>>, Handler, Stack, Config) ->
383 maybe_done(Rest, handle_event({literal, true}, Handler, Config), Stack, Config);
384true(_Bin, _Handler, _Stack, _Config) ->
385 erlang:error(badarg).
386
387
388false(<<$a, $l, $s, $e, Rest/binary>>, Handler, Stack, Config) ->
389 maybe_done(Rest, handle_event({literal, false}, Handler, Config), Stack, Config);
390false(_Bin, _Handler, _Stack, _Config) ->
391 erlang:error(badarg).
392
393
394null(<<$u, $l, $l, Rest/binary>>, Handler, Stack, Config) ->
395 maybe_done(Rest, handle_event({literal, null}, Handler, Config), Stack, Config);
396null(_Bin, _Handler, _Stack, _Config) ->
397 erlang:error(badarg).
398
399
400maybe_done(<<Rest/binary>>, Handler, [], Config) ->
401 done(Rest, handle_event(end_json, Handler, Config), [], Config);
402maybe_done(<<?end_object, Rest/binary>>, Handler, [object|Stack], Config) ->
403 maybe_done(Rest, handle_event(end_object, Handler, Config), Stack, Config);
404maybe_done(<<?end_array, Rest/binary>>, Handler, [array|Stack], Config) ->
405 maybe_done(Rest, handle_event(end_array, Handler, Config), Stack, Config);
406maybe_done(<<?comma, Rest/binary>>, Handler, [object|Stack], Config) ->
407 key(Rest, Handler, [key|Stack], Config);
408maybe_done(<<?comma, Rest/binary>>, Handler, [array|_] = Stack, Config) ->
409 value(Rest, Handler, Stack, Config);
410maybe_done(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_whitespace(S) ->
411 maybe_done(Rest, Handler, Stack, Config);
412maybe_done(_Bin, _Handler, _Stack, _Config) ->
413 erlang:error(badarg).
414
415
416done(<<S, Rest/binary>>, Handler, [], Config) when ?is_whitespace(S) ->
417 done(Rest, Handler, [], Config);
418done(<<>>, {_Handler, State}, [], _Config) -> State;
419done(_Bin, _Handler, _Stack, _Config) -> erlang:error(badarg).