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). 420