erlAarango 二进制序列化库
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

1619 lines
54 KiB

-module(eVPack).
-include("eVPack.hrl").
-compile(inline).
-compile({inline_size, 128}).
-import(lists, [reverse/1]).
-import(maps, [iterator/1, next/1, keys/1]).
-export([
%% decode
decodeAll/1
, decodeHeader/1
, decodePart/1
%% encode
, encodeIol/1
, encodeBin/1
, encodeIol/3
, encodeBin/3
%% other API
, encodeAtom/1
, encodeMap/3
, encodeList/3
, encodeFloat/1
, encodeString/1
, encodeInteger/1
, buildIndexTable_1/2
, buildIndexTable_2/2
, buildIndexTable_4/2
, buildIndexTable_8/2
]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% encode %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-spec encodeIol(term()) -> vpack() | {error, any()}.
encodeIol(Term) ->
{VPack, _Size} = encoder(Term, ?VpArrDef, ?VpObjDef),
VPack.
-spec encodeBin(term()) -> vpack() | {error, any()}.
encodeBin(Term) ->
{VPack, _Size} = encoder(Term, ?VpArrDef, ?VpObjDef),
iolist_to_binary(VPack).
-spec encodeIol(term(), vpOpt(), vpOpt()) -> vpack() | {error, any()}.
encodeIol(Term, ArrOpt, ObjOpt) ->
{VPack, _Size} = encoder(Term, ArrOpt, ObjOpt),
VPack.
-spec encodeBin(term(), vpOpt(), vpOpt()) -> vpack() | {error, any()}.
encodeBin(Term, ArrOpt, ObjOpt) ->
{VPack, _Size} = encoder(Term, ArrOpt, ObjOpt),
iolist_to_binary(VPack).
encoder(Map, ArrOpt, ObjOpt) when erlang:is_map(Map) ->
encodeMap(ObjOpt, Map, ArrOpt);
encoder(Atom, _, _) when erlang:is_atom(Atom) ->
encodeAtom(Atom);
encoder(Binary, _, _) when erlang:is_binary(Binary) ->
encodeString(Binary);
encoder(Integer, _, _) when erlang:is_integer(Integer) ->
encodeInteger(Integer);
encoder(Float, _, _) when erlang:is_float(Float) ->
encodeFloat(Float);
encoder(List, ArrOpt, ObjOpt) when erlang:is_list(List) ->
encodeList(ArrOpt, List, ObjOpt);
encoder({?blob, Blob}, _, _) when erlang:is_binary(Blob) ->
encodeBlob(Blob);
encoder(_Value, _, _) ->
erlang:throw({error, {invalid_type, dataType(_Value), _Value}}).
dataType(Data) when is_list(Data) -> list;
dataType(Data) when is_integer(Data) -> integer;
dataType(Data) when is_binary(Data) -> binary;
dataType(Data) when is_function(Data) -> function;
dataType(Data) when is_tuple(Data) -> tuple;
dataType(Data) when is_atom(Data) -> atom;
dataType(Data) when is_bitstring(Data) -> bitstring;
dataType(Data) when is_boolean(Data) -> boolean;
dataType(Data) when is_float(Data) -> float;
dataType(Data) when is_number(Data) -> number;
dataType(Data) when is_pid(Data) -> pid;
dataType(Data) when is_port(Data) -> port;
dataType(_Data) -> not_know.
encodeAtom(undefined) -> {<<24/integer>>, 1};
encodeAtom(false) -> {<<25/integer>>, 1};
encodeAtom(true) -> {<<26/integer>>, 1};
encodeAtom(minKey) -> {<<30/integer>>, 1};
encodeAtom(maxKey) -> {<<31/integer>>, 1};
encodeAtom(Atom) ->
encodeString(erlang:atom_to_binary(Atom, utf8)).
encodeInteger(0) ->
{<<48/integer>>, 1};
encodeInteger(1) ->
{<<49/integer>>, 1};
encodeInteger(2) ->
{<<50/integer>>, 1};
encodeInteger(3) ->
{<<51/integer>>, 1};
encodeInteger(4) ->
{<<52/integer>>, 1};
encodeInteger(5) ->
{<<53/integer>>, 1};
encodeInteger(6) ->
{<<54/integer>>, 1};
encodeInteger(7) ->
{<<55/integer>>, 1};
encodeInteger(8) ->
{<<56/integer>>, 1};
encodeInteger(9) ->
{<<57/integer>>, 1};
encodeInteger(-6) ->
{<<58/integer>>, 1};
encodeInteger(-5) ->
{<<59/integer>>, 1};
encodeInteger(-4) ->
{<<60/integer>>, 1};
encodeInteger(-3) ->
{<<61/integer>>, 1};
encodeInteger(-2) ->
{<<62/integer>>, 1};
encodeInteger(-1) ->
{<<63/integer>>, 1};
encodeInteger(Integer) ->
if
Integer < -9223372036854775808 ->
erlang:throw({error, too_small_integer});
Integer < -36028797018963968 ->
{<<39/integer, Integer:64/integer-little-signed>>, 9};
Integer < -140737488355328 ->
{<<38/integer, Integer:56/integer-little-signed>>, 8};
Integer < -549755813888 ->
{<<37/integer, Integer:48/integer-little-signed>>, 7};
Integer < -2147483648 ->
{<<36/integer, Integer:40/integer-little-signed>>, 6};
Integer < -8388608 ->
{<<35/integer, Integer:32/integer-little-signed>>, 5};
Integer < -32768 ->
{<<34/integer, Integer:24/integer-little-signed>>, 4};
Integer < -128 ->
{<<33/integer, Integer:16/integer-little-signed>>, 3};
Integer < 0 ->
{<<32/integer, Integer:8/integer-little-unsigned>>, 2};
Integer < 256 ->
{<<40/integer, Integer:8/integer-little-unsigned>>, 2};
Integer < 65536 ->
{<<41/integer, Integer:16/integer-little-unsigned>>, 3};
Integer < 16777216 ->
{<<42/integer, Integer:24/integer-little-unsigned>>, 4};
Integer < 4294967296 ->
{<<43/integer, Integer:32/integer-little-unsigned>>, 5};
Integer < 1099511627776 ->
{<<44/integer, Integer:40/integer-little-unsigned>>, 6};
Integer < 281474976710656 ->
{<<45/integer, Integer:48/integer-little-unsigned>>, 7};
Integer < 72057594037927936 ->
{<<46/integer, Integer:56/integer-little-unsigned>>, 8};
Integer < 18446744073709551616 ->
{<<47/integer, Integer:64/integer-little-unsigned>>, 9};
true ->
erlang:throw({error, too_big_integer})
end.
encodeFloat(Float) ->
{<<27/integer, Float:64/float-little>>, 9}.
encodeString(BinStr) ->
StrSize = erlang:byte_size(BinStr),
if
StrSize =< 126 ->
{<<(StrSize + 64)/integer, BinStr/binary>>, StrSize + 1};
StrSize < 18446744073709551616 ->
{<<191/integer, StrSize:64/integer-little-unsigned, BinStr/binary>>, StrSize + 9};
true ->
erlang:throw({error, too_max_str})
end.
encodeBlob(Blob) ->
StrSize = erlang:byte_size(Blob),
if
StrSize < 256 ->
{<<192/integer, StrSize:8/integer-little-unsigned, Blob/binary>>, StrSize + 2};
StrSize < 65536 ->
{<<193/integer, StrSize:16/integer-little-unsigned, Blob/binary>>, StrSize + 3};
StrSize < 16777216 ->
{<<194/integer, StrSize:24/integer-little-unsigned, Blob/binary>>, StrSize + 4};
StrSize < 4294967296 ->
{<<195/integer, StrSize:32/integer-little-unsigned, Blob/binary>>, StrSize + 5};
StrSize < 1099511627776 ->
{<<196/integer, StrSize:40/integer-little-unsigned, Blob/binary>>, StrSize + 6};
StrSize < 281474976710656 ->
{<<197/integer, StrSize:48/integer-little-unsigned, Blob/binary>>, StrSize + 7};
StrSize < 72057594037927936 ->
{<<198/integer, StrSize:56/integer-little-unsigned, Blob/binary>>, StrSize + 8};
StrSize < 18446744073709551616 ->
{<<199/integer, StrSize:64/integer-little-unsigned, Blob/binary>>, StrSize + 9};
true ->
erlang:throw({error, too_max_blob})
end.
doEncodeMap(Iterator, ArrOpt, ObjOpt, AccList, SumSize) ->
case maps:next(Iterator) of
{Key, Value, NextIter} ->
{KeyEn, KeySize} = encodeString(asKey(Key)),
{ValueEn, ValueSize} = encoder(Value, ArrOpt, ObjOpt),
doEncodeMap(NextIter, ArrOpt, ObjOpt, [ValueEn, KeyEn | AccList], SumSize + KeySize + ValueSize);
none ->
{AccList, SumSize}
end.
doEncodeMap(Iterator, ArrOpt, ObjOpt, AccList, Offsets, SumSize) ->
case maps:next(Iterator) of
{Key, Value, NextIter} ->
{KeyEn, KeySize} = encodeString(asKey(Key)),
{ValueEn, ValueSize} = encoder(Value, ArrOpt, ObjOpt),
doEncodeMap(NextIter, ArrOpt, ObjOpt, [ValueEn, KeyEn | AccList], [SumSize | Offsets], SumSize + KeySize + ValueSize);
none ->
{AccList, Offsets, SumSize}
end.
doEncodeMap([], _Map, _ArrOpt, _ObjOpt, AccList, Offsets, SumSize) ->
{AccList, Offsets, SumSize};
doEncodeMap([OneKeys | Left], Map, ArrOpt, ObjOpt, AccList, Offsets, SumSize) ->
case Map of
#{OneKeys := Value} ->
{KeyEn, KeySize} = encodeString(OneKeys),
{ValueEn, ValueSize} = encoder(Value, ArrOpt, ObjOpt),
doEncodeMap(Left, Map, ArrOpt, ObjOpt, [ValueEn, KeyEn | AccList], [SumSize | Offsets], SumSize + KeySize + ValueSize);
_ ->
AtomKey = binary_to_atom(OneKeys, utf8),
case Map of
#{AtomKey := Value} ->
{KeyEn, KeySize} = encodeString(OneKeys),
{ValueEn, ValueSize} = encoder(Value, ArrOpt, ObjOpt),
doEncodeMap(Left, Map, ArrOpt, ObjOpt, [ValueEn, KeyEn | AccList], [SumSize | Offsets], SumSize + KeySize + ValueSize);
_ ->
erlang:throw({error, {no_map_value, OneKeys}})
end
end.
encodeMap(?VpObjNcNs, Map, ArrOpt) ->
MapSize = erlang:map_size(Map),
case MapSize == 0 of
true ->
{<<10/integer>>, 1};
_ ->
{AccList, Offsets, SumSize} = doEncodeMap(maps:iterator(Map), ArrOpt, ?VpObjNcNs, [], [], 0),
IoData = lists:reverse(AccList),
encodeUnSortMapIndexTable(IoData, MapSize, Offsets, SumSize)
end;
encodeMap(?VpObjYc, Map, ArrOpt) ->
MapSize = erlang:map_size(Map),
case MapSize == 0 of
true ->
{<<10/integer>>, 1};
_ ->
{AccList, SumSize} = doEncodeMap(maps:iterator(Map), ArrOpt, ?VpObjYc, [], 0),
IoData = lists:reverse(AccList),
encodeCompactData(<<20/integer>>, IoData, SumSize, MapSize)
end;
encodeMap(?VpObjNcYs, Map, ArrOpt) ->
MapSize = erlang:map_size(Map),
case MapSize == 0 of
true ->
{<<10/integer>>, 1};
_ ->
Keys = maps:keys(Map),
StrKeys = [asKey(OneKey) || OneKey <- Keys],
{AccList, Offsets, SumSize} = doEncodeMap(lists:sort(StrKeys), Map, ArrOpt, ?VpObjNcYs, [], [], 0),
IoData = lists:reverse(AccList),
encodeSortMapIndexTable(IoData, MapSize, Offsets, SumSize)
end.
encodeSortMapIndexTable(IoData, Count, Offsets, SumSize) ->
TemSize = SumSize + Count,
if
TemSize < 253 ->
AllSize = TemSize + 3,
Header = <<11/integer, AllSize:8/integer-unsigned, Count:8/integer-unsigned>>,
{[Header, IoData, buildIndexTable_1(Offsets, 3)], AllSize};
TemSize + Count < 65531 ->
AllSize = TemSize + Count + 5,
Header = <<12/integer, AllSize:16/integer-little-unsigned, Count:16/integer-little-unsigned>>,
{[Header, IoData, buildIndexTable_2(Offsets, 5)], AllSize};
TemSize + Count * 3 < 4294967287 ->
AllSize = TemSize + Count * 3 + 9,
Header = <<13/integer, AllSize:32/integer-little-unsigned, Count:32/integer-little-unsigned>>,
{[Header, IoData, buildIndexTable_4(Offsets, 9)], AllSize};
TemSize + Count * 7 < 18446744073709551599 ->
AllSize = TemSize + Count * 7 + 17,
Header = <<14/integer, AllSize:64/integer-little-unsigned>>,
{[Header, IoData, buildIndexTable_8(Offsets, 9), <<Count:64/integer-little-unsigned>>], AllSize};
true ->
erlang:throw({error, too_much_sort_map_size})
end.
encodeUnSortMapIndexTable(IoData, Count, Offsets, SumSize) ->
TemSize = SumSize + Count,
if
TemSize < 253 ->
AllSize = TemSize + 3,
Header = <<15/integer, AllSize:8/integer-unsigned, Count:8/integer-unsigned>>,
{[Header, IoData, buildIndexTable_1(Offsets, 3)], AllSize};
TemSize + Count < 65531 ->
AllSize = TemSize + Count + 5,
Header = <<16/integer, AllSize:16/integer-little-unsigned, Count:16/integer-little-unsigned>>,
{[Header, IoData, buildIndexTable_2(Offsets, 5)], AllSize};
TemSize + Count * 3 < 4294967287 ->
AllSize = TemSize + Count * 3 + 9,
Header = <<17/integer, AllSize:32/integer-little-unsigned, Count:32/integer-little-unsigned>>,
{[Header, IoData, buildIndexTable_4(Offsets, 9)], AllSize};
TemSize + Count * 7 < 18446744073709551599 ->
AllSize = TemSize + Count * 7 + 17,
Header = <<18/integer, AllSize:64/integer-little-unsigned>>,
{[Header, IoData, buildIndexTable_8(Offsets, 9), <<Count:64/integer-little-unsigned>>], AllSize};
true ->
erlang:throw({error, too_much_unsort_map_size})
end.
buildIndexTable_1(Offsets, StartSize) ->
<<<<(OneOff + StartSize):1/integer-little-unsigned-unit:8>> || OneOff <- Offsets>>.
buildIndexTable_2(Offsets, StartSize) ->
<<<<(OneOff + StartSize):2/integer-little-unsigned-unit:8>> || OneOff <- Offsets>>.
buildIndexTable_4(Offsets, StartSize) ->
<<<<(OneOff + StartSize):4/integer-little-unsigned-unit:8>> || OneOff <- Offsets>>.
buildIndexTable_8(Offsets, StartSize) ->
<<<<(OneOff + StartSize):8/integer-little-unsigned-unit:8>> || OneOff <- Offsets>>.
compactIntegerList(Integer, AccList) ->
case Integer < 128 of
true ->
[<<Integer:8/integer-unsigned>> | AccList];
_ ->
TemInteger = Integer band 127 bor 128,
NewInteger = Integer bsr 7,
compactIntegerList(NewInteger, [<<TemInteger:8/integer-unsigned>> | AccList])
end.
compactInteger(Value, Reverse) ->
CompactList = compactIntegerList(Value, []),
case Reverse of
false -> lists:reverse(CompactList);
_ -> CompactList
end.
compactSize(AllSize) ->
TemByte = erlang:ceil(AllSize / 128),
FinalSize = AllSize + TemByte,
LastSize =
case TemByte == erlang:ceil(FinalSize / 128) of
false -> FinalSize + 1;
_ -> FinalSize
end,
{compactInteger(LastSize, false), LastSize}.
encodeCompactData(Type, IoData, SumSize, Count) ->
CompactList = compactInteger(Count, true),
AllSize = SumSize + 1 + erlang:length(CompactList),
{TotalSize, FinalSize} = compactSize(AllSize),
{[Type, TotalSize, IoData | CompactList], FinalSize}.
asKey(Value) when erlang:is_atom(Value) -> erlang:atom_to_binary(Value, utf8);
asKey(Value) when erlang:is_binary(Value) -> Value;
asKey(_Value) -> erlang:throw({error, invalid_key}).
doEncodeList([], _ArrOpt, _ObjOpt, AccList, SumSize, Count) ->
{AccList, SumSize, Count};
doEncodeList([One | Left], ArrOpt, ObjOpt, AccList, SumSize, Count) ->
{ValueEn, ValueSize} = encoder(One, ArrOpt, ObjOpt),
doEncodeList(Left, ArrOpt, ObjOpt, [ValueEn | AccList], SumSize + ValueSize, Count + 1).
doEncodeList([], _ArrOpt, _ObjOpt, AccList, Offsets, SumSize, Count, SizeOrIsNot) ->
{AccList, Offsets, SumSize, Count, SizeOrIsNot};
doEncodeList([One | Left], ArrOpt, ObjOpt, AccList, Offsets, SumSize, Count, SizeOrIsNot) ->
{ValueEn, ValueSize} = encoder(One, ArrOpt, ObjOpt),
case SizeOrIsNot of
true ->
doEncodeList(Left, ArrOpt, ObjOpt, [ValueEn | AccList], [SumSize | Offsets], ValueSize + SumSize, Count + 1, SizeOrIsNot);
init ->
doEncodeList(Left, ArrOpt, ObjOpt, [ValueEn | AccList], [SumSize | Offsets], ValueSize + SumSize, Count + 1, ValueSize);
_ ->
doEncodeList(Left, ArrOpt, ObjOpt, [ValueEn | AccList], [SumSize | Offsets], ValueSize + SumSize, Count + 1, ValueSize =/= SizeOrIsNot orelse SizeOrIsNot)
end.
encodeList(?VpArrNc, List, ObjOpt) ->
case List of
[] ->
{<<1/integer>>, 1};
_ ->
{AccList, Offsets, SumSize, Count, IsNotSameSize} = doEncodeList(List, ?VpArrNc, ObjOpt, [], [], 0, 0, init),
IoData = lists:reverse(AccList),
case IsNotSameSize of
true ->
encodeListWithIndexTable(IoData, Count, Offsets, SumSize);
_ ->
encodeListWithoutIndexTable(IoData, SumSize)
end
end;
encodeList(?VpArrYc, List, ObjOpt) ->
case List of
[] ->
{<<1/integer>>, 1};
_ ->
{AccList, SumSize, Count} = doEncodeList(List, ?VpArrYc, ObjOpt, [], 0, 0),
IoData = lists:reverse(AccList),
encodeCompactData(<<19/integer>>, IoData, SumSize, Count)
end.
encodeListWithoutIndexTable(IoData, SumSize) ->
if
SumSize < 254 ->
AllSize = SumSize + 2,
Header = <<2/integer, AllSize:1/integer-little-unsigned-unit:8>>,
{[Header, IoData], AllSize};
SumSize < 65533 ->
AllSize = SumSize + 3,
Header = <<3/integer, AllSize:2/integer-little-unsigned-unit:8>>,
{[Header, IoData], AllSize};
SumSize < 4294967291 ->
AllSize = SumSize + 5,
Header = <<4/integer, AllSize:4/integer-little-unsigned-unit:8>>,
{[Header, IoData], AllSize};
SumSize < 18446744073709551607 ->
AllSize = SumSize + 9,
Header = <<5/integer, AllSize:8/integer-little-unsigned-unit:8>>,
{[Header, IoData], AllSize};
true ->
erlang:throw({error, too_much_wo_list_size})
end.
encodeListWithIndexTable(IoData, Count, Offsets, SumSize) ->
TemSize = SumSize + Count,
if
TemSize < 253 ->
AllSize = TemSize + 3,
Header = <<6/integer, AllSize:8/integer-unsigned, Count:8/integer-unsigned>>,
{[Header, IoData, buildIndexTable_1(Offsets, 3)], AllSize};
TemSize + Count < 65531 ->
AllSize = TemSize + Count + 5,
Header = <<7/integer, AllSize:16/integer-little-unsigned, Count:16/integer-little-unsigned>>,
{[Header, IoData, buildIndexTable_2(Offsets, 5)], AllSize};
TemSize + Count * 3 < 4294967287 ->
AllSize = TemSize + Count * 3 + 9,
Header = <<8/integer, AllSize:32/integer-little-unsigned, Count:32/integer-little-unsigned>>,
{[Header, IoData, buildIndexTable_4(Offsets, 9)], AllSize};
TemSize + Count * 7 < 18446744073709551599 ->
AllSize = TemSize + Count * 7 + 17,
Header = <<9/integer, AllSize:64/integer-little-unsigned>>,
{[Header, IoData, buildIndexTable_8(Offsets, 9), <<Count:64/integer-little-unsigned>>], AllSize};
true ->
erlang:throw({error, too_much_wi_list_size})
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% decode %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-spec decodeAll(vpack()) -> {term(), term()}.
decodeAll(DataBin) ->
{HeaderTerm, BodyBin} = decoder(DataBin),
case BodyBin of
<<>> ->
{HeaderTerm, #{}};
_ ->
{BodyTerm, _LeftBin} = decoder(BodyBin),
{HeaderTerm, BodyTerm}
end.
-spec decodeHeader(vpack()) -> term().
decodeHeader(DataBin) ->
{HeaderTerm, _BodyBin} = decoder(DataBin),
HeaderTerm.
-spec decodePart(vpack()) -> {term(), binary()}.
decodePart(DataBin) ->
decoder(DataBin).
decoder(DataBin) ->
case DataBin of
<<Type/integer, RestBin/bitstring>> ->
decoder(Type, RestBin);
_ ->
erlang:throw({error, unexpected_end})
end.
decoder(0, RestBin) ->
erlang:throw({error, {unsupported_type, RestBin}});
decoder(1, RestBin) ->
{[], RestBin};
decoder(2, RestBin) ->
parseArrWithoutIndexTable(1, RestBin);
decoder(3, RestBin) ->
parseArrWithoutIndexTable(2, RestBin);
decoder(4, RestBin) ->
parseArrWithoutIndexTable(4, RestBin);
decoder(5, RestBin) ->
parseArrWithoutIndexTable(8, RestBin);
decoder(6, RestBin) ->
parseArrWithIndexTable(1, RestBin);
decoder(7, RestBin) ->
parseArrWithIndexTable(2, RestBin);
decoder(8, RestBin) ->
parseArrWithIndexTable(4, RestBin);
decoder(9, RestBin) ->
parseArrWithIndexTable(8, RestBin);
decoder(10, RestBin) ->
{#{}, RestBin};
decoder(11, RestBin) ->
parseObject(1, RestBin);
decoder(12, RestBin) ->
parseObject(2, RestBin);
decoder(13, RestBin) ->
parseObject(4, RestBin);
decoder(14, RestBin) ->
parseObject(8, RestBin);
decoder(15, RestBin) ->
parseObject(1, RestBin);
decoder(16, RestBin) ->
parseObject(2, RestBin);
decoder(17, RestBin) ->
parseObject(4, RestBin);
decoder(18, RestBin) ->
parseObject(8, RestBin);
decoder(19, RestBin) ->
parseCompactArr(RestBin);
decoder(20, RestBin) ->
parseCompactObj(RestBin);
decoder(21, _RestBin) ->
erlang:throw({error, {unsupported_type, 21}});
decoder(22, _RestBin) ->
erlang:throw({error, {unsupported_type, 22}});
decoder(23, RestBin) ->
{illegal, RestBin};
decoder(24, RestBin) -> {undefined, RestBin};
decoder(25, RestBin) -> {false, RestBin};
decoder(26, RestBin) -> {true, RestBin};
decoder(27, RestBin) ->
<<Float:64/float-little, LeftBin/bitstring>> = RestBin,
{Float, LeftBin};
decoder(28, RestBin) ->
<<TimeMs:64/integer-little-unsigned, LeftBin/bitstring>> = RestBin,
{TimeMs, LeftBin};
decoder(29, _RestBin) ->
erlang:throw({error, {unsupported_type, 29}});
decoder(30, RestBin) ->
{minKey, RestBin};
decoder(31, RestBin) ->
{maxKey, RestBin};
decoder(32, RestBin) ->
parseInt(1, RestBin);
decoder(33, RestBin) ->
parseInt(2, RestBin);
decoder(34, RestBin) ->
parseInt(3, RestBin);
decoder(35, RestBin) ->
parseInt(4, RestBin);
decoder(36, RestBin) ->
parseInt(5, RestBin);
decoder(37, RestBin) ->
parseInt(6, RestBin);
decoder(38, RestBin) ->
parseInt(7, RestBin);
decoder(39, RestBin) ->
parseInt(8, RestBin);
decoder(40, RestBin) ->
parseUint(1, RestBin);
decoder(41, RestBin) ->
parseUint(2, RestBin);
decoder(42, RestBin) ->
parseUint(3, RestBin);
decoder(43, RestBin) ->
parseUint(4, RestBin);
decoder(44, RestBin) ->
parseUint(5, RestBin);
decoder(45, RestBin) ->
parseUint(6, RestBin);
decoder(46, RestBin) ->
parseUint(7, RestBin);
decoder(47, RestBin) ->
parseUint(8, RestBin);
decoder(48, RestBin) ->
{0, RestBin};
decoder(49, RestBin) ->
{1, RestBin};
decoder(50, RestBin) ->
{2, RestBin};
decoder(51, RestBin) ->
{3, RestBin};
decoder(52, RestBin) ->
{4, RestBin};
decoder(53, RestBin) ->
{5, RestBin};
decoder(54, RestBin) ->
{6, RestBin};
decoder(55, RestBin) ->
{7, RestBin};
decoder(56, RestBin) ->
{8, RestBin};
decoder(57, RestBin) ->
{9, RestBin};
decoder(58, RestBin) ->
{-6, RestBin};
decoder(59, RestBin) ->
{-5, RestBin};
decoder(60, RestBin) ->
{-4, RestBin};
decoder(61, RestBin) ->
{-3, RestBin};
decoder(62, RestBin) ->
{-2, RestBin};
decoder(63, RestBin) ->
{-1, RestBin};
decoder(64, RestBin) ->
{<<>>, RestBin};
decoder(65, RestBin) ->
<<BinStr:1/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(66, RestBin) ->
<<BinStr:2/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(67, RestBin) ->
<<BinStr:3/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(68, RestBin) ->
<<BinStr:4/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(69, RestBin) ->
<<BinStr:5/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(70, RestBin) ->
<<BinStr:6/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(71, RestBin) ->
<<BinStr:7/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(72, RestBin) ->
<<BinStr:8/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(73, RestBin) ->
<<BinStr:9/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(74, RestBin) ->
<<BinStr:10/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(75, RestBin) ->
<<BinStr:11/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(76, RestBin) ->
<<BinStr:12/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(77, RestBin) ->
<<BinStr:13/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(78, RestBin) ->
<<BinStr:14/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(79, RestBin) ->
<<BinStr:15/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(80, RestBin) ->
<<BinStr:16/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(81, RestBin) ->
<<BinStr:17/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(82, RestBin) ->
<<BinStr:18/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(83, RestBin) ->
<<BinStr:19/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(84, RestBin) ->
<<BinStr:20/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(85, RestBin) ->
<<BinStr:21/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(86, RestBin) ->
<<BinStr:22/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(87, RestBin) ->
<<BinStr:23/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(88, RestBin) ->
<<BinStr:24/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(89, RestBin) ->
<<BinStr:25/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(90, RestBin) ->
<<BinStr:26/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(91, RestBin) ->
<<BinStr:27/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(92, RestBin) ->
<<BinStr:28/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(93, RestBin) ->
<<BinStr:29/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(94, RestBin) ->
<<BinStr:30/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(95, RestBin) ->
<<BinStr:31/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(96, RestBin) ->
<<BinStr:32/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(97, RestBin) ->
<<BinStr:33/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(98, RestBin) ->
<<BinStr:34/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(99, RestBin) ->
<<BinStr:35/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(100, RestBin) ->
<<BinStr:36/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(101, RestBin) ->
<<BinStr:37/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(102, RestBin) ->
<<BinStr:38/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(103, RestBin) ->
<<BinStr:39/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(104, RestBin) ->
<<BinStr:40/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(105, RestBin) ->
<<BinStr:41/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(106, RestBin) ->
<<BinStr:42/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(107, RestBin) ->
<<BinStr:43/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(108, RestBin) ->
<<BinStr:44/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(109, RestBin) ->
<<BinStr:45/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(110, RestBin) ->
<<BinStr:46/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(111, RestBin) ->
<<BinStr:47/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(112, RestBin) ->
<<BinStr:48/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(113, RestBin) ->
<<BinStr:49/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(114, RestBin) ->
<<BinStr:50/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(115, RestBin) ->
<<BinStr:51/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(116, RestBin) ->
<<BinStr:52/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(117, RestBin) ->
<<BinStr:53/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(118, RestBin) ->
<<BinStr:54/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(119, RestBin) ->
<<BinStr:55/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(120, RestBin) ->
<<BinStr:56/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(121, RestBin) ->
<<BinStr:57/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(122, RestBin) ->
<<BinStr:58/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(123, RestBin) ->
<<BinStr:59/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(124, RestBin) ->
<<BinStr:60/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(125, RestBin) ->
<<BinStr:61/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(126, RestBin) ->
<<BinStr:62/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(127, RestBin) ->
<<BinStr:63/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(128, RestBin) ->
<<BinStr:64/binary, LeftBin/bitstring>> = RestBin,
{BinStr, LeftBin};
decoder(129, RestBin) ->
<<BinStr:65/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 65 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(130, RestBin) ->
<<BinStr:66/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 66 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(131, RestBin) ->
<<BinStr:67/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 67 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(132, RestBin) ->
<<BinStr:68/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 68 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(133, RestBin) ->
<<BinStr:69/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 69 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(134, RestBin) ->
<<BinStr:70/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 70 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(135, RestBin) ->
<<BinStr:71/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 71 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(136, RestBin) ->
<<BinStr:72/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 72 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(137, RestBin) ->
<<BinStr:73/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 73 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(138, RestBin) ->
<<BinStr:74/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 74 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(139, RestBin) ->
<<BinStr:75/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 75 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(140, RestBin) ->
<<BinStr:76/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 76 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(141, RestBin) ->
<<BinStr:77/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 77 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(142, RestBin) ->
<<BinStr:78/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 78 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(143, RestBin) ->
<<BinStr:79/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 79 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(144, RestBin) ->
<<BinStr:80/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 80 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(145, RestBin) ->
<<BinStr:81/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 81 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(146, RestBin) ->
<<BinStr:82/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 82 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(147, RestBin) ->
<<BinStr:83/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 83 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(148, RestBin) ->
<<BinStr:84/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 84 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(149, RestBin) ->
<<BinStr:85/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 85 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(150, RestBin) ->
<<BinStr:86/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 86 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(151, RestBin) ->
<<BinStr:87/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 87 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(152, RestBin) ->
<<BinStr:88/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 88 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(153, RestBin) ->
<<BinStr:89/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 89 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(154, RestBin) ->
<<BinStr:90/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 90 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(155, RestBin) ->
<<BinStr:91/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 91 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(156, RestBin) ->
<<BinStr:92/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 92 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(157, RestBin) ->
<<BinStr:93/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 93 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(158, RestBin) ->
<<BinStr:94/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 94 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(159, RestBin) ->
<<BinStr:95/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 95 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(160, RestBin) ->
<<BinStr:96/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 96 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(161, RestBin) ->
<<BinStr:97/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 97 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(162, RestBin) ->
<<BinStr:98/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 98 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(163, RestBin) ->
<<BinStr:99/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 99 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(164, RestBin) ->
<<BinStr:100/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 100 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(165, RestBin) ->
<<BinStr:101/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 101 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(166, RestBin) ->
<<BinStr:102/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 102 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(167, RestBin) ->
<<BinStr:103/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 103 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(168, RestBin) ->
<<BinStr:104/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 104 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(169, RestBin) ->
<<BinStr:105/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 105 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(170, RestBin) ->
<<BinStr:106/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 106 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(171, RestBin) ->
<<BinStr:107/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 107 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(172, RestBin) ->
<<BinStr:108/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 108 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(173, RestBin) ->
<<BinStr:109/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 109 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(174, RestBin) ->
<<BinStr:110/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 110 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(175, RestBin) ->
<<BinStr:111/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 111 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(176, RestBin) ->
<<BinStr:112/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 112 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(177, RestBin) ->
<<BinStr:113/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 113 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(178, RestBin) ->
<<BinStr:114/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 114 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(179, RestBin) ->
<<BinStr:115/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 115 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(180, RestBin) ->
<<BinStr:116/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 116 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(181, RestBin) ->
<<BinStr:117/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 117 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(182, RestBin) ->
<<BinStr:118/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 118 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(183, RestBin) ->
<<BinStr:119/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 119 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(184, RestBin) ->
<<BinStr:120/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 120 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(185, RestBin) ->
<<BinStr:121/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 121 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(186, RestBin) ->
<<BinStr:122/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 122 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(187, RestBin) ->
<<BinStr:123/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 123 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(188, RestBin) ->
<<BinStr:124/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 124 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(189, RestBin) ->
<<BinStr:125/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 125 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(190, RestBin) ->
<<BinStr:126/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / 126 > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(191, RestBin) ->
<<Length:64/integer-little-unsigned, BinStr:Length/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / Length > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(192, RestBin) ->
<<Length:1/integer-little-unsigned-unit:8, BinStr:Length/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / Length > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(193, RestBin) ->
<<Length:2/integer-little-unsigned-unit:8, BinStr:Length/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / Length > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(194, RestBin) ->
<<Length:3/integer-little-unsigned-unit:8, BinStr:Length/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / Length > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(195, RestBin) ->
<<Length:4/integer-little-unsigned-unit:8, BinStr:Length/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / Length > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(196, RestBin) ->
<<Length:5/integer-little-unsigned-unit:8, BinStr:Length/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / Length > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(197, RestBin) ->
<<Length:6/integer-little-unsigned-unit:8, BinStr:Length/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / Length > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(198, RestBin) ->
<<Length:7/integer-little-unsigned-unit:8, BinStr:Length/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / Length > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(199, RestBin) ->
<<Length:8/integer-little-unsigned-unit:8, BinStr:Length/binary, LeftBin/bitstring>> = RestBin,
RefSize = binary:referenced_byte_size(RestBin),
case RefSize / Length > ?VpBinaryCopyRatio of
true ->
{binary:copy(BinStr), LeftBin};
_ ->
{BinStr, LeftBin}
end;
decoder(_, _) ->
erlang:throw({error, unexpected_end}).
parseArrayElements(<<>>, AccList) -> lists:reverse(AccList);
parseArrayElements(DataBin, AccList) ->
{Elem, Rest} = decoder(DataBin),
parseArrayElements(Rest, [Elem | AccList]).
parseArrWithIndexTable(1, DataBin) ->
<<SumSize:8/integer-little-unsigned, Count:8/integer-little-unsigned, RestBin/binary>> = DataBin,
DataSize = erlang:byte_size(RestBin),
DataLeftBin = skipZeros(RestBin),
ZerosSize = DataSize - erlang:byte_size(DataLeftBin),
ArrSize = SumSize - 3 - ZerosSize - Count,
<<ArrData:ArrSize/binary, _Index:Count/binary, LeftBin/binary>> = DataLeftBin,
ArrList = parseArrayElements(ArrData, []),
{ArrList, LeftBin};
parseArrWithIndexTable(2, DataBin) ->
<<SumSize:16/integer-little-unsigned, Count:16/integer-little-unsigned, RestBin/binary>> = DataBin,
IndexSize = 2 * Count,
DataSize = erlang:byte_size(RestBin),
DataLeftBin = skipZeros(RestBin),
ZerosSize = DataSize - erlang:byte_size(DataLeftBin),
ArrSize = SumSize - 5 - ZerosSize - IndexSize,
<<ArrData:ArrSize/binary, _Index:IndexSize/binary, LeftBin/binary>> = DataLeftBin,
ArrList = parseArrayElements(ArrData, []),
{ArrList, LeftBin};
parseArrWithIndexTable(4, DataBin) ->
<<SumSize:32/integer-little-unsigned, Count:32/integer-little-unsigned, RestBin/binary>> = DataBin,
IndexSize = 4 * Count,
DataSize = erlang:byte_size(RestBin),
DataLeftBin = skipZeros(RestBin),
ZerosSize = DataSize - erlang:byte_size(DataLeftBin),
ArrSize = SumSize - 9 - ZerosSize - IndexSize,
<<ArrData:ArrSize/binary, _Index:IndexSize/binary, LeftBin/binary>> = DataLeftBin,
ArrList = parseArrayElements(ArrData, []),
{ArrList, LeftBin};
parseArrWithIndexTable(8, DataBin) ->
<<SumSize:64/integer-little-unsigned, RestBin/binary>> = DataBin,
DataSize = SumSize - 17,
<<DataBin:DataSize/binary, Count:64/integer-little-unsigned, LeftBin/binary>> = RestBin,
IndexSize = Count * 8,
DataSize = DataSize - IndexSize,
<<ArrData:DataSize/binary, _Index:IndexSize/binary>> = DataBin,
ArrList = parseArrayElements(ArrData, []),
{ArrList, LeftBin}.
parseArrWithoutIndexTable(1, DataBin) ->
<<SumSize:8/integer-little-unsigned, RestBin/binary>> = DataBin,
DataSize = erlang:byte_size(RestBin),
DataLeftBin = skipZeros(RestBin),
ZerosSize = DataSize - erlang:byte_size(DataLeftBin),
ArrSize = SumSize - 2 - ZerosSize,
<<ArrData:ArrSize/binary, LeftBin/binary>> = DataLeftBin,
ArrList = parseArrayElements(ArrData, []),
{ArrList, LeftBin};
parseArrWithoutIndexTable(2, DataBin) ->
<<SumSize:16/integer-little-unsigned, RestBin/binary>> = DataBin,
DataSize = erlang:byte_size(RestBin),
DataLeftBin = skipZeros(RestBin),
ZerosSize = DataSize - erlang:byte_size(DataLeftBin),
ArrSize = SumSize - 3 - ZerosSize,
<<ArrData:ArrSize/binary, LeftBin/binary>> = DataLeftBin,
ArrList = parseArrayElements(ArrData, []),
{ArrList, LeftBin};
parseArrWithoutIndexTable(4, DataBin) ->
<<SumSize:32/integer-little-unsigned, RestBin/binary>> = DataBin,
DataSize = erlang:byte_size(RestBin),
DataLeftBin = skipZeros(RestBin),
ZerosSize = DataSize - erlang:byte_size(DataLeftBin),
ArrSize = SumSize - 5 - ZerosSize,
<<ArrData:ArrSize/binary, LeftBin/binary>> = DataLeftBin,
ArrList = parseArrayElements(ArrData, []),
{ArrList, LeftBin};
parseArrWithoutIndexTable(8, DataBin) ->
<<SumSize:64/integer-little-unsigned, RestBin/binary>> = DataBin,
DataSize = erlang:byte_size(RestBin),
DataLeftBin = skipZeros(RestBin),
ZerosSize = DataSize - erlang:byte_size(DataLeftBin),
ArrSize = SumSize - 9 - ZerosSize,
<<ArrData:ArrSize/binary, LeftBin/binary>> = DataLeftBin,
ArrList = parseArrayElements(ArrData, []),
{ArrList, LeftBin}.
parseCompactArr(DataBin) ->
{ArrData, _Length, RestBin} = parseCompactHeader(DataBin),
ArrList = parseArrayElements(ArrData, []),
{ArrList, RestBin}.
parseCompactHeader(DataBin) ->
{Size, RestBin} = parseLength(DataBin, 0, 0, false),
DataSize = Size - (erlang:byte_size(DataBin) - erlang:byte_size(RestBin)) - 1,
<<ArrData:DataSize/binary, LeftBin/binary>> = RestBin,
{Length, HeaderBin} = parseLength(ArrData, 0, 0, true),
{HeaderBin, Length, LeftBin}.
parseCompactObj(DataBin) ->
{ObjData, Length, RestBin} = parseCompactHeader(DataBin),
{Obj, <<>>} = parseObjMembers(Length, #{}, ObjData),
{Obj, RestBin}.
parseInt(IntegerSize, DataBin) ->
<<Integer:IntegerSize/integer-little-signed-unit:8, LeftBin/binary>> = DataBin,
{Integer, LeftBin}.
parseUint(IntegerSize, DataBin) ->
<<Integer:IntegerSize/integer-little-unsigned-unit:8, LeftBin/binary>> = DataBin,
{Integer, LeftBin}.
parseLength(DataBin, Len, Pt, Reverse) ->
{LastV, LeftBin} =
case Reverse of
false ->
<<V/integer, RestBin/binary>> = DataBin,
{V, RestBin};
_ ->
Size = erlang:byte_size(DataBin) - 1,
<<RestBin:Size/binary, V/integer>> = DataBin,
{V, RestBin}
end,
NewLen = Len + (LastV band 127 bsl Pt),
NewPt = Pt + 7,
case LastV band 128 /= 0 of
false -> {NewLen, LeftBin};
_ -> parseLength(LeftBin, NewLen, NewPt, Reverse)
end.
parseObject(1, DataBin) ->
<<SumSize:8/integer-little-unsigned, Count:8/integer-little-unsigned, ObjBin/binary>> = DataBin,
DataSize = SumSize - 3,
<<ZerosBin:DataSize/binary, LeftBin/binary>> = ObjBin,
{Obj, <<_IndexTable:Count/binary>>} = parseObjMembers(Count, #{}, skipZeros(ZerosBin)),
{Obj, LeftBin};
parseObject(2, DataBin) ->
<<SumSize:16/integer-little-unsigned, Count:16/integer-little-unsigned, ObjBin/binary>> = DataBin,
DataSize = SumSize - 5,
<<ZerosBin:DataSize/binary, LeftBin/binary>> = ObjBin,
IndexTableSize = Count * 2,
{Obj, <<_IndexTable:IndexTableSize/binary>>} = parseObjMembers(Count, #{}, skipZeros(ZerosBin)),
{Obj, LeftBin};
parseObject(4, DataBin) ->
<<SumSize:32/integer-little-unsigned, Count:32/integer-little-unsigned, ObjBin/binary>> = DataBin,
DataSize = SumSize - 9,
<<ZerosBin:DataSize/binary, LeftBin/binary>> = ObjBin,
IndexTableSize = Count * 4,
{Obj, <<_IndexTable:IndexTableSize/binary>>} = parseObjMembers(Count, #{}, skipZeros(ZerosBin)),
{Obj, LeftBin};
parseObject(8, DataBin) ->
<<SumSize:64/integer-little-unsigned, RestBin/binary>> = DataBin,
DataSize = SumSize - 17,
<<ObjBin:DataSize/binary, Count:64/integer-little-unsigned, LeftBin/binary>> = RestBin,
IndexTableSize = Count * 8,
{Obj, <<_IndexTable:IndexTableSize/binary>>} = parseObjMembers(Count, #{}, skipZeros(ObjBin)),
{Obj, LeftBin}.
parseObjMembers(0, Obj, DataBin) ->
{Obj, DataBin};
parseObjMembers(Length, Obj, DataBin) ->
{Key, ValueDataBin} = decoder(DataBin),
{Value, LeftBin} = decoder(ValueDataBin),
NewObj = Obj#{Key => Value},
parseObjMembers(Length - 1, NewObj, LeftBin).
skipZeros(<<0/integer, LeftBin/binary>>) ->
skipZeros(LeftBin);
skipZeros(DataBin) -> DataBin.