Skip to content

Instantly share code, notes, and snippets.

@iilyak
Created July 11, 2017 19:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iilyak/a11a481bd3f7311d8499e19f5e4c8f22 to your computer and use it in GitHub Desktop.
Save iilyak/a11a481bd3f7311d8499e19f5e4c8f22 to your computer and use it in GitHub Desktop.
skip binary encoded term
skip_n_terms(Bin, N) ->
lists:foldl(fun(_, {Acc, Bin}) ->
{Skipped, R} = skip_term(Bin),
{Skipped + Acc, R}
end, {0, Bin}, lists:seq(1, N)).
skip_term(<<97, _:1/binary, Rest/binary>>) -> %% SMALL_INTEGER_EXT
{2, Rest};
skip_term(<<98, _:4/binary, Rest/binary>>) -> %% INTEGER_EXT
{5, Rest};
skip_term(<<99, _:31/binary, Rest/binary>>) -> %% FLOAT_EXT
{32, Rest};
skip_term(<<100, Len:16/integer, Rest/binary>>) -> %% ATOM_EXT
<<_Name:Len/binary, Rest1/binary>> = Rest,
{Len + 3, Rest1};
skip_term(<<101, Rest/binary>>) -> %% REFERENCE_EXT
{NodeSize, <<_ID:4/binary, _Create:1/binary, Rest1/binary>>} = skip_term(Rest), %% skip Node
{NodeSize + 6, Rest1};
skip_term(<<102, Rest/binary>>) -> %% PORT_EXT
{NodeSize, <<_ID:4/binary, _Create:1/binary, Rest1/binary>>} = skip_term(Rest), %% skip Node
{NodeSize + 6, Rest1};
skip_term(<<103, Rest/binary>>) -> %% PID_EXT
{NodeSize, <<_ID:4/binary, _Serial:4/binary, _Create:1/binary, Rest1/binary>>} =
skip_term(Rest), %% skip Node
{NodeSize + 10, Rest1};
skip_term(<<104, Arity:8/integer, Rest/binary>>) -> %% SMALL_TUPLE_EXT
{Skipped, Rest1} = skip_n_terms(Rest, Arity),
{Skipped + 2, Rest1};
skip_term(<<105, Arity:32/integer, Rest/binary>>) -> %% LARGE_TUPLE_EXT
{Skipped, Rest1} = skip_n_terms(Rest, Arity),
{Skipped + 5, Rest1};
skip_term(<<116, Arity:32/integer, Rest/binary>>) -> %% MAP_EXT
{Skipped, Rest1} = skip_n_terms(Rest, Arity),
{Skipped + 5, Rest1};
skip_term(<<106, Rest/binary>>) -> %% NIL_EXT
{1, Rest};
skip_term(<<107, Len:16/integer, Rest/binary>>) -> %% STRING_EXT
<<_:Len/binary, Rest1/binary>> = Rest,
{Len + 3, Rest1};
skip_term(<<108, Len:32/integer, Rest/binary>>) -> %% LIST_EXT
{Skipped, Rest1} = skip_n_terms(Rest, Len),
{TailSize, Rest2} = skip_term(Rest1),
{Skipped + TailSize + 5, Rest2}; %% skip tail
skip_term(<<109, Len:32/integer, Rest/binary>>) -> %% BINARY_EXT
<<_:Len/binary, Rest1/binary>> = Rest,
{Len + 5, Rest1};
skip_term(<<110, Len:8/integer, _Sign:1/binary, Rest/binary>>) -> %% SMALL_BIG_EXT
<<_:Len/binary, Rest1/binary>> = Rest,
{Len + 3, Rest1};
skip_term(<<111, Len:32/integer, _Sign:1/binary, Rest/binary>>) -> %% LARGE_BIG_EXT
<<_:Len/binary, Rest1/binary>> = Rest,
{Len + 6, Rest1};
skip_term(<<114, Len:16/integer, Rest/binary>>) -> %% NEW_REFERENCE_EXT
IdLen = Len * 4,
{NodeSize, <<_ID:4/binary, _Create:1/binary, _ID:IdLen/binary, Rest1/binary>>} =
skip_term(Rest), %% skip Node
{NodeSize + 8 + IdLen, Rest1};
skip_term(<<115, Len:8/integer, Rest/binary>>) -> %% SMALL_ATOM_EXT
<<_:Len/binary, Rest1/binary>> = Rest,
{Len + 2, Rest1};
skip_term(<<117, NumFree:32/integer, Rest/binary>>) -> %% FUN_EXT
{PidSize, Rest1} = skip_term(Rest), %% skip Pid
{ModuleSize, Rest2} = skip_term(Rest1), %% skip Module
{IndexSize, Rest3} = skip_term(Rest2), %% skip Index
{UniqSize, Rest4} = skip_term(Rest3), %% skip Uniq
{Skipped, Rest5} = skip_n_terms(Rest4, NumFree),
{PidSize + ModuleSize + IndexSize + UniqSize + Skipped + 5, Rest5};
skip_term(<<112, Size:32/integer, Rest/binary>>) -> %% NEW_FUN_EXT
Len = Size - 4,
<<_:Len/binary, Rest1/binary>> = Rest,
{Len + 5, Rest1};
skip_term(<<113, Rest/binary>>) -> %% EXPORT_EXT
{ModuleSize, Rest1} = skip_term(Rest), %% skip Module
{FunctionSize, Rest2} = skip_term(Rest1), %% skip Function
{AritySize, Rest3} = skip_term(Rest2), %% skip Arity
{ModuleSize + FunctionSize + AritySize, Rest3};
skip_term(<<77, Len:32/integer, _:1/binary, Rest/binary>>) -> %% BIT_BINARY_EXT
<<_:Len/binary, Rest1/binary>> = Rest,
{Len + 6, Rest1};
skip_term(<<70, Len:64/integer, Rest/binary>>) -> %% NEW_FLOAT_EXT
{9, Rest};
skip_term(<<118, Len:16/integer, Rest/binary>>) -> %% ATOM_UTF8_EXT
<<_:Len/binary, Rest1/binary>> = Rest,
{Len + 3, Rest1};
skip_term(<<119, Len:8/integer, Rest/binary>>) -> %% SMAL_ATOM_UTF8_EXT
<<_:Len/binary, Rest1/binary>> = Rest,
{Len + 2, Rest1};
skip_term(<<>>) -> {0, <<>>}.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment