Current section
Files
Jump to
Current section
Files
src/pb_lite.erl
-module(pb_lite).
-compile(no_auto_import).
-export([dvarint/1, dtag_type/1, decode/1, decode_1/2]).
-export_type([value_type/0]).
-type value_type() :: {var_int, integer()} |
{int64, integer()} |
{binary, bitstring()} |
{group, list({integer(), value_type()})} |
{int32, integer()}.
-spec dvarint(bitstring()) -> {ok, {integer(), bitstring()}} | {error, nil}.
dvarint(Bin) ->
dvarint_1(Bin, 0, 0).
-spec dvarint_1(bitstring(), integer(), integer()) -> {ok,
{integer(), bitstring()}} |
{error, nil}.
dvarint_1(Bin, Count, Acc) ->
case Bin of
<<1:1, I:7, R/binary>> ->
New_acc = Acc + helper:f_bsl(I, Count * 7),
dvarint_1(R, Count + 1, New_acc);
<<0:1, I@1:7, R@1/binary>> ->
Num = Acc + helper:f_bsl(I@1, Count * 7),
<<Signed:64/signed>> = <<Num:64>>,
{ok, {Signed, R@1}};
<<>> ->
{error, nil}
end.
-spec dbit64(bitstring()) -> {ok, {integer(), bitstring()}} | {error, nil}.
dbit64(Bin) ->
case Bin of
<<Int64:64/little-signed, R/binary>> ->
{ok, {Int64, R}};
_@1 ->
{error, nil}
end.
-spec dlen_delimited(bitstring()) -> {ok, {bitstring(), bitstring()}} |
{error, nil}.
dlen_delimited(Bin) ->
case dvarint(Bin) of
{error, _try} -> {error, _try};
{ok, {Value, R}} ->
case R of
<<V:Value/binary, R@1/binary>> ->
{ok, {V, R@1}};
_@1 ->
{error, nil}
end
end.
-spec dbit32(bitstring()) -> {ok, {integer(), bitstring()}} | {error, nil}.
dbit32(Bin) ->
case Bin of
<<Int64:32/little-signed, R/binary>> ->
{ok, {Int64, R}};
_@1 ->
{error, nil}
end.
-spec dtag_type(bitstring()) -> {ok, {integer(), integer(), bitstring()}} |
{error, nil}.
dtag_type(Bin) ->
case Bin of
<<Tag:5, Ftype:3, R/binary>> ->
case helper:f_band(Tag, 16) of
16 ->
case dvarint(R) of
{error, _try} -> {error, _try};
{ok, {Value, R@1}} ->
V = helper:f_bsl(Value, 4) + helper:f_band(
Tag,
16#F
),
{ok, {V, Ftype, R@1}}
end;
_@1 ->
{ok, {Tag, Ftype, R}}
end
end.
-spec decode(bitstring()) -> {ok,
{list({integer(), value_type()}), bitstring()}} |
{error, nil}.
decode(Bin) ->
decode_1(Bin, []).
-spec decode_1(bitstring(), list({integer(), value_type()})) -> {ok,
{list({integer(),
value_type()}),
bitstring()}} |
{error, nil}.
decode_1(Bin, Acc) ->
case Bin of
<<>> ->
{ok, {gleam@list:reverse(Acc), <<>>}};
_@1 ->
case dtag_type(Bin) of
{error, _try} -> {error, _try};
{ok, {Tag, F_type, R}} ->
case F_type of
0 ->
case dvarint(R) of
{error, _try@1} -> {error, _try@1};
{ok, {Value, R@1}} ->
V = {Tag, {var_int, Value}},
decode_1(R@1, [V | Acc])
end;
1 ->
case dbit64(R) of
{error, _try@2} -> {error, _try@2};
{ok, {Value@1, R@2}} ->
V@1 = {Tag, {int64, Value@1}},
decode_1(R@2, [V@1 | Acc])
end;
2 ->
case dlen_delimited(R) of
{error, _try@3} -> {error, _try@3};
{ok, {Value@2, R@3}} ->
V@2 = {Tag, {binary, Value@2}},
decode_1(R@3, [V@2 | Acc])
end;
3 ->
case decode_1(R, []) of
{error, _try@4} -> {error, _try@4};
{ok, {Value@3, R@4}} ->
V@3 = {Tag, {group, Value@3}},
decode_1(R@4, [V@3 | Acc])
end;
4 ->
{ok, {gleam@list:reverse(Acc), R}};
5 ->
case dbit32(R) of
{error, _try@5} -> {error, _try@5};
{ok, {Value@4, R@5}} ->
V@4 = {Tag, {int32, Value@4}},
decode_1(R@5, [V@4 | Acc])
end
end
end
end.