%%%--------------------------------------------------------------------- %%% @copyright 2023 William Fank Thomé %%% @author William Fank Thomé %%% @doc JSON parser. %%% %%% Copyright 2023 William Fank Thomé %%% %%% Licensed under the Apache License, Version 2.0 (the "License"); %%% you may not use this file except in compliance with the License. %%% You may obtain a copy of the License at %%% %%% http://www.apache.org/licenses/LICENSE-2.0 %%% %%% Unless required by applicable law or agreed to in writing, software %%% distributed under the License is distributed on an "AS IS" BASIS, %%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %%% See the License for the specific language governing permissions and %%% limitations under the License. %%% %%% @end %%%--------------------------------------------------------------------- -module(euneus_decoder). -compile({ inline, plugins/3 }). -compile({ inline, string/6 }). -compile({ inline, string/7 }). -compile({ inline, number/6 }). -compile({ inline, number_exp_cont/7 }). -compile({ inline, number_exp_sign/6 }). -compile({ inline, number_exp_sign/7 }). -compile({ inline, number_exp_copy/6 }). -compile({ inline, number_zero/6 }). -compile({ inline, escapeu_1/8 }). -compile({ inline, escapeu_2/8 }). -compile({ inline, try_parse_integer/7 }). -compile({ inline, try_parse_float/7 }). -compile({ inline, object/6 }). -compile({ inline, array/6 }). -compile({ inline, empty_array/5 }). -compile({ inline, escape/6 }). -compile({ inline, continue/6 }). -compile({ inline, chars_to_integer/2 }). -compile({ inline, chars_to_integer/3 }). -compile({ inline, chars_to_integer/4 }). -compile({ inline, maps_get/3 }). -compile({ inline_list_funcs, true }). -dialyzer({ no_return, throw_byte/5 }). -dialyzer({ no_return, throw_token/6 }). -dialyzer({ no_return, throw_eof/4 }). -dialyzer( no_improper_lists ). %% API functions -export([ decode/2 ]). -export([ parse_opts/1 ]). -export([ get_null_term_option/1 ]). -export([ get_keys_option/1 ]). -export([ get_values_option/1 ]). -export([ get_arrays_option/1 ]). -export([ get_objects_option/1 ]). -export([ get_error_handler_option/1 ]). -export([ get_plugins_option/1 ]). -export([ decode_parsed/2 ]). -export([ resume/6 ]). -export([ resume/7 ]). -export([ handle_error/3 ]). %% Types -export_type([ input/0 ]). -export_type([ options/0 ]). -export_type([ parsed_options/0 ]). -export_type([ result/0 ]). -export_type([ normalizer/1 ]). -export_type([ error_reason/0 ]). -export_type([ error_handler/0 ]). -record(opts, { null_term :: term() , keys :: undefined | copy | to_atom | to_existing_atom | to_integer | normalizer(Key :: binary()) , values :: undefined | copy | to_atom | to_existing_atom | to_integer | normalizer(Value :: binary()) , arrays :: undefined | normalizer(Array :: list()) , objects :: undefined | normalizer(Object :: map()) , error_handler :: error_handler() , plugins :: [plugin()] }). -type input() :: binary() | iolist(). -type options() :: map(). -type parsed_options() :: #opts{}. -type position() :: non_neg_integer(). -type result() :: {ok, term()} | {error, error_reason()}. -type normalizer(Term) :: fun((Term, parsed_options()) -> term()). -type error_class() :: error | exit | throw. -type unexpected_end_of_input_error() :: unexpected_end_of_input. -type unexpected_byte_error() :: {unexpected_byte, binary(), position()}. -type unexpected_sequence_error() :: {unexpected_sequence, binary(), position()}. -type invalid_option_error() :: {invalid_option, term()}. -type error_reason() :: unexpected_end_of_input_error() | unexpected_byte_error() | unexpected_sequence_error() | invalid_option_error(). -type error_stacktrace() :: erlang:stacktrace(). -type error_handler() :: fun(( error_class() , error_reason() , error_stacktrace() ) -> error_stacktrace()). -type plugin() :: datetime | inet | pid | port | reference | timestamp | module() . %% Macros % NOTE: We use integers instead of atoms to take advantage of % the jump table optimization. -define(terminate, 0). -define(array, 1). -define(key, 2). -define(object, 3). -define(range(X, Min, Max), is_integer(X) andalso X >= Min andalso X =< Max). -define(is_number(X), X >= $0, X =< $9). -define(NON_PRINTABLE_LAST, 31). -define(ONE_BYTE_LAST, 127). -define(TWO_BYTE_LAST, 2_047). -define(THREE_BYTE_LAST, 65_535). %%%===================================================================== %%% API functions %%%===================================================================== %%---------------------------------------------------------------------- %% @doc Parses JSON to Erlang term. %% %% @param Input :: {@link euneus_decoder:input()}. %% @param Opts :: {@link euneus_decoder:options()}. %% %% @returns {@link euneus_decoder:result()}. %% %% @end %%---------------------------------------------------------------------- -spec decode(input(), options()) -> result(). decode(Input, Opts) when is_map(Opts) -> decode_parsed(Input, parse_opts(Opts)). %%---------------------------------------------------------------------- %% @doc Parses {@link euneus_decoder:options()} to {@link euneus_decoder:parsed_options()}. %% %% The parsed map can be expanded in compile time or stored to be %% reused, avoiding parsing the options in every encoding. %% %% @param Opts :: {@link euneus_decoder:options()}. %% %% @returns {@link euneus_decoder:parsed_options()}. %% %% @end %%---------------------------------------------------------------------- -spec parse_opts(options()) -> parsed_options(). parse_opts(Opts) -> #opts{ null_term = maps_get(null_term, Opts, undefined), keys = case maps_get(keys, Opts, undefined) of undefined -> undefined; copy -> fun(X, _O) -> binary:copy(X) end; to_atom -> fun(X, _O) -> binary_to_atom(X, utf8) end; to_existing_atom -> fun(X, _O) -> binary_to_existing_atom(X, utf8) end; to_integer -> fun(X, _O) -> binary_to_integer(X) end; Fun when is_function(Fun, 2) -> Fun end, values = case maps_get(values, Opts, undefined) of undefined -> undefined; copy -> fun(X, _O) -> binary:copy(X) end; to_atom -> fun(X, _O) -> binary_to_atom(X, utf8) end; to_existing_atom -> fun(X, _O) -> binary_to_existing_atom(X, utf8) end; to_integer -> fun(X, _O) -> binary_to_integer(X) end; Fun when is_function(Fun, 2) -> Fun end, arrays = case maps_get(arrays, Opts, undefined) of undefined -> undefined; Fun when is_function(Fun, 2) -> Fun end, objects = case maps_get(objects, Opts, undefined) of undefined -> undefined; Fun when is_function(Fun, 2) -> Fun end, error_handler = case maps_get(error_handler, Opts, undefined) of undefined -> fun(C, R, S) -> handle_error(C, R, S) end; Fun when is_function(Fun, 3) -> Fun end, plugins = maps_get(plugins, Opts, []) }. %%%--------------------------------------------------------------------- %%% Options %%%--------------------------------------------------------------------- get_null_term_option(#opts{null_term = Null}) -> Null. get_keys_option(#opts{keys = Keys}) -> Keys. get_values_option(#opts{values = Values}) -> Values. get_arrays_option(#opts{arrays = Arrays}) -> Arrays. get_objects_option(#opts{objects = Objects}) -> Objects. get_error_handler_option(#opts{error_handler = Handler}) -> Handler. get_plugins_option(#opts{plugins = Plugins}) -> Plugins. %%---------------------------------------------------------------------- %% @doc Parses JSON to Erlang term. %% %% @param JSON :: {@link erlang:binary()}. %% @param IOList :: {@link erlang:iolist()}. %% @param Opts :: {@link euneus_decoder:parsed_options()}. %% %% @returns {@link euneus_decoder:result()}. %% %% @end %%---------------------------------------------------------------------- -spec decode_parsed(input(), parsed_options()) -> result(). decode_parsed(JSON, Opts) when is_binary(JSON) -> try {ok, value(JSON, Opts, JSON, 0, [?terminate])} catch Class:Reason:Stacktrace -> Handle = Opts#opts.error_handler, Handle(Class, Reason, Stacktrace) end; decode_parsed(IOList, Opts) -> try decode_parsed(iolist_to_binary(IOList), Opts) catch error:badarg -> {error, not_an_iodata} end. %%---------------------------------------------------------------------- %% @doc Resumes the decoding after a token error. %% %% Passes the null_term option as the Replacement argument of {@link euneus_decoder:resume/7}. %% %% @param Token :: {@link erlang:binary()}. %% @param Rest :: {@link erlang:bitstring()}. %% @param Opts :: {@link euneus_decoder:parsed_options()}. %% @param Input :: {@link erlang:binary()}. %% @param Pos :: {@link erlang:non_neg_integer()}. %% @param Buffer :: {@link erlang:list()}. %% %% @returns {@link euneus_decoder:result()}. %% %% @end %%---------------------------------------------------------------------- -spec resume(Token, Rest, Opts, Input, Pos, Buffer) -> Result when Token :: binary(), Rest :: bitstring(), Opts :: parsed_options(), Input :: binary(), Pos :: non_neg_integer(), Buffer :: list(), Result :: result(). resume(Token, Rest0, #opts{null_term = Null} = Opts, Input, Pos0, Buffer) -> resume(Token, Null, Rest0, Opts, Input, Pos0, Buffer). %%---------------------------------------------------------------------- %% @doc Resumes the decoding after a token error. %% %% @param :: Token {@link erlang:binary()}. %% @param :: Replacement {@link erlang:term()}. %% @param :: Rest {@link erlang:bitstring()}. %% @param :: Opts {@link euneus_decoder:parsed_options()}. %% @param :: Input {@link erlang:binary()}. %% @param :: Pos {@link erlang:non_neg_integer()}. %% @param :: Buffer {@link erlang:list()}. %% %% @returns {@link euneus_decoder:result()}. %% %% @end %%---------------------------------------------------------------------- -spec resume(Token, Replacement, Rest, Opts, Input, Pos, Buffer) -> Result when Token :: binary(), Replacement :: term(), Rest :: bitstring(), Opts :: parsed_options(), Input :: binary(), Pos :: non_neg_integer(), Buffer :: list(), Result :: result(). resume(Token, Replacement, Rest0, Opts, Input, Pos0, Buffer) -> Pos = Pos0 + byte_size(Token), try {ok, continue(Rest0, Opts, Input, Pos, Buffer, Replacement)} catch Class:Reason:Stacktrace -> Handle = Opts#opts.error_handler, Handle(Class, Reason, Stacktrace) end. %%---------------------------------------------------------------------- %% @doc Handles decoding errors. %% %% @param Class :: 'error' | 'exit' | 'throw'. %% @param Reason :: {@link erlang:term()}. %% @param Stacktrace :: {@link erlang:stacktrace()}. %% %% @returns {error, {@link erlang:term()}} | {@link erlang:no_return()}. %% %% @end %%---------------------------------------------------------------------- -spec handle_error(Class, Reason, Stacktrace) -> Result when Class :: error | exit | throw, Reason :: term(), Stacktrace :: erlang:stacktrace(), Result :: {error, term()} | no_return(). handle_error(throw, Reason, _Stacktrace) -> case Reason of {eof, _Opts, _Input, _Pos, _Buffer} -> {error, unexpected_end_of_input}; {{byte, Byte}, _Rest, _Opts, _Input, Pos, _Buffer} -> Hex = <<"0x"/utf8,(integer_to_binary(Byte, 16))/binary>>, {error, {unexpected_byte, Hex, Pos}}; {{token, Token}, _Rest, _Opts, _Input, Pos, _Buffer} -> {error, {unexpected_sequence, Token, Pos}}; {invalid_option, Key} -> {error, {invalid_option, Key}}; _ -> {error, Reason} end; handle_error(Class, Reason, Stacktrace) -> erlang:raise(Class, Reason, Stacktrace). %%%===================================================================== %%% Internal functions %%%===================================================================== key(Data, Opts, Input, Pos, Buffer) -> case Data of <<$\s/integer, Rest/bitstring>> -> key(Rest, Opts, Input, Pos + 1, Buffer); <<$\t/integer, Rest/bitstring>> -> key(Rest, Opts, Input, Pos + 1, Buffer); <<$\r/integer, Rest/bitstring>> -> key(Rest, Opts, Input, Pos + 1, Buffer); <<$\n/integer, Rest/bitstring>> -> key(Rest, Opts, Input, Pos + 1, Buffer); <<$"/integer, Rest/bitstring>> -> string(Rest, Opts, Input, Pos + 1, [?key | Buffer], 0); <<$}/integer, Rest/bitstring>> -> case Buffer of [[] | Buffer1] -> continue(Rest, Opts, Input, Pos + 1, Buffer1, #{}); [_|_] -> throw_byte(Data, Opts, Input, Pos, Buffer) end; <<_/integer, _/bitstring>> -> throw_byte(Data, Opts, Input, Pos, Buffer); <<_/bitstring>> -> throw_eof(Opts, Input, Pos, Buffer) end. key(Data, Opts, Input, Pos, Buffer, Value) -> case Data of <<$\s/integer, Rest/bitstring>> -> key(Rest, Opts, Input, Pos + 1, Buffer, Value); <<$\t/integer, Rest/bitstring>> -> key(Rest, Opts, Input, Pos + 1, Buffer, Value); <<$\r/integer, Rest/bitstring>> -> key(Rest, Opts, Input, Pos + 1, Buffer, Value); <<$\n/integer, Rest/bitstring>> -> key(Rest, Opts, Input, Pos + 1, Buffer, Value); <<$:/integer, Rest/bitstring>> -> value(Rest, Opts, Input, Pos + 1, [?object, Value | Buffer]); <<_/integer, _/bitstring>> -> throw_byte(Data, Opts, Input, Pos, Buffer); <<_/bitstring>> -> throw_eof(Opts, Input, Pos, Buffer) end. value(Data, Opts, Input, Pos, Buffer) -> case Data of <<$\s/integer, Rest/bitstring>> -> value(Rest, Opts, Input, Pos + 1, Buffer); <<$\t/integer, Rest/bitstring>> -> value(Rest, Opts, Input, Pos + 1, Buffer); <<$\r/integer, Rest/bitstring>> -> value(Rest, Opts, Input, Pos + 1, Buffer); <<$\n/integer, Rest/bitstring>> -> value(Rest, Opts, Input, Pos + 1, Buffer); <<$"/integer, Rest/bitstring>> -> string(Rest, Opts, Input, Pos + 1, Buffer, 0); <<$0/integer, Rest/bitstring>> -> number_zero(Rest, Opts, Input, Pos, Buffer, 1); <<$1/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, 1); <<$2/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, 1); <<$3/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, 1); <<$4/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, 1); <<$5/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, 1); <<$6/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, 1); <<$7/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, 1); <<$8/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, 1); <<$9/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, 1); <<$-/integer, Rest/bitstring>> -> number_minus(Rest, Opts, Input, Pos, Buffer); <<$[/integer, Rest/bitstring>> -> value(Rest, Opts, Input, Pos + 1, [?array, [] | Buffer]); <<$]/integer, Rest/bitstring>> -> empty_array(Rest, Opts, Input, Pos + 1, Buffer); <<${/integer, Rest/bitstring>> -> key(Rest, Opts, Input, Pos + 1, [[] | Buffer]); <<"false", Rest/bitstring>> -> continue(Rest, Opts, Input, Pos + 5, Buffer, false); <<"null", Rest/bitstring>> -> continue(Rest, Opts, Input, Pos + 4, Buffer, Opts#opts.null_term); <<"true", Rest/bitstring>> -> continue(Rest, Opts, Input, Pos + 4, Buffer, true); <<_/integer, Rest/bitstring>> -> throw_byte(Rest, Opts, Input, Pos, Buffer); <<_/bitstring>> -> throw_eof(Opts, Input, Pos, Buffer) end. string(Data, Opts, Input, Pos, Buffer, Len) -> case Data of <<$"/integer, Rest/bitstring>> -> Last = binary_part(Input, Pos, Len), Value = case Buffer of [?key | _] -> case plugins(Opts#opts.plugins, Last, Opts) of next -> case Opts of #opts{keys = undefined} -> Last; #opts{keys = Normalize} -> Normalize(Last, Opts) end; {halt, Term} -> Term end; [_|_] -> case plugins(Opts#opts.plugins, Last, Opts) of next -> case Opts of #opts{values = undefined} -> Last; #opts{values = Normalize} -> Normalize(Last, Opts) end; {halt, Term} -> Term end end, continue(Rest, Opts, Input, Pos + Len + 1, Buffer, Value); <<$\\/integer, Rest/bitstring>> -> Part = binary_part(Input, Pos, Len), escape(Rest, Opts, Input, Pos + Len, Buffer, Part); <> when X =< ?NON_PRINTABLE_LAST -> throw_byte(Data, Opts, Input, Pos, Buffer); <> when X =< ?ONE_BYTE_LAST -> string(Rest, Opts, Input, Pos, Buffer, Len + 1); <> when Char =< ?TWO_BYTE_LAST -> string(Rest, Opts, Input, Pos, Buffer, Len + 2); <> when Char =< ?THREE_BYTE_LAST -> string(Rest, Opts, Input, Pos, Buffer, Len + 3); <<_Char/utf8, Rest/bitstring>> -> string(Rest, Opts, Input, Pos, Buffer, Len + 4); <<_/integer, _/bitstring>> -> throw_byte(Data, Opts, Input, Pos, Buffer); <<_/bitstring>> -> throw_eof(Opts, Input, Pos, Buffer) end. string(Data, Opts, Input, Pos, Buffer, Acc, Len) -> case Data of <<$"/integer, Rest/bitstring>> -> Last = binary_part(Input, Pos, Len), String = iolist_to_binary([Acc | Last]), continue(Rest, Opts, Input, Pos + Len + 1, Buffer, String); <<$\\/integer, Rest/bitstring>> -> Part = binary_part(Input, Pos, Len), escape(Rest, Opts, Input, Pos + Len, Buffer, [Acc | Part]); <> when X =< ?NON_PRINTABLE_LAST -> throw_byte(Data, Opts, Input, Pos, Buffer); <> when X =< ?ONE_BYTE_LAST -> string(Rest, Opts, Input, Pos, Buffer, Acc, Len + 1); <> when Char =< ?TWO_BYTE_LAST -> string(Rest, Opts, Input, Pos, Buffer, Acc, Len + 2); <> when Char =< ?THREE_BYTE_LAST -> string(Rest, Opts, Input, Pos, Buffer, Acc, Len + 3); <<_Char/utf8, Rest/bitstring>> -> string(Rest, Opts, Input, Pos, Buffer, Acc, Len + 4); <<_/integer, _/bitstring>> -> throw_byte(Data, Opts, Input, Pos, Buffer); <<_/bitstring>> -> throw_eof(Opts, Input, Pos, Buffer) end. number(Data, Opts, Input, Pos, Buffer, Len) -> case Data of <<$0/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$1/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$2/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$3/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$4/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$5/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$6/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$7/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$8/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$9/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$./integer, Rest/bitstring>> -> number_frac(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$e/integer, Rest/bitstring>> -> Prefix = binary_part(Input, Pos, Len), number_exp_copy(Rest, Opts, Input, Pos + Len + 1, Buffer, Prefix); <<$E/integer, Rest/bitstring>> -> Prefix = binary_part(Input, Pos, Len), number_exp_copy(Rest, Opts, Input, Pos + Len + 1, Buffer, Prefix); <> -> Token = binary_part(Input, Pos, Len), Int = try_parse_integer(Token, Token, Rest, Opts, Input, Pos, Buffer), continue(Rest, Opts, Input, Pos + Len, Buffer, Int) end. number_exp(Data, Opts, Input, Pos, Buffer, Len) -> case Data of <<$0/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$1/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$2/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$3/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$4/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$5/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$6/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$7/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$8/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$9/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$-/integer, Rest/bitstring>> -> number_exp_sign(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$+/integer, Rest/bitstring>> -> number_exp_sign(Rest, Opts, Input, Pos, Buffer, Len + 1); <<_/integer, _/bitstring>> -> throw_byte(Data, Opts, Input, Pos + Len, Buffer); <<_/bitstring>> -> throw_eof(Opts, Input, Pos, Buffer) end. number_exp_cont(Data, Opts, Input, Pos, Buffer, Len) -> case Data of <<$0/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$1/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$2/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$3/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$4/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$5/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$6/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$7/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$8/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$9/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <> -> Token = binary_part(Input, Pos, Len), Float = try_parse_float(Token, Token, Rest, Opts, Input, Pos, Buffer), continue(Rest, Opts, Input, Pos + Len, Buffer, Float) end. number_exp_cont(Data, Opts, Input, Pos, Buffer, Prefix, Len) -> case Data of <<$0/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <<$1/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <<$2/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <<$3/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <<$4/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <<$5/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <<$6/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <<$7/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <<$8/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <<$9/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <> -> Suffix = binary_part(Input, Pos, Len), String = <>, PrefixSize = byte_size(Prefix), InitialPos = Pos - PrefixSize - 1, FinalPos = Pos + Len, Token = binary_part(Input, InitialPos, PrefixSize + Len + 1), Float = try_parse_float(String, Token, Rest, Opts, Input, InitialPos, Buffer), continue(Rest, Opts, Input, FinalPos, Buffer, Float) end. number_exp_copy(Data, Opts, Input, Pos, Buffer, Prefix) -> case Data of <<$0/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, 1); <<$1/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, 1); <<$2/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, 1); <<$3/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, 1); <<$4/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, 1); <<$5/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, 1); <<$6/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, 1); <<$7/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, 1); <<$8/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, 1); <<$9/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, 1); <<$-/integer, Rest/bitstring>> -> number_exp_sign(Rest, Opts, Input, Pos, Buffer, Prefix, 1); <<$+/integer, Rest/bitstring>> -> number_exp_sign(Rest, Opts, Input, Pos, Buffer, Prefix, 1); <<_/integer, _/bitstring>> -> throw_byte(Data, Opts, Input, Pos, Buffer); <<_/bitstring>> -> throw_eof(Opts, Input, Pos, Buffer) end. number_exp_sign(Data, Opts, Input, Pos, Buffer, Len) -> case Data of <<$0/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$1/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$2/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$3/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$4/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$5/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$6/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$7/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$8/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$9/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<_/integer, _/bitstring>> -> throw_byte(Data, Opts, Input, Pos + Len, Buffer); <<_/bitstring>> -> throw_eof(Opts, Input, Pos, Buffer) end. number_exp_sign(Data, Opts, Input, Pos, Buffer, Prefix, Len) -> case Data of <<$0/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <<$1/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <<$2/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <<$3/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <<$4/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <<$5/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <<$6/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <<$7/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <<$8/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <<$9/integer, Rest/bitstring>> -> number_exp_cont(Rest, Opts, Input, Pos, Buffer, Prefix, Len + 1); <<_/integer, _/bitstring>> -> throw_byte(Data, Opts, Input, Pos + Len, Buffer); <<_/bitstring>> -> throw_eof(Opts, Input, Pos, Buffer) end. number_frac(Data, Opts, Input, Pos, Buffer, Len) -> case Data of <<$0/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$1/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$2/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$3/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$4/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$5/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$6/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$7/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$8/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$9/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<_/integer, _/bitstring>> -> throw_byte(Data, Opts, Input, Pos + Len, Buffer); <<_/bitstring>> -> throw_eof(Opts, Input, Pos, Buffer) end. number_frac_cont(Data, Opts, Input, Pos, Buffer, Len) -> case Data of <<$0/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$1/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$2/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$3/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$4/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$5/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$6/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$7/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$8/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$9/integer, Rest/bitstring>> -> number_frac_cont(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$e/integer, Rest/bitstring>> -> number_exp(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$E/integer, Rest/bitstring>> -> number_exp(Rest, Opts, Input, Pos, Buffer, Len + 1); <> -> Token = binary_part(Input, Pos, Len), Float = try_parse_float(Token, Token, Rest, Opts, Input, Pos, Buffer), continue(Rest, Opts, Input, Pos + Len, Buffer, Float) end. number_minus(Data, Opts, Input, Pos, Buffer) -> case Data of <<$0/integer, Rest/bitstring>> -> number_zero(Rest, Opts, Input, Pos, Buffer, 2); <<$1/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, 2); <<$2/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, 2); <<$3/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, 2); <<$4/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, 2); <<$5/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, 2); <<$6/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, 2); <<$7/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, 2); <<$8/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, 2); <<$9/integer, Rest/bitstring>> -> number(Rest, Opts, Input, Pos, Buffer, 2); <<_/integer, _/bitstring>> -> throw_byte(Data, Opts, Input, Pos + 1, Buffer); <<_/bitstring>> -> throw_eof(Opts, Input, Pos, Buffer) end. number_zero(Data, Opts, Input, Pos, Buffer, Len) -> case Data of <<$./integer, Rest/bitstring>> -> number_frac(Rest, Opts, Input, Pos, Buffer, Len + 1); <<$e/integer, Rest/bitstring>> -> number_exp_copy(Rest, Opts, Input, Pos + Len + 1, Buffer, <<"0">>); <<$E/integer, Rest/bitstring>> -> number_exp_copy(Rest, Opts, Input, Pos + Len + 1, Buffer, <<"0">>); <> -> continue(Rest, Opts, Input, Pos + Len, Buffer, 0) end. try_parse_integer(Bin, Token, Rest, Opts, Input, Pos, Buffer) -> try binary_to_integer(Bin) catch error:badarg -> throw_token(Token, Rest, Opts, Input, Pos, Buffer) end. try_parse_float(Bin, Token, Rest, Opts, Input, Pos, Buffer) -> try binary_to_float(Bin) catch error:badarg -> throw_token(Token, Rest, Opts, Input, Pos, Buffer) end. object(Data, Opts, Input, Pos, Buffer, Value) -> case Data of <<$\s/integer, Rest/bitstring>> -> object(Rest, Opts, Input, Pos + 1, Buffer, Value); <<$\t/integer, Rest/bitstring>> -> object(Rest, Opts, Input, Pos + 1, Buffer, Value); <<$\r/integer, Rest/bitstring>> -> object(Rest, Opts, Input, Pos + 1, Buffer, Value); <<$\n/integer, Rest/bitstring>> -> object(Rest, Opts, Input, Pos + 1, Buffer, Value); <<$,/integer, Rest/bitstring>> -> [Key, Acc | Buffer2] = Buffer, Acc2 = [{Key, Value} | Acc], key(Rest, Opts, Input, Pos + 1, [Acc2 | Buffer2]); <<$}/integer, Rest/bitstring>> -> [Key, Acc2 | Buffer2] = Buffer, Map = maps:from_list([{Key, Value} | Acc2]), Value1 = case plugins(Opts#opts.plugins, Map, Opts) of next -> case Opts of #opts{objects = undefined} -> Map; #opts{objects = Normalize} -> Normalize(Map, Opts) end; {halt, Term} -> Term end, continue(Rest, Opts, Input, Pos + 1, Buffer2, Value1); <<_/integer, _/bitstring>> -> throw_byte(Data, Opts, Input, Pos, Buffer); <<_/bitstring>> -> throw_eof(Opts, Input, Pos, Buffer) end. array(Data, Opts, Input, Pos, Buffer, Value) -> case Data of <<$\t/integer, Rest/bitstring>> -> array(Rest, Opts, Input, Pos + 1, Buffer, Value); <<$\n/integer, Rest/bitstring>> -> array(Rest, Opts, Input, Pos + 1, Buffer, Value); <<$\r/integer, Rest/bitstring>> -> array(Rest, Opts, Input, Pos + 1, Buffer, Value); <<$\s/integer, Rest/bitstring>> -> array(Rest, Opts, Input, Pos + 1, Buffer, Value); <<$,/integer, Rest/bitstring>> -> [Acc | Buffer2] = Buffer, value(Rest, Opts, Input, Pos + 1, [?array, [Value | Acc] | Buffer2]); <<$]/integer, Rest/bitstring>> -> [Acc | Buffer2] = Buffer, List = lists:reverse(Acc, [Value]), Value1 = case plugins(Opts#opts.plugins, List, Opts) of next -> case Opts of #opts{arrays = undefined} -> List; #opts{arrays = Normalize} -> Normalize(List, Opts) end; {halt, Term} -> Term end, continue(Rest, Opts, Input, Pos + 1, Buffer2, Value1); <<_/integer, _/bitstring>> -> throw_byte(Data, Opts, Input, Pos, Buffer); <<_/bitstring>> -> throw_eof(Opts, Input, Pos, Buffer) end. empty_array(Rest, Opts, Input, Pos, Buffer) -> case Buffer of [?array, [] | Buffer1] -> List = case Opts of #opts{arrays = undefined} -> []; #opts{arrays = Normalize} -> Normalize([], Opts) end, continue(Rest, Opts, Input, Pos, Buffer1, List); [_|_] -> throw_byte(Rest, Opts, Input, Pos - 1, Buffer) end. plugins([], _Bin, _Opts) -> next; plugins([datetime | T], Term, Opts) -> case Term of << Y4/integer, Y3/integer, Y2/integer, Y1/integer, $-/integer , M2/integer, M1/integer, $-/integer , D2/integer, D1/integer , $T/integer , H2/integer, H1/integer, $:/integer , Min2/integer, Min1/integer, $:/integer , S2/integer, S1/integer , $Z/integer >> when ?is_number(Y4), ?is_number(Y3), ?is_number(Y2), ?is_number(Y1) , ?is_number(M2), ?is_number(M1) , ?is_number(D2), ?is_number(D1) , ?is_number(H2), ?is_number(H1) , ?is_number(Min2), ?is_number(Min1) , ?is_number(S2), ?is_number(S1) -> Date = { chars_to_integer(Y4, Y3, Y2, Y1) , chars_to_integer(M2, M1) , chars_to_integer(D2, D1) }, Time = { chars_to_integer(H2, H1) , chars_to_integer(Min2, Min1) , chars_to_integer(S2, S1) }, DateTime = {Date, Time}, {halt, DateTime}; _ -> plugins(T, Term, Opts) end; plugins([inet | T], Term, Opts) -> case Term of <> when ?range(A, 0, 255); ?range(B, 0, 255); ?range(C, 0, 255) -> case inet_parse:ipv4_address(binary_to_list(Term)) of {ok, Ip} -> {halt, Ip}; {error, einval} -> plugins(T, Term, Opts) end; <> when ?range(A, 0, 255); ?range(B, 0, 255) -> case inet_parse:ipv4_address(binary_to_list(Term)) of {ok, Ip} -> {halt, Ip}; {error, einval} -> plugins(T, Term, Opts) end; <> when ?range(A, 0, 255) -> case inet_parse:ipv4_address(binary_to_list(Term)) of {ok, Ip} -> {halt, Ip}; {error, einval} -> plugins(T, Term, Opts) end; <<$:, $:>> -> {halt, {0,0,0,0,0,0,0,0}}; <<$:, $:, _/bitstring>> -> case inet_parse:ipv6strict_address(binary_to_list(Term)) of {ok, Ipv6} -> {halt, Ipv6}; {error, einval} -> plugins(T, Term, Opts) end; <<_/integer, _/integer, _/integer, _/integer, $:, _/bitstring>> -> case inet_parse:ipv6strict_address(binary_to_list(Term)) of {ok, Ipv6} -> {halt, Ipv6}; {error, einval} -> plugins(T, Term, Opts) end; _ -> plugins(T, Term, Opts) end; plugins([pid | T], Term, Opts) -> case Term of <<$<, _/bitstring>> -> try Pid = list_to_pid(binary_to_list(Term)), {halt, Pid} catch error:badarg -> plugins(T, Term, Opts) end; _ -> plugins(T, Term, Opts) end; plugins([port | T], Term, Opts) -> case Term of <<"#Port<", _/bitstring>> -> try Port = list_to_port(binary_to_list(Term)), {halt, Port} catch error:badarg -> plugins(T, Term, Opts) end; _ -> plugins(T, Term, Opts) end; plugins([reference | T], Term, Opts) -> case Term of <<"#Ref<", _/bitstring>> -> try Ref = list_to_ref(binary_to_list(Term)), {halt, Ref} catch error:badarg -> plugins(T, Term, Opts) end; _ -> plugins(T, Term, Opts) end; plugins([timestamp | T], Term, Opts) -> case Term of << Y4/integer, Y3/integer, Y2/integer, Y1/integer, $-/integer , M2/integer, M1/integer, $-/integer , D2/integer, D1/integer , $T/integer , H2/integer, H1/integer, $:/integer , Min2/integer, Min1/integer, $:/integer , S2/integer, S1/integer , $./integer , MSec3/integer, MSec2/integer, MSec1/integer , $Z/integer >> when ?is_number(Y4), ?is_number(Y3), ?is_number(Y2), ?is_number(Y1) , ?is_number(M2), ?is_number(M1) , ?is_number(D2), ?is_number(D1) , ?is_number(H2), ?is_number(H1) , ?is_number(Min2), ?is_number(Min1) , ?is_number(S2), ?is_number(S1) , ?is_number(MSec3), ?is_number(MSec2), ?is_number(MSec1) -> Date = { chars_to_integer(Y4, Y3, Y2, Y1) , chars_to_integer(M2, M1) , chars_to_integer(D2, D1) }, Time = { chars_to_integer(H2, H1) , chars_to_integer(Min2, Min1) , chars_to_integer(S2, S1) }, DateTime = {Date, Time}, MilliSeconds = chars_to_integer(MSec3, MSec2, MSec1), GregSeconds = calendar:datetime_to_gregorian_seconds(DateTime), Seconds = GregSeconds - 62167219200, Timestamp = { Seconds div 1000000 , Seconds rem 1000000 , MilliSeconds * 1000 }, {halt, Timestamp}; _ -> plugins(T, Term, Opts) end; plugins([Plugin | T], Term, Opts) -> case Plugin:decode(Term, Opts) of next -> plugins(T, Term, Opts); {halt, Decoded} -> {halt, Decoded} end. continue(Rest, Opts, Input, Pos, [Continue | Buffer], Value) -> case Continue of ?key -> key(Rest, Opts, Input, Pos, Buffer, Value); ?object -> object(Rest, Opts, Input, Pos, Buffer, Value); ?array -> array(Rest, Opts, Input, Pos, Buffer, Value); ?terminate -> terminate(Rest, Opts, Input, Pos, Buffer, Value) end. terminate(Data, Opts, Input, Pos, Buffer, Value) -> case Data of <<$\s/integer, Rest/bitstring>> -> terminate(Rest, Opts, Input, Pos + 1, Buffer, Value); <<$\t/integer, Rest/bitstring>> -> terminate(Rest, Opts, Input, Pos + 1, Buffer, Value); <<$\r/integer, Rest/bitstring>> -> terminate(Rest, Opts, Input, Pos + 1, Buffer, Value); <<$\n/integer, Rest/bitstring>> -> terminate(Rest, Opts, Input, Pos + 1, Buffer, Value); <<>> -> Value; <<_/bitstring>> -> throw_byte(Data, Opts, Input, Pos, Buffer) end. escape(Data, Opts, Input, Pos, Buffer, Acc) -> case Data of <<$\"/integer, Rest/bitstring>> -> string(Rest, Opts, Input, Pos + 2, Buffer, [Acc, $\"], 0); <<$//integer, Rest/bitstring>> -> string(Rest, Opts, Input, Pos + 2, Buffer, [Acc, $/], 0); <<$\\/integer, Rest/bitstring>> -> string(Rest, Opts, Input, Pos + 2, Buffer, [Acc, $\\], 0); <<$b/integer, Rest/bitstring>> -> string(Rest, Opts, Input, Pos + 2, Buffer, [Acc, $\b], 0); <<$f/integer, Rest/bitstring>> -> string(Rest, Opts, Input, Pos + 2, Buffer, [Acc, $\f], 0); <<$n/integer, Rest/bitstring>> -> string(Rest, Opts, Input, Pos + 2, Buffer, [Acc, $\n], 0); <<$r/integer, Rest/bitstring>> -> string(Rest, Opts, Input, Pos + 2, Buffer, [Acc, $\r], 0); <<$t/integer, Rest/bitstring>> -> string(Rest, Opts, Input, Pos + 2, Buffer, [Acc, $\t], 0); <<$u/integer, Rest/bitstring>> -> escapeu(Rest, Opts, Input, Pos, Buffer, Acc); <<_/integer, _/bitstring>> -> throw_byte(Data, Opts, Input, Pos + 1, Buffer); <<_/bitstring>> -> throw_eof(Opts, Input, Pos, Buffer) end. escapeu(Data, Opts, Input, Pos, Buffer, Acc) -> case Data of <> -> Last = escapeu_last(Int2, Rest, Opts, Input, Pos, Buffer), case Int1 of 12336 -> string(Rest, Opts, Input, Pos + 6, Buffer, begin _@1 = Acc, _@2 = 0, _@3 = Last, case _@3 =< 127 of false -> _@4 = 6 bsl 5 + (_@2 bsl 2) + (_@3 bsr 6), _@5 = 2 bsl 6 + _@3 band 63, [_@1, _@4, _@5]; true -> [_@1, _@3] end end, 0); 12337 -> escapeu_1(Rest, Opts, Input, Pos, Buffer, Acc, Last, 1); 12338 -> escapeu_1(Rest, Opts, Input, Pos, Buffer, Acc, Last, 2); 12339 -> escapeu_1(Rest, Opts, Input, Pos, Buffer, Acc, Last, 3); 12340 -> escapeu_1(Rest, Opts, Input, Pos, Buffer, Acc, Last, 4); 12341 -> escapeu_1(Rest, Opts, Input, Pos, Buffer, Acc, Last, 5); 12342 -> escapeu_1(Rest, Opts, Input, Pos, Buffer, Acc, Last, 6); 12343 -> escapeu_1(Rest, Opts, Input, Pos, Buffer, Acc, Last, 7); 12344 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 8); 12345 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 9); 12353 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 10); 12354 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 11); 12355 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 12); 12356 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 13); 12357 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 14); 12358 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 15); 12385 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 10); 12386 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 11); 12387 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 12); 12388 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 13); 12389 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 14); 12390 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 15); 12592 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 16); 12593 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 17); 12594 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 18); 12595 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 19); 12596 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 20); 12597 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 21); 12598 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 22); 12599 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 23); 12600 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 24); 12601 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 25); 12609 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 26); 12610 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 27); 12611 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 28); 12612 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 29); 12613 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 30); 12614 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 31); 12641 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 26); 12642 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 27); 12643 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 28); 12644 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 29); 12645 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 30); 12646 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 31); 12848 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 32); 12849 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 33); 12850 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 34); 12851 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 35); 12852 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 36); 12853 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 37); 12854 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 38); 12855 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 39); 12856 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 40); 12857 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 41); 12865 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 42); 12866 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 43); 12867 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 44); 12868 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 45); 12869 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 46); 12870 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 47); 12897 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 42); 12898 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 43); 12899 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 44); 12900 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 45); 12901 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 46); 12902 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 47); 13104 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 48); 13105 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 49); 13106 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 50); 13107 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 51); 13108 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 52); 13109 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 53); 13110 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 54); 13111 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 55); 13112 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 56); 13113 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 57); 13121 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 58); 13122 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 59); 13123 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 60); 13124 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 61); 13125 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 62); 13126 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 63); 13153 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 58); 13154 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 59); 13155 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 60); 13156 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 61); 13157 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 62); 13158 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 63); 13360 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 64); 13361 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 65); 13362 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 66); 13363 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 67); 13364 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 68); 13365 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 69); 13366 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 70); 13367 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 71); 13368 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 72); 13369 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 73); 13377 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 74); 13378 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 75); 13379 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 76); 13380 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 77); 13381 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 78); 13382 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 79); 13409 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 74); 13410 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 75); 13411 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 76); 13412 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 77); 13413 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 78); 13414 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 79); 13616 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 80); 13617 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 81); 13618 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 82); 13619 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 83); 13620 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 84); 13621 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 85); 13622 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 86); 13623 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 87); 13624 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 88); 13625 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 89); 13633 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 90); 13634 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 91); 13635 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 92); 13636 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 93); 13637 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 94); 13638 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 95); 13665 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 90); 13666 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 91); 13667 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 92); 13668 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 93); 13669 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 94); 13670 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 95); 13872 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 96); 13873 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 97); 13874 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 98); 13875 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 99); 13876 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 100); 13877 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 101); 13878 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 102); 13879 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 103); 13880 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 104); 13881 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 105); 13889 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 106); 13890 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 107); 13891 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 108); 13892 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 109); 13893 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 110); 13894 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 111); 13921 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 106); 13922 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 107); 13923 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 108); 13924 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 109); 13925 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 110); 13926 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 111); 14128 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 112); 14129 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 113); 14130 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 114); 14131 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 115); 14132 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 116); 14133 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 117); 14134 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 118); 14135 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 119); 14136 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 120); 14137 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 121); 14145 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 122); 14146 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 123); 14147 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 124); 14148 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 125); 14149 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 126); 14150 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 127); 14177 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 122); 14178 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 123); 14179 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 124); 14180 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 125); 14181 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 126); 14182 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 127); 14384 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 128); 14385 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 129); 14386 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 130); 14387 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 131); 14388 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 132); 14389 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 133); 14390 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 134); 14391 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 135); 14392 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 136); 14393 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 137); 14401 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 138); 14402 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 139); 14403 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 140); 14404 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 141); 14405 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 142); 14406 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 143); 14433 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 138); 14434 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 139); 14435 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 140); 14436 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 141); 14437 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 142); 14438 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 143); 14640 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 144); 14641 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 145); 14642 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 146); 14643 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 147); 14644 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 148); 14645 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 149); 14646 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 150); 14647 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 151); 14648 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 152); 14649 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 153); 14657 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 154); 14658 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 155); 14659 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 156); 14660 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 157); 14661 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 158); 14662 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 159); 14689 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 154); 14690 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 155); 14691 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 156); 14692 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 157); 14693 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 158); 14694 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 159); 16688 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 160); 16689 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 161); 16690 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 162); 16691 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 163); 16692 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 164); 16693 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 165); 16694 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 166); 16695 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 167); 16696 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 168); 16697 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 169); 16705 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 170); 16706 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 171); 16707 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 172); 16708 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 173); 16709 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 174); 16710 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 175); 16737 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 170); 16738 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 171); 16739 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 172); 16740 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 173); 16741 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 174); 16742 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 175); 16944 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 176); 16945 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 177); 16946 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 178); 16947 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 179); 16948 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 180); 16949 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 181); 16950 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 182); 16951 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 183); 16952 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 184); 16953 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 185); 16961 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 186); 16962 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 187); 16963 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 188); 16964 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 189); 16965 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 190); 16966 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 191); 16993 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 186); 16994 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 187); 16995 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 188); 16996 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 189); 16997 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 190); 16998 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 191); 17200 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 192); 17201 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 193); 17202 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 194); 17203 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 195); 17204 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 196); 17205 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 197); 17206 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 198); 17207 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 199); 17208 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 200); 17209 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 201); 17217 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 202); 17218 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 203); 17219 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 204); 17220 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 205); 17221 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 206); 17222 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 207); 17249 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 202); 17250 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 203); 17251 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 204); 17252 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 205); 17253 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 206); 17254 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 207); 17456 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 208); 17457 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 209); 17458 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 210); 17459 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 211); 17460 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 212); 17461 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 213); 17462 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 214); 17463 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 215); 17464 -> escape_surrogate(Rest, Opts, Input, Pos, Buffer, Acc, begin _@1757 = 216, _@1758 = Last, 65536 + (_@1757 band 3 bsl 8 + _@1758 bsl 10) end); 17465 -> escape_surrogate(Rest, Opts, Input, Pos, Buffer, Acc, begin _@1759 = 217, _@1760 = Last, 65536 + (_@1759 band 3 bsl 8 + _@1760 bsl 10) end); 17473 -> escape_surrogate(Rest, Opts, Input, Pos, Buffer, Acc, begin _@1761 = 218, _@1762 = Last, 65536 + (_@1761 band 3 bsl 8 + _@1762 bsl 10) end); 17474 -> escape_surrogate(Rest, Opts, Input, Pos, Buffer, Acc, begin _@1763 = 219, _@1764 = Last, 65536 + (_@1763 band 3 bsl 8 + _@1764 bsl 10) end); 17505 -> escape_surrogate(Rest, Opts, Input, Pos, Buffer, Acc, begin _@1765 = 218, _@1766 = Last, 65536 + (_@1765 band 3 bsl 8 + _@1766 bsl 10) end); 17506 -> escape_surrogate(Rest, Opts, Input, Pos, Buffer, Acc, begin _@1767 = 219, _@1768 = Last, 65536 + (_@1767 band 3 bsl 8 + _@1768 bsl 10) end); 17712 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 224); 17713 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 225); 17714 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 226); 17715 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 227); 17716 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 228); 17717 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 229); 17718 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 230); 17719 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 231); 17720 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 232); 17721 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 233); 17729 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 234); 17730 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 235); 17731 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 236); 17732 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 237); 17733 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 238); 17734 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 239); 17761 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 234); 17762 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 235); 17763 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 236); 17764 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 237); 17765 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 238); 17766 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 239); 17968 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 240); 17969 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 241); 17970 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 242); 17971 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 243); 17972 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 244); 17973 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 245); 17974 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 246); 17975 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 247); 17976 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 248); 17977 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 249); 17985 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 250); 17986 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 251); 17987 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 252); 17988 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 253); 17989 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 254); 17990 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 255); 18017 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 250); 18018 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 251); 18019 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 252); 18020 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 253); 18021 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 254); 18022 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 255); 24880 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 160); 24881 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 161); 24882 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 162); 24883 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 163); 24884 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 164); 24885 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 165); 24886 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 166); 24887 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 167); 24888 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 168); 24889 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 169); 24897 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 170); 24898 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 171); 24899 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 172); 24900 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 173); 24901 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 174); 24902 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 175); 24929 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 170); 24930 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 171); 24931 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 172); 24932 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 173); 24933 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 174); 24934 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 175); 25136 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 176); 25137 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 177); 25138 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 178); 25139 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 179); 25140 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 180); 25141 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 181); 25142 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 182); 25143 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 183); 25144 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 184); 25145 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 185); 25153 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 186); 25154 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 187); 25155 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 188); 25156 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 189); 25157 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 190); 25158 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 191); 25185 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 186); 25186 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 187); 25187 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 188); 25188 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 189); 25189 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 190); 25190 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 191); 25392 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 192); 25393 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 193); 25394 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 194); 25395 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 195); 25396 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 196); 25397 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 197); 25398 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 198); 25399 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 199); 25400 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 200); 25401 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 201); 25409 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 202); 25410 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 203); 25411 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 204); 25412 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 205); 25413 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 206); 25414 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 207); 25441 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 202); 25442 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 203); 25443 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 204); 25444 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 205); 25445 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 206); 25446 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 207); 25648 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 208); 25649 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 209); 25650 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 210); 25651 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 211); 25652 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 212); 25653 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 213); 25654 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 214); 25655 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 215); 25656 -> escape_surrogate(Rest, Opts, Input, Pos, Buffer, Acc, begin _@2477 = 216, _@2478 = Last, 65536 + (_@2477 band 3 bsl 8 + _@2478 bsl 10) end); 25657 -> escape_surrogate(Rest, Opts, Input, Pos, Buffer, Acc, begin _@2479 = 217, _@2480 = Last, 65536 + (_@2479 band 3 bsl 8 + _@2480 bsl 10) end); 25665 -> escape_surrogate(Rest, Opts, Input, Pos, Buffer, Acc, begin _@2481 = 218, _@2482 = Last, 65536 + (_@2481 band 3 bsl 8 + _@2482 bsl 10) end); 25666 -> escape_surrogate(Rest, Opts, Input, Pos, Buffer, Acc, begin _@2483 = 219, _@2484 = Last, 65536 + (_@2483 band 3 bsl 8 + _@2484 bsl 10) end); 25697 -> escape_surrogate(Rest, Opts, Input, Pos, Buffer, Acc, begin _@2485 = 218, _@2486 = Last, 65536 + (_@2485 band 3 bsl 8 + _@2486 bsl 10) end); 25698 -> escape_surrogate(Rest, Opts, Input, Pos, Buffer, Acc, begin _@2487 = 219, _@2488 = Last, 65536 + (_@2487 band 3 bsl 8 + _@2488 bsl 10) end); 25904 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 224); 25905 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 225); 25906 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 226); 25907 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 227); 25908 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 228); 25909 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 229); 25910 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 230); 25911 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 231); 25912 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 232); 25913 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 233); 25921 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 234); 25922 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 235); 25923 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 236); 25924 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 237); 25925 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 238); 25926 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 239); 25953 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 234); 25954 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 235); 25955 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 236); 25956 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 237); 25957 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 238); 25958 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 239); 26160 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 240); 26161 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 241); 26162 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 242); 26163 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 243); 26164 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 244); 26165 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 245); 26166 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 246); 26167 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 247); 26168 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 248); 26169 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 249); 26177 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 250); 26178 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 251); 26179 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 252); 26180 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 253); 26181 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 254); 26182 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 255); 26209 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 250); 26210 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 251); 26211 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 252); 26212 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 253); 26213 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 254); 26214 -> escapeu_2(Rest, Opts, Input, Pos, Buffer, Acc, Last, 255); _ -> throw_token(6, Rest, Opts, Input, Pos, Buffer) end; <<_/bitstring>> -> throw_eof(Opts, Input, Pos, Buffer) end. escapeu_last(Int, Rest, Opts, Input, Pos, Buffer) -> case Int of 12336 -> 0; 12337 -> 1; 12338 -> 2; 12339 -> 3; 12340 -> 4; 12341 -> 5; 12342 -> 6; 12343 -> 7; 12344 -> 8; 12345 -> 9; 12353 -> 10; 12354 -> 11; 12355 -> 12; 12356 -> 13; 12357 -> 14; 12358 -> 15; 12385 -> 10; 12386 -> 11; 12387 -> 12; 12388 -> 13; 12389 -> 14; 12390 -> 15; 12592 -> 16; 12593 -> 17; 12594 -> 18; 12595 -> 19; 12596 -> 20; 12597 -> 21; 12598 -> 22; 12599 -> 23; 12600 -> 24; 12601 -> 25; 12609 -> 26; 12610 -> 27; 12611 -> 28; 12612 -> 29; 12613 -> 30; 12614 -> 31; 12641 -> 26; 12642 -> 27; 12643 -> 28; 12644 -> 29; 12645 -> 30; 12646 -> 31; 12848 -> 32; 12849 -> 33; 12850 -> 34; 12851 -> 35; 12852 -> 36; 12853 -> 37; 12854 -> 38; 12855 -> 39; 12856 -> 40; 12857 -> 41; 12865 -> 42; 12866 -> 43; 12867 -> 44; 12868 -> 45; 12869 -> 46; 12870 -> 47; 12897 -> 42; 12898 -> 43; 12899 -> 44; 12900 -> 45; 12901 -> 46; 12902 -> 47; 13104 -> 48; 13105 -> 49; 13106 -> 50; 13107 -> 51; 13108 -> 52; 13109 -> 53; 13110 -> 54; 13111 -> 55; 13112 -> 56; 13113 -> 57; 13121 -> 58; 13122 -> 59; 13123 -> 60; 13124 -> 61; 13125 -> 62; 13126 -> 63; 13153 -> 58; 13154 -> 59; 13155 -> 60; 13156 -> 61; 13157 -> 62; 13158 -> 63; 13360 -> 64; 13361 -> 65; 13362 -> 66; 13363 -> 67; 13364 -> 68; 13365 -> 69; 13366 -> 70; 13367 -> 71; 13368 -> 72; 13369 -> 73; 13377 -> 74; 13378 -> 75; 13379 -> 76; 13380 -> 77; 13381 -> 78; 13382 -> 79; 13409 -> 74; 13410 -> 75; 13411 -> 76; 13412 -> 77; 13413 -> 78; 13414 -> 79; 13616 -> 80; 13617 -> 81; 13618 -> 82; 13619 -> 83; 13620 -> 84; 13621 -> 85; 13622 -> 86; 13623 -> 87; 13624 -> 88; 13625 -> 89; 13633 -> 90; 13634 -> 91; 13635 -> 92; 13636 -> 93; 13637 -> 94; 13638 -> 95; 13665 -> 90; 13666 -> 91; 13667 -> 92; 13668 -> 93; 13669 -> 94; 13670 -> 95; 13872 -> 96; 13873 -> 97; 13874 -> 98; 13875 -> 99; 13876 -> 100; 13877 -> 101; 13878 -> 102; 13879 -> 103; 13880 -> 104; 13881 -> 105; 13889 -> 106; 13890 -> 107; 13891 -> 108; 13892 -> 109; 13893 -> 110; 13894 -> 111; 13921 -> 106; 13922 -> 107; 13923 -> 108; 13924 -> 109; 13925 -> 110; 13926 -> 111; 14128 -> 112; 14129 -> 113; 14130 -> 114; 14131 -> 115; 14132 -> 116; 14133 -> 117; 14134 -> 118; 14135 -> 119; 14136 -> 120; 14137 -> 121; 14145 -> 122; 14146 -> 123; 14147 -> 124; 14148 -> 125; 14149 -> 126; 14150 -> 127; 14177 -> 122; 14178 -> 123; 14179 -> 124; 14180 -> 125; 14181 -> 126; 14182 -> 127; 14384 -> 128; 14385 -> 129; 14386 -> 130; 14387 -> 131; 14388 -> 132; 14389 -> 133; 14390 -> 134; 14391 -> 135; 14392 -> 136; 14393 -> 137; 14401 -> 138; 14402 -> 139; 14403 -> 140; 14404 -> 141; 14405 -> 142; 14406 -> 143; 14433 -> 138; 14434 -> 139; 14435 -> 140; 14436 -> 141; 14437 -> 142; 14438 -> 143; 14640 -> 144; 14641 -> 145; 14642 -> 146; 14643 -> 147; 14644 -> 148; 14645 -> 149; 14646 -> 150; 14647 -> 151; 14648 -> 152; 14649 -> 153; 14657 -> 154; 14658 -> 155; 14659 -> 156; 14660 -> 157; 14661 -> 158; 14662 -> 159; 14689 -> 154; 14690 -> 155; 14691 -> 156; 14692 -> 157; 14693 -> 158; 14694 -> 159; 16688 -> 160; 16689 -> 161; 16690 -> 162; 16691 -> 163; 16692 -> 164; 16693 -> 165; 16694 -> 166; 16695 -> 167; 16696 -> 168; 16697 -> 169; 16705 -> 170; 16706 -> 171; 16707 -> 172; 16708 -> 173; 16709 -> 174; 16710 -> 175; 16737 -> 170; 16738 -> 171; 16739 -> 172; 16740 -> 173; 16741 -> 174; 16742 -> 175; 16944 -> 176; 16945 -> 177; 16946 -> 178; 16947 -> 179; 16948 -> 180; 16949 -> 181; 16950 -> 182; 16951 -> 183; 16952 -> 184; 16953 -> 185; 16961 -> 186; 16962 -> 187; 16963 -> 188; 16964 -> 189; 16965 -> 190; 16966 -> 191; 16993 -> 186; 16994 -> 187; 16995 -> 188; 16996 -> 189; 16997 -> 190; 16998 -> 191; 17200 -> 192; 17201 -> 193; 17202 -> 194; 17203 -> 195; 17204 -> 196; 17205 -> 197; 17206 -> 198; 17207 -> 199; 17208 -> 200; 17209 -> 201; 17217 -> 202; 17218 -> 203; 17219 -> 204; 17220 -> 205; 17221 -> 206; 17222 -> 207; 17249 -> 202; 17250 -> 203; 17251 -> 204; 17252 -> 205; 17253 -> 206; 17254 -> 207; 17456 -> 208; 17457 -> 209; 17458 -> 210; 17459 -> 211; 17460 -> 212; 17461 -> 213; 17462 -> 214; 17463 -> 215; 17464 -> 216; 17465 -> 217; 17473 -> 218; 17474 -> 219; 17475 -> 220; 17476 -> 221; 17477 -> 222; 17478 -> 223; 17505 -> 218; 17506 -> 219; 17507 -> 220; 17508 -> 221; 17509 -> 222; 17510 -> 223; 17712 -> 224; 17713 -> 225; 17714 -> 226; 17715 -> 227; 17716 -> 228; 17717 -> 229; 17718 -> 230; 17719 -> 231; 17720 -> 232; 17721 -> 233; 17729 -> 234; 17730 -> 235; 17731 -> 236; 17732 -> 237; 17733 -> 238; 17734 -> 239; 17761 -> 234; 17762 -> 235; 17763 -> 236; 17764 -> 237; 17765 -> 238; 17766 -> 239; 17968 -> 240; 17969 -> 241; 17970 -> 242; 17971 -> 243; 17972 -> 244; 17973 -> 245; 17974 -> 246; 17975 -> 247; 17976 -> 248; 17977 -> 249; 17985 -> 250; 17986 -> 251; 17987 -> 252; 17988 -> 253; 17989 -> 254; 17990 -> 255; 18017 -> 250; 18018 -> 251; 18019 -> 252; 18020 -> 253; 18021 -> 254; 18022 -> 255; 24880 -> 160; 24881 -> 161; 24882 -> 162; 24883 -> 163; 24884 -> 164; 24885 -> 165; 24886 -> 166; 24887 -> 167; 24888 -> 168; 24889 -> 169; 24897 -> 170; 24898 -> 171; 24899 -> 172; 24900 -> 173; 24901 -> 174; 24902 -> 175; 24929 -> 170; 24930 -> 171; 24931 -> 172; 24932 -> 173; 24933 -> 174; 24934 -> 175; 25136 -> 176; 25137 -> 177; 25138 -> 178; 25139 -> 179; 25140 -> 180; 25141 -> 181; 25142 -> 182; 25143 -> 183; 25144 -> 184; 25145 -> 185; 25153 -> 186; 25154 -> 187; 25155 -> 188; 25156 -> 189; 25157 -> 190; 25158 -> 191; 25185 -> 186; 25186 -> 187; 25187 -> 188; 25188 -> 189; 25189 -> 190; 25190 -> 191; 25392 -> 192; 25393 -> 193; 25394 -> 194; 25395 -> 195; 25396 -> 196; 25397 -> 197; 25398 -> 198; 25399 -> 199; 25400 -> 200; 25401 -> 201; 25409 -> 202; 25410 -> 203; 25411 -> 204; 25412 -> 205; 25413 -> 206; 25414 -> 207; 25441 -> 202; 25442 -> 203; 25443 -> 204; 25444 -> 205; 25445 -> 206; 25446 -> 207; 25648 -> 208; 25649 -> 209; 25650 -> 210; 25651 -> 211; 25652 -> 212; 25653 -> 213; 25654 -> 214; 25655 -> 215; 25656 -> 216; 25657 -> 217; 25665 -> 218; 25666 -> 219; 25667 -> 220; 25668 -> 221; 25669 -> 222; 25670 -> 223; 25697 -> 218; 25698 -> 219; 25699 -> 220; 25700 -> 221; 25701 -> 222; 25702 -> 223; 25904 -> 224; 25905 -> 225; 25906 -> 226; 25907 -> 227; 25908 -> 228; 25909 -> 229; 25910 -> 230; 25911 -> 231; 25912 -> 232; 25913 -> 233; 25921 -> 234; 25922 -> 235; 25923 -> 236; 25924 -> 237; 25925 -> 238; 25926 -> 239; 25953 -> 234; 25954 -> 235; 25955 -> 236; 25956 -> 237; 25957 -> 238; 25958 -> 239; 26160 -> 240; 26161 -> 241; 26162 -> 242; 26163 -> 243; 26164 -> 244; 26165 -> 245; 26166 -> 246; 26167 -> 247; 26168 -> 248; 26169 -> 249; 26177 -> 250; 26178 -> 251; 26179 -> 252; 26180 -> 253; 26181 -> 254; 26182 -> 255; 26209 -> 250; 26210 -> 251; 26211 -> 252; 26212 -> 253; 26213 -> 254; 26214 -> 255; _ -> throw_token(6, Rest, Opts, Input, Pos, Buffer) end. escapeu_1(<<_/bitstring>> = Rest, Opts, Input, Pos, Buffer, Acc, Last, X) -> A = 6 bsl 5 + (X bsl 2) + (Last bsr 6), B = 2 bsl 6 + Last band 63, C = [Acc, A, B], string(Rest, Opts, Input, Pos + 6, Buffer, C, 0). escapeu_2(<<_/bitstring>> = Rest, Opts, Input, Pos, Buffer, Acc, Last, X) -> A = 14 bsl 4 + (X bsr 4), B = 2 bsl 6 + (X band 15 bsl 2) + (Last bsr 6), C = 2 bsl 6 + Last band 63, D = [Acc, A, B, C], string(Rest, Opts, Input, Pos + 6, Buffer, D, 0). escape_surrogate(Data, Opts, Input, Pos, Buffer, Acc, Hi) -> case Data of <<92/integer, 117/integer, Int1:16/integer, Int2:16/integer, Rest/bitstring>> -> Last = escapeu_last(Int2, Rest, Opts, Input, Pos + 6, Buffer), X = case Int1 of 17475 -> 220; 17476 -> 221; 17477 -> 222; 17478 -> 223; 17507 -> 220; 17508 -> 221; 17509 -> 222; 17510 -> 223; 25667 -> 220; 25668 -> 221; 25669 -> 222; 25670 -> 223; 25699 -> 220; 25700 -> 221; 25701 -> 222; 25702 -> 223; _ -> throw_token(12, Rest, Opts, Input, Pos, Buffer) end, Y = X band 3 bsl 8 + Last, Acc1 = [Acc | <<(Hi + Y)/utf8>>], string(Rest, Opts, Input, Pos + 12, Buffer, Acc1, 0); <<_/integer, _/bitstring>> -> throw_byte(Data, Opts, Input, Pos + 6, Buffer); <<_/bitstring>> -> throw_eof(Opts, Input, Pos, Buffer) end. throw_byte(<>, Opts, Input, Pos, Buffer) -> Byte = binary:at(Input, Pos), throw({{byte, Byte}, Rest, Opts, Input, Pos, Buffer}). throw_token(Len, Rest, Opts, Input, Pos, Buffer) when is_integer(Len) -> Token = binary_part(Input, Pos, Len), throw_token(Token, Rest, Opts, Input, Pos, Buffer); throw_token(Token, Rest, Opts, Input, Pos, Buffer) -> throw({{token, Token}, Rest, Opts, Input, Pos, Buffer}). throw_eof(Opts, Input, Pos, Buffer) -> throw({eof, Opts, Input, Pos, Buffer}). chars_to_integer(N2, N1) -> ((N2 - $0) * 10) + (N1 - $0). chars_to_integer(N3, N2, N1) -> ((N3 - $0) * 100) + ((N2 - $0) * 10) + (N1 - $0). chars_to_integer(N4, N3, N2, N1) -> ((N4 - $0) * 1000) + ((N3 - $0) * 100) + ((N2 - $0) * 10) + (N1 - $0). %%%===================================================================== %%% Support functions %%%===================================================================== maps_get(Key, Map, Default) -> case Map of #{Key := Value} -> Value; #{} -> Default end. %%%===================================================================== %%% Eunit tests %%%===================================================================== -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). decode_test() -> [ ?assertEqual(Expect, decode(Input, Opts)) || {Expect, Input, Opts} <- [ {{ok, <<"foo">>}, <<"\"foo\"">>, #{}}, {{ok, 123}, <<"123">>, #{}}, {{ok, 1.234}, <<"1.234">>, #{}}, {{ok, 6.02e23}, <<"6.02e+23">>, #{}}, { {ok, [<<"foo">>, 123, 6.02e+23, true]} , <<"[\"foo\",123,6.02e+23,true]">>, #{} }, { {ok, #{<<"foo">> => <<"bar">>, <<"bar">> => <<"baz">>}} , <<"{\"foo\": \"bar\", \"bar\": \"baz\"}">> , #{} }, {{ok, true}, <<"true">>, #{}}, {{ok, false}, <<"false">>, #{}}, {{ok, undefined}, <<"null">>, #{}}, {{ok, <<"ABC">>}, <<"\"\\u0041\\u0042\\u0043\"">>, #{}}, { {ok, #{foo => 1}} , <<"{\"foo\": \"1\"}">> , #{ keys => to_atom, values => to_integer } }, {{error, not_an_iodata}, error, #{}} ]]. resume_test() -> [ ?assertEqual(Expect, decode(Input, Opts)) || {Expect, Input, Opts} <- [ { {ok, [undefined, undefined, #{<<"foo">> => undefined}]} , <<"[1e999,1e999,{\"foo\": 1e999}]">> , #{ error_handler => fun do_handle_error/3 } } ]]. do_handle_error(throw, {{token, Token}, Rest, Opts, Input, Pos, Buffer}, _Stacktrace) -> resume(Token, Rest, Opts, Input, Pos, Buffer); do_handle_error(Class, Reason, Stacktrace) -> handle_error(Class, Reason, Stacktrace). datetime_plugin_test() -> [ ?assertEqual(Expect, decode(Input, Opts)) || {Expect, Input, Opts} <- [ { {ok, <<"1970-01-01T00:00:00Z">>} , <<"\"1970-01-01T00:00:00Z\"">> , #{} }, { {ok, {{1970,1,1},{0,0,0}}} , <<"\"1970-01-01T00:00:00Z\"">> , #{plugins => [datetime]} } ]]. inet_plugin_test() -> [ ?assertEqual(Expect, decode(Input, Opts)) || {Expect, Input, Opts} <- [ % ipv4 {{ok, <<"0.0.0.0">>}, <<"\"0.0.0.0\"">>, #{} }, { {ok, {0,0,0,0}}, <<"\"0.0.0.0\"">>, #{plugins => [inet]} }, { {ok, {255,255,255,255}} , <<"\"255.255.255.255\"">> , #{plugins => [inet]} }, % ipv6 {{ok, <<"::">>}, <<"\"::\"">>, #{}}, {{ok, {0,0,0,0,0,0,0,0}}, <<"\"::\"">>, #{plugins => [inet]}}, {{ok, {0,0,0,0,0,0,0,1}}, <<"\"::1\"">>, #{plugins => [inet]}}, { {ok, {0,0,0,0,0,0,(192 bsl 8) bor 168,(42 bsl 8) bor 2}} , <<"\"::192.168.42.2\"">> , #{plugins => [inet]} }, { {ok, {0,0,0,0,0,16#FFFF,(192 bsl 8) bor 168,(42 bsl 8) bor 2}} , <<"\"::ffff:192.168.42.2\"">> , #{plugins => [inet]} }, { {ok, {16#3ffe,16#b80,16#1f8d,16#2,16#204,16#acff,16#fe17,16#bf38}} , <<"\"3ffe:b80:1f8d:2:204:acff:fe17:bf38\"">> , #{plugins => [inet]} }, { {ok, {16#fe80,0,0,0,16#204,16#acff,16#fe17,16#bf38}} , <<"\"fe80::204:acff:fe17:bf38\"">> , #{plugins => [inet]} } ]]. pid_plugin_test() -> [ ?assertEqual(Expect, decode(Input, Opts)) || {Expect, Input, Opts} <- [ {{ok, <<"<0.92.0>">>}, <<"\"<0.92.0>\"">>, #{}}, { {ok, list_to_pid("<0.92.0>")} , <<"\"<0.92.0>\"">> , #{plugins => [pid]} } ]]. port_plugin_test() -> [ ?assertEqual(Expect, decode(Input, Opts)) || {Expect, Input, Opts} <- [ {{ok, <<"#Port<0.1>">>}, <<"\"#Port<0.1>\"">>, #{}}, { {ok, list_to_port("#Port<0.1>")} , <<"\"#Port<0.1>\"">> , #{plugins => [port]} } ]]. reference_plugin_test() -> [ ?assertEqual(Expect, decode(Input, Opts)) || {Expect, Input, Opts} <- [ { {ok, <<"#Ref<0.314572725.1088159747.110918>">>} , <<"\"#Ref<0.314572725.1088159747.110918>\"">> , #{} }, { {ok, list_to_ref("#Ref<0.314572725.1088159747.110918>")} , <<"\"#Ref<0.314572725.1088159747.110918>\"">> , #{plugins => [reference]} } ]]. timestamp_plugin_test() -> [ ?assertEqual(Expect, decode(Input, Opts)) || {Expect, Input, Opts} <- [ { {ok, <<"1970-01-01T00:00:00.000Z">>} , <<"\"1970-01-01T00:00:00.000Z\"">> , #{} }, { {ok, {0,0,0}} , <<"\"1970-01-01T00:00:00.000Z\"">> , #{plugins => [timestamp]} } ]]. plugins_type_check_test() -> Plugins = [ datetime , inet , pid , port , reference , timestamp ], [ ?assertEqual(Expect, decode(Input, Opts#{plugins => Plugins})) || {Expect, Input, Opts} <- [ {{ok, <<"foo">>}, <<"\"foo\"">>, #{}}, {{ok, 0}, <<"0">>, #{}}, {{ok, 0.0}, <<"0.0">>, #{}}, {{ok, #{}}, <<"{}">>, #{}}, {{ok, []}, <<"[]">>, #{}} ]]. -endif.