1%% ``Licensed under the Apache License, Version 2.0 (the "License");
2%% you may not use this file except in compliance with the License.
3%% You may obtain a copy of the License at
4%%
5%%     http://www.apache.org/licenses/LICENSE-2.0
6%%
7%% Unless required by applicable law or agreed to in writing, software
8%% distributed under the License is distributed on an "AS IS" BASIS,
9%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10%% See the License for the specific language governing permissions and
11%% limitations under the License.
12%%
13%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
14%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
15%% AB. All Rights Reserved.''
16%%
17%%     $Id: asn1rt_per_bin_rt2ct.erl,v 1.1 2008/12/17 09:53:31 mikpe Exp $
18-module(asn1rt_per_bin_rt2ct).
19
20%% encoding / decoding of PER aligned
21
22-include("asn1_records.hrl").
23
24-export([dec_fixup/3, cindex/3, list_to_record/2]).
25-export([setchoiceext/1, setext/1, fixoptionals/3, fixextensions/2,
26	 getext/1, getextension/2, skipextensions/3, getbit/1, getchoice/3 ]).
27-export([getoptionals/2, getoptionals2/2,
28	 set_choice/3, encode_integer/2, encode_integer/3  ]).
29-export([decode_integer/2, decode_integer/3, encode_small_number/1,
30	 decode_boolean/1, encode_length/2, decode_length/1, decode_length/2,
31	 encode_small_length/1, decode_small_length/1,
32	 decode_compact_bit_string/3]).
33-export([decode_enumerated/3,
34	 encode_bit_string/3, decode_bit_string/3  ]).
35-export([encode_octet_string/2, decode_octet_string/2,
36	 encode_null/1, decode_null/1,
37	 encode_object_identifier/1, decode_object_identifier/1,
38	 complete/1]).
39
40
41-export([encode_open_type/2, decode_open_type/2]).
42
43-export([%encode_UniversalString/2, decode_UniversalString/2,
44	 %encode_PrintableString/2, decode_PrintableString/2,
45	 encode_GeneralString/2, decode_GeneralString/2,
46	 encode_GraphicString/2, decode_GraphicString/2,
47	 encode_TeletexString/2, decode_TeletexString/2,
48	 encode_VideotexString/2, decode_VideotexString/2,
49	 %encode_VisibleString/2, decode_VisibleString/2,
50	 %encode_BMPString/2, decode_BMPString/2,
51	 %encode_IA5String/2, decode_IA5String/2,
52	 %encode_NumericString/2, decode_NumericString/2,
53	 encode_ObjectDescriptor/2, decode_ObjectDescriptor/1
54	]).
55
56-export([decode_constrained_number/2,
57	 decode_constrained_number/3,
58	 decode_unconstrained_number/1,
59	 decode_semi_constrained_number/2,
60	 encode_unconstrained_number/1,
61	 decode_constrained_number/4,
62	 encode_octet_string/3,
63	 decode_octet_string/3,
64	 encode_known_multiplier_string/5,
65	 decode_known_multiplier_string/5,
66	 getoctets/2, getbits/2
67%	 start_drv/1,start_drv2/1,init_drv/1
68	]).
69
70
71-export([eint_positive/1]).
72-export([pre_complete_bits/2]).
73
74-define('16K',16384).
75-define('32K',32768).
76-define('64K',65536).
77
78%%-define(nodriver,true).
79
80dec_fixup(Terms,Cnames,RemBytes) ->
81    dec_fixup(Terms,Cnames,RemBytes,[]).
82
83dec_fixup([novalue|T],[_Hc|Tc],RemBytes,Acc) ->
84    dec_fixup(T,Tc,RemBytes,Acc);
85dec_fixup([{_Name,novalue}|T],[_Hc|Tc],RemBytes,Acc) ->
86    dec_fixup(T,Tc,RemBytes,Acc);
87dec_fixup([H|T],[Hc|Tc],RemBytes,Acc) ->
88    dec_fixup(T,Tc,RemBytes,[{Hc,H}|Acc]);
89dec_fixup([],_Cnames,RemBytes,Acc) ->
90    {lists:reverse(Acc),RemBytes}.
91
92cindex(Ix,Val,Cname) ->
93    case element(Ix,Val) of
94	{Cname,Val2} -> Val2;
95	X -> X
96    end.
97
98%% converts a list to a record if necessary
99list_to_record(_,Tuple) when tuple(Tuple) ->
100    Tuple;
101list_to_record(Name,List) when list(List) ->
102    list_to_tuple([Name|List]).
103
104%%--------------------------------------------------------
105%% setchoiceext(InRootSet) -> [{bit,X}]
106%% X  is set to  1 when InRootSet==false
107%% X  is set to  0 when InRootSet==true
108%%
109setchoiceext(true) ->
110%    [{debug,choiceext},{bits,1,0}];
111    [0];
112setchoiceext(false) ->
113%    [{debug,choiceext},{bits,1,1}].
114    [1].
115
116%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
117%% setext(true|false) ->  CompleteList
118%%
119
120setext(false) ->
121%    [{debug,ext},{bits,1,0}];
122    [0];
123setext(true) ->
124%    [{debug,ext},{bits,1,1}];
125    [1].
126
127fixoptionals(OptList,_OptLength,Val) when tuple(Val) ->
128%    Bits = fixoptionals(OptList,Val,0),
129%    {Val,{bits,OptLength,Bits}};
130%    {Val,[10,OptLength,Bits]};
131    {Val,fixoptionals(OptList,Val,[])};
132
133fixoptionals([],_,Acc) ->
134    %% Optbits
135    lists:reverse(Acc);
136fixoptionals([Pos|Ot],Val,Acc) ->
137    case element(Pos,Val) of
138% 	asn1_NOVALUE -> fixoptionals(Ot,Val,Acc bsl 1);
139% 	asn1_DEFAULT -> fixoptionals(Ot,Val,Acc bsl 1);
140% 	_ -> fixoptionals(Ot,Val,(Acc bsl 1) + 1)
141	asn1_NOVALUE -> fixoptionals(Ot,Val,[0|Acc]);
142	asn1_DEFAULT -> fixoptionals(Ot,Val,[0|Acc]);
143	_ -> fixoptionals(Ot,Val,[1|Acc])
144    end.
145
146
147getext(Bytes) when tuple(Bytes) ->
148    getbit(Bytes);
149getext(Bytes) when binary(Bytes) ->
150    getbit({0,Bytes});
151getext(Bytes) when list(Bytes) ->
152    getbit({0,Bytes}).
153
154getextension(0, Bytes) ->
155    {{},Bytes};
156getextension(1, Bytes) ->
157    {Len,Bytes2} = decode_small_length(Bytes),
158    {Blist, Bytes3} = getbits_as_list(Len,Bytes2),
159    {list_to_tuple(Blist),Bytes3}.
160
161fixextensions({ext,ExtPos,ExtNum},Val) ->
162    case fixextensions(ExtPos,ExtNum+ExtPos,Val,0) of
163	0 -> [];
164	ExtBits ->
165%	    [encode_small_length(ExtNum),{bits,ExtNum,ExtBits}]
166%	    [encode_small_length(ExtNum),[10,ExtNum,ExtBits]]
167	    [encode_small_length(ExtNum),pre_complete_bits(ExtNum,ExtBits)]
168    end.
169
170fixextensions(Pos,MaxPos,_,Acc) when Pos >= MaxPos ->
171    Acc;
172fixextensions(Pos,ExtPos,Val,Acc) ->
173    Bit = case catch(element(Pos+1,Val)) of
174	      asn1_NOVALUE ->
175		  0;
176	      asn1_NOEXTVALUE ->
177		  0;
178	      {'EXIT',_} ->
179		  0;
180	      _ ->
181		  1
182	  end,
183    fixextensions(Pos+1,ExtPos,Val,(Acc bsl 1)+Bit).
184
185skipextensions(Bytes,Nr,ExtensionBitPattern) ->
186    case (catch element(Nr,ExtensionBitPattern)) of
187	1 ->
188	    {_,Bytes2} = decode_open_type(Bytes,[]),
189	    skipextensions(Bytes2, Nr+1, ExtensionBitPattern);
190	0 ->
191	    skipextensions(Bytes, Nr+1, ExtensionBitPattern);
192	{'EXIT',_} -> % badarg, no more extensions
193	    Bytes
194    end.
195
196
197getchoice(Bytes,1,0) -> % only 1 alternative is not encoded
198    {0,Bytes};
199getchoice(Bytes,_,1) ->
200    decode_small_number(Bytes);
201getchoice(Bytes,NumChoices,0) ->
202    decode_constrained_number(Bytes,{0,NumChoices-1}).
203
204%% old version kept for backward compatibility with generates from R7B01
205getoptionals(Bytes,NumOpt) ->
206    {Blist,Bytes1} = getbits_as_list(NumOpt,Bytes),
207    {list_to_tuple(Blist),Bytes1}.
208
209%% new version used in generates from r8b_patch/3 and later
210getoptionals2(Bytes,NumOpt) ->
211    {_,_} = getbits(Bytes,NumOpt).
212
213
214%% getbits_as_binary(Num,Bytes) -> {{Unused,BinBits},RestBytes},
215%% Num = integer(),
216%% Bytes = list() | tuple(),
217%% Unused = integer(),
218%% BinBits = binary(),
219%% RestBytes = tuple()
220getbits_as_binary(Num,Bytes) when binary(Bytes) ->
221    getbits_as_binary(Num,{0,Bytes});
222getbits_as_binary(0,Buffer) ->
223    {{0,<<>>},Buffer};
224getbits_as_binary(Num,{0,Bin}) when Num > 16 ->
225    Used = Num rem 8,
226    Pad = (8 - Used) rem 8,
227%%    Nbytes = Num div 8,
228    <<Bits:Num,_:Pad,RestBin/binary>> = Bin,
229    {{Pad,<<Bits:Num,0:Pad>>},RestBin};
230getbits_as_binary(Num,Buffer={_Used,_Bin}) -> % Unaligned buffer
231    %% Num =< 16,
232    {Bits2,Buffer2} = getbits(Buffer,Num),
233    Pad = (8 - (Num rem 8)) rem 8,
234    {{Pad,<<Bits2:Num,0:Pad>>},Buffer2}.
235
236
237% integer_from_list(Int,[],BigInt) ->
238%     BigInt;
239% integer_from_list(Int,[H|T],BigInt) when Int < 8 ->
240%     (BigInt bsl Int) bor (H bsr (8-Int));
241% integer_from_list(Int,[H|T],BigInt) ->
242%     integer_from_list(Int-8,T,(BigInt bsl 8) bor H).
243
244getbits_as_list(Num,Bytes) when binary(Bytes) ->
245    getbits_as_list(Num,{0,Bytes},[]);
246getbits_as_list(Num,Bytes) ->
247    getbits_as_list(Num,Bytes,[]).
248
249%% If buffer is empty and nothing more will be picked.
250getbits_as_list(0, B, Acc) ->
251    {lists:reverse(Acc),B};
252%% If first byte in buffer is full and at least one byte will be picked,
253%% then pick one byte.
254getbits_as_list(N,{0,Bin},Acc) when N >= 8 ->
255    <<B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,Rest/binary>> = Bin,
256    getbits_as_list(N-8,{0,Rest},[B0,B1,B2,B3,B4,B5,B6,B7|Acc]);
257getbits_as_list(N,{Used,Bin},Acc) when N >= 4, Used =< 4 ->
258    NewUsed = Used + 4,
259    Rem = 8 - NewUsed,
260    <<_:Used,B3:1,B2:1,B1:1,B0:1,_:Rem, Rest/binary>> = Bin,
261    NewRest = case Rem of 0 -> Rest; _ -> Bin end,
262    getbits_as_list(N-4,{NewUsed rem 8,NewRest},[B0,B1,B2,B3|Acc]);
263getbits_as_list(N,{Used,Bin},Acc) when N >= 2, Used =< 6  ->
264    NewUsed = Used + 2,
265    Rem = 8 - NewUsed,
266    <<_:Used,B1:1,B0:1,_:Rem, Rest/binary>> = Bin,
267    NewRest = case Rem of 0 -> Rest; _ -> Bin end,
268    getbits_as_list(N-2,{NewUsed rem 8,NewRest},[B0,B1|Acc]);
269getbits_as_list(N,{Used,Bin},Acc) when Used =< 7 ->
270    NewUsed = Used + 1,
271    Rem = 8 - NewUsed,
272    <<_:Used,B0:1,_:Rem, Rest/binary>> = Bin,
273    NewRest = case Rem of 0 -> Rest; _ -> Bin end,
274    getbits_as_list(N-1,{NewUsed rem 8,NewRest},[B0|Acc]).
275
276
277getbit({7,<<_:7,B:1,Rest/binary>>}) ->
278    {B,{0,Rest}};
279getbit({0,Buffer = <<B:1,_:7,_/binary>>}) ->
280    {B,{1,Buffer}};
281getbit({Used,Buffer}) ->
282    Unused = (8 - Used) - 1,
283    <<_:Used,B:1,_:Unused,_/binary>> = Buffer,
284    {B,{Used+1,Buffer}};
285getbit(Buffer) when binary(Buffer) ->
286    getbit({0,Buffer}).
287
288
289getbits({0,Buffer},Num) when (Num rem 8) == 0 ->
290    <<Bits:Num,Rest/binary>> = Buffer,
291    {Bits,{0,Rest}};
292getbits({Used,Bin},Num) ->
293    NumPlusUsed = Num + Used,
294    NewUsed = NumPlusUsed rem 8,
295    Unused = (8-NewUsed) rem 8,
296    case Unused of
297	0 ->
298	    <<_:Used,Bits:Num,Rest/binary>> = Bin,
299	    {Bits,{0,Rest}};
300	_ ->
301	    Bytes = NumPlusUsed div 8,
302	    <<_:Used,Bits:Num,_:Unused,_/binary>> = Bin,
303	    <<_:Bytes/binary,Rest/binary>> = Bin,
304	    {Bits,{NewUsed,Rest}}
305    end;
306getbits(Bin,Num) when binary(Bin) ->
307    getbits({0,Bin},Num).
308
309
310
311% getoctet(Bytes) when list(Bytes) ->
312%     getoctet({0,Bytes});
313% getoctet(Bytes) ->
314%     %%    io:format("getoctet:Buffer = ~p~n",[Bytes]),
315%     getoctet1(Bytes).
316
317% getoctet1({0,[H|T]}) ->
318%     {H,{0,T}};
319% getoctet1({Pos,[_,H|T]}) ->
320%     {H,{0,T}}.
321
322align({0,L}) ->
323    {0,L};
324align({_Pos,<<_H,T/binary>>}) ->
325    {0,T};
326align(Bytes) ->
327    {0,Bytes}.
328
329%% First align buffer, then pick the first Num octets.
330%% Returns octets as an integer with bit significance as in buffer.
331getoctets({0,Buffer},Num) ->
332    <<Val:Num/integer-unit:8,RestBin/binary>> = Buffer,
333    {Val,{0,RestBin}};
334getoctets({U,<<_Padding,Rest/binary>>},Num) when U /= 0 ->
335    getoctets({0,Rest},Num);
336getoctets(Buffer,Num) when binary(Buffer) ->
337    getoctets({0,Buffer},Num).
338% getoctets(Buffer,Num) ->
339%     %%    io:format("getoctets:Buffer = ~p~nNum = ~p~n",[Buffer,Num]),
340%     getoctets(Buffer,Num,0).
341
342% getoctets(Buffer,0,Acc) ->
343%     {Acc,Buffer};
344% getoctets(Buffer,Num,Acc) ->
345%     {Oct,NewBuffer} = getoctet(Buffer),
346%     getoctets(NewBuffer,Num-1,(Acc bsl 8)+Oct).
347
348% getoctets_as_list(Buffer,Num) ->
349%     getoctets_as_list(Buffer,Num,[]).
350
351% getoctets_as_list(Buffer,0,Acc) ->
352%     {lists:reverse(Acc),Buffer};
353% getoctets_as_list(Buffer,Num,Acc) ->
354%     {Oct,NewBuffer} = getoctet(Buffer),
355%     getoctets_as_list(NewBuffer,Num-1,[Oct|Acc]).
356
357%% First align buffer, then pick the first Num octets.
358%% Returns octets as a binary
359getoctets_as_bin({0,Bin},Num)->
360    <<Octets:Num/binary,RestBin/binary>> = Bin,
361    {Octets,{0,RestBin}};
362getoctets_as_bin({_U,Bin},Num) ->
363    <<_Padding,Octets:Num/binary,RestBin/binary>> = Bin,
364    {Octets,{0,RestBin}};
365getoctets_as_bin(Bin,Num) when binary(Bin) ->
366    getoctets_as_bin({0,Bin},Num).
367
368%% same as above but returns octets as a List
369getoctets_as_list(Buffer,Num) ->
370    {Bin,Buffer2} = getoctets_as_bin(Buffer,Num),
371    {binary_to_list(Bin),Buffer2}.
372%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
373%% set_choice(Alt,Choices,Altnum) -> ListofBitSettings
374%% Alt = atom()
375%% Altnum = integer() | {integer(),integer()}% number of alternatives
376%% Choices = [atom()] | {[atom()],[atom()]}
377%% When Choices is a tuple the first list is the Rootset and the
378%% second is the Extensions and then Altnum must also be a tuple with the
379%% lengths of the 2 lists
380%%
381set_choice(Alt,{L1,L2},{Len1,_Len2}) ->
382    case set_choice_tag(Alt,L1) of
383	N when integer(N), Len1 > 1 ->
384%	    [{bits,1,0}, % the value is in the root set
385%	     encode_constrained_number({0,Len1-1},N)];
386	    [0, % the value is in the root set
387	     encode_constrained_number({0,Len1-1},N)];
388	N when integer(N) ->
389%	    [{bits,1,0}]; % no encoding if only 0 or 1 alternative
390	    [0]; % no encoding if only 0 or 1 alternative
391	false ->
392%	    [{bits,1,1}, % extension value
393	    [1, % extension value
394	     case set_choice_tag(Alt,L2) of
395		 N2 when integer(N2) ->
396		     encode_small_number(N2);
397		 false ->
398		     unknown_choice_alt
399	     end]
400    end;
401set_choice(Alt,L,Len) ->
402    case set_choice_tag(Alt,L) of
403	N when integer(N), Len > 1 ->
404	    encode_constrained_number({0,Len-1},N);
405	N when integer(N) ->
406	    []; % no encoding if only 0 or 1 alternative
407	false ->
408	    [unknown_choice_alt]
409    end.
410
411set_choice_tag(Alt,Choices) ->
412    set_choice_tag(Alt,Choices,0).
413
414set_choice_tag(Alt,[Alt|_Rest],Tag) ->
415    Tag;
416set_choice_tag(Alt,[_H|Rest],Tag) ->
417    set_choice_tag(Alt,Rest,Tag+1);
418set_choice_tag(_Alt,[],_Tag) ->
419    false.
420
421%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
422%% decode_fragmented_XXX; decode of values encoded fragmented according
423%% to ITU-T X.691 clause 10.9.3.8. The unit (XXX) is either bits, octets,
424%% characters or number of components (in a choice,sequence or similar).
425%% Buffer is a buffer {Used, Bin}.
426%% C is the constrained length.
427%% If the buffer is not aligned, this function does that.
428decode_fragmented_bits({0,Buffer},C) ->
429    decode_fragmented_bits(Buffer,C,[]);
430decode_fragmented_bits({_N,<<_B,Bs/binary>>},C) ->
431    decode_fragmented_bits(Bs,C,[]).
432
433decode_fragmented_bits(<<3:2,Len:6,Bin/binary>>,C,Acc) ->
434    {Value,Bin2} = split_binary(Bin, Len * ?'16K'),
435    decode_fragmented_bits(Bin2,C,[Value,Acc]);
436decode_fragmented_bits(<<0:1,0:7,Bin/binary>>,C,Acc) ->
437    BinBits = list_to_binary(lists:reverse(Acc)),
438    case C of
439	Int when integer(Int),C == size(BinBits) ->
440	    {BinBits,{0,Bin}};
441	Int when integer(Int) ->
442	    exit({error,{asn1,{illegal_value,C,BinBits}}});
443	_ ->
444	    {BinBits,{0,Bin}}
445    end;
446decode_fragmented_bits(<<0:1,Len:7,Bin/binary>>,C,Acc) ->
447    Result = {BinBits,{Used,_Rest}} =
448	case (Len rem 8) of
449	    0 ->
450		<<Value:Len/binary-unit:1,Bin2/binary>> = Bin,
451		{list_to_binary(lists:reverse([Value|Acc])),{0,Bin2}};
452	    Rem ->
453		Bytes = Len div 8,
454		U = 8 - Rem,
455		<<Value:Bytes/binary-unit:8,Bits1:Rem,Bits2:U,Bin2/binary>> = Bin,
456		{list_to_binary(lists:reverse([Bits1 bsl U,Value|Acc])),
457		 {Rem,<<Bits2,Bin2/binary>>}}
458	end,
459    case C of
460	 Int when integer(Int),C == (size(BinBits) - ((8 - Used) rem 8)) ->
461	    Result;
462	Int when integer(Int) ->
463	    exit({error,{asn1,{illegal_value,C,BinBits}}});
464	_ ->
465	    Result
466    end.
467
468
469decode_fragmented_octets({0,Bin},C) ->
470    decode_fragmented_octets(Bin,C,[]);
471decode_fragmented_octets({_N,<<_B,Bs/binary>>},C) ->
472    decode_fragmented_octets(Bs,C,[]).
473
474decode_fragmented_octets(<<3:2,Len:6,Bin/binary>>,C,Acc) ->
475    {Value,Bin2} = split_binary(Bin,Len * ?'16K'),
476    decode_fragmented_octets(Bin2,C,[Value,Acc]);
477decode_fragmented_octets(<<0:1,0:7,Bin/binary>>,C,Acc) ->
478    Octets = list_to_binary(lists:reverse(Acc)),
479    case C of
480	Int when integer(Int), C == size(Octets) ->
481	    {Octets,{0,Bin}};
482	Int when integer(Int) ->
483	    exit({error,{asn1,{illegal_value,C,Octets}}});
484	_ ->
485	    {Octets,{0,Bin}}
486    end;
487decode_fragmented_octets(<<0:1,Len:7,Bin/binary>>,C,Acc) ->
488    <<Value:Len/binary-unit:8,Bin2/binary>> = Bin,
489    BinOctets = list_to_binary(lists:reverse([Value|Acc])),
490    case C of
491	Int when integer(Int),size(BinOctets) == Int ->
492	    {BinOctets,Bin2};
493	Int when integer(Int) ->
494	    exit({error,{asn1,{illegal_value,C,BinOctets}}});
495	_ ->
496	    {BinOctets,Bin2}
497    end.
498
499
500
501%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
502%% encode_open_type(Constraint, Value) -> CompleteList
503%% Value = list of bytes of an already encoded value (the list must be flat)
504%%         | binary
505%% Contraint = not used in this version
506%%
507encode_open_type(_Constraint, Val) when list(Val) ->
508    Bin = list_to_binary(Val),
509    case size(Bin) of
510	Size when Size>255 ->
511	    [encode_length(undefined,Size),[21,<<Size:16>>,Bin]];
512	Size ->
513	    [encode_length(undefined,Size),[20,Size,Bin]]
514    end;
515%    [encode_length(undefined,size(Bin)),{octets,Bin}]; % octets implies align
516encode_open_type(_Constraint, Val) when binary(Val) ->
517%    [encode_length(undefined,size(Val)),{octets,Val}]. % octets implies align
518    case size(Val) of
519	Size when Size>255 ->
520	    [encode_length(undefined,size(Val)),[21,<<Size:16>>,Val]]; % octets implies align
521	Size ->
522	    [encode_length(undefined,Size),[20,Size,Val]]
523    end.
524%% the binary_to_list is not optimal but compatible with the current solution
525
526%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
527%% decode_open_type(Buffer,Constraint) -> Value
528%% Constraint is not used in this version
529%% Buffer = [byte] with PER encoded data
530%% Value = [byte] with decoded data (which must be decoded again as some type)
531%%
532decode_open_type(Bytes, _Constraint) ->
533    {Len,Bytes2} = decode_length(Bytes,undefined),
534    getoctets_as_bin(Bytes2,Len).
535
536%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
537%% encode_integer(Constraint,Value,NamedNumberList) -> CompleteList
538%% encode_integer(Constraint,Value) -> CompleteList
539%% encode_integer(Constraint,{Name,Value}) -> CompleteList
540%%
541%%
542encode_integer(C,V,NamedNumberList) when atom(V) ->
543    case lists:keysearch(V,1,NamedNumberList) of
544	{value,{_,NewV}} ->
545	    encode_integer(C,NewV);
546	_ ->
547	    exit({error,{asn1,{namednumber,V}}})
548    end;
549encode_integer(C,V,_NamedNumberList) when integer(V) ->
550    encode_integer(C,V);
551encode_integer(C,{Name,V},NamedNumberList) when atom(Name) ->
552    encode_integer(C,V,NamedNumberList).
553
554encode_integer(C,{Name,Val}) when atom(Name) ->
555    encode_integer(C,Val);
556
557encode_integer([{Rc,_Ec}],Val) when tuple(Rc) -> % XXX when is this invoked? First argument most often a list,...Ok this is the extension case...but it doesn't work.
558    case (catch encode_integer([Rc],Val)) of
559	{'EXIT',{error,{asn1,_}}} ->
560%	    [{bits,1,1},encode_unconstrained_number(Val)];
561	    [1,encode_unconstrained_number(Val)];
562	Encoded ->
563%	    [{bits,1,0},Encoded]
564	    [0,Encoded]
565    end;
566
567encode_integer([],Val) ->
568    encode_unconstrained_number(Val);
569%% The constraint is the effective constraint, and in this case is a number
570encode_integer([{'SingleValue',V}],V) ->
571    [];
572encode_integer([{'ValueRange',VR={Lb,Ub},Range,PreEnc}],Val) when Val >= Lb,
573						Ub >= Val ->
574    %% this case when NamedNumberList
575    encode_constrained_number(VR,Range,PreEnc,Val);
576encode_integer([{'ValueRange',{Lb,'MAX'}}],Val) ->
577    encode_semi_constrained_number(Lb,Val);
578encode_integer([{'ValueRange',{'MIN',_}}],Val) ->
579    encode_unconstrained_number(Val);
580encode_integer([{'ValueRange',VR={_Lb,_Ub}}],Val) ->
581    encode_constrained_number(VR,Val);
582encode_integer(_,Val) ->
583    exit({error,{asn1,{illegal_value,Val}}}).
584
585
586
587decode_integer(Buffer,Range,NamedNumberList) ->
588    {Val,Buffer2} = decode_integer(Buffer,Range),
589    case lists:keysearch(Val,2,NamedNumberList) of
590	{value,{NewVal,_}} -> {NewVal,Buffer2};
591	_ -> {Val,Buffer2}
592    end.
593
594decode_integer(Buffer,[{Rc,_Ec}]) when tuple(Rc) ->
595    {Ext,Buffer2} = getext(Buffer),
596    case Ext of
597	0 -> decode_integer(Buffer2,[Rc]);
598	1 -> decode_unconstrained_number(Buffer2)
599    end;
600decode_integer(Buffer,undefined) ->
601    decode_unconstrained_number(Buffer);
602decode_integer(Buffer,C) ->
603    case get_constraint(C,'SingleValue') of
604	V when integer(V) ->
605	    {V,Buffer};
606	_ ->
607	    decode_integer1(Buffer,C)
608    end.
609
610decode_integer1(Buffer,C) ->
611    case VR = get_constraint(C,'ValueRange') of
612	no ->
613	    decode_unconstrained_number(Buffer);
614	{Lb, 'MAX'} ->
615	    decode_semi_constrained_number(Buffer,Lb);
616	{_Lb,_Ub} ->
617	    decode_constrained_number(Buffer,VR)
618    end.
619
620%% X.691:10.6 Encoding of a normally small non-negative whole number
621%% Use this for encoding of CHOICE index if there is an extension marker in
622%% the CHOICE
623encode_small_number({Name,Val}) when atom(Name) ->
624    encode_small_number(Val);
625encode_small_number(Val) when Val =< 63 ->
626%    [{bits,1,0},{bits,6,Val}];
627%    [{bits,7,Val}]; % same as above but more efficient
628    [10,7,Val]; % same as above but more efficient
629encode_small_number(Val) ->
630%    [{bits,1,1},encode_semi_constrained_number(0,Val)].
631    [1,encode_semi_constrained_number(0,Val)].
632
633decode_small_number(Bytes) ->
634    {Bit,Bytes2} = getbit(Bytes),
635    case Bit of
636	0 ->
637	    getbits(Bytes2,6);
638	1 ->
639	    decode_semi_constrained_number(Bytes2,0)
640    end.
641
642%% X.691:10.7 Encoding of a semi-constrained whole number
643%% might be an optimization encode_semi_constrained_number(0,Val) ->
644encode_semi_constrained_number(C,{Name,Val}) when atom(Name) ->
645    encode_semi_constrained_number(C,Val);
646encode_semi_constrained_number({Lb,'MAX'},Val) ->
647    encode_semi_constrained_number(Lb,Val);
648encode_semi_constrained_number(Lb,Val) ->
649    Val2 = Val - Lb,
650    Oct = eint_positive(Val2),
651    Len = length(Oct),
652    if
653	Len < 128 ->
654	    %{octets,[Len|Oct]}; % equiv with encode_length(undefined,Len) but faster
655	    [20,Len+1,[Len|Oct]];
656	Len < 256 ->
657	    [encode_length(undefined,Len),[20,Len,Oct]];
658	true ->
659	    [encode_length(undefined,Len),[21,<<Len:16>>,Oct]]
660    end.
661
662decode_semi_constrained_number(Bytes,{Lb,_}) ->
663    decode_semi_constrained_number(Bytes,Lb);
664decode_semi_constrained_number(Bytes,Lb) ->
665    {Len,Bytes2} = decode_length(Bytes,undefined),
666    {V,Bytes3} = getoctets(Bytes2,Len),
667    {V+Lb,Bytes3}.
668
669encode_constrained_number({Lb,_Ub},_Range,{bits,N},Val) ->
670    Val2 = Val-Lb,
671%    {bits,N,Val2};
672    [10,N,Val2];
673encode_constrained_number({Lb,_Ub},_Range,{octets,N},Val) when N < 256->
674    %% N is 8 or 16 (1 or 2 octets)
675    Val2 = Val-Lb,
676%    {octets,<<Val2:N/unit:8>>};
677    [20,N,Val2];
678encode_constrained_number({Lb,_Ub},_Range,{octets,N},Val) -> % N>255
679    %% N is 8 or 16 (1 or 2 octets)
680    Val2 = Val-Lb,
681%    {octets,<<Val2:N/unit:8>>};
682    [21,<<N:16>>,Val2];
683encode_constrained_number({Lb,_Ub},Range,_,Val) ->
684    Val2 = Val-Lb,
685    if
686	Range =< 16#1000000  -> % max 3 octets
687	    Octs = eint_positive(Val2),
688%	    [encode_length({1,3},size(Octs)),{octets,Octs}];
689	    L = length(Octs),
690	    [encode_length({1,3},L),[20,L,Octs]];
691	Range =< 16#100000000  -> % max 4 octets
692	    Octs = eint_positive(Val2),
693%	    [encode_length({1,4},size(Octs)),{octets,Octs}];
694	    L = length(Octs),
695	    [encode_length({1,4},L),[20,L,Octs]];
696	Range =< 16#10000000000  -> % max 5 octets
697	    Octs = eint_positive(Val2),
698%	    [encode_length({1,5},size(Octs)),{octets,Octs}];
699	    L = length(Octs),
700	    [encode_length({1,5},L),[20,L,Octs]];
701	true  ->
702	    exit({not_supported,{integer_range,Range}})
703    end.
704
705encode_constrained_number(Range,{Name,Val}) when atom(Name) ->
706    encode_constrained_number(Range,Val);
707encode_constrained_number({Lb,Ub},Val) when Val >= Lb, Ub >= Val ->
708    Range = Ub - Lb + 1,
709    Val2 = Val - Lb,
710    if
711	Range  == 2 ->
712%	    Size = {bits,1,Val2};
713	    [Val2];
714	Range  =< 4 ->
715%	    Size = {bits,2,Val2};
716	    [10,2,Val2];
717	Range  =< 8 ->
718	    [10,3,Val2];
719	Range  =< 16 ->
720	    [10,4,Val2];
721	Range  =< 32 ->
722	    [10,5,Val2];
723	Range  =< 64 ->
724	    [10,6,Val2];
725	Range  =< 128 ->
726	    [10,7,Val2];
727	Range  =< 255 ->
728	    [10,8,Val2];
729	Range  =< 256 ->
730%	    Size = {octets,[Val2]};
731	    [20,1,Val2];
732	Range  =< 65536 ->
733%	    Size = {octets,<<Val2:16>>};
734	    [20,2,<<Val2:16>>];
735	Range =< 16#1000000  ->
736	    Octs = eint_positive(Val2),
737%	    [{bits,2,length(Octs)-1},{octets,Octs}];
738	    Len = length(Octs),
739	    [10,2,Len-1,20,Len,Octs];
740	Range =< 16#100000000  ->
741	    Octs = eint_positive(Val2),
742	    Len = length(Octs),
743	    [10,2,Len-1,20,Len,Octs];
744	Range =< 16#10000000000  ->
745	    Octs = eint_positive(Val2),
746	    Len = length(Octs),
747	    [10,3,Len-1,20,Len,Octs];
748	true  ->
749	    exit({not_supported,{integer_range,Range}})
750    end;
751encode_constrained_number({_,_},Val) ->
752    exit({error,{asn1,{illegal_value,Val}}}).
753
754decode_constrained_number(Buffer,VR={Lb,Ub}) ->
755    Range = Ub - Lb + 1,
756    decode_constrained_number(Buffer,VR,Range).
757
758decode_constrained_number(Buffer,{Lb,_Ub},_Range,{bits,N}) ->
759    {Val,Remain} = getbits(Buffer,N),
760    {Val+Lb,Remain};
761decode_constrained_number(Buffer,{Lb,_Ub},_Range,{octets,N}) ->
762    {Val,Remain} = getoctets(Buffer,N),
763    {Val+Lb,Remain}.
764
765decode_constrained_number(Buffer,{Lb,_Ub},Range) ->
766						%    Val2 = Val - Lb,
767    {Val,Remain} =
768	if
769	    Range  == 2 ->
770		getbits(Buffer,1);
771	    Range  =< 4 ->
772		getbits(Buffer,2);
773	    Range  =< 8 ->
774		getbits(Buffer,3);
775	    Range  =< 16 ->
776		getbits(Buffer,4);
777	    Range  =< 32 ->
778		getbits(Buffer,5);
779	    Range  =< 64 ->
780		getbits(Buffer,6);
781	    Range  =< 128 ->
782		getbits(Buffer,7);
783	    Range  =< 255 ->
784		getbits(Buffer,8);
785	    Range  =< 256 ->
786		getoctets(Buffer,1);
787	    Range  =< 65536 ->
788		getoctets(Buffer,2);
789	    Range =< 16#1000000  ->
790		{Len,Bytes2} = decode_length(Buffer,{1,3}),
791		{Octs,Bytes3} = getoctets_as_list(Bytes2,Len),
792		{dec_pos_integer(Octs),Bytes3};
793	    Range =< 16#100000000  ->
794		{Len,Bytes2} = decode_length(Buffer,{1,4}),
795		{Octs,Bytes3} = getoctets_as_list(Bytes2,Len),
796		{dec_pos_integer(Octs),Bytes3};
797	    Range =< 16#10000000000  ->
798		{Len,Bytes2} = decode_length(Buffer,{1,5}),
799		{Octs,Bytes3} = getoctets_as_list(Bytes2,Len),
800		{dec_pos_integer(Octs),Bytes3};
801	    true  ->
802		exit({not_supported,{integer_range,Range}})
803	end,
804    {Val+Lb,Remain}.
805
806%% X.691:10.8 Encoding of an unconstrained whole number
807
808encode_unconstrained_number(Val) when Val >= 0 ->
809    Oct = eint(Val,[]),
810    Len = length(Oct),
811    if
812	Len < 128 ->
813	    %{octets,[Len|Oct]}; % equiv with encode_length(undefined,Len) but faster
814	    [20,Len+1,[Len|Oct]];
815	Len < 256 ->
816%	    [encode_length(undefined,Len),20,Len,Oct];
817	    [20,Len+2,<<2:2,Len:14>>,Oct];% equiv with encode_length(undefined,Len) but faster
818	true ->
819%	    [encode_length(undefined,Len),{octets,Oct}]
820	    [encode_length(undefined,Len),[21,<<Len:16>>,Oct]]
821    end;
822encode_unconstrained_number(Val) -> % negative
823    Oct = enint(Val,[]),
824    Len = length(Oct),
825    if
826	Len < 128 ->
827%	    {octets,[Len|Oct]}; % equiv with encode_length(undefined,Len) but faster
828	    [20,Len+1,[Len|Oct]];% equiv with encode_length(undefined,Len) but faster
829	Len < 256 ->
830%	    [encode_length(undefined,Len),20,Len,Oct];
831	    [20,Len+2,<<2:2,Len:14>>,Oct];% equiv with encode_length(undefined,Len) but faster
832	true ->
833	    %[encode_length(undefined,Len),{octets,Oct}]
834	    [encode_length(undefined,Len),[21,<<Len:16>>,Oct]]
835    end.
836
837
838%% used for positive Values which don't need a sign bit
839%% returns a list
840eint_positive(Val) ->
841    case eint(Val,[]) of
842	[0,B1|T] ->
843	    [B1|T];
844	T ->
845	    T
846    end.
847
848
849eint(0, [B|Acc]) when B < 128 ->
850    [B|Acc];
851eint(N, Acc) ->
852    eint(N bsr 8, [N band 16#ff| Acc]).
853
854enint(-1, [B1|T]) when B1 > 127 ->
855    [B1|T];
856enint(N, Acc) ->
857    enint(N bsr 8, [N band 16#ff|Acc]).
858
859decode_unconstrained_number(Bytes) ->
860    {Len,Bytes2} = decode_length(Bytes,undefined),
861    {Ints,Bytes3} = getoctets_as_list(Bytes2,Len),
862    {dec_integer(Ints),Bytes3}.
863
864dec_pos_integer(Ints) ->
865    decpint(Ints, 8 * (length(Ints) - 1)).
866dec_integer(Ints) when hd(Ints) band 255 =< 127 -> %% Positive number
867    decpint(Ints, 8 * (length(Ints) - 1));
868dec_integer(Ints) ->                        %% Negative
869    decnint(Ints,  8 * (length(Ints) - 1)).
870
871decpint([Byte|Tail], Shift) ->
872    (Byte bsl Shift) bor decpint(Tail, Shift-8);
873decpint([], _) -> 0.
874
875decnint([Byte|Tail], Shift) ->
876    (-128 + (Byte band 127) bsl Shift) bor decpint(Tail, Shift-8).
877
878% minimum_octets(Val) ->
879%     minimum_octets(Val,[]).
880
881% minimum_octets(Val,Acc) when Val > 0 ->
882%     minimum_octets((Val bsr 8),[Val band 16#FF|Acc]);
883% minimum_octets(0,Acc) ->
884%     Acc.
885
886
887%% X.691:10.9 Encoding of a length determinant
888%%encode_small_length(undefined,Len) -> % null means no UpperBound
889%%    encode_small_number(Len).
890
891%% X.691:10.9.3.5
892%% X.691:10.9.3.7
893encode_length(undefined,Len) -> % un-constrained
894    if
895	Len < 128 ->
896%	    {octets,[Len]};
897	    [20,1,Len];
898	Len < 16384 ->
899	    %{octets,<<2:2,Len:14>>};
900	    [20,2,<<2:2,Len:14>>];
901	true  -> % should be able to endode length >= 16384 i.e. fragmented length
902	    exit({error,{asn1,{encode_length,{nyi,above_16k}}}})
903    end;
904
905encode_length({0,'MAX'},Len) ->
906    encode_length(undefined,Len);
907encode_length(Vr={Lb,Ub},Len) when Ub =< 65535 ,Lb >= 0 -> % constrained
908    encode_constrained_number(Vr,Len);
909encode_length({Lb,_Ub},Len) when integer(Lb), Lb >= 0 -> % Ub > 65535
910    encode_length(undefined,Len);
911encode_length({Vr={Lb,Ub},[]},Len) when Ub =< 65535 ,Lb >= 0,Len=<Ub ->
912    %% constrained extensible
913%    [{bits,1,0},encode_constrained_number(Vr,Len)];
914    [0,encode_constrained_number(Vr,Len)];
915encode_length({{Lb,_},[]},Len) ->
916    [1,encode_semi_constrained_number(Lb,Len)];
917encode_length(SingleValue,_Len) when integer(SingleValue) ->
918    [].
919
920%% X.691 10.9.3.4 (only used for length of bitmap that prefixes extension
921%% additions in a sequence or set
922encode_small_length(Len) when Len =< 64 ->
923%%    [{bits,1,0},{bits,6,Len-1}];
924%    {bits,7,Len-1}; % the same as above but more efficient
925    [10,7,Len-1];
926encode_small_length(Len) ->
927%    [{bits,1,1},encode_length(undefined,Len)].
928    [1,encode_length(undefined,Len)].
929
930% decode_small_length({Used,<<_:Used,0:1,Num:6,_:((8-Used+1) rem 8),Rest/binary>>}) ->
931%     case Buffer of
932% 	<<_:Used,0:1,Num:6,_:((8-Used+1) rem 8),Rest/binary>> ->
933% 	    {Num,
934%     case getbit(Buffer) of
935% 	{0,Remain} ->
936% 	    {Bits,Remain2} = getbits(Remain,6),
937% 	    {Bits+1,Remain2};
938% 	{1,Remain} ->
939% 	    decode_length(Remain,undefined)
940%     end.
941
942decode_small_length(Buffer) ->
943    case getbit(Buffer) of
944	{0,Remain} ->
945	    {Bits,Remain2} = getbits(Remain,6),
946	    {Bits+1,Remain2};
947	{1,Remain} ->
948	    decode_length(Remain,undefined)
949    end.
950
951decode_length(Buffer) ->
952    decode_length(Buffer,undefined).
953
954decode_length(Buffer,undefined)  -> % un-constrained
955    {0,Buffer2} = align(Buffer),
956    case Buffer2 of
957	<<0:1,Oct:7,Rest/binary>> ->
958	    {Oct,{0,Rest}};
959	<<2:2,Val:14,Rest/binary>> ->
960	    {Val,{0,Rest}};
961	<<3:2,_Val:14,_Rest/binary>> ->
962	    %% this case should be fixed
963	    exit({error,{asn1,{decode_length,{nyi,above_16k}}}})
964    end;
965%%    {Bits,_} = getbits(Buffer2,2),
966%     case Bits of
967% 	2 ->
968% 	    {Val,Bytes3} = getoctets(Buffer2,2),
969% 	    {(Val band 16#3FFF),Bytes3};
970% 	3 ->
971% 	    exit({error,{asn1,{decode_length,{nyi,above_16k}}}});
972% 	_ ->
973% 	    {Val,Bytes3} = getoctet(Buffer2),
974% 	    {Val band 16#7F,Bytes3}
975%     end;
976
977decode_length(Buffer,{Lb,Ub}) when Ub =< 65535 ,Lb >= 0 -> % constrained
978    decode_constrained_number(Buffer,{Lb,Ub});
979decode_length(_Buffer,{Lb,_Ub}) when integer(Lb), Lb >= 0 -> % Ub > 65535
980    exit({error,{asn1,{decode_length,{nyi,above_64K}}}});
981decode_length(Buffer,{{Lb,Ub},[]}) ->
982    case getbit(Buffer) of
983	{0,Buffer2} ->
984	    decode_length(Buffer2, {Lb,Ub})
985    end;
986
987
988%When does this case occur with {_,_Lb,Ub} ??
989% X.691:10.9.3.5
990decode_length({Used,Bin},{_,_Lb,_Ub}) -> %when Len =< 127 -> % Unconstrained or large Ub NOTE! this case does not cover case when Ub > 65535
991    Unused = (8-Used) rem 8,
992    case Bin of
993	<<_:Used,0:1,Val:7,R:Unused,Rest/binary>> ->
994	    {Val,{Used,<<R,Rest/binary>>}};
995	<<_:Used,_:Unused,2:2,Val:14,Rest/binary>> ->
996	    {Val, {0,Rest}};
997	<<_:Used,_:Unused,3:2,_:14,_Rest/binary>> ->
998	    exit({error,{asn1,{decode_length,{nyi,length_above_64K}}}})
999    end;
1000% decode_length(Buffer,{_,_Lb,Ub}) -> %when Len =< 127 -> % Unconstrained or large Ub
1001%     case getbit(Buffer) of
1002% 	{0,Remain} ->
1003% 	    getbits(Remain,7);
1004% 	{1,Remain} ->
1005% 	    {Val,Remain2} = getoctets(Buffer,2),
1006% 	    {Val band 2#0111111111111111, Remain2}
1007%     end;
1008decode_length(Buffer,SingleValue) when integer(SingleValue) ->
1009    {SingleValue,Buffer}.
1010
1011
1012						% X.691:11
1013decode_boolean(Buffer) -> %when record(Buffer,buffer)
1014    case getbit(Buffer) of
1015	{1,Remain} -> {true,Remain};
1016	{0,Remain} -> {false,Remain}
1017    end.
1018
1019
1020%% ENUMERATED with extension marker
1021decode_enumerated(Buffer,C,{Ntup1,Ntup2}) when tuple(Ntup1), tuple(Ntup2) ->
1022    {Ext,Buffer2} = getext(Buffer),
1023    case Ext of
1024	0 -> % not an extension value
1025	    {Val,Buffer3} = decode_integer(Buffer2,C),
1026	    case catch (element(Val+1,Ntup1)) of
1027		NewVal when atom(NewVal) -> {NewVal,Buffer3};
1028		_Error -> exit({error,{asn1,{decode_enumerated,{Val,[Ntup1,Ntup2]}}}})
1029	    end;
1030	1 -> % this an extension value
1031	    {Val,Buffer3} = decode_small_number(Buffer2),
1032	    case catch (element(Val+1,Ntup2)) of
1033		NewVal when atom(NewVal) -> {NewVal,Buffer3};
1034		_ -> {{asn1_enum,Val},Buffer3}
1035	    end
1036    end;
1037
1038decode_enumerated(Buffer,C,NamedNumberTup) when tuple(NamedNumberTup) ->
1039    {Val,Buffer2} = decode_integer(Buffer,C),
1040    case catch (element(Val+1,NamedNumberTup)) of
1041	NewVal when atom(NewVal) -> {NewVal,Buffer2};
1042	_Error -> exit({error,{asn1,{decode_enumerated,{Val,NamedNumberTup}}}})
1043    end.
1044
1045%%===============================================================================
1046%%===============================================================================
1047%%===============================================================================
1048%% Bitstring value, ITU_T X.690 Chapter 8.5
1049%%===============================================================================
1050%%===============================================================================
1051%%===============================================================================
1052
1053%%===============================================================================
1054%% encode bitstring value
1055%%===============================================================================
1056
1057
1058
1059%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1060%% bitstring NamedBitList
1061%% Val can be  of:
1062%% - [identifiers] where only named identifiers are set to one,
1063%%   the Constraint must then have some information of the
1064%%   bitlength.
1065%% - [list of ones and zeroes] all bits
1066%% - integer value representing the bitlist
1067%% C is constraint Len, only valid when identifiers
1068
1069
1070%% when the value is a list of {Unused,BinBits}, where
1071%% Unused = integer(),
1072%% BinBits = binary().
1073
1074encode_bit_string(C,Bin={Unused,BinBits},NamedBitList) when integer(Unused),
1075							    binary(BinBits) ->
1076    encode_bin_bit_string(C,Bin,NamedBitList);
1077
1078%% when the value is a list of named bits
1079
1080encode_bit_string(C, LoNB=[FirstVal | _RestVal], NamedBitList) when atom(FirstVal) ->
1081    ToSetPos = get_all_bitposes(LoNB, NamedBitList, []),
1082    BitList = make_and_set_list(ToSetPos,0),
1083    encode_bit_string(C,BitList,NamedBitList);% consider the constraint
1084
1085encode_bit_string(C, BL=[{bit,_} | _RestVal], NamedBitList) ->
1086    ToSetPos = get_all_bitposes(BL, NamedBitList, []),
1087    BitList = make_and_set_list(ToSetPos,0),
1088    encode_bit_string(C,BitList,NamedBitList);
1089
1090%% when the value is a list of ones and zeroes
1091encode_bit_string(Int, BitListValue, _)
1092  when list(BitListValue),integer(Int) ->
1093    %% The type is constrained by a single value size constraint
1094    [40,Int,length(BitListValue),BitListValue];
1095% encode_bit_string(C, BitListValue,NamedBitList)
1096%   when list(BitListValue) ->
1097%     [encode_bit_str_length(C,BitListValue),
1098%      2,45,BitListValue];
1099encode_bit_string(no, BitListValue,[])
1100  when list(BitListValue) ->
1101    [encode_length(undefined,length(BitListValue)),
1102     2,BitListValue];
1103encode_bit_string(C, BitListValue,[])
1104  when list(BitListValue) ->
1105    [encode_length(C,length(BitListValue)),
1106     2,BitListValue];
1107encode_bit_string(no, BitListValue,_NamedBitList)
1108  when list(BitListValue) ->
1109    %% this case with an unconstrained BIT STRING can be made more efficient
1110    %% if the complete driver can take a special code so the length field
1111    %% is encoded there.
1112    NewBitLVal = lists:reverse(lists:dropwhile(fun(0)->true;(1)->false end,
1113					    lists:reverse(BitListValue))),
1114    [encode_length(undefined,length(NewBitLVal)),
1115     2,NewBitLVal];
1116encode_bit_string(C,BitListValue,_NamedBitList)
1117  when list(BitListValue) ->% C = {_,'MAX'}
1118%     NewBitLVal = lists:reverse(lists:dropwhile(fun(0)->true;(1)->false end,
1119% 					    lists:reverse(BitListValue))),
1120    NewBitLVal = bit_string_trailing_zeros(BitListValue,C),
1121    [encode_length(C,length(NewBitLVal)),
1122     2,NewBitLVal];
1123
1124% encode_bit_string(C, BitListValue, NamedBitList) when list(BitListValue) ->
1125%     BitListToBinary =
1126% 	%% fun that transforms a list of 1 and 0 to a tuple:
1127% 	%% {UnusedBitsInLastByte, Binary}
1128% 	fun([H|T],Acc,N,Fun) ->
1129% 		Fun(T,(Acc bsl 1)+H,N+1,Fun);
1130% 	   ([],Acc,N,_) -> % length fits in one byte
1131% 		Unused = (8 - (N rem 8)) rem 8,
1132% % 		case N/8 of
1133% % 		    _Len =< 255 ->
1134% % 			[30,Unused,(Unused+N)/8,<<Acc:N,0:Unused>>];
1135% % 		    _Len ->
1136% % 			Len = (Unused+N)/8,
1137% % 			[31,Unused,<<Len:16>>,<<Acc:N,0:Unused>>]
1138% % 		end
1139% 		{Unused,<<Acc:N,0:Unused>>}
1140% 	end,
1141%     UnusedAndBin =
1142% 	case NamedBitList of
1143% 	    [] ->  % dont remove trailing zeroes
1144% 		BitListToBinary(BitListValue,0,0,BitListToBinary);
1145% 	    _ ->
1146% 		BitListToBinary(lists:reverse(
1147% 				  lists:dropwhile(fun(0)->true;(1)->false end,
1148% 						  lists:reverse(BitListValue))),
1149% 				0,0,BitListToBinary)
1150% 	end,
1151%     encode_bin_bit_string(C,UnusedAndBin,NamedBitList);
1152
1153%% when the value is an integer
1154encode_bit_string(C, IntegerVal, NamedBitList) when integer(IntegerVal)->
1155    BitList = int_to_bitlist(IntegerVal),
1156    encode_bit_string(C,BitList,NamedBitList);
1157
1158%% when the value is a tuple
1159encode_bit_string(C,{Name,Val}, NamedBitList) when atom(Name) ->
1160    encode_bit_string(C,Val,NamedBitList).
1161
1162bit_string_trailing_zeros(BitList,C) when integer(C) ->
1163    bit_string_trailing_zeros1(BitList,C,C);
1164bit_string_trailing_zeros(BitList,{Lb,Ub}) when integer(Lb) ->
1165    bit_string_trailing_zeros1(BitList,Lb,Ub);
1166bit_string_trailing_zeros(BitList,{{Lb,Ub},_}) when integer(Lb) ->
1167    bit_string_trailing_zeros1(BitList,Lb,Ub);
1168bit_string_trailing_zeros(BitList,_) ->
1169    BitList.
1170
1171bit_string_trailing_zeros1(BitList,Lb,Ub) ->
1172    case length(BitList) of
1173	Lb -> BitList;
1174	B when B<Lb -> BitList++lists:duplicate(Lb-B,0);
1175	D -> F = fun(L,LB,LB,_,_)->lists:reverse(L);
1176		    ([0|R],L1,LB,UB,Fun)->Fun(R,L1-1,LB,UB,Fun);
1177		    (L,L1,_,UB,_)when L1 =< UB -> lists:reverse(L);
1178		    (_,_L1,_,_,_) ->exit({error,{list_length_BIT_STRING,
1179						 BitList}}) end,
1180	     F(lists:reverse(BitList),D,Lb,Ub,F)
1181    end.
1182
1183%% encode_bin_bit_string/3, when value is a tuple of Unused and BinBits.
1184%% Unused = integer(),i.e. number unused bits in least sign. byte of
1185%% BinBits = binary().
1186encode_bin_bit_string(C,{_,BinBits},_NamedBitList)
1187  when integer(C),C=<16 ->
1188    [45,C,size(BinBits),BinBits];
1189encode_bin_bit_string(C,{_Unused,BinBits},_NamedBitList)
1190  when integer(C) ->
1191    [2,45,C,size(BinBits),BinBits];
1192encode_bin_bit_string(C,UnusedAndBin={_,_},NamedBitList) ->
1193%    UnusedAndBin1 = {Unused1,Bin1} =
1194    {Unused1,Bin1} =
1195	%% removes all trailing bits if NamedBitList is not empty
1196	remove_trailing_bin(NamedBitList,UnusedAndBin),
1197    case C of
1198%    case get_constraint(C,'SizeConstraint') of
1199
1200% 	0 ->
1201% 	    []; % should be dont in compile time
1202% 	V when integer(V),V=<16 ->
1203% 	    {Unused2,Bin2} = pad_list(V,UnusedAndBin1),
1204% 	    <<BitVal:V,_:Unused2>> = Bin2,
1205% %	    {bits,V,BitVal};
1206% 	    [10,V,BitVal];
1207% 	V when integer(V) ->
1208% 	    %[align, pad_list(V, UnusedAndBin1)];
1209% 	    {Unused2,Bin2} = pad_list(V, UnusedAndBin1),
1210% 	    <<BitVal:V,_:Unused2>> = Bin2,
1211% 	    [2,octets_unused_to_complete(Unused2,size(Bin2),Bin2)];
1212
1213	{Lb,Ub} when integer(Lb),integer(Ub) ->
1214%	    [encode_length({Lb,Ub},size(Bin1)*8 - Unused1),
1215%	     align,UnusedAndBin1];
1216	    Size=size(Bin1),
1217	    [encode_length({Lb,Ub},Size*8 - Unused1),
1218	     2,octets_unused_to_complete(Unused1,Size,Bin1)];
1219	no ->
1220	    Size=size(Bin1),
1221	    [encode_length(undefined,Size*8 - Unused1),
1222	     2,octets_unused_to_complete(Unused1,Size,Bin1)];
1223	Sc ->
1224	    Size=size(Bin1),
1225	    [encode_length(Sc,Size*8 - Unused1),
1226	     2,octets_unused_to_complete(Unused1,Size,Bin1)]
1227    end.
1228
1229remove_trailing_bin([], {Unused,Bin}) ->
1230    {Unused,Bin};
1231remove_trailing_bin(NamedNumberList, {_Unused,Bin}) ->
1232    Size = size(Bin)-1,
1233    <<Bfront:Size/binary, LastByte:8>> = Bin,
1234    %% clear the Unused bits to be sure
1235%    LastByte1 = LastByte band (((1 bsl Unused) -1) bxor 255),% why this???
1236    Unused1 = trailingZeroesInNibble(LastByte band 15),
1237    Unused2 =
1238	case Unused1 of
1239	    4 ->
1240		4 + trailingZeroesInNibble(LastByte bsr 4);
1241	    _ -> Unused1
1242	end,
1243    case Unused2 of
1244	8 ->
1245	    remove_trailing_bin(NamedNumberList,{0,Bfront});
1246	_ ->
1247	    {Unused2,Bin}
1248    end.
1249
1250
1251trailingZeroesInNibble(0) ->
1252    4;
1253trailingZeroesInNibble(1) ->
1254    0;
1255trailingZeroesInNibble(2) ->
1256    1;
1257trailingZeroesInNibble(3) ->
1258    0;
1259trailingZeroesInNibble(4) ->
1260    2;
1261trailingZeroesInNibble(5) ->
1262    0;
1263trailingZeroesInNibble(6) ->
1264    1;
1265trailingZeroesInNibble(7) ->
1266    0;
1267trailingZeroesInNibble(8) ->
1268    3;
1269trailingZeroesInNibble(9) ->
1270    0;
1271trailingZeroesInNibble(10) ->
1272    1;
1273trailingZeroesInNibble(11) ->
1274    0;
1275trailingZeroesInNibble(12) -> %#1100
1276    2;
1277trailingZeroesInNibble(13) ->
1278    0;
1279trailingZeroesInNibble(14) ->
1280    1;
1281trailingZeroesInNibble(15) ->
1282    0.
1283
1284%%%%%%%%%%%%%%%
1285%% The result is presented as a list of named bits (if possible)
1286%% else as a tuple {Unused,Bits}. Unused is the number of unused
1287%% bits, least significant bits in the last byte of Bits. Bits is
1288%% the BIT STRING represented as a binary.
1289%%
1290decode_compact_bit_string(Buffer, C, NamedNumberList) ->
1291    case get_constraint(C,'SizeConstraint') of
1292	0 -> % fixed length
1293	    {{8,0},Buffer};
1294	V when integer(V),V=<16 -> %fixed length 16 bits or less
1295	    compact_bit_string(Buffer,V,NamedNumberList);
1296	V when integer(V),V=<65536 -> %fixed length > 16 bits
1297	    Bytes2 = align(Buffer),
1298	    compact_bit_string(Bytes2,V,NamedNumberList);
1299	V when integer(V) -> % V > 65536 => fragmented value
1300	    {Bin,Buffer2} = decode_fragmented_bits(Buffer,V),
1301	    case Buffer2 of
1302		{0,_} -> {{0,Bin},Buffer2};
1303		{U,_} -> {{8-U,Bin},Buffer2}
1304	    end;
1305	{Lb,Ub} when integer(Lb),integer(Ub) ->
1306	    %% This case may demand decoding of fragmented length/value
1307	    {Len,Bytes2} = decode_length(Buffer,{Lb,Ub}),
1308	    Bytes3 = align(Bytes2),
1309	    compact_bit_string(Bytes3,Len,NamedNumberList);
1310	no ->
1311	    %% This case may demand decoding of fragmented length/value
1312	    {Len,Bytes2} = decode_length(Buffer,undefined),
1313	    Bytes3 = align(Bytes2),
1314	    compact_bit_string(Bytes3,Len,NamedNumberList);
1315	Sc ->
1316	    {Len,Bytes2} = decode_length(Buffer,Sc),
1317	    Bytes3 = align(Bytes2),
1318	    compact_bit_string(Bytes3,Len,NamedNumberList)
1319    end.
1320
1321
1322%%%%%%%%%%%%%%%
1323%% The result is presented as a list of named bits (if possible)
1324%% else as a list of 0 and 1.
1325%%
1326decode_bit_string(Buffer, C, NamedNumberList) ->
1327    case get_constraint(C,'SizeConstraint') of
1328	{Lb,Ub} when integer(Lb),integer(Ub) ->
1329	    {Len,Bytes2} = decode_length(Buffer,{Lb,Ub}),
1330	    Bytes3 = align(Bytes2),
1331	    bit_list_or_named(Bytes3,Len,NamedNumberList);
1332	no ->
1333	    {Len,Bytes2} = decode_length(Buffer,undefined),
1334	    Bytes3 = align(Bytes2),
1335	    bit_list_or_named(Bytes3,Len,NamedNumberList);
1336	0 -> % fixed length
1337	    {[],Buffer}; % nothing to encode
1338	V when integer(V),V=<16 -> % fixed length 16 bits or less
1339	    bit_list_or_named(Buffer,V,NamedNumberList);
1340	V when integer(V),V=<65536 ->
1341	    Bytes2 = align(Buffer),
1342	    bit_list_or_named(Bytes2,V,NamedNumberList);
1343	V when integer(V) ->
1344	    Bytes2 = align(Buffer),
1345	    {BinBits,_Bytes3} = decode_fragmented_bits(Bytes2,V),
1346	    bit_list_or_named(BinBits,V,NamedNumberList);
1347	Sc -> % extension marker
1348	    {Len,Bytes2} = decode_length(Buffer,Sc),
1349	    Bytes3 = align(Bytes2),
1350	    bit_list_or_named(Bytes3,Len,NamedNumberList)
1351    end.
1352
1353
1354%% if no named bits are declared we will return a
1355%% {Unused,Bits}. Unused = integer(),
1356%% Bits = binary().
1357compact_bit_string(Buffer,Len,[]) ->
1358    getbits_as_binary(Len,Buffer); % {{Unused,BinBits},NewBuffer}
1359compact_bit_string(Buffer,Len,NamedNumberList) ->
1360    bit_list_or_named(Buffer,Len,NamedNumberList).
1361
1362
1363%% if no named bits are declared we will return a
1364%% BitList = [0 | 1]
1365
1366bit_list_or_named(Buffer,Len,[]) ->
1367    getbits_as_list(Len,Buffer);
1368
1369%% if there are named bits declared we will return a named
1370%% BitList where the names are atoms and unnamed bits represented
1371%% as {bit,Pos}
1372%% BitList = [atom() | {bit,Pos}]
1373%% Pos = integer()
1374
1375bit_list_or_named(Buffer,Len,NamedNumberList) ->
1376    {BitList,Rest} = getbits_as_list(Len,Buffer),
1377    {bit_list_or_named1(0,BitList,NamedNumberList,[]), Rest}.
1378
1379bit_list_or_named1(Pos,[0|Bt],Names,Acc) ->
1380    bit_list_or_named1(Pos+1,Bt,Names,Acc);
1381bit_list_or_named1(Pos,[1|Bt],Names,Acc) ->
1382    case lists:keysearch(Pos,2,Names) of
1383	{value,{Name,_}} ->
1384	    bit_list_or_named1(Pos+1,Bt,Names,[Name|Acc]);
1385	_  ->
1386	    bit_list_or_named1(Pos+1,Bt,Names,[{bit,Pos}|Acc])
1387    end;
1388bit_list_or_named1(_Pos,[],_Names,Acc) ->
1389    lists:reverse(Acc).
1390
1391
1392
1393%%%%%%%%%%%%%%%
1394%%
1395
1396int_to_bitlist(Int) when integer(Int), Int > 0 ->
1397    [Int band 1 | int_to_bitlist(Int bsr 1)];
1398int_to_bitlist(0) ->
1399    [].
1400
1401
1402%%%%%%%%%%%%%%%%%%
1403%% get_all_bitposes([list of named bits to set], named_bit_db, []) ->
1404%%   [sorted_list_of_bitpositions_to_set]
1405
1406get_all_bitposes([{bit,ValPos}|Rest], NamedBitList, Ack) ->
1407    get_all_bitposes(Rest, NamedBitList, [ValPos | Ack ]);
1408
1409get_all_bitposes([Val | Rest], NamedBitList, Ack) ->
1410    case lists:keysearch(Val, 1, NamedBitList) of
1411	{value, {_ValName, ValPos}} ->
1412	    get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]);
1413	_ ->
1414	    exit({error,{asn1, {bitstring_namedbit, Val}}})
1415    end;
1416get_all_bitposes([], _NamedBitList, Ack) ->
1417    lists:sort(Ack).
1418
1419%%%%%%%%%%%%%%%%%%
1420%% make_and_set_list([list of positions to set to 1])->
1421%% returns list with all in SetPos set.
1422%% in positioning in list the first element is 0, the second 1 etc.., but
1423%%
1424
1425make_and_set_list([XPos|SetPos], XPos) ->
1426    [1 | make_and_set_list(SetPos, XPos + 1)];
1427make_and_set_list([Pos|SetPos], XPos) ->
1428    [0 | make_and_set_list([Pos | SetPos], XPos + 1)];
1429make_and_set_list([], _) ->
1430    [].
1431
1432%%%%%%%%%%%%%%%%%
1433%% pad_list(N,BitList) -> PaddedList
1434%% returns a padded (with trailing {bit,0} elements) list of length N
1435%% if Bitlist contains more than N significant bits set an exit asn1_error
1436%% is generated
1437
1438% pad_list(N,In={Unused,Bin}) ->
1439%     pad_list(N, size(Bin)*8 - Unused, In).
1440
1441% pad_list(N,Size,In={Unused,Bin}) when N < Size ->
1442%     exit({error,{asn1,{range_error,{bit_string,In}}}});
1443% pad_list(N,Size,{Unused,Bin}) when N > Size, Unused > 0 ->
1444%     pad_list(N,Size+1,{Unused-1,Bin});
1445% pad_list(N,Size,{Unused,Bin}) when N > Size ->
1446%     pad_list(N,Size+1,{7,<<Bin/binary,0>>});
1447% pad_list(N,N,In={Unused,Bin}) ->
1448%     In.
1449
1450
1451%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1452%% X.691:16
1453%% encode_octet_string(Constraint,ExtensionMarker,Val)
1454%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1455
1456encode_octet_string(C,Val) ->
1457    encode_octet_string(C,false,Val).
1458
1459encode_octet_string(C,Bool,{_Name,Val}) ->
1460    encode_octet_string(C,Bool,Val);
1461encode_octet_string(_C,true,_Val) ->
1462    exit({error,{asn1,{'not_supported',extensionmarker}}});
1463encode_octet_string(SZ={_,_},false,Val) ->
1464%    [encode_length(SZ,length(Val)),align,
1465%	     {octets,Val}];
1466    Len = length(Val),
1467    [encode_length(SZ,Len),2,
1468     octets_to_complete(Len,Val)];
1469encode_octet_string(SZ,false,Val) when list(SZ) ->
1470    Len = length(Val),
1471    [encode_length({hd(SZ),lists:max(SZ)},Len),2,
1472     octets_to_complete(Len,Val)];
1473encode_octet_string(no,false,Val) ->
1474    Len = length(Val),
1475    [encode_length(undefined,Len),2,
1476     octets_to_complete(Len,Val)];
1477encode_octet_string(C,_,_) ->
1478    exit({error,{not_implemented,C}}).
1479
1480
1481decode_octet_string(Bytes,Range) ->
1482    decode_octet_string(Bytes,Range,false).
1483
1484decode_octet_string(Bytes,1,false) ->
1485    {B1,Bytes2} = getbits(Bytes,8),
1486    {[B1],Bytes2};
1487decode_octet_string(Bytes,2,false) ->
1488    {Bs,Bytes2}= getbits(Bytes,16),
1489    {binary_to_list(<<Bs:16>>),Bytes2};
1490decode_octet_string(Bytes,Sv,false) when integer(Sv),Sv=<65535 ->
1491    Bytes2 = align(Bytes),
1492    getoctets_as_list(Bytes2,Sv);
1493decode_octet_string(Bytes,Sv,false) when integer(Sv) ->
1494    Bytes2 = align(Bytes),
1495    decode_fragmented_octets(Bytes2,Sv);
1496decode_octet_string(Bytes,{Lb,Ub},false) ->
1497    {Len,Bytes2} = decode_length(Bytes,{Lb,Ub}),
1498    Bytes3 = align(Bytes2),
1499    getoctets_as_list(Bytes3,Len);
1500decode_octet_string(Bytes,Sv,false) when list(Sv) ->
1501    {Len,Bytes2} = decode_length(Bytes,{hd(Sv),lists:max(Sv)}),
1502    Bytes3 = align(Bytes2),
1503    getoctets_as_list(Bytes3,Len);
1504decode_octet_string(Bytes,no,false) ->
1505    {Len,Bytes2} = decode_length(Bytes,undefined),
1506    Bytes3 = align(Bytes2),
1507    getoctets_as_list(Bytes3,Len).
1508
1509
1510%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1511%% Restricted char string types
1512%% (NumericString, PrintableString,VisibleString,IA5String,BMPString,UniversalString)
1513%% X.691:26 and X.680:34-36
1514%%encode_restricted_string(aligned,'BMPString',Constraints,Extension,Val)
1515
1516
1517encode_restricted_string(aligned,{Name,Val}) when atom(Name) ->
1518    encode_restricted_string(aligned,Val);
1519
1520encode_restricted_string(aligned,Val) when list(Val)->
1521    Len = length(Val),
1522%    [encode_length(undefined,length(Val)),{octets,Val}].
1523    [encode_length(undefined,Len),octets_to_complete(Len,Val)].
1524
1525
1526encode_known_multiplier_string(StringType,SizeC,NumBits,CharOutTab,{Name,Val}) when atom(Name) ->
1527    encode_known_multiplier_string(StringType,SizeC,NumBits,CharOutTab,Val);
1528encode_known_multiplier_string(StringType,SizeC,NumBits,CharOutTab,Val) ->
1529    Result = chars_encode2(Val,NumBits,CharOutTab),
1530    case SizeC of
1531	Ub when integer(Ub), Ub*NumBits =< 16  ->
1532	    case {StringType,Result} of
1533		{'BMPString',{octets,Ol}} -> %% this case cannot happen !!??
1534		    [{bits,8,Oct}||Oct <- Ol];
1535		_ ->
1536		    Result
1537	    end;
1538	Ub when integer(Ub),Ub =<65535 -> % fixed length
1539%%	    [align,Result];
1540	    [2,Result];
1541	{Ub,Lb} ->
1542%	    [encode_length({Ub,Lb},length(Val)),align,Result];
1543	    [encode_length({Ub,Lb},length(Val)),2,Result];
1544	no  ->
1545%	    [encode_length(undefined,length(Val)),align,Result]
1546	    [encode_length(undefined,length(Val)),2,Result]
1547    end.
1548
1549decode_restricted_string(Bytes,aligned) ->
1550    {Len,Bytes2} = decode_length(Bytes,undefined),
1551    getoctets_as_list(Bytes2,Len).
1552
1553decode_known_multiplier_string(StringType,SizeC,NumBits,CharInTab,Bytes) ->
1554    case SizeC of
1555	Ub when integer(Ub), Ub*NumBits =< 16  ->
1556	    chars_decode(Bytes,NumBits,StringType,CharInTab,Ub);
1557	Ub when integer(Ub),Ub =<65535 -> % fixed length
1558	    Bytes1 = align(Bytes),
1559	    chars_decode(Bytes1,NumBits,StringType,CharInTab,Ub);
1560	Vl when list(Vl) ->
1561	    {Len,Bytes1} = decode_length(Bytes,{hd(Vl),lists:max(Vl)}),
1562	    Bytes2 = align(Bytes1),
1563	    chars_decode(Bytes2,NumBits,StringType,CharInTab,Len);
1564	no  ->
1565	    {Len,Bytes1} = decode_length(Bytes,undefined),
1566	    Bytes2 = align(Bytes1),
1567	    chars_decode(Bytes2,NumBits,StringType,CharInTab,Len);
1568	{Lb,Ub}->
1569	    {Len,Bytes1} = decode_length(Bytes,{Lb,Ub}),
1570	    Bytes2 = align(Bytes1),
1571	    chars_decode(Bytes2,NumBits,StringType,CharInTab,Len)
1572    end.
1573
1574encode_GeneralString(_C,Val) ->
1575    encode_restricted_string(aligned,Val).
1576decode_GeneralString(Bytes,_C) ->
1577    decode_restricted_string(Bytes,aligned).
1578
1579encode_GraphicString(_C,Val) ->
1580    encode_restricted_string(aligned,Val).
1581decode_GraphicString(Bytes,_C) ->
1582    decode_restricted_string(Bytes,aligned).
1583
1584encode_ObjectDescriptor(_C,Val) ->
1585    encode_restricted_string(aligned,Val).
1586decode_ObjectDescriptor(Bytes) ->
1587    decode_restricted_string(Bytes,aligned).
1588
1589encode_TeletexString(_C,Val) -> % equivalent with T61String
1590    encode_restricted_string(aligned,Val).
1591decode_TeletexString(Bytes,_C) ->
1592    decode_restricted_string(Bytes,aligned).
1593
1594encode_VideotexString(_C,Val) ->
1595    encode_restricted_string(aligned,Val).
1596decode_VideotexString(Bytes,_C) ->
1597    decode_restricted_string(Bytes,aligned).
1598
1599
1600
1601
1602%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1603%% getBMPChars(Bytes,Len) ->{BMPcharList,RemainingBytes}
1604%%
1605getBMPChars(Bytes,1) ->
1606    {O1,Bytes2} = getbits(Bytes,8),
1607    {O2,Bytes3} = getbits(Bytes2,8),
1608    if
1609	O1 == 0 ->
1610	    {[O2],Bytes3};
1611	true ->
1612	    {[{0,0,O1,O2}],Bytes3}
1613    end;
1614getBMPChars(Bytes,Len) ->
1615    getBMPChars(Bytes,Len,[]).
1616
1617getBMPChars(Bytes,0,Acc) ->
1618    {lists:reverse(Acc),Bytes};
1619getBMPChars(Bytes,Len,Acc) ->
1620    {Octs,Bytes1} = getoctets_as_list(Bytes,2),
1621    case Octs of
1622	[0,O2] ->
1623	    getBMPChars(Bytes1,Len-1,[O2|Acc]);
1624	[O1,O2]->
1625	    getBMPChars(Bytes1,Len-1,[{0,0,O1,O2}|Acc])
1626    end.
1627
1628
1629%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1630%% chars_encode(C,StringType,Value) -> ValueList
1631%%
1632%% encodes chars according to the per rules taking the constraint PermittedAlphabet
1633%% into account.
1634%% This function does only encode the value part and NOT the length
1635
1636% chars_encode(C,StringType,Value) ->
1637%     case {StringType,get_constraint(C,'PermittedAlphabet')} of
1638% 	{'UniversalString',{_,Sv}} ->
1639% 	    exit({error,{asn1,{'not implemented',"UniversalString with PermittedAlphabet constraint"}}});
1640% 	{'BMPString',{_,Sv}} ->
1641% 	    exit({error,{asn1,{'not implemented',"BMPString with PermittedAlphabet constraint"}}});
1642% 	_ ->
1643% 	    {NumBits,CharOutTab} = {get_NumBits(C,StringType),get_CharOutTab(C,StringType)},
1644% 	    chars_encode2(Value,NumBits,CharOutTab)
1645%     end.
1646
1647
1648chars_encode2([H|T],NumBits,T1={Min,Max,notab}) when  H =< Max, H >= Min ->
1649%    [[10,NumBits,H-Min]|chars_encode2(T,NumBits,T1)];
1650    [pre_complete_bits(NumBits,H-Min)|chars_encode2(T,NumBits,T1)];
1651chars_encode2([H|T],NumBits,T1={Min,Max,Tab}) when H =< Max, H >= Min ->
1652%    [[10,NumBits,element(H-Min+1,Tab)]|chars_encode2(T,NumBits,T1)];
1653    [pre_complete_bits(NumBits,exit_if_false(H,element(H-Min+1,Tab)))|
1654     chars_encode2(T,NumBits,T1)];
1655chars_encode2([{A,B,C,D}|T],NumBits,T1={Min,_Max,notab}) ->
1656    %% no value range check here (ought to be, but very expensive)
1657%    [{bits,NumBits,(A*B*C*D)-Min}|chars_encode2(T,NumBits,{Min,Max,notab})];
1658%    [[10,NumBits,((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min]|chars_encode2(T,NumBits,T1)];
1659    [pre_complete_bits(NumBits,
1660			       ((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min)|
1661     chars_encode2(T,NumBits,T1)];
1662chars_encode2([H={A,B,C,D}|T],NumBits,{Min,Max,Tab}) ->
1663    %% no value range check here (ought to be, but very expensive)
1664    [pre_complete_bits(NumBits,exit_if_false(H,element(((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min,Tab)))|chars_encode2(T,NumBits,{Min,Max,notab})];
1665chars_encode2([H|_T],_NumBits,{_Min,_Max,_Tab}) ->
1666    exit({error,{asn1,{illegal_char_value,H}}});
1667chars_encode2([],_,_) ->
1668    [].
1669
1670exit_if_false(V,false)->
1671    exit({error,{asn1,{"illegal value according to Permitted alphabet constraint",V}}});
1672exit_if_false(_,V) ->V.
1673
1674pre_complete_bits(NumBits,Val) when NumBits =< 8 ->
1675    [10,NumBits,Val];
1676pre_complete_bits(NumBits,Val) when NumBits =< 16 ->
1677    [10,NumBits-8,Val bsr 8,10,8,(Val band 255)];
1678pre_complete_bits(NumBits,Val) when NumBits =< 2040 -> % 255 * 8
1679%     LBUsed = NumBits rem 8,
1680%     {Unused,Len} = case (8 - LBUsed) of
1681% 		       8 -> {0,NumBits div 8};
1682% 		       U -> {U,(NumBits div 8) + 1}
1683% 		   end,
1684%     NewVal = Val bsr LBUsed,
1685%     [30,Unused,Len,<<NewVal:Len/unit:8,Val:LBUsed,0:Unused>>].
1686    Unused = (8 - (NumBits rem 8)) rem 8,
1687    Len = NumBits + Unused,
1688    [30,Unused,Len div 8,<<(Val bsl Unused):Len>>].
1689
1690% get_NumBits(C,StringType) ->
1691%     case get_constraint(C,'PermittedAlphabet') of
1692% 	{'SingleValue',Sv} ->
1693% 	    charbits(length(Sv),aligned);
1694% 	no ->
1695% 	    case StringType of
1696% 		'IA5String' ->
1697% 		    charbits(128,aligned); % 16#00..16#7F
1698% 		'VisibleString' ->
1699% 		    charbits(95,aligned); % 16#20..16#7E
1700% 		'PrintableString' ->
1701% 		    charbits(74,aligned); % [$\s,$',$(,$),$+,$,,$-,$.,$/,"0123456789",$:,$=,$?,$A..$Z,$a..$z
1702% 		'NumericString' ->
1703% 		    charbits(11,aligned); % $ ,"0123456789"
1704% 		'UniversalString' ->
1705% 		    32;
1706% 		'BMPString' ->
1707% 		    16
1708% 	    end
1709%     end.
1710
1711%%Maybe used later
1712%%get_MaxChar(C,StringType) ->
1713%%    case get_constraint(C,'PermittedAlphabet') of
1714%%	{'SingleValue',Sv} ->
1715%%	    lists:nth(length(Sv),Sv);
1716%%	no ->
1717%%	    case StringType of
1718%%		'IA5String' ->
1719%%		    16#7F; % 16#00..16#7F
1720%%		'VisibleString' ->
1721%%		    16#7E; % 16#20..16#7E
1722%%		'PrintableString' ->
1723%%		    $z; % [$\s,$',$(,$),$+,$,,$-,$.,$/,"0123456789",$:,$=,$?,$A..$Z,$a..$z
1724%%		'NumericString' ->
1725%%		    $9; % $ ,"0123456789"
1726%%		'UniversalString' ->
1727%%		    16#ffffffff;
1728%%		'BMPString' ->
1729%%		    16#ffff
1730%%	    end
1731%%    end.
1732
1733%%Maybe used later
1734%%get_MinChar(C,StringType) ->
1735%%    case get_constraint(C,'PermittedAlphabet') of
1736%%	{'SingleValue',Sv} ->
1737%%	    hd(Sv);
1738%%	no ->
1739%%	    case StringType of
1740%%		'IA5String' ->
1741%%		    16#00; % 16#00..16#7F
1742%%		'VisibleString' ->
1743%%		    16#20; % 16#20..16#7E
1744%%		'PrintableString' ->
1745%%		    $\s; % [$\s,$',$(,$),$+,$,,$-,$.,$/,"0123456789",$:,$=,$?,$A..$Z,$a..$z
1746%%		'NumericString' ->
1747%%		    $\s; % $ ,"0123456789"
1748%%		'UniversalString' ->
1749%%		    16#00;
1750%%		'BMPString' ->
1751%%		    16#00
1752%%	    end
1753%%    end.
1754
1755% get_CharOutTab(C,StringType) ->
1756%     get_CharTab(C,StringType,out).
1757
1758% get_CharInTab(C,StringType) ->
1759%     get_CharTab(C,StringType,in).
1760
1761% get_CharTab(C,StringType,InOut) ->
1762%     case get_constraint(C,'PermittedAlphabet') of
1763% 	{'SingleValue',Sv} ->
1764% 	    get_CharTab2(C,StringType,hd(Sv),lists:max(Sv),Sv,InOut);
1765% 	no ->
1766% 	    case StringType of
1767% 		'IA5String' ->
1768% 		    {0,16#7F,notab};
1769% 		'VisibleString' ->
1770% 		    get_CharTab2(C,StringType,16#20,16#7F,notab,InOut);
1771% 		'PrintableString' ->
1772% 		    Chars = lists:sort(
1773% 			      " '()+,-./0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"),
1774% 		    get_CharTab2(C,StringType,hd(Chars),lists:max(Chars),Chars,InOut);
1775% 		'NumericString' ->
1776% 		    get_CharTab2(C,StringType,16#20,$9," 0123456789",InOut);
1777% 		'UniversalString' ->
1778% 		    {0,16#FFFFFFFF,notab};
1779% 		'BMPString' ->
1780% 		    {0,16#FFFF,notab}
1781% 	    end
1782%     end.
1783
1784% get_CharTab2(C,StringType,Min,Max,Chars,InOut) ->
1785%     BitValMax = (1 bsl get_NumBits(C,StringType))-1,
1786%     if
1787% 	Max =< BitValMax ->
1788% 	    {0,Max,notab};
1789% 	true ->
1790% 	    case InOut of
1791% 		out ->
1792% 		    {Min,Max,create_char_tab(Min,Chars)};
1793% 		in  ->
1794% 		    {Min,Max,list_to_tuple(Chars)}
1795% 	    end
1796%     end.
1797
1798% create_char_tab(Min,L) ->
1799%     list_to_tuple(create_char_tab(Min,L,0)).
1800% create_char_tab(Min,[Min|T],V) ->
1801%     [V|create_char_tab(Min+1,T,V+1)];
1802% create_char_tab(_Min,[],_V) ->
1803%     [];
1804% create_char_tab(Min,L,V) ->
1805%     [false|create_char_tab(Min+1,L,V)].
1806
1807%% This very inefficient and should be moved to compiletime
1808% charbits(NumOfChars,aligned) ->
1809%     case charbits(NumOfChars) of
1810% 	1 -> 1;
1811% 	2 -> 2;
1812% 	B when B =< 4 -> 4;
1813% 	B when B =< 8 -> 8;
1814% 	B when B =< 16 -> 16;
1815% 	B when B =< 32 -> 32
1816%     end.
1817
1818% charbits(NumOfChars) when NumOfChars =< 2 -> 1;
1819% charbits(NumOfChars) when NumOfChars =< 4 -> 2;
1820% charbits(NumOfChars) when NumOfChars =< 8 -> 3;
1821% charbits(NumOfChars) when NumOfChars =< 16 -> 4;
1822% charbits(NumOfChars) when NumOfChars =< 32 -> 5;
1823% charbits(NumOfChars) when NumOfChars =< 64 -> 6;
1824% charbits(NumOfChars) when NumOfChars =< 128 -> 7;
1825% charbits(NumOfChars) when NumOfChars =< 256 -> 8;
1826% charbits(NumOfChars) when NumOfChars =< 512 -> 9;
1827% charbits(NumOfChars) when NumOfChars =< 1024 -> 10;
1828% charbits(NumOfChars) when NumOfChars =< 2048 -> 11;
1829% charbits(NumOfChars) when NumOfChars =< 4096 -> 12;
1830% charbits(NumOfChars) when NumOfChars =< 8192 -> 13;
1831% charbits(NumOfChars) when NumOfChars =< 16384 -> 14;
1832% charbits(NumOfChars) when NumOfChars =< 32768 -> 15;
1833% charbits(NumOfChars) when NumOfChars =< 65536 -> 16;
1834% charbits(NumOfChars) when integer(NumOfChars) ->
1835%     16 + charbits1(NumOfChars bsr 16).
1836
1837% charbits1(0) ->
1838%     0;
1839% charbits1(NumOfChars) ->
1840%     1 + charbits1(NumOfChars bsr 1).
1841
1842
1843chars_decode(Bytes,_,'BMPString',_,Len) ->
1844    getBMPChars(Bytes,Len);
1845chars_decode(Bytes,NumBits,_StringType,CharInTab,Len) ->
1846    chars_decode2(Bytes,CharInTab,NumBits,Len).
1847
1848
1849chars_decode2(Bytes,CharInTab,NumBits,Len) ->
1850    chars_decode2(Bytes,CharInTab,NumBits,Len,[]).
1851
1852chars_decode2(Bytes,_CharInTab,_NumBits,0,Acc) ->
1853    {lists:reverse(Acc),Bytes};
1854chars_decode2(Bytes,{Min,Max,notab},NumBits,Len,Acc) when NumBits > 8 ->
1855    {Char,Bytes2} = getbits(Bytes,NumBits),
1856    Result =
1857	if
1858	    Char < 256 -> Char;
1859	    true ->
1860		list_to_tuple(binary_to_list(<<Char:32>>))
1861	end,
1862    chars_decode2(Bytes2,{Min,Max,notab},NumBits,Len -1,[Result|Acc]);
1863chars_decode2(Bytes,{Min,Max,notab},NumBits,Len,Acc) ->
1864    {Char,Bytes2} = getbits(Bytes,NumBits),
1865    chars_decode2(Bytes2,{Min,Max,notab},NumBits,Len -1,[Char+Min|Acc]);
1866
1867%% BMPString and UniversalString with PermittedAlphabet is currently not supported
1868chars_decode2(Bytes,{Min,Max,CharInTab},NumBits,Len,Acc) ->
1869    {Char,Bytes2} = getbits(Bytes,NumBits),
1870    chars_decode2(Bytes2,{Min,Max,CharInTab},NumBits,Len -1,[element(Char+1,CharInTab)|Acc]).
1871
1872
1873						% X.691:17
1874encode_null(_Val) -> []; % encodes to nothing
1875encode_null({Name,Val}) when atom(Name) ->
1876    encode_null(Val).
1877
1878decode_null(Bytes) ->
1879    {'NULL',Bytes}.
1880
1881%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1882%% encode_object_identifier(Val) -> CompleteList
1883%% encode_object_identifier({Name,Val}) -> CompleteList
1884%% Val -> {Int1,Int2,...,IntN} % N >= 2
1885%% Name -> atom()
1886%% Int1 -> integer(0..2)
1887%% Int2 -> integer(0..39) when Int1 (0..1) else integer()
1888%% Int3-N -> integer()
1889%% CompleteList -> [{bits,8,Val}|{octets,Ol}|align|...]
1890%%
1891encode_object_identifier({Name,Val}) when atom(Name) ->
1892    encode_object_identifier(Val);
1893encode_object_identifier(Val) ->
1894    OctetList = e_object_identifier(Val),
1895    Octets = list_to_binary(OctetList), % performs a flatten at the same time
1896%    [{debug,object_identifier},encode_length(undefined,size(Octets)),{octets,Octets}].
1897    [encode_length(undefined,size(Octets)),
1898     octets_to_complete(size(Octets),Octets)].
1899
1900%% This code is copied from asn1_encode.erl (BER) and corrected and modified
1901
1902e_object_identifier({'OBJECT IDENTIFIER',V}) ->
1903    e_object_identifier(V);
1904e_object_identifier({Cname,V}) when atom(Cname),tuple(V) ->
1905    e_object_identifier(tuple_to_list(V));
1906e_object_identifier({Cname,V}) when atom(Cname),list(V) ->
1907    e_object_identifier(V);
1908e_object_identifier(V) when tuple(V) ->
1909    e_object_identifier(tuple_to_list(V));
1910
1911%% E1 = 0|1|2 and (E2 < 40 when E1 = 0|1)
1912e_object_identifier([E1,E2|Tail]) when E1 >= 0, E1 < 2, E2 < 40 ; E1==2 ->
1913    Head = 40*E1 + E2,  % weird
1914    e_object_elements([Head|Tail],[]);
1915e_object_identifier(Oid=[_,_|_Tail]) ->
1916    exit({error,{asn1,{'illegal_value',Oid}}}).
1917
1918e_object_elements([],Acc) ->
1919    lists:reverse(Acc);
1920e_object_elements([H|T],Acc) ->
1921    e_object_elements(T,[e_object_element(H)|Acc]).
1922
1923e_object_element(Num) when Num < 128 ->
1924    Num;
1925%% must be changed to handle more than 2 octets
1926e_object_element(Num) ->  %% when Num < ???
1927    Left = ((Num band 2#11111110000000) bsr 7) bor 2#10000000,
1928    Right = Num band 2#1111111 ,
1929    [Left,Right].
1930
1931
1932
1933%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1934%% decode_object_identifier(Bytes) -> {ObjId,RemainingBytes}
1935%% ObjId -> {integer(),integer(),...} % at least 2 integers
1936%% RemainingBytes -> [integer()] when integer() (0..255)
1937decode_object_identifier(Bytes) ->
1938    {Len,Bytes2} = decode_length(Bytes,undefined),
1939    {Octs,Bytes3} = getoctets_as_list(Bytes2,Len),
1940    [First|Rest] = dec_subidentifiers(Octs,0,[]),
1941    Idlist = if
1942		 First < 40 ->
1943		     [0,First|Rest];
1944		 First < 80 ->
1945		     [1,First - 40|Rest];
1946		 true ->
1947		     [2,First - 80|Rest]
1948	     end,
1949    {list_to_tuple(Idlist),Bytes3}.
1950
1951dec_subidentifiers([H|T],Av,Al) when H >=16#80 ->
1952    dec_subidentifiers(T,(Av bsl 7) + (H band 16#7F),Al);
1953dec_subidentifiers([H|T],Av,Al) ->
1954    dec_subidentifiers(T,0,[(Av bsl 7) + H |Al]);
1955dec_subidentifiers([],_Av,Al) ->
1956    lists:reverse(Al).
1957
1958get_constraint([{Key,V}],Key) ->
1959    V;
1960get_constraint([],_) ->
1961    no;
1962get_constraint(C,Key) ->
1963    case lists:keysearch(Key,1,C) of
1964	false ->
1965	    no;
1966	{value,{_,V}} ->
1967	    V
1968    end.
1969
1970
1971%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1972%% complete(InList) -> ByteList
1973%% Takes a coded list with bits and bytes and converts it to a list of bytes
1974%% Should be applied as the last step at encode of a complete ASN.1 type
1975%%
1976
1977-ifdef(nodriver).
1978
1979complete(L) ->
1980    case complete1(L) of
1981	{[],[]} ->
1982	    <<0>>;
1983	{Acc,[]} ->
1984	    Acc;
1985	{Acc,Bacc}  ->
1986	    [Acc|complete_bytes(Bacc)]
1987    end.
1988
1989
1990% this function builds the ugly form of lists [E1|E2] to avoid having to reverse it at the end.
1991% this is done because it is efficient and that the result always will be sent on a port or
1992% converted by means of list_to_binary/1
1993 complete1(InList) when list(InList) ->
1994     complete1(InList,[],[]);
1995 complete1(InList) ->
1996     complete1([InList],[],[]).
1997
1998 complete1([],Acc,Bacc) ->
1999     {Acc,Bacc};
2000 complete1([H|T],Acc,Bacc) when list(H) ->
2001     {NewH,NewBacc} = complete1(H,Acc,Bacc),
2002     complete1(T,NewH,NewBacc);
2003
2004 complete1([{octets,Bin}|T],Acc,[]) ->
2005     complete1(T,[Acc|Bin],[]);
2006
2007 complete1([{octets,Bin}|T],Acc,Bacc) ->
2008     complete1(T,[Acc|[complete_bytes(Bacc),Bin]],[]);
2009
2010 complete1([{debug,_}|T], Acc,Bacc) ->
2011     complete1(T,Acc,Bacc);
2012
2013 complete1([{bits,N,Val}|T],Acc,Bacc) ->
2014     complete1(T,Acc,complete_update_byte(Bacc,Val,N));
2015
2016 complete1([{bit,Val}|T],Acc,Bacc) ->
2017     complete1(T,Acc,complete_update_byte(Bacc,Val,1));
2018
2019 complete1([align|T],Acc,[]) ->
2020     complete1(T,Acc,[]);
2021 complete1([align|T],Acc,Bacc) ->
2022     complete1(T,[Acc|complete_bytes(Bacc)],[]);
2023 complete1([{0,Bin}|T],Acc,[]) when binary(Bin) ->
2024     complete1(T,[Acc|Bin],[]);
2025 complete1([{Unused,Bin}|T],Acc,[]) when integer(Unused),binary(Bin) ->
2026     Size = size(Bin)-1,
2027     <<Bs:Size/binary,B>> = Bin,
2028     NumBits = 8-Unused,
2029     complete1(T,[Acc|Bs],[[B bsr Unused]|NumBits]);
2030 complete1([{Unused,Bin}|T],Acc,Bacc) when integer(Unused),binary(Bin) ->
2031     Size = size(Bin)-1,
2032     <<Bs:Size/binary,B>> = Bin,
2033     NumBits = 8 - Unused,
2034     Bf = complete_bytes(Bacc),
2035     complete1(T,[Acc|[Bf,Bs]],[[B bsr Unused]|NumBits]).
2036
2037
2038 complete_update_byte([],Val,Len) ->
2039     complete_update_byte([[0]|0],Val,Len);
2040 complete_update_byte([[Byte|Bacc]|NumBits],Val,Len) when NumBits + Len == 8 ->
2041     [[0,((Byte bsl Len) + Val) band 255|Bacc]|0];
2042 complete_update_byte([[Byte|Bacc]|NumBits],Val,Len) when NumBits + Len > 8  ->
2043     Rem = 8 - NumBits,
2044     Rest = Len - Rem,
2045     complete_update_byte([[0,((Byte bsl Rem) + (Val bsr Rest)) band 255 |Bacc]|0],Val,Rest);
2046 complete_update_byte([[Byte|Bacc]|NumBits],Val,Len) ->
2047     [[((Byte bsl Len) + Val) band 255|Bacc]|NumBits+Len].
2048
2049
2050 complete_bytes([[Byte|Bacc]|0]) ->
2051     lists:reverse(Bacc);
2052 complete_bytes([[Byte|Bacc]|NumBytes]) ->
2053     lists:reverse([(Byte bsl (8-NumBytes)) band 255|Bacc]);
2054 complete_bytes([]) ->
2055     [].
2056
2057-else.
2058
2059
2060 complete(L) ->
2061    case catch port_control(drv_complete,1,L) of
2062	Bin when binary(Bin) ->
2063	    Bin;
2064	List when list(List) -> handle_error(List,L);
2065	{'EXIT',{badarg,Reason}} ->
2066	    asn1rt_driver_handler:load_driver(),
2067	    receive
2068		driver_ready ->
2069		    case catch port_control(drv_complete,1,L) of
2070			Bin2 when binary(Bin2) -> Bin2;
2071			List when list(List) -> handle_error(List,L);
2072			Error -> exit(Error)
2073		    end;
2074		{error,Error} -> % error when loading driver
2075		    %% the driver could not be loaded
2076		    exit(Error);
2077		Error={port_error,Reason} ->
2078		    exit(Error)
2079	    end;
2080	{'EXIT',Reason} ->
2081	    exit(Reason)
2082    end.
2083
2084handle_error([],_)->
2085    exit({error,{"memory allocation problem"}});
2086handle_error("1",L) -> % error in complete in driver
2087    exit({error,{asn1_error,L}});
2088handle_error(ErrL,L) ->
2089    exit({error,{unknown_error,ErrL,L}}).
2090
2091-endif.
2092
2093
2094octets_to_complete(Len,Val) when Len < 256 ->
2095    [20,Len,Val];
2096octets_to_complete(Len,Val) ->
2097    [21,<<Len:16>>,Val].
2098
2099octets_unused_to_complete(Unused,Len,Val) when Len < 256 ->
2100    [30,Unused,Len,Val];
2101octets_unused_to_complete(Unused,Len,Val) ->
2102    [31,Unused,<<Len:16>>,Val].
2103