aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dialyzer/test/r9c_tests_SUITE_data/src/asn1/asn1rt_per_v1.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dialyzer/test/r9c_tests_SUITE_data/src/asn1/asn1rt_per_v1.erl')
-rw-r--r--lib/dialyzer/test/r9c_tests_SUITE_data/src/asn1/asn1rt_per_v1.erl1843
1 files changed, 0 insertions, 1843 deletions
diff --git a/lib/dialyzer/test/r9c_tests_SUITE_data/src/asn1/asn1rt_per_v1.erl b/lib/dialyzer/test/r9c_tests_SUITE_data/src/asn1/asn1rt_per_v1.erl
deleted file mode 100644
index ebab269f5d..0000000000
--- a/lib/dialyzer/test/r9c_tests_SUITE_data/src/asn1/asn1rt_per_v1.erl
+++ /dev/null
@@ -1,1843 +0,0 @@
-%% ``The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved via the world wide web at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
-%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
-%% AB. All Rights Reserved.''
-%%
-%% $Id: asn1rt_per_v1.erl,v 1.1 2008/12/17 09:53:31 mikpe Exp $
-%%
--module(asn1rt_per_v1).
-
-%% encoding / decoding of PER aligned
-
--include("asn1_records.hrl").
-
--export([dec_fixup/3, cindex/3, list_to_record/2]).
--export([setchoiceext/1, setext/1, fixoptionals/2, fixextensions/2,
- setoptionals/1, fixoptionals2/3, getext/1, getextension/2,
- skipextensions/3, getbit/1, getchoice/3 ]).
--export([getoptionals/2, getoptionals/3, set_choice/3,
- getoptionals2/2,
- encode_integer/2, encode_integer/3 ]).
--export([decode_integer/2, decode_integer/3, encode_small_number/1,
- encode_boolean/1, decode_boolean/1, encode_length/2,
- decode_length/1, decode_length/2,
- encode_small_length/1, decode_small_length/1,
- decode_compact_bit_string/3]).
--export([encode_enumerated/3, decode_enumerated/3,
- encode_bit_string/3, decode_bit_string/3 ]).
--export([encode_octet_string/2, decode_octet_string/2,
- encode_null/1, decode_null/1,
- encode_object_identifier/1, decode_object_identifier/1,
- complete/1]).
-
--export([encode_open_type/2, decode_open_type/2]).
-
--export([encode_UniversalString/2, decode_UniversalString/2,
- encode_PrintableString/2, decode_PrintableString/2,
- encode_GeneralString/2, decode_GeneralString/2,
- encode_GraphicString/2, decode_GraphicString/2,
- encode_TeletexString/2, decode_TeletexString/2,
- encode_VideotexString/2, decode_VideotexString/2,
- encode_VisibleString/2, decode_VisibleString/2,
- encode_BMPString/2, decode_BMPString/2,
- encode_IA5String/2, decode_IA5String/2,
- encode_NumericString/2, decode_NumericString/2,
- encode_ObjectDescriptor/2, decode_ObjectDescriptor/1
- ]).
-
-
-dec_fixup(Terms,Cnames,RemBytes) ->
- dec_fixup(Terms,Cnames,RemBytes,[]).
-
-dec_fixup([novalue|T],[_Hc|Tc],RemBytes,Acc) ->
- dec_fixup(T,Tc,RemBytes,Acc);
-dec_fixup([{_Name,novalue}|T],[_Hc|Tc],RemBytes,Acc) ->
- dec_fixup(T,Tc,RemBytes,Acc);
-dec_fixup([H|T],[Hc|Tc],RemBytes,Acc) ->
- dec_fixup(T,Tc,RemBytes,[{Hc,H}|Acc]);
-dec_fixup([],_Cnames,RemBytes,Acc) ->
- {lists:reverse(Acc),RemBytes}.
-
-cindex(Ix,Val,Cname) ->
- case element(Ix,Val) of
- {Cname,Val2} -> Val2;
- X -> X
- end.
-
-% converts a list to a record if necessary
-list_to_record(Name,List) when list(List) ->
- list_to_tuple([Name|List]);
-list_to_record(_Name,Tuple) when tuple(Tuple) ->
- Tuple.
-
-%%--------------------------------------------------------
-%% setchoiceext(InRootSet) -> [{bit,X}]
-%% X is set to 1 when InRootSet==false
-%% X is set to 0 when InRootSet==true
-%%
-setchoiceext(true) ->
- [{debug,choiceext},{bit,0}];
-setchoiceext(false) ->
- [{debug,choiceext},{bit,1}].
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% setext(true|false) -> CompleteList
-%%
-
-setext(true) ->
- [{debug,ext},{bit,1}];
-setext(false) ->
- [{debug,ext},{bit,0}].
-
-%%
-
-fixoptionals2(OptList,OptLength,Val) when tuple(Val) ->
- Bits = fixoptionals2(OptList,Val,0),
- {Val,{bits,OptLength,Bits}};
-
-fixoptionals2([],_Val,Acc) ->
- %% Optbits
- Acc;
-fixoptionals2([Pos|Ot],Val,Acc) ->
- case element(Pos,Val) of
- asn1_NOVALUE -> fixoptionals2(Ot,Val,Acc bsl 1);
- asn1_DEFAULT -> fixoptionals2(Ot,Val,Acc bsl 1);
- _ -> fixoptionals2(Ot,Val,(Acc bsl 1) + 1)
- end.
-
-
-%%
-%% fixoptionals remains only for backward compatibility purpose
-fixoptionals(OptList,Val) when tuple(Val) ->
- fixoptionals(OptList,Val,[]);
-
-fixoptionals(OptList,Val) when list(Val) ->
- fixoptionals(OptList,Val,1,[],[]).
-
-fixoptionals([],Val,Acc) ->
- % return {Val,Opt}
- {Val,lists:reverse(Acc)};
-fixoptionals([{_,Pos}|Ot],Val,Acc) ->
- case element(Pos+1,Val) of
- asn1_NOVALUE -> fixoptionals(Ot,Val,[0|Acc]);
- asn1_DEFAULT -> fixoptionals(Ot,Val,[0|Acc]);
- _ -> fixoptionals(Ot,Val,[1|Acc])
- end.
-
-
-%setoptionals(OptList,Val) ->
-% Vlist = tuple_to_list(Val),
-% setoptionals(OptList,Vlist,1,[]).
-
-fixoptionals([{Name,Pos}|Ot],[{Name,Val}|Vt],_Opt,Acc1,Acc2) ->
- fixoptionals(Ot,Vt,Pos+1,[1|Acc1],[{Name,Val}|Acc2]);
-fixoptionals([{_Name,Pos}|Ot],V,Pos,Acc1,Acc2) ->
- fixoptionals(Ot,V,Pos+1,[0|Acc1],[asn1_NOVALUE|Acc2]);
-fixoptionals(O,[Vh|Vt],Pos,Acc1,Acc2) ->
- fixoptionals(O,Vt,Pos+1,Acc1,[Vh|Acc2]);
-fixoptionals([],[Vh|Vt],Pos,Acc1,Acc2) ->
- fixoptionals([],Vt,Pos+1,Acc1,[Vh|Acc2]);
-fixoptionals([],[],_,Acc1,Acc2) ->
- % return {Val,Opt}
- {list_to_tuple([asn1_RECORDNAME|lists:reverse(Acc2)]),lists:reverse(Acc1)}.
-
-setoptionals([H|T]) ->
- [{bit,H}|setoptionals(T)];
-setoptionals([]) ->
- [{debug,optionals}].
-
-getext(Bytes) when tuple(Bytes) ->
- getbit(Bytes);
-getext(Bytes) when list(Bytes) ->
- getbit({0,Bytes}).
-
-getextension(0, Bytes) ->
- {{},Bytes};
-getextension(1, Bytes) ->
- {Len,Bytes2} = decode_small_length(Bytes),
- {Blist, Bytes3} = getbits_as_list(Len,Bytes2),
- {list_to_tuple(Blist),Bytes3}.
-
-fixextensions({ext,ExtPos,ExtNum},Val) ->
- case fixextensions(ExtPos,ExtNum+ExtPos,Val,0) of
- 0 -> [];
- ExtBits ->
- [encode_small_length(ExtNum),{bits,ExtNum,ExtBits}]
- end.
-
-fixextensions(Pos,MaxPos,_,Acc) when Pos >= MaxPos ->
- Acc;
-fixextensions(Pos,ExtPos,Val,Acc) ->
- Bit = case catch(element(Pos+1,Val)) of
- asn1_NOVALUE ->
- 0;
- asn1_NOEXTVALUE ->
- 0;
- {'EXIT',_} ->
- 0;
- _ ->
- 1
- end,
- fixextensions(Pos+1,ExtPos,Val,(Acc bsl 1)+Bit).
-
-skipextensions(Bytes,Nr,ExtensionBitPattern) ->
- case (catch element(Nr,ExtensionBitPattern)) of
- 1 ->
- {_,Bytes2} = decode_open_type(Bytes,[]),
- skipextensions(Bytes2, Nr+1, ExtensionBitPattern);
- 0 ->
- skipextensions(Bytes, Nr+1, ExtensionBitPattern);
- {'EXIT',_} -> % badarg, no more extensions
- Bytes
- end.
-
-
-getchoice(Bytes,1,0) -> % only 1 alternative is not encoded
- {0,Bytes};
-getchoice(Bytes,_NumChoices,1) ->
- decode_small_number(Bytes);
-getchoice(Bytes,NumChoices,0) ->
- decode_integer(Bytes,[{'ValueRange',{0,NumChoices-1}}]).
-
-getoptionals2(Bytes,NumOpt) ->
- getbits(Bytes,NumOpt).
-
-%% getoptionals is kept only for bakwards compatibility
-getoptionals(Bytes,NumOpt) ->
- {Blist,Bytes1} = getbits_as_list(NumOpt,Bytes),
- {list_to_tuple(Blist),Bytes1}.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% getoptionals/3 is only here for compatibility from 1.3.2
-%% the codegenerator uses getoptionals/2
-
-getoptionals(Bytes,L,NumComp) when list(L) ->
- {Blist,Bytes1} = getbits_as_list(length(L),Bytes),
- {list_to_tuple(comptuple(Blist,L,NumComp,1)),Bytes1}.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% comptuple is only here for compatibility not used from 1.3.2
-comptuple([Bh|Bt],[{_Name,Nr}|T],NumComp,Nr) ->
- [Bh|comptuple(Bt,T,NumComp-1,Nr+1)];
-comptuple(Bl,[{Name,Tnr}|Tl],NumComp,Nr) ->
- [0|comptuple(Bl,[{Name,Tnr}|Tl],NumComp-1,Nr+1)];
-comptuple(_B,_L,0,_Nr) ->
- [];
-comptuple(B,O,N,Nr) ->
- [0|comptuple(B,O,N-1,Nr+1)].
-
-%% getbits_as_binary(Num,Bytes) -> {{Unused,BinBits},RestBytes},
-%% Num = integer(),
-%% Bytes = list() | tuple(),
-%% Unused = integer(),
-%% BinBits = binary(),
-%% RestBytes = tuple()
-getbits_as_binary(Num,Bytes) when list(Bytes) ->
- getbits_as_binary(Num,{0,Bytes});
-getbits_as_binary(_Num,{Used,[]}) ->
- {{0,<<>>},{Used,[]}};
-getbits_as_binary(Num,{Used,Bits=[H|T]}) ->
- B1 = case (Num+Used) =< 8 of
- true -> Num;
- _ -> 8-Used
- end,
- B2 = Num - B1,
- Pad = (8 - ((B1+B2) rem 8)) rem 8,% Pad /= 8
- RestBits = lists:nthtail((B1+B2) div 8,Bits),
- Int = integer_from_list(B2,T,0),
- NewUsed = (Used + Num) rem 8,
- {{Pad,<<(H bsr (8-(Used+B1))):B1,Int:B2,0:Pad>>},{NewUsed,RestBits}}.
-
-integer_from_list(_Int,[],BigInt) ->
- BigInt;
-integer_from_list(Int,[H|_T],BigInt) when Int < 8 ->
- (BigInt bsl Int) bor (H bsr (8-Int));
-integer_from_list(Int,[H|T],BigInt) ->
- integer_from_list(Int-8,T,(BigInt bsl 8) bor H).
-
-getbits_as_list(Num,Bytes) ->
- getbits_as_list(Num,Bytes,[]).
-
-getbits_as_list(0,Bytes,Acc) ->
- {lists:reverse(Acc),Bytes};
-getbits_as_list(Num,Bytes,Acc) ->
- {Bit,NewBytes} = getbit(Bytes),
- getbits_as_list(Num-1,NewBytes,[Bit|Acc]).
-
-getbit(Bytes) ->
-% io:format("getbit:~p~n",[Bytes]),
- getbit1(Bytes).
-
-getbit1({7,[H|T]}) ->
- {H band 1,{0,T}};
-getbit1({Pos,[H|T]}) ->
- {(H bsr (7-Pos)) band 1,{(Pos+1) rem 8,[H|T]}};
-getbit1(Bytes) when list(Bytes) ->
- getbit1({0,Bytes}).
-
-%% This could be optimized
-getbits(Buffer,Num) ->
-% io:format("getbits:Buffer = ~p~nNum=~p~n",[Buffer,Num]),
- getbits(Buffer,Num,0).
-
-getbits(Buffer,0,Acc) ->
- {Acc,Buffer};
-getbits(Buffer,Num,Acc) ->
- {B,NewBuffer} = getbit(Buffer),
- getbits(NewBuffer,Num-1,B + (Acc bsl 1)).
-
-
-getoctet(Bytes) when list(Bytes) ->
- getoctet({0,Bytes});
-getoctet(Bytes) ->
-% io:format("getoctet:Buffer = ~p~n",[Bytes]),
- getoctet1(Bytes).
-
-getoctet1({0,[H|T]}) ->
- {H,{0,T}};
-getoctet1({_Pos,[_,H|T]}) ->
- {H,{0,T}}.
-
-align({0,L}) ->
- {0,L};
-align({_Pos,[_H|T]}) ->
- {0,T};
-align(Bytes) ->
- {0,Bytes}.
-
-getoctets(Buffer,Num) ->
-% io:format("getoctets:Buffer = ~p~nNum = ~p~n",[Buffer,Num]),
- getoctets(Buffer,Num,0).
-
-getoctets(Buffer,0,Acc) ->
- {Acc,Buffer};
-getoctets(Buffer,Num,Acc) ->
- {Oct,NewBuffer} = getoctet(Buffer),
- getoctets(NewBuffer,Num-1,(Acc bsl 8)+Oct).
-
-getoctets_as_list(Buffer,Num) ->
- getoctets_as_list(Buffer,Num,[]).
-
-getoctets_as_list(Buffer,0,Acc) ->
- {lists:reverse(Acc),Buffer};
-getoctets_as_list(Buffer,Num,Acc) ->
- {Oct,NewBuffer} = getoctet(Buffer),
- getoctets_as_list(NewBuffer,Num-1,[Oct|Acc]).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% set_choice(Alt,Choices,Altnum) -> ListofBitSettings
-%% Alt = atom()
-%% Altnum = integer() | {integer(),integer()}% number of alternatives
-%% Choices = [atom()] | {[atom()],[atom()]}
-%% When Choices is a tuple the first list is the Rootset and the
-%% second is the Extensions and then Altnum must also be a tuple with the
-%% lengths of the 2 lists
-%%
-set_choice(Alt,{L1,L2},{Len1,_Len2}) ->
- case set_choice_tag(Alt,L1) of
- N when integer(N), Len1 > 1 ->
- [{bit,0}, % the value is in the root set
- encode_integer([{'ValueRange',{0,Len1-1}}],N)];
- N when integer(N) ->
- [{bit,0}]; % no encoding if only 0 or 1 alternative
- false ->
- [{bit,1}, % extension value
- case set_choice_tag(Alt,L2) of
- N2 when integer(N2) ->
- encode_small_number(N2);
- false ->
- unknown_choice_alt
- end]
- end;
-set_choice(Alt,L,Len) ->
- case set_choice_tag(Alt,L) of
- N when integer(N), Len > 1 ->
- encode_integer([{'ValueRange',{0,Len-1}}],N);
- N when integer(N) ->
- []; % no encoding if only 0 or 1 alternative
- false ->
- [unknown_choice_alt]
- end.
-
-set_choice_tag(Alt,Choices) ->
- set_choice_tag(Alt,Choices,0).
-
-set_choice_tag(Alt,[Alt|_Rest],Tag) ->
- Tag;
-set_choice_tag(Alt,[_H|Rest],Tag) ->
- set_choice_tag(Alt,Rest,Tag+1);
-set_choice_tag(_Alt,[],_Tag) ->
- false.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% encode_open_type(Constraint, Value) -> CompleteList
-%% Value = list of bytes of an already encoded value (the list must be flat)
-%% | binary
-%% Contraint = not used in this version
-%%
-encode_open_type(_Constraint, Val) when list(Val) ->
- [encode_length(undefined,length(Val)),align,
- {octets,Val}];
-encode_open_type(_Constraint, Val) when binary(Val) ->
- [encode_length(undefined,size(Val)),align,
- {octets,binary_to_list(Val)}].
-%% the binary_to_list is not optimal but compatible with the current solution
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% decode_open_type(Buffer,Constraint) -> Value
-%% Constraint is not used in this version
-%% Buffer = [byte] with PER encoded data
-%% Value = [byte] with decoded data (which must be decoded again as some type)
-%%
-decode_open_type(Bytes, _Constraint) ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- Bytes3 = align(Bytes2),
- getoctets_as_list(Bytes3,Len).
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% encode_integer(Constraint,Value,NamedNumberList) -> CompleteList
-%% encode_integer(Constraint,Value) -> CompleteList
-%% encode_integer(Constraint,{Name,Value}) -> CompleteList
-%%
-%%
-encode_integer(C,V,NamedNumberList) when atom(V) ->
- case lists:keysearch(V,1,NamedNumberList) of
- {value,{_,NewV}} ->
- encode_integer(C,NewV);
- _ ->
- exit({error,{asn1,{namednumber,V}}})
- end;
-encode_integer(C,V,_) when integer(V) ->
- encode_integer(C,V);
-encode_integer(C,{Name,V},NamedNumberList) when atom(Name) ->
- encode_integer(C,V,NamedNumberList).
-
-encode_integer(C,{Name,Val}) when atom(Name) ->
- encode_integer(C,Val);
-
-encode_integer({Rc,_Ec},Val) ->
- case (catch encode_integer(Rc,Val)) of
- {'EXIT',{error,{asn1,_}}} ->
- [{bit,1},encode_unconstrained_number(Val)];
- Encoded ->
- [{bit,0},Encoded]
- end;
-encode_integer(C,Val ) when list(C) ->
- case get_constraint(C,'SingleValue') of
- no ->
- encode_integer1(C,Val);
- V when integer(V),V == Val ->
- []; % a type restricted to a single value encodes to nothing
- V when list(V) ->
- case lists:member(Val,V) of
- true ->
- encode_integer1(C,Val);
- _ ->
- exit({error,{asn1,{illegal_value,Val}}})
- end;
- _ ->
- exit({error,{asn1,{illegal_value,Val}}})
- end.
-
-encode_integer1(C, Val) ->
- case VR = get_constraint(C,'ValueRange') of
- no ->
- encode_unconstrained_number(Val);
- {Lb,'MAX'} ->
- encode_semi_constrained_number(Lb,Val);
- %% positive with range
- {Lb,Ub} when Val >= Lb,
- Ub >= Val ->
- encode_constrained_number(VR,Val);
- _ ->
- exit({error,{asn1,{illegal_value,VR,Val}}})
- end.
-
-decode_integer(Buffer,Range,NamedNumberList) ->
- {Val,Buffer2} = decode_integer(Buffer,Range),
- case lists:keysearch(Val,2,NamedNumberList) of
- {value,{NewVal,_}} -> {NewVal,Buffer2};
- _ -> {Val,Buffer2}
- end.
-
-decode_integer(Buffer,{Rc,_Ec}) ->
- {Ext,Buffer2} = getext(Buffer),
- case Ext of
- 0 -> decode_integer(Buffer2,Rc);
- 1 -> decode_unconstrained_number(Buffer2)
- end;
-decode_integer(Buffer,undefined) ->
- decode_unconstrained_number(Buffer);
-decode_integer(Buffer,C) ->
- case get_constraint(C,'SingleValue') of
- V when integer(V) ->
- {V,Buffer};
- V when list(V) ->
- {Val,Buffer2} = decode_integer1(Buffer,C),
- case lists:member(Val,V) of
- true ->
- {Val,Buffer2};
- _ ->
- exit({error,{asn1,{illegal_value,Val}}})
- end;
- _ ->
- decode_integer1(Buffer,C)
- end.
-
-decode_integer1(Buffer,C) ->
- case VR = get_constraint(C,'ValueRange') of
- no ->
- decode_unconstrained_number(Buffer);
- {Lb, 'MAX'} ->
- decode_semi_constrained_number(Buffer,Lb);
- {_,_} ->
- decode_constrained_number(Buffer,VR)
- end.
-
-% X.691:10.6 Encoding of a normally small non-negative whole number
-% Use this for encoding of CHOICE index if there is an extension marker in
-% the CHOICE
-encode_small_number({Name,Val}) when atom(Name) ->
- encode_small_number(Val);
-encode_small_number(Val) when Val =< 63 ->
- [{bit,0},{bits,6,Val}];
-encode_small_number(Val) ->
- [{bit,1},encode_semi_constrained_number(0,Val)].
-
-decode_small_number(Bytes) ->
- {Bit,Bytes2} = getbit(Bytes),
- case Bit of
- 0 ->
- getbits(Bytes2,6);
- 1 ->
- decode_semi_constrained_number(Bytes2,{0,'MAX'})
- end.
-
-% X.691:10.7 Encoding of a semi-constrained whole number
-%% might be an optimization encode_semi_constrained_number(0,Val) ->
-encode_semi_constrained_number(C,{Name,Val}) when atom(Name) ->
- encode_semi_constrained_number(C,Val);
-encode_semi_constrained_number({Lb,'MAX'},Val) ->
- encode_semi_constrained_number(Lb,Val);
-encode_semi_constrained_number(Lb,Val) ->
- Val2 = Val - Lb,
- Octs = eint_positive(Val2),
- [encode_length(undefined,length(Octs)),{octets,Octs}].
-
-decode_semi_constrained_number(Bytes,{Lb,_}) ->
- decode_semi_constrained_number(Bytes,Lb);
-decode_semi_constrained_number(Bytes,Lb) ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- {V,Bytes3} = getoctets(Bytes2,Len),
- {V+Lb,Bytes3}.
-
-encode_constrained_number(Range,{Name,Val}) when atom(Name) ->
- encode_constrained_number(Range,Val);
-encode_constrained_number({Lb,Ub},Val) when Val >= Lb, Ub >= Val ->
- Range = Ub - Lb + 1,
- Val2 = Val - Lb,
- if
- Range == 2 ->
- {bits,1,Val2};
- Range =< 4 ->
- {bits,2,Val2};
- Range =< 8 ->
- {bits,3,Val2};
- Range =< 16 ->
- {bits,4,Val2};
- Range =< 32 ->
- {bits,5,Val2};
- Range =< 64 ->
- {bits,6,Val2};
- Range =< 128 ->
- {bits,7,Val2};
- Range =< 255 ->
- {bits,8,Val2};
- Range =< 256 ->
- {octets,1,Val2};
- Range =< 65536 ->
- {octets,2,Val2};
- Range =< 16#1000000 ->
- Octs = eint_positive(Val2),
- [encode_length({1,3},length(Octs)),{octets,Octs}];
- Range =< 16#100000000 ->
- Octs = eint_positive(Val2),
- [encode_length({1,4},length(Octs)),{octets,Octs}];
- Range =< 16#10000000000 ->
- Octs = eint_positive(Val2),
- [encode_length({1,5},length(Octs)),{octets,Octs}];
- true ->
- exit({not_supported,{integer_range,Range}})
- end.
-
-decode_constrained_number(Buffer,{Lb,Ub}) ->
- Range = Ub - Lb + 1,
-% Val2 = Val - Lb,
- {Val,Remain} =
- if
- Range == 2 ->
- getbits(Buffer,1);
- Range =< 4 ->
- getbits(Buffer,2);
- Range =< 8 ->
- getbits(Buffer,3);
- Range =< 16 ->
- getbits(Buffer,4);
- Range =< 32 ->
- getbits(Buffer,5);
- Range =< 64 ->
- getbits(Buffer,6);
- Range =< 128 ->
- getbits(Buffer,7);
- Range =< 255 ->
- getbits(Buffer,8);
- Range =< 256 ->
- getoctets(Buffer,1);
- Range =< 65536 ->
- getoctets(Buffer,2);
- Range =< 16#1000000 ->
- {Len,Bytes2} = decode_length(Buffer,{1,3}),
- {Octs,Bytes3} = getoctets_as_list(Bytes2,Len),
- {dec_pos_integer(Octs),Bytes3};
- Range =< 16#100000000 ->
- {Len,Bytes2} = decode_length(Buffer,{1,4}),
- {Octs,Bytes3} = getoctets_as_list(Bytes2,Len),
- {dec_pos_integer(Octs),Bytes3};
- Range =< 16#10000000000 ->
- {Len,Bytes2} = decode_length(Buffer,{1,5}),
- {Octs,Bytes3} = getoctets_as_list(Bytes2,Len),
- {dec_pos_integer(Octs),Bytes3};
- true ->
- exit({not_supported,{integer_range,Range}})
- end,
- {Val+Lb,Remain}.
-
-% X.691:10.8 Encoding of an unconstrained whole number
-
-encode_unconstrained_number(Val) when Val >= 0 ->
- Oct = eint(Val,[]),
- [{debug,unconstrained_number},
- encode_length({0,'MAX'},length(Oct)),
- {octets,Oct}];
-encode_unconstrained_number(Val) -> % negative
- Oct = enint(Val,[]),
- [{debug,unconstrained_number},
- encode_length({0,'MAX'},length(Oct)),
- {octets,Oct}].
-
-%% used for positive Values which don't need a sign bit
-eint_positive(Val) ->
- case eint(Val,[]) of
- [0,B1|T] ->
- [B1|T];
- T ->
- T
- end.
-
-eint(0, [B|Acc]) when B < 128 ->
- [B|Acc];
-eint(N, Acc) ->
- eint(N bsr 8, [N band 16#ff| Acc]).
-
-enint(-1, [B1|T]) when B1 > 127 ->
- [B1|T];
-enint(N, Acc) ->
- enint(N bsr 8, [N band 16#ff|Acc]).
-
-%% used for signed positive values
-
-%eint(Val, Ack) ->
-% X = Val band 255,
-% Next = Val bsr 8,
-% if
-% Next == 0, X >= 127 ->
-% [0,X|Ack];
-% Next == 0 ->
-% [X|Ack];
-% true ->
-% eint(Next,[X|Ack])
-% end.
-
-%%% used for signed negative values
-%enint(Val, Acc) ->
-% NumOctets = if
-% -Val < 16#80 -> 1;
-% -Val < 16#8000 ->2;
-% -Val < 16#800000 ->3;
-% -Val < 16#80000000 ->4;
-% -Val < 16#8000000000 ->5;
-% -Val < 16#800000000000 ->6;
-% -Val < 16#80000000000000 ->7;
-% -Val < 16#8000000000000000 ->8;
-% -Val < 16#800000000000000000 ->9
-% end,
-% enint(Val,Acc,NumOctets).
-
-%enint(Val, Acc,0) ->
-% Acc;
-%enint(Val, Acc,NumOctets) ->
-% enint(Val bsr 8,[Val band 255|Acc],NumOctets-1).
-
-
-decode_unconstrained_number(Bytes) ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- {Ints,Bytes3} = getoctets_as_list(Bytes2,Len),
- {dec_integer(Ints),Bytes3}.
-
-dec_pos_integer(Ints) ->
- decpint(Ints, 8 * (length(Ints) - 1)).
-dec_integer(Ints) when hd(Ints) band 255 =< 127 -> %% Positive number
- decpint(Ints, 8 * (length(Ints) - 1));
-dec_integer(Ints) -> %% Negative
- decnint(Ints, 8 * (length(Ints) - 1)).
-
-decpint([Byte|Tail], Shift) ->
- (Byte bsl Shift) bor decpint(Tail, Shift-8);
-decpint([], _) -> 0.
-
-decnint([Byte|Tail], Shift) ->
- (-128 + (Byte band 127) bsl Shift) bor decpint(Tail, Shift-8).
-
-minimum_octets(Val) ->
- minimum_octets(Val,[]).
-
-minimum_octets(Val,Acc) when Val > 0 ->
- minimum_octets((Val bsr 8),[Val band 16#FF|Acc]);
-minimum_octets(0,Acc) ->
- Acc.
-
-
-%% X.691:10.9 Encoding of a length determinant
-%%encode_small_length(undefined,Len) -> % null means no UpperBound
-%% encode_small_number(Len).
-
-%% X.691:10.9.3.5
-%% X.691:10.9.3.7
-encode_length(undefined,Len) -> % un-constrained
- if
- Len < 128 ->
- {octet,Len band 16#7F};
- Len < 16384 ->
- {octets,2,2#1000000000000000 bor Len};
- true ->
- exit({error,{asn1,{encode_length,{nyi,above_16k}}}})
- end;
-
-encode_length({0,'MAX'},Len) ->
- encode_length(undefined,Len);
-encode_length({Lb,Ub},Len) when Ub =< 65535 ,Lb >= 0 -> % constrained
- encode_constrained_number({Lb,Ub},Len);
-encode_length({{Lb,Ub},[]},Len) when Ub =< 65535 ,Lb >= 0 ->
- %% constrained extensible
- [{bit,0},encode_constrained_number({Lb,Ub},Len)];
-encode_length(SingleValue,_) when integer(SingleValue) ->
- [].
-
-encode_small_length(Len) when Len =< 64 ->
- [{bit,0},{bits,6,Len-1}];
-encode_small_length(Len) ->
- [{bit,1},encode_length(undefined,Len)].
-
-decode_small_length(Buffer) ->
- case getbit(Buffer) of
- {0,Remain} ->
- {Bits,Remain2} = getbits(Remain,6),
- {Bits+1,Remain2};
- {1,Remain} ->
- decode_length(Remain,undefined)
- end.
-
-decode_length(Buffer) ->
- decode_length(Buffer,undefined).
-
-decode_length(Buffer,undefined) -> % un-constrained
- Buffer2 = align(Buffer),
- {Bits,_} = getbits(Buffer2,2),
- case Bits of
- 2 ->
- {Val,Bytes3} = getoctets(Buffer2,2),
- {(Val band 16#3FFF),Bytes3};
- 3 ->
- exit({error,{asn1,{decode_length,{nyi,above_16k}}}});
- _ ->
- {Val,Bytes3} = getoctet(Buffer2),
- {Val band 16#7F,Bytes3}
- end;
-
-decode_length(Buffer,{Lb,Ub}) when Ub =< 65535 ,Lb >= 0 -> % constrained
- decode_constrained_number(Buffer,{Lb,Ub});
-
-decode_length(Buffer,{{Lb,Ub},[]}) ->
- case getbit(Buffer) of
- {0,Buffer2} ->
- decode_length(Buffer2, {Lb,Ub})
- end;
- % X.691:10.9.3.5
-decode_length(Buffer,{_,_Lb,_Ub}) -> %when Len =< 127 -> % Unconstrained or large Ub
- case getbit(Buffer) of
- {0,Remain} ->
- getbits(Remain,7);
- {1,_Remain} ->
- {Val,Remain2} = getoctets(Buffer,2),
- {Val band 2#0111111111111111, Remain2}
- end;
-decode_length(Buffer,SingleValue) when integer(SingleValue) ->
- {SingleValue,Buffer}.
-
-
-% X.691:11
-encode_boolean({Name,Val}) when atom(Name) ->
- encode_boolean(Val);
-encode_boolean(true) ->
- {bit,1};
-encode_boolean(false) ->
- {bit,0};
-encode_boolean(Val) ->
- exit({error,{asn1,{encode_boolean,Val}}}).
-
-
-decode_boolean(Buffer) -> %when record(Buffer,buffer)
- case getbit(Buffer) of
- {1,Remain} -> {true,Remain};
- {0,Remain} -> {false,Remain}
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% X.691:12
-%% ENUMERATED
-%%
-%% encode_enumerated(C,Value,NamedNumberTup) -> CompleteList
-%%
-%%
-
-encode_enumerated(C,{Name,Value},NamedNumberList) when
- atom(Name),list(NamedNumberList) ->
- encode_enumerated(C,Value,NamedNumberList);
-
-%% ENUMERATED with extension mark
-encode_enumerated(_C,{asn1_enum,Value},{_Nlist1,Nlist2}) when Value >= length(Nlist2) ->
- [{bit,1},encode_small_number(Value)];
-encode_enumerated(C,Value,{Nlist1,Nlist2}) ->
- case enum_search(Value,Nlist1,0) of
- NewV when integer(NewV) ->
- [{bit,0},encode_integer(C,NewV)];
- false ->
- case enum_search(Value,Nlist2,0) of
- ExtV when integer(ExtV) ->
- [{bit,1},encode_small_number(ExtV)];
- false ->
- exit({error,{asn1,{encode_enumerated,Value}}})
- end
- end;
-
-encode_enumerated(C,Value,NamedNumberList) when list(NamedNumberList) ->
- case enum_search(Value,NamedNumberList,0) of
- NewV when integer(NewV) ->
- encode_integer(C,NewV);
- false ->
- exit({error,{asn1,{encode_enumerated,Value}}})
- end.
-
-%% returns the ordinal number from 0 ,1 ... in the list where Name is found
-%% or false if not found
-%%
-enum_search(Name,[Name|_NamedNumberList],Acc) ->
- Acc;
-enum_search(Name,[_H|T],Acc) ->
- enum_search(Name,T,Acc+1);
-enum_search(_,[],_) ->
- false. % name not found !error
-
-%% ENUMERATED with extension marker
-decode_enumerated(Buffer,C,{Ntup1,Ntup2}) when tuple(Ntup1), tuple(Ntup2) ->
- {Ext,Buffer2} = getext(Buffer),
- case Ext of
- 0 -> % not an extension value
- {Val,Buffer3} = decode_integer(Buffer2,C),
- case catch (element(Val+1,Ntup1)) of
- NewVal when atom(NewVal) -> {NewVal,Buffer3};
- _Error -> exit({error,{asn1,{decode_enumerated,{Val,[Ntup1,Ntup2]}}}})
- end;
- 1 -> % this an extension value
- {Val,Buffer3} = decode_small_number(Buffer2),
- case catch (element(Val+1,Ntup2)) of
- NewVal when atom(NewVal) -> {NewVal,Buffer3};
- _ -> {{asn1_enum,Val},Buffer3}
- end
- end;
-
-decode_enumerated(Buffer,C,NamedNumberTup) when tuple(NamedNumberTup) ->
- {Val,Buffer2} = decode_integer(Buffer,C),
- case catch (element(Val+1,NamedNumberTup)) of
- NewVal when atom(NewVal) -> {NewVal,Buffer2};
- _Error -> exit({error,{asn1,{decode_enumerated,{Val,NamedNumberTup}}}})
- end.
-
-%%===============================================================================
-%%===============================================================================
-%%===============================================================================
-%% Bitstring value, ITU_T X.690 Chapter 8.5
-%%===============================================================================
-%%===============================================================================
-%%===============================================================================
-
-%%===============================================================================
-%% encode bitstring value
-%%===============================================================================
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% bitstring NamedBitList
-%% Val can be of:
-%% - [identifiers] where only named identifers are set to one,
-%% the Constraint must then have some information of the
-%% bitlength.
-%% - [list of ones and zeroes] all bits
-%% - integer value representing the bitlist
-%% C is constraint Len, only valid when identifiers
-
-
-%% when the value is a list of {Unused,BinBits}, where
-%% Unused = integer(),
-%% BinBits = binary().
-encode_bit_string(C,Bin={Unused,BinBits},NamedBitList) when integer(Unused),
- binary(BinBits) ->
- encode_bin_bit_string(C,Bin,NamedBitList);
-
-%% when the value is a list of named bits
-encode_bit_string(C, [FirstVal | RestVal], NamedBitList) when atom(FirstVal) ->
- ToSetPos = get_all_bitposes([FirstVal | RestVal], NamedBitList, []),
- BitList = make_and_set_list(ToSetPos,0),
- encode_bit_string(C,BitList,NamedBitList);
-
-encode_bit_string(C, [{bit,No} | RestVal], NamedBitList) ->
- ToSetPos = get_all_bitposes([{bit,No} | RestVal], NamedBitList, []),
- BitList = make_and_set_list(ToSetPos,0),
- encode_bit_string(C,BitList,NamedBitList);
-
-%% when the value is a list of ones and zeroes
-
-encode_bit_string(C, BitListValue, NamedBitList) when list(BitListValue) ->
- Bl1 =
- case NamedBitList of
- [] -> % dont remove trailing zeroes
- BitListValue;
- _ -> % first remove any trailing zeroes
- lists:reverse(lists:dropwhile(fun(0)->true;(1)->false end,
- lists:reverse(BitListValue)))
- end,
- BitList = [{bit,X} || X <- Bl1],
- BListLen = length(BitList),
- case get_constraint(C,'SizeConstraint') of
- 0 -> % fixed length
- []; % nothing to encode
- V when integer(V),V=<16 -> % fixed length 16 bits or less
- pad_list(V,BitList);
- V when integer(V) -> % fixed length 16 bits or less
- [align,pad_list(V,BitList)];
- {Lb,Ub} when integer(Lb),integer(Ub),BListLen<Lb ->
- %% padding due to OTP-4353
- [encode_length({Lb,Ub},Lb),align,pad_list(Lb,BitList)];
- {Lb,Ub} when integer(Lb),integer(Ub) ->
- [encode_length({Lb,Ub},length(BitList)),align,BitList];
- no ->
- [encode_length(undefined,length(BitList)),align,BitList];
- Sc={{Lb,Ub},_} when integer(Lb),integer(Ub),BListLen<Lb ->
- %% padding due to OTP-4353
- [encode_length(Sc,Lb),align,pad_list(Lb,BitList)];
- Sc -> % extension marker
- [encode_length(Sc,length(BitList)),align,BitList]
- end;
-
-%% when the value is an integer
-encode_bit_string(C, IntegerVal, NamedBitList) when integer(IntegerVal)->
- BitList = int_to_bitlist(IntegerVal),
- encode_bit_string(C,BitList,NamedBitList);
-
-%% when the value is a tuple
-encode_bit_string(C,{Name,Val}, NamedBitList) when atom(Name) ->
- encode_bit_string(C,Val,NamedBitList).
-
-
-%% encode_bin_bit_string/3, when value is a tuple of Unused and BinBits.
-%% Unused = integer(),
-%% BinBits = binary().
-
-encode_bin_bit_string(C,{Unused,BinBits},NamedBitList) ->
- RemoveZerosIfNNL =
- fun({NNL,BitList}) ->
- case NNL of
- [] -> BitList;
- _ ->
- lists:reverse(
- lists:dropwhile(fun(0)->true;(1)->false end,
- lists:reverse(BitList)))
- end
- end,
- {OctetList,OLSize,LastBits} =
- case size(BinBits) of
- N when N>1 ->
- IntList = binary_to_list(BinBits),
- [H|T] = lists:reverse(IntList),
- Bl1 = RemoveZerosIfNNL({NamedBitList,lists:reverse(int_to_bitlist(H,8-Unused))}),% lists:sublist obsolete if trailing bits are zero !
- {[{octet,X} || X <- lists:reverse(T)],size(BinBits)-1,
- [{bit,X} || X <- Bl1]};
- 1 ->
- <<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1>> = BinBits,
- {[],0,[{bit,X} || X <- lists:sublist([B7,B6,B5,B4,B3,B2,B1,B0],8-Unused)]};
- _ ->
- {[],0,[]}
- end,
- case get_constraint(C,'SizeConstraint') of
- 0 ->
- [];
- V when integer(V),V=<16 ->
- [OctetList, pad_list(V,LastBits)];
- V when integer(V) ->
-% [OctetList, align, pad_list(V rem 8,LastBits)];
- [align,OctetList, pad_list(V rem 8,LastBits)];
- {Lb,Ub} when integer(Lb),integer(Ub) ->
- NewLastBits = maybe_pad(Lb,length(LastBits)+(OLSize*8),LastBits,NamedBitList),
- [encode_length({Lb,Ub},length(NewLastBits)+(OLSize*8)),
-% OctetList,align,LastBits];
- align,OctetList,NewLastBits];
- no ->
- [encode_length(undefined,length(LastBits)+(OLSize*8)),
-% OctetList,align,LastBits];
- align,OctetList,LastBits];
- Sc={{Lb,_},_} when integer(Lb) ->
- NewLastBits = maybe_pad(Lb,length(LastBits)+(OLSize*8),LastBits,NamedBitList),
- [encode_length(Sc,length(NewLastBits)+(OLSize*8)),
- align,OctetList,NewLastBits];
- Sc ->
- [encode_length(Sc,length(LastBits)+(OLSize*8)),
-% OctetList,align,LastBits]
- align,OctetList,LastBits]
- end.
-
-maybe_pad(_,_,Bits,[]) ->
- Bits;
-maybe_pad(Lb,LenBits,Bits,_) when Lb>LenBits ->
- pad_list(Lb,Bits);
-maybe_pad(_,_,Bits,_) ->
- Bits.
-
-%%%%%%%%%%%%%%%
-%% The result is presented as a list of named bits (if possible)
-%% else as a tuple {Unused,Bits}. Unused is the number of unused
-%% bits, least significant bits in the last byte of Bits. Bits is
-%% the BIT STRING represented as a binary.
-%%
-decode_compact_bit_string(Buffer, C, NamedNumberList) ->
- case get_constraint(C,'SizeConstraint') of
- 0 -> % fixed length
- {{0,<<>>},Buffer};
- V when integer(V),V=<16 -> %fixed length 16 bits or less
- compact_bit_string(Buffer,V,NamedNumberList);
- V when integer(V) -> %fixed length > 16 bits
- Bytes2 = align(Buffer),
- compact_bit_string(Bytes2,V,NamedNumberList);
- {Lb,Ub} when integer(Lb),integer(Ub) ->
- {Len,Bytes2} = decode_length(Buffer,{Lb,Ub}),
- Bytes3 = align(Bytes2),
- compact_bit_string(Bytes3,Len,NamedNumberList);
- no ->
- {Len,Bytes2} = decode_length(Buffer,undefined),
- Bytes3 = align(Bytes2),
- compact_bit_string(Bytes3,Len,NamedNumberList);
- Sc ->
- {Len,Bytes2} = decode_length(Buffer,Sc),
- Bytes3 = align(Bytes2),
- compact_bit_string(Bytes3,Len,NamedNumberList)
- end.
-
-
-%%%%%%%%%%%%%%%
-%% The result is presented as a list of named bits (if possible)
-%% else as a list of 0 and 1.
-%%
-decode_bit_string(Buffer, C, NamedNumberList) ->
- case get_constraint(C,'SizeConstraint') of
- 0 -> % fixed length
- {[],Buffer}; % nothing to encode
- V when integer(V),V=<16 -> % fixed length 16 bits or less
- bit_list_to_named(Buffer,V,NamedNumberList);
- V when integer(V) -> % fixed length 16 bits or less
- Bytes2 = align(Buffer),
- bit_list_to_named(Bytes2,V,NamedNumberList);
- {Lb,Ub} when integer(Lb),integer(Ub) ->
- {Len,Bytes2} = decode_length(Buffer,{Lb,Ub}),
- Bytes3 = align(Bytes2),
- bit_list_to_named(Bytes3,Len,NamedNumberList);
- no ->
- {Len,Bytes2} = decode_length(Buffer,undefined),
- Bytes3 = align(Bytes2),
- bit_list_to_named(Bytes3,Len,NamedNumberList);
- Sc -> % extension marker
- {Len,Bytes2} = decode_length(Buffer,Sc),
- Bytes3 = align(Bytes2),
- bit_list_to_named(Bytes3,Len,NamedNumberList)
- end.
-
-
-%% if no named bits are declared we will return a
-%% {Unused,Bits}. Unused = integer(),
-%% Bits = binary().
-compact_bit_string(Buffer,Len,[]) ->
- getbits_as_binary(Len,Buffer); % {{Unused,BinBits},NewBuffer}
-compact_bit_string(Buffer,Len,NamedNumberList) ->
- bit_list_to_named(Buffer,Len,NamedNumberList).
-
-
-%% if no named bits are declared we will return a
-%% BitList = [0 | 1]
-
-bit_list_to_named(Buffer,Len,[]) ->
- getbits_as_list(Len,Buffer);
-
-%% if there are named bits declared we will return a named
-%% BitList where the names are atoms and unnamed bits represented
-%% as {bit,Pos}
-%% BitList = [atom() | {bit,Pos}]
-%% Pos = integer()
-
-bit_list_to_named(Buffer,Len,NamedNumberList) ->
- {BitList,Rest} = getbits_as_list(Len,Buffer),
- {bit_list_to_named1(0,BitList,NamedNumberList,[]), Rest}.
-
-bit_list_to_named1(Pos,[0|Bt],Names,Acc) ->
- bit_list_to_named1(Pos+1,Bt,Names,Acc);
-bit_list_to_named1(Pos,[1|Bt],Names,Acc) ->
- case lists:keysearch(Pos,2,Names) of
- {value,{Name,_}} ->
- bit_list_to_named1(Pos+1,Bt,Names,[Name|Acc]);
- _ ->
- bit_list_to_named1(Pos+1,Bt,Names,[{bit,Pos}|Acc])
- end;
-bit_list_to_named1(_Pos,[],_Names,Acc) ->
- lists:reverse(Acc).
-
-
-
-%%%%%%%%%%%%%%%
-%%
-
-int_to_bitlist(0) ->
- [];
-int_to_bitlist(Int) when integer(Int), Int >= 0 ->
- [Int band 1 | int_to_bitlist(Int bsr 1)].
-
-int_to_bitlist(_Int,0) ->
- [];
-int_to_bitlist(0,N) ->
- [0|int_to_bitlist(0,N-1)];
-int_to_bitlist(Int,N) ->
- [Int band 1 | int_to_bitlist(Int bsr 1, N-1)].
-
-
-%%%%%%%%%%%%%%%%%%
-%% get_all_bitposes([list of named bits to set], named_bit_db, []) ->
-%% [sorted_list_of_bitpositions_to_set]
-
-get_all_bitposes([{bit,ValPos}|Rest], NamedBitList, Ack) ->
- get_all_bitposes(Rest, NamedBitList, [ValPos | Ack ]);
-
-get_all_bitposes([Val | Rest], NamedBitList, Ack) ->
- case lists:keysearch(Val, 1, NamedBitList) of
- {value, {_ValName, ValPos}} ->
- get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]);
- _ ->
- exit({error,{asn1, {bitstring_namedbit, Val}}})
- end;
-get_all_bitposes([], _NamedBitList, Ack) ->
- lists:sort(Ack).
-
-%%%%%%%%%%%%%%%%%%
-%% make_and_set_list([list of positions to set to 1])->
-%% returns list with all in SetPos set.
-%% in positioning in list the first element is 0, the second 1 etc.., but
-%%
-
-make_and_set_list([XPos|SetPos], XPos) ->
- [1 | make_and_set_list(SetPos, XPos + 1)];
-make_and_set_list([Pos|SetPos], XPos) ->
- [0 | make_and_set_list([Pos | SetPos], XPos + 1)];
-make_and_set_list([], _XPos) ->
- [].
-
-%%%%%%%%%%%%%%%%%
-%% pad_list(N,BitList) -> PaddedList
-%% returns a padded (with trailing {bit,0} elements) list of length N
-%% if Bitlist contains more than N significant bits set an exit asn1_error
-%% is generated
-
-pad_list(0,BitList) ->
- case BitList of
- [] -> [];
- _ -> exit({error,{asn1,{range_error,{bit_string,BitList}}}})
- end;
-pad_list(N,[Bh|Bt]) ->
- [Bh|pad_list(N-1,Bt)];
-pad_list(N,[]) ->
- [{bit,0},pad_list(N-1,[])].
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% X.691:16
-%% encode_octet_string(Constraint,ExtensionMarker,Val)
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-encode_octet_string(C,{Name,Val}) when atom(Name) ->
- encode_octet_string(C,false,Val);
-encode_octet_string(C,Val) ->
- encode_octet_string(C,false,Val).
-
-encode_octet_string(C,Bool,{_Name,Val}) ->
- encode_octet_string(C,Bool,Val);
-encode_octet_string(_,true,_) ->
- exit({error,{asn1,{'not_supported',extensionmarker}}});
-encode_octet_string(C,false,Val) ->
- case get_constraint(C,'SizeConstraint') of
- 0 ->
- [];
- 1 ->
- [V] = Val,
- {bits,8,V};
- 2 ->
- [V1,V2] = Val,
- [{bits,8,V1},{bits,8,V2}];
- Sv when Sv =<65535, Sv == length(Val) -> % fixed length
- [align,{octets,Val}];
- {Lb,Ub} ->
- [encode_length({Lb,Ub},length(Val)),align,
- {octets,Val}];
- Sv when list(Sv) ->
- [encode_length({hd(Sv),lists:max(Sv)},length(Val)),align,
- {octets,Val}];
- no ->
- [encode_length(undefined,length(Val)),align,
- {octets,Val}]
- end.
-
-decode_octet_string(Bytes,Range) ->
- decode_octet_string(Bytes,Range,false).
-
-decode_octet_string(Bytes,C,false) ->
- case get_constraint(C,'SizeConstraint') of
- 0 ->
- {[],Bytes};
- 1 ->
- {B1,Bytes2} = getbits(Bytes,8),
- {[B1],Bytes2};
- 2 ->
- {B1,Bytes2}= getbits(Bytes,8),
- {B2,Bytes3}= getbits(Bytes2,8),
- {[B1,B2],Bytes3};
- {_,0} ->
- {[],Bytes};
- Sv when integer(Sv), Sv =<65535 -> % fixed length
- Bytes2 = align(Bytes),
- getoctets_as_list(Bytes2,Sv);
- {Lb,Ub} ->
- {Len,Bytes2} = decode_length(Bytes,{Lb,Ub}),
- Bytes3 = align(Bytes2),
- getoctets_as_list(Bytes3,Len);
- Sv when list(Sv) ->
- {Len,Bytes2} = decode_length(Bytes,{hd(Sv),lists:max(Sv)}),
- Bytes3 = align(Bytes2),
- getoctets_as_list(Bytes3,Len);
- no ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- Bytes3 = align(Bytes2),
- getoctets_as_list(Bytes3,Len)
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Restricted char string types
-%% (NumericString, PrintableString,VisibleString,IA5String,BMPString,UniversalString)
-%% X.691:26 and X.680:34-36
-%%encode_restricted_string(aligned,'BMPString',Constraints,Extension,Val)
-
-
-encode_restricted_string(aligned,{Name,Val}) when atom(Name) ->
- encode_restricted_string(aligned,Val);
-
-encode_restricted_string(aligned,Val) when list(Val)->
- [encode_length(undefined,length(Val)),align,
- {octets,Val}].
-
-encode_known_multiplier_string(aligned,StringType,C,_Ext,{Name,Val}) when atom(Name) ->
- encode_known_multiplier_string(aligned,StringType,C,false,Val);
-
-encode_known_multiplier_string(aligned,StringType,C,_Ext,Val) ->
- Result = chars_encode(C,StringType,Val),
- NumBits = get_NumBits(C,StringType),
- case get_constraint(C,'SizeConstraint') of
- Ub when integer(Ub), Ub*NumBits =< 16 ->
- case {StringType,Result} of
- {'BMPString',{octets,Ol}} ->
- [{bits,8,Oct}||Oct <- Ol];
- _ ->
- Result
- end;
- 0 ->
- [];
- Ub when integer(Ub),Ub =<65535 -> % fixed length
- [align,Result];
- {Ub,Lb} ->
- [encode_length({Ub,Lb},length(Val)),align,Result];
- Vl when list(Vl) ->
- [encode_length({lists:min(Vl),lists:max(Vl)},length(Val)),align,Result];
- no ->
- [encode_length(undefined,length(Val)),align,Result]
- end.
-
-decode_restricted_string(Bytes,aligned) ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- Bytes3 = align(Bytes2),
- getoctets_as_list(Bytes3,Len).
-
-decode_known_multiplier_string(Bytes,aligned,StringType,C,_Ext) ->
- NumBits = get_NumBits(C,StringType),
- case get_constraint(C,'SizeConstraint') of
- Ub when integer(Ub), Ub*NumBits =< 16 ->
- chars_decode(Bytes,NumBits,StringType,C,Ub);
- Ub when integer(Ub),Ub =<65535 -> % fixed length
- Bytes1 = align(Bytes),
- chars_decode(Bytes1,NumBits,StringType,C,Ub);
- 0 ->
- {[],Bytes};
- Vl when list(Vl) ->
- {Len,Bytes1} = decode_length(Bytes,{hd(Vl),lists:max(Vl)}),
- Bytes2 = align(Bytes1),
- chars_decode(Bytes2,NumBits,StringType,C,Len);
- no ->
- {Len,Bytes1} = decode_length(Bytes,undefined),
- Bytes2 = align(Bytes1),
- chars_decode(Bytes2,NumBits,StringType,C,Len);
- {Lb,Ub}->
- {Len,Bytes1} = decode_length(Bytes,{Lb,Ub}),
- Bytes2 = align(Bytes1),
- chars_decode(Bytes2,NumBits,StringType,C,Len)
- end.
-
-
-encode_NumericString(C,Val) ->
- encode_known_multiplier_string(aligned,'NumericString',C,false,Val).
-decode_NumericString(Bytes,C) ->
- decode_known_multiplier_string(Bytes,aligned,'NumericString',C,false).
-
-encode_PrintableString(C,Val) ->
- encode_known_multiplier_string(aligned,'PrintableString',C,false,Val).
-decode_PrintableString(Bytes,C) ->
- decode_known_multiplier_string(Bytes,aligned,'PrintableString',C,false).
-
-encode_VisibleString(C,Val) -> % equivalent with ISO646String
- encode_known_multiplier_string(aligned,'VisibleString',C,false,Val).
-decode_VisibleString(Bytes,C) ->
- decode_known_multiplier_string(Bytes,aligned,'VisibleString',C,false).
-
-encode_IA5String(C,Val) ->
- encode_known_multiplier_string(aligned,'IA5String',C,false,Val).
-decode_IA5String(Bytes,C) ->
- decode_known_multiplier_string(Bytes,aligned,'IA5String',C,false).
-
-encode_BMPString(C,Val) ->
- encode_known_multiplier_string(aligned,'BMPString',C,false,Val).
-decode_BMPString(Bytes,C) ->
- decode_known_multiplier_string(Bytes,aligned,'BMPString',C,false).
-
-encode_UniversalString(C,Val) ->
- encode_known_multiplier_string(aligned,'UniversalString',C,false,Val).
-decode_UniversalString(Bytes,C) ->
- decode_known_multiplier_string(Bytes,aligned,'UniversalString',C,false).
-
-%% end of known-multiplier strings for which PER visible constraints are
-%% applied
-
-encode_GeneralString(_C,Val) ->
- encode_restricted_string(aligned,Val).
-decode_GeneralString(Bytes,_C) ->
- decode_restricted_string(Bytes,aligned).
-
-encode_GraphicString(_C,Val) ->
- encode_restricted_string(aligned,Val).
-decode_GraphicString(Bytes,_C) ->
- decode_restricted_string(Bytes,aligned).
-
-encode_ObjectDescriptor(_C,Val) ->
- encode_restricted_string(aligned,Val).
-decode_ObjectDescriptor(Bytes) ->
- decode_restricted_string(Bytes,aligned).
-
-encode_TeletexString(_C,Val) -> % equivalent with T61String
- encode_restricted_string(aligned,Val).
-decode_TeletexString(Bytes,_C) ->
- decode_restricted_string(Bytes,aligned).
-
-encode_VideotexString(_C,Val) ->
- encode_restricted_string(aligned,Val).
-decode_VideotexString(Bytes,_C) ->
- decode_restricted_string(Bytes,aligned).
-
-
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% getBMPChars(Bytes,Len) ->{BMPcharList,RemainingBytes}
-%%
-getBMPChars(Bytes,1) ->
- {O1,Bytes2} = getbits(Bytes,8),
- {O2,Bytes3} = getbits(Bytes2,8),
- if
- O1 == 0 ->
- {[O2],Bytes3};
- true ->
- {[{0,0,O1,O2}],Bytes3}
- end;
-getBMPChars(Bytes,Len) ->
- getBMPChars(Bytes,Len,[]).
-
-getBMPChars(Bytes,0,Acc) ->
- {lists:reverse(Acc),Bytes};
-getBMPChars(Bytes,Len,Acc) ->
- {Octs,Bytes1} = getoctets_as_list(Bytes,2),
- case Octs of
- [0,O2] ->
- getBMPChars(Bytes1,Len-1,[O2|Acc]);
- [O1,O2]->
- getBMPChars(Bytes1,Len-1,[{0,0,O1,O2}|Acc])
- end.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% chars_encode(C,StringType,Value) -> ValueList
-%%
-%% encodes chars according to the per rules taking the constraint PermittedAlphabet
-%% into account.
-%% This function does only encode the value part and NOT the length
-
-chars_encode(C,StringType,Value) ->
- case {StringType,get_constraint(C,'PermittedAlphabet')} of
- {'UniversalString',{_,_Sv}} ->
- exit({error,{asn1,{'not implemented',"UniversalString with PermittedAlphabet constraint"}}});
- {'BMPString',{_,_Sv}} ->
- exit({error,{asn1,{'not implemented',"BMPString with PermittedAlphabet constraint"}}});
- _ ->
- {NumBits,CharOutTab} = {get_NumBits(C,StringType),get_CharOutTab(C,StringType)},
- chars_encode2(Value,NumBits,CharOutTab)
- end.
-
-chars_encode2([H|T],NumBits,{Min,Max,notab}) when H =< Max, H >= Min ->
- [{bits,NumBits,H-Min}|chars_encode2(T,NumBits,{Min,Max,notab})];
-chars_encode2([H|T],NumBits,{Min,Max,Tab}) when H =< Max, H >= Min ->
- [{bits,NumBits,element(H-Min+1,Tab)}|chars_encode2(T,NumBits,{Min,Max,Tab})];
-chars_encode2([{A,B,C,D}|T],NumBits,{Min,Max,notab}) ->
- %% no value range check here (ought to be, but very expensive)
-% [{bits,NumBits,(A*B*C*D)-Min}|chars_encode2(T,NumBits,{Min,Max,notab})];
- [{bits,NumBits,((((((A bsl 8) + B) bsl 8) + C) bsl 8) + D)-Min}|chars_encode2(T,NumBits,{Min,Max,notab})];
-chars_encode2([{A,B,C,D}|T],NumBits,{Min,Max,Tab}) ->
- %% no value range check here (ought to be, but very expensive)
-% [{bits,NumBits,element((A*B*C*D)-Min,Tab)}|chars_encode2(T,NumBits,{Min,Max,notab})];
- [{bits,NumBits,element(((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min,Tab)}|chars_encode2(T,NumBits,{Min,Max,notab})];
-chars_encode2([H|_T],_,{_,_,_}) ->
- exit({error,{asn1,{illegal_char_value,H}}});
-chars_encode2([],_,_) ->
- [].
-
-
-get_NumBits(C,StringType) ->
- case get_constraint(C,'PermittedAlphabet') of
- {'SingleValue',Sv} ->
- charbits(length(Sv),aligned);
- no ->
- case StringType of
- 'IA5String' ->
- charbits(128,aligned); % 16#00..16#7F
- 'VisibleString' ->
- charbits(95,aligned); % 16#20..16#7E
- 'PrintableString' ->
- charbits(74,aligned); % [$\s,$',$(,$),$+,$,,$-,$.,$/,"0123456789",$:,$=,$?,$A..$Z,$a..$z
- 'NumericString' ->
- charbits(11,aligned); % $ ,"0123456789"
- 'UniversalString' ->
- 32;
- 'BMPString' ->
- 16
- end
- end.
-
-%%Maybe used later
-%%get_MaxChar(C,StringType) ->
-%% case get_constraint(C,'PermittedAlphabet') of
-%% {'SingleValue',Sv} ->
-%% lists:nth(length(Sv),Sv);
-%% no ->
-%% case StringType of
-%% 'IA5String' ->
-%% 16#7F; % 16#00..16#7F
-%% 'VisibleString' ->
-%% 16#7E; % 16#20..16#7E
-%% 'PrintableString' ->
-%% $z; % [$\s,$',$(,$),$+,$,,$-,$.,$/,"0123456789",$:,$=,$?,$A..$Z,$a..$z
-%% 'NumericString' ->
-%% $9; % $ ,"0123456789"
-%% 'UniversalString' ->
-%% 16#ffffffff;
-%% 'BMPString' ->
-%% 16#ffff
-%% end
-%% end.
-
-%%Maybe used later
-%%get_MinChar(C,StringType) ->
-%% case get_constraint(C,'PermittedAlphabet') of
-%% {'SingleValue',Sv} ->
-%% hd(Sv);
-%% no ->
-%% case StringType of
-%% 'IA5String' ->
-%% 16#00; % 16#00..16#7F
-%% 'VisibleString' ->
-%% 16#20; % 16#20..16#7E
-%% 'PrintableString' ->
-%% $\s; % [$\s,$',$(,$),$+,$,,$-,$.,$/,"0123456789",$:,$=,$?,$A..$Z,$a..$z
-%% 'NumericString' ->
-%% $\s; % $ ,"0123456789"
-%% 'UniversalString' ->
-%% 16#00;
-%% 'BMPString' ->
-%% 16#00
-%% end
-%% end.
-
-get_CharOutTab(C,StringType) ->
- get_CharTab(C,StringType,out).
-
-get_CharInTab(C,StringType) ->
- get_CharTab(C,StringType,in).
-
-get_CharTab(C,StringType,InOut) ->
- case get_constraint(C,'PermittedAlphabet') of
- {'SingleValue',Sv} ->
- get_CharTab2(C,StringType,hd(Sv),lists:max(Sv),Sv,InOut);
- no ->
- case StringType of
- 'IA5String' ->
- {0,16#7F,notab};
- 'VisibleString' ->
- get_CharTab2(C,StringType,16#20,16#7F,notab,InOut);
- 'PrintableString' ->
- Chars = lists:sort(
- " '()+,-./0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"),
- get_CharTab2(C,StringType,hd(Chars),lists:max(Chars),Chars,InOut);
- 'NumericString' ->
- get_CharTab2(C,StringType,16#20,$9," 0123456789",InOut);
- 'UniversalString' ->
- {0,16#FFFFFFFF,notab};
- 'BMPString' ->
- {0,16#FFFF,notab}
- end
- end.
-
-get_CharTab2(C,StringType,Min,Max,Chars,InOut) ->
- BitValMax = (1 bsl get_NumBits(C,StringType))-1,
- if
- Max =< BitValMax ->
- {0,Max,notab};
- true ->
- case InOut of
- out ->
- {Min,Max,create_char_tab(Min,Chars)};
- in ->
- {Min,Max,list_to_tuple(Chars)}
- end
- end.
-
-create_char_tab(Min,L) ->
- list_to_tuple(create_char_tab(Min,L,0)).
-create_char_tab(Min,[Min|T],V) ->
- [V|create_char_tab(Min+1,T,V+1)];
-create_char_tab(_Min,[],_V) ->
- [];
-create_char_tab(Min,L,V) ->
- [false|create_char_tab(Min+1,L,V)].
-
-%% This very inefficient and should be moved to compiletime
-charbits(NumOfChars,aligned) ->
- case charbits(NumOfChars) of
- 1 -> 1;
- 2 -> 2;
- B when B > 2, B =< 4 -> 4;
- B when B > 4, B =< 8 -> 8;
- B when B > 8, B =< 16 -> 16;
- B when B > 16, B =< 32 -> 32
- end.
-
-charbits(NumOfChars) when NumOfChars =< 2 -> 1;
-charbits(NumOfChars) when NumOfChars =< 4 -> 2;
-charbits(NumOfChars) when NumOfChars =< 8 -> 3;
-charbits(NumOfChars) when NumOfChars =< 16 -> 4;
-charbits(NumOfChars) when NumOfChars =< 32 -> 5;
-charbits(NumOfChars) when NumOfChars =< 64 -> 6;
-charbits(NumOfChars) when NumOfChars =< 128 -> 7;
-charbits(NumOfChars) when NumOfChars =< 256 -> 8;
-charbits(NumOfChars) when NumOfChars =< 512 -> 9;
-charbits(NumOfChars) when NumOfChars =< 1024 -> 10;
-charbits(NumOfChars) when NumOfChars =< 2048 -> 11;
-charbits(NumOfChars) when NumOfChars =< 4096 -> 12;
-charbits(NumOfChars) when NumOfChars =< 8192 -> 13;
-charbits(NumOfChars) when NumOfChars =< 16384 -> 14;
-charbits(NumOfChars) when NumOfChars =< 32768 -> 15;
-charbits(NumOfChars) when NumOfChars =< 65536 -> 16;
-charbits(NumOfChars) when integer(NumOfChars) ->
- 16 + charbits1(NumOfChars bsr 16).
-
-charbits1(0) ->
- 0;
-charbits1(NumOfChars) ->
- 1 + charbits1(NumOfChars bsr 1).
-
-
-chars_decode(Bytes,_,'BMPString',C,Len) ->
- case get_constraint(C,'PermittedAlphabet') of
- no ->
- getBMPChars(Bytes,Len);
- _ ->
- exit({error,{asn1,
- {'not implemented',
- "BMPString with PermittedAlphabet constraint"}}})
- end;
-chars_decode(Bytes,NumBits,StringType,C,Len) ->
- CharInTab = get_CharInTab(C,StringType),
- chars_decode2(Bytes,CharInTab,NumBits,Len).
-
-
-chars_decode2(Bytes,CharInTab,NumBits,Len) ->
- chars_decode2(Bytes,CharInTab,NumBits,Len,[]).
-
-chars_decode2(Bytes,_CharInTab,_NumBits,0,Acc) ->
- {lists:reverse(Acc),Bytes};
-chars_decode2(Bytes,{Min,Max,notab},NumBits,Len,Acc) when NumBits > 8 ->
- {Char,Bytes2} = getbits(Bytes,NumBits),
- Result = case minimum_octets(Char+Min) of
- [NewChar] -> NewChar;
- [C1,C2] -> {0,0,C1,C2};
- [C1,C2,C3] -> {0,C1,C2,C3};
- [C1,C2,C3,C4] -> {C1,C2,C3,C4}
- end,
- chars_decode2(Bytes2,{Min,Max,notab},NumBits,Len -1,[Result|Acc]);
-chars_decode2(Bytes,{Min,Max,notab},NumBits,Len,Acc) ->
- {Char,Bytes2} = getbits(Bytes,NumBits),
- chars_decode2(Bytes2,{Min,Max,notab},NumBits,Len -1,[Char+Min|Acc]);
-
-%% BMPString and UniversalString with PermittedAlphabet is currently not supported
-chars_decode2(Bytes,{Min,Max,CharInTab},NumBits,Len,Acc) ->
- {Char,Bytes2} = getbits(Bytes,NumBits),
- chars_decode2(Bytes2,{Min,Max,CharInTab},NumBits,Len -1,[element(Char+1,CharInTab)|Acc]).
-
-
- % X.691:17
-encode_null({Name,Val}) when atom(Name) ->
- encode_null(Val);
-encode_null(_) -> []. % encodes to nothing
-
-decode_null(Bytes) ->
- {'NULL',Bytes}.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% encode_object_identifier(Val) -> CompleteList
-%% encode_object_identifier({Name,Val}) -> CompleteList
-%% Val -> {Int1,Int2,...,IntN} % N >= 2
-%% Name -> atom()
-%% Int1 -> integer(0..2)
-%% Int2 -> integer(0..39) when Int1 (0..1) else integer()
-%% Int3-N -> integer()
-%% CompleteList -> [{bits,8,Val}|{octets,Ol}|align|...]
-%%
-encode_object_identifier({Name,Val}) when atom(Name) ->
- encode_object_identifier(Val);
-encode_object_identifier(Val) ->
- Octets = e_object_identifier(Val,notag),
- [{debug,object_identifier},encode_length(undefined,length(Octets)),{octets,Octets}].
-
-%% This code is copied from asn1_encode.erl (BER) and corrected and modified
-
-e_object_identifier({'OBJECT IDENTIFIER',V},DoTag) ->
- e_object_identifier(V,DoTag);
-e_object_identifier({Cname,V},DoTag) when atom(Cname),tuple(V) ->
- e_object_identifier(tuple_to_list(V),DoTag);
-e_object_identifier({Cname,V},DoTag) when atom(Cname),list(V) ->
- e_object_identifier(V,DoTag);
-e_object_identifier(V,DoTag) when tuple(V) ->
- e_object_identifier(tuple_to_list(V),DoTag);
-
-% E1 = 0|1|2 and (E2 < 40 when E1 = 0|1)
-e_object_identifier([E1,E2|Tail],_DoTag) when E1 =< 2 ->
- Head = 40*E1 + E2, % weird
- Res = e_object_elements([Head|Tail]),
-% dotag(DoTag,[6],elength(length(Res)+1),[Head|Res]),
- Res.
-
-e_object_elements([]) ->
- [];
-e_object_elements([H|T]) ->
- lists:append(e_object_element(H),e_object_elements(T)).
-
-e_object_element(Num) when Num < 128 ->
- [Num];
-% must be changed to handle more than 2 octets
-e_object_element(Num) -> %% when Num < ???
- Left = ((Num band 2#11111110000000) bsr 7) bor 2#10000000,
- Right = Num band 2#1111111 ,
- [Left,Right].
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% decode_object_identifier(Bytes) -> {ObjId,RemainingBytes}
-%% ObjId -> {integer(),integer(),...} % at least 2 integers
-%% RemainingBytes -> [integer()] when integer() (0..255)
-decode_object_identifier(Bytes) ->
- {Len,Bytes2} = decode_length(Bytes,undefined),
- {Octs,Bytes3} = getoctets_as_list(Bytes2,Len),
- [First|Rest] = dec_subidentifiers(Octs,0,[]),
- Idlist = if
- First < 40 ->
- [0,First|Rest];
- First < 80 ->
- [1,First - 40|Rest];
- true ->
- [2,First - 80|Rest]
- end,
- {list_to_tuple(Idlist),Bytes3}.
-
-dec_subidentifiers([H|T],Av,Al) when H >=16#80 ->
- dec_subidentifiers(T,(Av bsl 7) + (H band 16#7F),Al);
-dec_subidentifiers([H|T],Av,Al) ->
- dec_subidentifiers(T,0,[(Av bsl 7) + H |Al]);
-dec_subidentifiers([],_Av,Al) ->
- lists:reverse(Al).
-
-get_constraint(C,Key) ->
- case lists:keysearch(Key,1,C) of
- false ->
- no;
- {value,{_,V}} ->
- V
- end.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% complete(InList) -> ByteList
-%% Takes a coded list with bits and bytes and converts it to a list of bytes
-%% Should be applied as the last step at encode of a complete ASN.1 type
-%%
-complete(InList) when list(InList) ->
- complete(InList,[],0);
-complete(InList) ->
- complete([InList],[],0).
-
-complete([{debug,_}|T], Acc, Acclen) ->
- complete(T,Acc,Acclen);
-complete([H|T],Acc,Acclen) when list(H) ->
- complete(lists:concat([H,T]),Acc,Acclen);
-
-
-complete([{octets,N,Val}|T],Acc,Acclen) when N =< 4 ,integer(Val) ->
- Newval = case N of
- 1 ->
- Val4 = Val band 16#FF,
- [Val4];
- 2 ->
- Val3 = (Val bsr 8) band 16#FF,
- Val4 = Val band 16#FF,
- [Val3,Val4];
- 3 ->
- Val2 = (Val bsr 16) band 16#FF,
- Val3 = (Val bsr 8) band 16#FF,
- Val4 = Val band 16#FF,
- [Val2,Val3,Val4];
- 4 ->
- Val1 = (Val bsr 24) band 16#FF,
- Val2 = (Val bsr 16) band 16#FF,
- Val3 = (Val bsr 8) band 16#FF,
- Val4 = Val band 16#FF,
- [Val1,Val2,Val3,Val4]
- end,
- complete([{octets,Newval}|T],Acc,Acclen);
-
-complete([{octets,Oct}|T],[],_Acclen) when list(Oct) ->
- complete(T,lists:reverse(Oct),0);
-complete([{octets,Oct}|T],[Hacc|Tacc],Acclen) when list(Oct) ->
- Rest = 8 - Acclen,
- if
- Rest == 8 ->
- complete(T,lists:concat([lists:reverse(Oct),[Hacc|Tacc]]),0);
- true ->
- complete(T,lists:concat([lists:reverse(Oct),[Hacc bsl Rest|Tacc]]),0)
- end;
-
-complete([{bit,Val}|T], Acc, Acclen) ->
- complete([{bits,1,Val}|T],Acc,Acclen);
-complete([{octet,Val}|T], Acc, Acclen) ->
- complete([{octets,1,Val}|T],Acc,Acclen);
-
-complete([{bits,N,Val}|T], Acc, 0) when N =< 8 ->
- complete(T,[Val|Acc],N);
-complete([{bits,N,Val}|T], [Hacc|Tacc], Acclen) when N =< 8 ->
- Rest = 8 - Acclen,
- if
- Rest >= N ->
- complete(T,[(Hacc bsl N) + Val|Tacc],(Acclen+N) rem 8);
- true ->
- Diff = N - Rest,
- NewHacc = (Hacc bsl Rest) + (Val bsr Diff),
- Mask = element(Diff,{1,3,7,15,31,63,127,255}),
- complete(T,[(Val band Mask),NewHacc|Tacc],(Acclen+N) rem 8)
- end;
-complete([{bits,N,Val}|T], Acc, Acclen) -> % N > 8
- complete([{bits,N-8,Val bsr 8},{bits,8,Val band 255}|T],Acc,Acclen);
-
-complete([align|T],Acc,0) ->
- complete(T,Acc,0);
-complete([align|T],[Hacc|Tacc],Acclen) ->
- Rest = 8 - Acclen,
- complete(T,[Hacc bsl Rest|Tacc],0);
-complete([{octets,_N,Val}|T],Acc,Acclen) when list(Val) -> % no security check here
- complete([{octets,Val}|T],Acc,Acclen);
-
-complete([],[],0) ->
- [0]; % a complete encoding must always be at least 1 byte
-complete([],Acc,0) ->
- lists:reverse(Acc);
-complete([],[Hacc|Tacc],Acclen) when Acclen > 0->
- Rest = 8 - Acclen,
- NewHacc = Hacc bsl Rest,
- lists:reverse([NewHacc|Tacc]).
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-