|
|
@ -27,6 +27,9 @@ |
|
|
|
, encodeFloat/1 |
|
|
|
, encodeString/1 |
|
|
|
, encodeInteger/1 |
|
|
|
|
|
|
|
|
|
|
|
, doEncodeList1/3 |
|
|
|
]). |
|
|
|
|
|
|
|
setSV(Size) -> |
|
|
@ -379,8 +382,8 @@ compactIntegerList(Integer, AccList) -> |
|
|
|
compactInteger(Value, Reverse) -> |
|
|
|
CompactList = compactIntegerList(Value, []), |
|
|
|
case Reverse of |
|
|
|
false -> lists:reverse(CompactList); |
|
|
|
_ -> CompactList |
|
|
|
false -> iolist_to_binary(lists:reverse(CompactList)); |
|
|
|
_ -> iolist_to_binary(CompactList) |
|
|
|
end. |
|
|
|
|
|
|
|
compactSize(AllSize) -> |
|
|
@ -398,33 +401,31 @@ encodeCompactData(Type, IoData, SumSize, Count) -> |
|
|
|
AllSize = SumSize + 1 + erlang:length(CompactList), |
|
|
|
{TotalSize, FinalSize} = compactSize(AllSize), |
|
|
|
setSV(FinalSize), |
|
|
|
[Type, TotalSize, IoData | CompactList]. |
|
|
|
|
|
|
|
<<Type/binary, TotalSize/binary, IoData/binary, CompactList/binary>>. |
|
|
|
|
|
|
|
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) -> |
|
|
|
doEncodeList([], _ArrOpt, _ObjOpt, AccBin, SumSize, Count) -> |
|
|
|
{AccBin, SumSize, Count}; |
|
|
|
doEncodeList([One | Left], ArrOpt, ObjOpt, AccBin, SumSize, Count) -> |
|
|
|
ValueEn = encoder(One, ArrOpt, ObjOpt), |
|
|
|
ValueSize = getSV(), |
|
|
|
doEncodeList(Left, ArrOpt, ObjOpt, [ValueEn | AccList], SumSize + ValueSize, Count + 1). |
|
|
|
doEncodeList(Left, ArrOpt, ObjOpt, <<AccBin/binary, ValueEn/binary>>, 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) -> |
|
|
|
doEncodeList1([One | Left], ArrOpt, ObjOpt) -> |
|
|
|
ValueEn = encoder(One, ArrOpt, ObjOpt), |
|
|
|
ValueSize = getSV(), |
|
|
|
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. |
|
|
|
doEncodeList2(Left, ArrOpt, ObjOpt, <<ValueEn/binary>>, [0], ValueSize, 1, ValueSize). |
|
|
|
|
|
|
|
doEncodeList2([], _ArrOpt, _ObjOpt, AccBin, Offsets, SumSize, Count, SizeOrIsNotSameSize) -> |
|
|
|
{AccBin, Offsets, SumSize, Count, SizeOrIsNotSameSize}; |
|
|
|
doEncodeList2([One | Left], ArrOpt, ObjOpt, AccBin, Offsets, SumSize, Count, SizeOrIsNotSameSize) -> |
|
|
|
ValueEn = encoder(One, ArrOpt, ObjOpt), |
|
|
|
ValueSize = getSV(), |
|
|
|
NewSizeOrIsNotSameSize = ValueSize /= SizeOrIsNotSameSize orelse SizeOrIsNotSameSize, |
|
|
|
doEncodeList2(Left, ArrOpt, ObjOpt, <<AccBin/binary, ValueEn/binary>>, [SumSize | Offsets], ValueSize + SumSize, Count + 1, NewSizeOrIsNotSameSize). |
|
|
|
|
|
|
|
encodeList(?VpArrNc, List, ObjOpt) -> |
|
|
|
case List of |
|
|
@ -432,14 +433,12 @@ encodeList(?VpArrNc, List, ObjOpt) -> |
|
|
|
setSV(1), |
|
|
|
<<1/integer>>; |
|
|
|
_ -> |
|
|
|
{AccList, Offsets, SumSize, Count, IsNotSameSize} = doEncodeList(List, ?VpArrNc, ObjOpt, [], [], 0, 0, init), |
|
|
|
|
|
|
|
IoData = lists:reverse(AccList), |
|
|
|
{AccBin, Offsets, SumSize, Count, IsNotSameSize} = doEncodeList1(List, ?VpArrNc, ObjOpt), |
|
|
|
case IsNotSameSize of |
|
|
|
true -> |
|
|
|
encodeListWithIndexTable(IoData, Count, Offsets, SumSize); |
|
|
|
encodeListWithIndexTable(AccBin, Count, Offsets, SumSize); |
|
|
|
_ -> |
|
|
|
encodeListWithoutIndexTable(IoData, SumSize) |
|
|
|
encodeListWithoutIndexTable(AccBin, SumSize) |
|
|
|
end |
|
|
|
end; |
|
|
|
encodeList(?VpArrYc, List, ObjOpt) -> |
|
|
@ -448,65 +447,63 @@ encodeList(?VpArrYc, List, ObjOpt) -> |
|
|
|
setSV(1), |
|
|
|
<<1/integer>>; |
|
|
|
_ -> |
|
|
|
{AccList, SumSize, Count} = doEncodeList(List, ?VpArrYc, ObjOpt, [], 0, 0), |
|
|
|
IoData = lists:reverse(AccList), |
|
|
|
encodeCompactData(<<19/integer>>, IoData, SumSize, Count) |
|
|
|
{AccBin, SumSize, Count} = doEncodeList(List, ?VpArrYc, ObjOpt, <<>>, 0, 0), |
|
|
|
encodeCompactData(<<19/integer>>, AccBin, SumSize, Count) |
|
|
|
end. |
|
|
|
|
|
|
|
encodeListWithoutIndexTable(IoData, SumSize) -> |
|
|
|
encodeListWithoutIndexTable(BinData, SumSize) -> |
|
|
|
if |
|
|
|
SumSize < 254 -> |
|
|
|
AllSize = SumSize + 2, |
|
|
|
Header = <<2/integer, AllSize:8/integer-little-unsigned>>, |
|
|
|
setSV(AllSize), |
|
|
|
[Header, IoData]; |
|
|
|
<<Header/binary, BinData/binary>>; |
|
|
|
SumSize < 65533 -> |
|
|
|
AllSize = SumSize + 3, |
|
|
|
Header = <<3/integer, AllSize:16/integer-little-unsigned>>, |
|
|
|
setSV(AllSize), |
|
|
|
[Header, IoData]; |
|
|
|
<<Header/binary, BinData/binary>>; |
|
|
|
SumSize < 4294967291 -> |
|
|
|
AllSize = SumSize + 5, |
|
|
|
Header = <<4/integer, AllSize:32/integer-little-unsigned>>, |
|
|
|
setSV(AllSize), |
|
|
|
[Header, IoData]; |
|
|
|
<<Header/binary, BinData/binary>>; |
|
|
|
SumSize < 18446744073709551607 -> |
|
|
|
AllSize = SumSize + 9, |
|
|
|
Header = <<5/integer, AllSize:64/integer-little-unsigned>>, |
|
|
|
setSV(AllSize), |
|
|
|
[Header, IoData]; |
|
|
|
<<Header/binary, BinData/binary>>; |
|
|
|
true -> |
|
|
|
erlang:throw({error, too_much_wo_list_size}) |
|
|
|
end. |
|
|
|
|
|
|
|
encodeListWithIndexTable(IoData, Count, Offsets, SumSize) -> |
|
|
|
encodeListWithIndexTable(BinData, Count, Offsets, SumSize) -> |
|
|
|
TemSize = SumSize + Count, |
|
|
|
if |
|
|
|
TemSize < 253 -> |
|
|
|
AllSize = TemSize + 3, |
|
|
|
Header = <<6/integer, AllSize:8/integer-unsigned, Count:8/integer-unsigned>>, |
|
|
|
setSV(AllSize), |
|
|
|
[Header, IoData, buildIndexTable_1(Offsets, 3)]; |
|
|
|
<<Header/binary, BinData/binary, (buildIndexTable_1(Offsets, 3))/binary>>; |
|
|
|
TemSize + Count < 65531 -> |
|
|
|
AllSize = TemSize + Count + 5, |
|
|
|
Header = <<7/integer, AllSize:16/integer-little-unsigned, Count:16/integer-little-unsigned>>, |
|
|
|
setSV(AllSize), |
|
|
|
[Header, IoData, buildIndexTable_2(Offsets, 5)]; |
|
|
|
<<Header/binary, BinData/binary, (buildIndexTable_2(Offsets, 5))/binary>>; |
|
|
|
TemSize + Count * 3 < 4294967287 -> |
|
|
|
AllSize = TemSize + Count * 3 + 9, |
|
|
|
Header = <<8/integer, AllSize:32/integer-little-unsigned, Count:32/integer-little-unsigned>>, |
|
|
|
setSV(AllSize), |
|
|
|
[Header, IoData, buildIndexTable_4(Offsets, 9)]; |
|
|
|
<<Header/binary, BinData/binary, (buildIndexTable_4(Offsets, 9))/binary>>; |
|
|
|
TemSize + Count * 7 < 18446744073709551599 -> |
|
|
|
AllSize = TemSize + Count * 7 + 17, |
|
|
|
Header = <<9/integer, AllSize:64/integer-little-unsigned>>, |
|
|
|
Header = <<9/integer, AllSize:64/integer-little-unsigned, Count:64/integer-little-unsigned>>, |
|
|
|
setSV(AllSize), |
|
|
|
[Header, IoData, buildIndexTable_8(Offsets, 9), <<Count:64/integer-little-unsigned>>]; |
|
|
|
<<Header/binary, BinData/binary, (buildIndexTable_8(Offsets, 9))/binary>>; |
|
|
|
true -> |
|
|
|
erlang:throw({error, too_much_wi_list_size}) |
|
|
|
end. |
|
|
|
|
|
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% decode %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
|
-spec decodeAll(vpack()) -> {term(), term()}. |
|
|
|
decodeAll(DataBin) -> |
|
|
|