Skip to content
This repository was archived by the owner on Jan 26, 2023. It is now read-only.

Commit ad6d4d2

Browse files
authored
Merge pull request #1 from AdRoll/unpacker-bin-optimizations
Apply bin optimizations to msgpack_unpacker
2 parents f1e1b98 + 3415b47 commit ad6d4d2

File tree

1 file changed

+21
-15
lines changed

1 file changed

+21
-15
lines changed

src/msgpack_unpacker.erl

+21-15
Original file line numberDiff line numberDiff line change
@@ -170,14 +170,16 @@ unpack_stream(<<16#C9, Len:32, Type:1/signed-integer-unit:8, Data:Len/binary, Re
170170
?OPTION{ext_unpacker=Unpack, original_list=Orig} = Opt) ->
171171
maybe_unpack_ext(16#C9, Unpack, Type, Data, Rest, Orig, Opt);
172172

173-
unpack_stream(_Bin, _Opt) ->
173+
%% Do not remove the binary wrapper from the function clause, it is a bin optimization for reusing the context
174+
unpack_stream(<<_Bin/binary>>, _Opt) ->
174175
throw(incomplete).
175176

177+
%% Do not remove the binary wrapper from the function clauses, it is a bin optimization for reusing the context
176178
-spec unpack_array(binary(), non_neg_integer(), [msgpack:object()], ?OPTION{}) ->
177-
{[msgpack:object()], binary()} | no_return().
178-
unpack_array(Bin, 0, Acc, _) ->
179+
{[msgpack:object()], binary()} | no_return().
180+
unpack_array(<<Bin/binary>>, 0, Acc, _) ->
179181
{lists:reverse(Acc), Bin};
180-
unpack_array(Bin, Len, Acc, Opt) ->
182+
unpack_array(<<Bin/binary>>, Len, Acc, Opt) ->
181183
{Term, Rest} = unpack_stream(Bin, Opt),
182184
unpack_array(Rest, Len-1, [Term|Acc], Opt).
183185

@@ -216,18 +218,20 @@ unpack_map_jsx(Bin, Len, Opt) ->
216218
{Map, Rest} -> {Map, Rest}
217219
end.
218220

221+
%% Do not remove the binary wrapper from the function clause, it is a bin optimization for reusing the context
219222
-spec unpack_map_as_proplist(binary(), non_neg_integer(), proplists:proplist(), ?OPTION{}) ->
220223
{proplists:proplist(), binary()} | no_return().
221-
unpack_map_as_proplist(Bin, 0, Acc, _) ->
224+
unpack_map_as_proplist(<<Bin/binary>>, 0, Acc, _) ->
222225
{lists:reverse(Acc), Bin};
223-
unpack_map_as_proplist(Bin, Len, Acc, Opt) ->
226+
unpack_map_as_proplist(<<Bin/binary>>, Len, Acc, Opt) ->
224227
{Key, Rest} = unpack_stream(Bin, Opt),
225228
{Value, Rest2} = unpack_stream(Rest, Opt),
226229
unpack_map_as_proplist(Rest2, Len-1, [{Key,Value}|Acc], Opt).
227230

228-
unpack_str_or_raw(V, ?OPTION{spec=old} = Opt, Rest) ->
231+
%% Do not remove the binary wrapper from the function clauses, it is a bin optimization for reusing the context
232+
unpack_str_or_raw(<<V/binary>>, ?OPTION{spec=old} = Opt, Rest) ->
229233
{maybe_bin(V, Opt), Rest};
230-
unpack_str_or_raw(V, ?OPTION{spec=new,
234+
unpack_str_or_raw(<<V/binary>>, ?OPTION{spec=new,
231235
unpack_str=UnpackStr,
232236
validate_string=ValidateString} = Opt, Rest) ->
233237
{case UnpackStr of
@@ -237,37 +241,39 @@ unpack_str_or_raw(V, ?OPTION{spec=new,
237241
as_tagged_list -> {string, unpack_str(V)}
238242
end, Rest}.
239243

240-
maybe_bin(Bin, ?OPTION{known_atoms=Known}) when Known=/=[] ->
244+
%% Do not remove the binary wrapper from the function clauses, it is a bin optimization for reusing the context
245+
maybe_bin(<<Bin/binary>>, ?OPTION{known_atoms=Known}) when Known=/=[] ->
241246
case lists:member(Bin,Known) of
242247
true ->
243248
erlang:binary_to_existing_atom(Bin,utf8);
244249
false ->
245250
Bin
246251
end;
247252

248-
maybe_bin(Bin, _) ->
253+
maybe_bin(<<Bin/binary>>, _) ->
249254
Bin.
250255

251256
%% NOTE: msgpack DOES validate the binary as valid unicode string.
252-
unpack_str(Binary) ->
257+
unpack_str(<<Binary/binary>>) ->
253258
case unicode:characters_to_list(Binary) of
254259
{error, _S, _Rest} -> throw({invalid_string, Binary});
255260
{incomplete, _S, _Rest} -> throw({invalid_string, Binary});
256261
String -> String
257262
end.
258263

259-
maybe_unpack_ext(F, _, _, _, _Rest, _, ?OPTION{spec=old}) ->
264+
%% Do not remove the binary wrapper from the function clauses, it is a bin optimization for reusing the context
265+
maybe_unpack_ext(F, _, _, <<_/binary>>, <<_Rest/binary>>, _, ?OPTION{spec=old}) ->
260266
%% trying to unpack new ext formats with old unpacker
261267
throw({badarg, {new_spec, F}});
262-
maybe_unpack_ext(F, undefined, _, _, _Rest, _, _) ->
268+
maybe_unpack_ext(F, undefined, _, <<_/binary>>, <<_Rest/binary>>, _, _) ->
263269
throw({badarg, {bad_ext, F}});
264-
maybe_unpack_ext(_, Unpack, Type, Data, Rest, Orig, _)
270+
maybe_unpack_ext(_, Unpack, Type, <<Data/binary>>, <<Rest/binary>>, Orig, _)
265271
when is_function(Unpack, 3) ->
266272
case Unpack(Type, Data, Orig) of
267273
{ok, Term} -> {Term, Rest};
268274
{error, E} -> {error, E}
269275
end;
270-
maybe_unpack_ext(_, Unpack, Type, Data, Rest, _, _)
276+
maybe_unpack_ext(_, Unpack, Type, <<Data/binary>>, <<Rest/binary>>, _, _)
271277
when is_function(Unpack, 2) ->
272278
case Unpack(Type, Data) of
273279
{ok, Term} -> {Term, Rest};

0 commit comments

Comments
 (0)