Skip to content

Instantly share code, notes, and snippets.

@garazdawi
Created August 3, 2018 09:53
Show Gist options
  • Save garazdawi/1fa0a052ced600503a4f15d9f418aadf to your computer and use it in GitHub Desktop.
Save garazdawi/1fa0a052ced600503a4f15d9f418aadf to your computer and use it in GitHub Desktop.
Decode of partial erlang external term format
-module(decode).
-export([term/1]).
term(<<131,Rest/binary>>) ->
element(1,term(Rest));
%% List
term(<<108,Sz:32,Rest/binary>>) ->
{Lst, R} = lists:foldl(
fun(_, {Acc, B}) ->
{H, LRest} = term(B),
{[H|Acc], LRest}
end, {[],Rest}, lists:seq(1,Sz)),
{Tl, MR} = term(R),
{lists:reverse(Lst,Tl), MR};
%% Tuple
term(<<104,Sz,Rest/binary>>) ->
{Lst, R} = lists:foldl(
fun(_, {Acc, B}) ->
{H, LRest} = term(B),
{[H|Acc], LRest}
end, {[],Rest}, lists:seq(1,Sz)),
{list_to_tuple(lists:reverse(Lst)), R};
%% map
term(<<116,Sz:32,Rest/binary>>) ->
{_Lst, Lst, R} = lists:foldl(
fun F(A, {[V,K], M, B}) ->
F(A,{[], [{K,V}|M], B});
F(_, {Acc, M, B}) ->
{H, LRest} = term(B),
{[H|Acc], M, LRest}
end, {[],[],Rest}, lists:seq(1,Sz*2)),
{maps:from_list(Lst), R};
%% big
term(<<110, Sz, Sign, Num:Sz/binary, Rest/binary>>) ->
Big = lists:sum([D * (1 bsl N) || {D, N} <- lists:zip(binary_to_list(Num), lists:seq(0,Sz-1))]),
{Big, Rest};
%% Atom
term(<<100,Sz:16,Name:Sz/binary,Rest/binary>>) ->
{list_to_atom(binary_to_list(Name)),Rest};
%% Reference
term(<<114,Len:16,Rest/binary>>) ->
BLen = (Len*4),
{Node,<<C,Ref:BLen/binary,NodeRest/binary>>} = term(Rest),
{{ref,Node,C,Ref},NodeRest};
%% pid
term(<<103,Rest/binary>>) ->
{Node,<<Id:32,Ser:32,C:8,NodeRest/binary>>} = term(Rest),
{{pid,Node,Id,Ser,C},NodeRest};
%% NIL
term(<<106,Rest/binary>>) ->
{[],Rest};
%% num
term(<<97,Num,Rest/binary>>) ->
{Num,Rest};
%% num
term(<<98,Num:32,Rest/binary>>) ->
{Num,Rest};
%% String
term(<<107,Len:16,Txt:Len/binary,Rest/binary>>) ->
{binary_to_list(Txt),Rest};
term(<<>>) ->
{'$$cut$$',<<>>};
term(R) ->
{{'$$abc$$',R},<<>>}.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment