diff options
Diffstat (limited to 'lib/asn1/src/asn1rt_per_bin.erl')
-rw-r--r-- | lib/asn1/src/asn1rt_per_bin.erl | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/lib/asn1/src/asn1rt_per_bin.erl b/lib/asn1/src/asn1rt_per_bin.erl index 5772f09bf4..1f8c9729e7 100644 --- a/lib/asn1/src/asn1rt_per_bin.erl +++ b/lib/asn1/src/asn1rt_per_bin.erl @@ -505,12 +505,21 @@ decode_fragmented_octets(<<0:1,Len:7,Bin/binary>>,C,Acc) -> %% | binary %% Contraint = not used in this version %% -encode_open_type(_C, Val) when is_list(Val) -> - Bin = list_to_binary(Val), - [encode_length(undefined,size(Bin)),{octets,Bin}]; % octets implies align -encode_open_type(_C, Val) when is_binary(Val) -> - [encode_length(undefined,size(Val)),{octets,Val}]. % octets implies align -%% the binary_to_list is not optimal but compatible with the current solution +encode_open_type(_Constraint, Val) when is_list(Val) -> + encode_open_type_1(list_to_binary(Val)); +encode_open_type(_Constraint, Val) when is_binary(Val) -> + encode_open_type_1(Val). + +encode_open_type_1(Val0) -> + case byte_size(Val0) of + Size when Size < 16384 -> + [encode_length(undefined, Size),{octets,Val0}]; + Size -> + F = min(Size bsr 14, 4), + SegSz = F * ?'16K', + <<Val:SegSz/binary,T/binary>> = Val0, + [{octets,<<3:2,F:6>>},{octets,Val}|encode_open_type_1(T)] + end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% decode_open_type(Buffer,Constraint) -> Value @@ -518,9 +527,20 @@ encode_open_type(_C, Val) when is_binary(Val) -> %% Buffer = [byte] with PER encoded data %% Value = [byte] with decoded data (which must be decoded again as some type) %% -decode_open_type(Bytes, _C) -> - {Len,Bytes2} = decode_length(Bytes,undefined), - getoctets_as_bin(Bytes2,Len). +decode_open_type(Bytes, _Constraint) -> + decode_open_type_1(Bytes, []). + +decode_open_type_1(Bytes0, Acc) -> + case decode_length_unlimited(Bytes0) of + {Len,Bytes} when Len < ?'16K', Acc =:= [] -> + getoctets_as_bin(Bytes, Len); + {Len,Bytes1} when Len < ?'16K' -> + {Bin,Bytes} = getoctets_as_bin(Bytes1, Len), + {iolist_to_binary([Acc,Bin]),Bytes}; + {Len,Bytes1} -> + {Bin,Bytes} = getoctets_as_bin(Bytes1, Len), + decode_open_type_1(Bytes, [Acc,Bin]) + end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% encode_integer(Constraint,Value,NamedNumberList) -> CompleteList @@ -884,6 +904,17 @@ decode_small_length(Buffer) -> decode_length(Remain,undefined) end. +decode_length_unlimited(Buffer) -> + case align(Buffer) of + {0,<<0:1,Oct:7,Rest/binary>>} -> + {Oct,{0,Rest}}; + {0,<<1:1,0:1,Val:14,Rest/binary>>} -> + {Val,{0,Rest}}; + {0,<<1:1,1:1,F:6,Rest/binary>>} -> + SegSz = F * ?'16K', + {SegSz,{0,Rest}} + end. + decode_length(Buffer) -> decode_length(Buffer,undefined). |