2
%% <year>2008-2008</year>
3
%% <holder>Ericsson AB, All Rights Reserved</holder>
6
%% The contents of this file are subject to the Erlang Public License,
7
%% Version 1.1, (the "License"); you may not use this file except in
8
%% compliance with the License. You should have received a copy of the
9
%% Erlang Public License along with this software. If not, it can be
10
%% retrieved online at http://www.erlang.org/.
12
%% Software distributed under the License is distributed on an "AS IS"
13
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
%% the License for the specific language governing rights and limitations
17
%% The Initial Developer of the Original Code is Ericsson AB.
20
-module(asn1rt_uper_bin).
22
%% encoding / decoding of PER unaligned
24
-include("asn1_records.hrl").
26
%%-compile(export_all).
28
-export([cindex/3, list_to_record/2]).
29
-export([setext/1, fixoptionals/3,
31
getext/1, getextension/2, skipextensions/3, getbit/1, getchoice/3 ]).
32
-export([getoptionals2/2, set_choice/3, encode_integer/2, encode_integer/3 ]).
33
-export([decode_integer/2, decode_integer/3, encode_small_number/1, encode_boolean/1,
34
decode_boolean/1, encode_length/2, decode_length/1, decode_length/2,
35
encode_small_length/1, decode_small_length/1,
36
decode_compact_bit_string/3]).
37
-export([decode_enumerated/3,
38
encode_bit_string/3, decode_bit_string/3 ]).
39
-export([encode_octet_string/2, decode_octet_string/2,
40
encode_null/1, decode_null/1,
41
encode_relative_oid/1, decode_relative_oid/1,
42
encode_object_identifier/1, decode_object_identifier/1,
43
encode_real/1, decode_real/1,
44
complete/1, complete_NFP/1]).
47
-export([encode_open_type/2, decode_open_type/2]).
49
-export([encode_UniversalString/2, decode_UniversalString/2,
50
encode_PrintableString/2, decode_PrintableString/2,
51
encode_GeneralString/2, decode_GeneralString/2,
52
encode_GraphicString/2, decode_GraphicString/2,
53
encode_TeletexString/2, decode_TeletexString/2,
54
encode_VideotexString/2, decode_VideotexString/2,
55
encode_VisibleString/2, decode_VisibleString/2,
56
encode_UTF8String/1, decode_UTF8String/1,
57
encode_BMPString/2, decode_BMPString/2,
58
encode_IA5String/2, decode_IA5String/2,
59
encode_NumericString/2, decode_NumericString/2,
60
encode_ObjectDescriptor/2, decode_ObjectDescriptor/1
68
cindex(Ix,Val,Cname) ->
69
case element(Ix,Val) of
74
%% converts a list to a record if necessary
75
list_to_record(_Name,Tuple) when tuple(Tuple) ->
77
list_to_record(Name,List) when list(List) ->
78
list_to_tuple([Name|List]).
81
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82
%% setext(true|false) -> CompleteList
92
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
93
%% This is the new fixoptionals/3 which is used by the new generates
95
fixoptionals(OptList,OptLength,Val) when tuple(Val) ->
96
Bits = fixoptionals(OptList,Val,0),
97
{Val,<<Bits:OptLength>>};
99
fixoptionals([],_Val,Acc) ->
102
fixoptionals([Pos|Ot],Val,Acc) ->
103
case element(Pos,Val) of
104
asn1_NOVALUE -> fixoptionals(Ot,Val,Acc bsl 1);
105
asn1_DEFAULT -> fixoptionals(Ot,Val,Acc bsl 1);
106
_ -> fixoptionals(Ot,Val,(Acc bsl 1) + 1)
110
getext(Bytes) when is_bitstring(Bytes) ->
113
getextension(0, Bytes) ->
115
getextension(1, Bytes) ->
116
{Len,Bytes2} = decode_small_length(Bytes),
117
{Blist, Bytes3} = getbits_as_list(Len,Bytes2),
118
{list_to_tuple(Blist),Bytes3}.
120
fixextensions({ext,ExtPos,ExtNum},Val) ->
121
case fixextensions(ExtPos,ExtNum+ExtPos,Val,0) of
124
[encode_small_length(ExtNum),<<ExtBits:ExtNum>>]
127
fixextensions(Pos,MaxPos,_,Acc) when Pos >= MaxPos ->
129
fixextensions(Pos,ExtPos,Val,Acc) ->
130
Bit = case catch(element(Pos+1,Val)) of
140
fixextensions(Pos+1,ExtPos,Val,(Acc bsl 1)+Bit).
142
skipextensions(Bytes,Nr,ExtensionBitPattern) ->
143
case (catch element(Nr,ExtensionBitPattern)) of
145
{_,Bytes2} = decode_open_type(Bytes,[]),
146
skipextensions(Bytes2, Nr+1, ExtensionBitPattern);
148
skipextensions(Bytes, Nr+1, ExtensionBitPattern);
149
{'EXIT',_} -> % badarg, no more extensions
154
getchoice(Bytes,1,0) -> % only 1 alternative is not encoded
156
getchoice(Bytes,_,1) ->
157
decode_small_number(Bytes);
158
getchoice(Bytes,NumChoices,0) ->
159
decode_constrained_number(Bytes,{0,NumChoices-1}).
163
getoptionals2(Bytes,NumOpt) ->
164
getbits(Bytes,NumOpt).
167
%% getbits_as_binary(Num,Bytes) -> {{Unused,BinBits},RestBytes},
169
%% Bytes = list() | tuple(),
170
%% Unused = integer(),
171
%% BinBits = binary(),
172
%% RestBytes = tuple()
173
getbits_as_binary(Num,Bytes) when is_bitstring(Bytes) ->
174
<<BS:Num/bitstring,Rest/bitstring>> = Bytes,
177
getbits_as_list(Num,Bytes) when is_bitstring(Bytes) ->
178
<<BitStr:Num/bitstring,Rest/bitstring>> = Bytes,
179
{[ B || <<B:1>> <= BitStr],Rest}.
182
<<B:1,Rest/bitstring>> = Buffer,
186
getbits(Buffer,Num) when is_bitstring(Buffer) ->
187
<<Bs:Num,Rest/bitstring>> = Buffer,
192
%% Pick the first Num octets.
193
%% Returns octets as an integer with bit significance as in buffer.
194
getoctets(Buffer,Num) when is_bitstring(Buffer) ->
195
<<Val:Num/integer-unit:8,RestBitStr/bitstring>> = Buffer,
198
%% Pick the first Num octets.
199
%% Returns octets as a binary
200
getoctets_as_bin(Bin,Num) when is_bitstring(Bin) ->
201
<<Octets:Num/binary,RestBin/bitstring>> = Bin,
204
%% same as above but returns octets as a List
205
getoctets_as_list(Buffer,Num) ->
206
{Bin,Buffer2} = getoctets_as_bin(Buffer,Num),
207
{binary_to_list(Bin),Buffer2}.
208
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
209
%% set_choice(Alt,Choices,Altnum) -> ListofBitSettings
211
%% Altnum = integer() | {integer(),integer()}% number of alternatives
212
%% Choices = [atom()] | {[atom()],[atom()]}
213
%% When Choices is a tuple the first list is the Rootset and the
214
%% second is the Extensions and then Altnum must also be a tuple with the
215
%% lengths of the 2 lists
217
set_choice(Alt,{L1,L2},{Len1,_Len2}) ->
218
case set_choice_tag(Alt,L1) of
219
N when integer(N), Len1 > 1 ->
220
[<<0:1>>, % the value is in the root set
221
encode_integer([{'ValueRange',{0,Len1-1}}],N)];
223
<<0:1>>; % no encoding if only 0 or 1 alternative
225
[<<1:1>>, % extension value
226
case set_choice_tag(Alt,L2) of
227
N2 when integer(N2) ->
228
encode_small_number(N2);
233
set_choice(Alt,L,Len) ->
234
case set_choice_tag(Alt,L) of
235
N when integer(N), Len > 1 ->
236
encode_integer([{'ValueRange',{0,Len-1}}],N);
238
[]; % no encoding if only 0 or 1 alternative
243
set_choice_tag(Alt,Choices) ->
244
set_choice_tag(Alt,Choices,0).
246
set_choice_tag(Alt,[Alt|_Rest],Tag) ->
248
set_choice_tag(Alt,[_H|Rest],Tag) ->
249
set_choice_tag(Alt,Rest,Tag+1);
250
set_choice_tag(_Alt,[],_Tag) ->
253
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
254
%% decode_fragmented_XXX; decode of values encoded fragmented according
255
%% to ITU-T X.691 clause 10.9.3.8. The unit (XXX) is either bits, octets,
256
%% characters or number of components (in a choice,sequence or similar).
257
%% Buffer is a buffer {Used, Bin}.
258
%% C is the constrained length.
259
%% If the buffer is not aligned, this function does that.
260
decode_fragmented_bits(Buffer,C) ->
261
decode_fragmented_bits(Buffer,C,[]).
262
decode_fragmented_bits(<<3:2,Len:6,BitStr/bitstring>>,C,Acc) ->
263
%% {Value,Bin2} = split_binary(Bin, Len * ?'16K'),
264
FragLen = (Len*?'16K') div 8,
265
<<Value:FragLen/binary,BitStr2/bitstring>> = BitStr,
266
decode_fragmented_bits(BitStr2,C,[Value|Acc]);
267
decode_fragmented_bits(<<0:1,0:7,BitStr/bitstring>>,C,Acc) ->
268
BinBits = list_to_binary(lists:reverse(Acc)),
270
Int when integer(Int),C == size(BinBits) ->
272
Int when integer(Int) ->
273
exit({error,{asn1,{illegal_value,C,BinBits}}})
275
decode_fragmented_bits(<<0:1,Len:7,BitStr/bitstring>>,C,Acc) ->
276
<<Val:Len/bitstring,Rest/bitstring>> = BitStr,
277
%% <<Value:Len/binary-unit:1,Bin2/binary>> = Bin,
278
ResBitStr = list_to_bitstring(lists:reverse([Val|Acc])),
280
Int when integer(Int),C == bit_size(ResBitStr) ->
282
Int when integer(Int) ->
283
exit({error,{asn1,{illegal_value,C,ResBitStr}}})
287
decode_fragmented_octets({0,Bin},C) ->
288
decode_fragmented_octets(Bin,C,[]).
290
decode_fragmented_octets(<<3:2,Len:6,BitStr/bitstring>>,C,Acc) ->
291
FragLen = Len * ?'16K',
292
<<Value:FragLen/binary,Rest/bitstring>> = BitStr,
293
decode_fragmented_octets(Rest,C,[Value|Acc]);
294
decode_fragmented_octets(<<0:1,0:7,Bin/bitstring>>,C,Acc) ->
295
Octets = list_to_binary(lists:reverse(Acc)),
297
Int when integer(Int), C == size(Octets) ->
299
Int when integer(Int) ->
300
exit({error,{asn1,{illegal_value,C,Octets}}})
302
decode_fragmented_octets(<<0:1,Len:7,BitStr/bitstring>>,C,Acc) ->
303
<<Value:Len/binary-unit:8,BitStr2/binary>> = BitStr,
304
BinOctets = list_to_binary(lists:reverse([Value|Acc])),
306
Int when integer(Int),size(BinOctets) == Int ->
308
Int when integer(Int) ->
309
exit({error,{asn1,{illegal_value,C,BinOctets}}})
314
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
315
%% encode_open_type(Constraint, Value) -> CompleteList
316
%% Value = list of bytes of an already encoded value (the list must be flat)
318
%% Contraint = not used in this version
320
encode_open_type(C, Val) when list(Val) ->
321
encode_open_type(C, list_to_binary(Val));
322
encode_open_type(_C, Val) when binary(Val) ->
323
[encode_length(undefined,size(Val)),Val].
326
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
327
%% decode_open_type(Buffer,Constraint) -> Value
328
%% Constraint is not used in this version
329
%% Buffer = [byte] with PER encoded data
330
%% Value = [byte] with decoded data (which must be decoded again as some type)
332
decode_open_type(Bytes, _C) ->
333
{Len,Bytes2} = decode_length(Bytes,undefined),
334
getoctets_as_bin(Bytes2,Len).
336
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
337
%% encode_integer(Constraint,Value,NamedNumberList) -> CompleteList
338
%% encode_integer(Constraint,Value) -> CompleteList
339
%% encode_integer(Constraint,{Name,Value}) -> CompleteList
342
encode_integer(C,V,NamedNumberList) when atom(V) ->
343
case lists:keysearch(V,1,NamedNumberList) of
345
encode_integer(C,NewV);
347
exit({error,{asn1,{namednumber,V}}})
349
encode_integer(C,V,_NamedNumberList) when integer(V) ->
351
encode_integer(C,{Name,V},NamedNumberList) when atom(Name) ->
352
encode_integer(C,V,NamedNumberList).
354
encode_integer(C,{Name,Val}) when atom(Name) ->
355
encode_integer(C,Val);
357
encode_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.
358
case (catch encode_integer([Rc],Val)) of
359
{'EXIT',{error,{asn1,_}}} ->
360
[<<1:1>>,encode_unconstrained_number(Val)];
364
encode_integer(C,Val ) when list(C) ->
365
case get_constraint(C,'SingleValue') of
367
encode_integer1(C,Val);
368
V when integer(V),V == Val ->
369
[]; % a type restricted to a single value encodes to nothing
371
case lists:member(Val,V) of
373
encode_integer1(C,Val);
375
exit({error,{asn1,{illegal_value,Val}}})
378
exit({error,{asn1,{illegal_value,Val}}})
381
encode_integer1(C, Val) ->
382
case VR = get_constraint(C,'ValueRange') of
384
encode_unconstrained_number(Val);
386
encode_semi_constrained_number(Lb,Val);
387
%% positive with range
388
{Lb,Ub} when Val >= Lb,
390
encode_constrained_number(VR,Val);
392
exit({error,{asn1,{illegal_value,VR,Val}}})
395
decode_integer(Buffer,Range,NamedNumberList) ->
396
{Val,Buffer2} = decode_integer(Buffer,Range),
397
case lists:keysearch(Val,2,NamedNumberList) of
398
{value,{NewVal,_}} -> {NewVal,Buffer2};
402
decode_integer(Buffer,[{Rc,_Ec}]) when tuple(Rc) ->
403
{Ext,Buffer2} = getext(Buffer),
405
0 -> decode_integer(Buffer2,[Rc]); %% Value in root of constraint
406
1 -> decode_unconstrained_number(Buffer2)
408
decode_integer(Buffer,undefined) ->
409
decode_unconstrained_number(Buffer);
410
decode_integer(Buffer,C) ->
411
case get_constraint(C,'SingleValue') of
415
{Val,Buffer2} = decode_integer1(Buffer,C),
416
case lists:member(Val,V) of
420
exit({error,{asn1,{illegal_value,Val}}})
423
decode_integer1(Buffer,C)
426
decode_integer1(Buffer,C) ->
427
case VR = get_constraint(C,'ValueRange') of
429
decode_unconstrained_number(Buffer);
431
decode_semi_constrained_number(Buffer,Lb);
433
decode_constrained_number(Buffer,VR)
436
%% X.691:10.6 Encoding of a normally small non-negative whole number
437
%% Use this for encoding of CHOICE index if there is an extension marker in
439
encode_small_number({Name,Val}) when atom(Name) ->
440
encode_small_number(Val);
441
encode_small_number(Val) when Val =< 63 ->
443
encode_small_number(Val) ->
444
[<<1:1>>,encode_semi_constrained_number(0,Val)].
446
decode_small_number(Bytes) ->
447
{Bit,Bytes2} = getbit(Bytes),
452
decode_semi_constrained_number(Bytes2,0)
455
%% X.691:10.7 Encoding of a semi-constrained whole number
456
%% might be an optimization encode_semi_constrained_number(0,Val) ->
457
encode_semi_constrained_number(C,{Name,Val}) when atom(Name) ->
458
encode_semi_constrained_number(C,Val);
459
encode_semi_constrained_number({Lb,'MAX'},Val) ->
460
encode_semi_constrained_number(Lb,Val);
461
encode_semi_constrained_number(Lb,Val) ->
462
%% encoding in minimum no of octets preceeded by a length
464
%% NumBits = num_bits(Val2),
465
Bin = eint_bin_positive(Val2),
469
[<<Size>>,Bin]; % equiv with encode_length(undefined,Len) but faster
471
[<<2:2,Size:14>>,Bin];
473
[encode_length(undefined,Size),Bin]
476
decode_semi_constrained_number(Bytes,{Lb,_}) ->
477
decode_semi_constrained_number(Bytes,Lb);
478
decode_semi_constrained_number(Bytes,Lb) ->
479
{Len,Bytes2} = decode_length(Bytes,undefined),
480
{V,Bytes3} = getoctets(Bytes2,Len),
483
encode_constrained_number(Range,{Name,Val}) when atom(Name) ->
484
encode_constrained_number(Range,Val);
485
encode_constrained_number({Lb,Ub},Val) when Val >= Lb, Ub >= Val ->
488
NumBits = num_bits(Range),
490
encode_constrained_number(Range,Val) ->
491
exit({error,{asn1,{integer_range,Range,value,Val}}}).
494
decode_constrained_number(Buffer,{Lb,Ub}) ->
496
NumBits = num_bits(Range),
497
{Val,Remain} = getbits(Buffer,NumBits),
500
%% X.691:10.8 Encoding of an unconstrained whole number
502
encode_unconstrained_number(Val) when Val >= 0 ->
503
Oct = eint_bin_2Cs(Val),
507
[<<Len>>,Oct]; % equiv with encode_length(undefined,Len) but faster
509
[<<2:2,Len:14>>,Oct];
511
[encode_length(undefined,Len),<<Len:16>>,Oct]
513
encode_unconstrained_number(Val) -> % negative
518
[<<Len>>,Oct]; % equiv with encode_length(undefined,Len) but faster
520
[<<2:2,Len:14>>,Oct];
522
[encode_length(undefined,Len),Oct]
527
case eint_bin_positive(Int) of
528
Bin = <<B,_/binary>> when B > 16#7f ->
533
%% returns the integer as a binary
534
eint_bin_positive(Val) when Val < 16#100 ->
536
eint_bin_positive(Val) when Val < 16#10000 ->
538
eint_bin_positive(Val) when Val < 16#1000000 ->
540
eint_bin_positive(Val) when Val < 16#100000000 ->
542
eint_bin_positive(Val) ->
543
list_to_binary([eint_bin_positive2(Val bsr 32)|<<Val:32>>]).
544
eint_bin_positive2(Val) when Val < 16#100 ->
546
eint_bin_positive2(Val) when Val < 16#10000 ->
548
eint_bin_positive2(Val) when Val < 16#1000000 ->
550
eint_bin_positive2(Val) when Val < 16#100000000 ->
552
eint_bin_positive2(Val) ->
553
[eint_bin_positive2(Val bsr 32)|<<Val:32>>].
558
enint(-1, [B1|T]) when B1 > 127 ->
559
list_to_binary([B1|T]);
561
enint(N bsr 8, [N band 16#ff|Acc]).
563
decode_unconstrained_number(Bytes) ->
564
{Len,Bytes2} = decode_length(Bytes,undefined),
565
{Ints,Bytes3} = getoctets_as_bin(Bytes2,Len),
566
{dec_integer(Ints),Bytes3}.
568
dec_integer(Bin = <<0:1,_:7,_/bitstring>>) ->
570
dec_integer(<<_:1,B:7,BitStr/bitstring>>) ->
571
Size = bit_size(BitStr),
573
(-128 + B) bsl bit_size(BitStr) bor I.
576
Size = bit_size(Bin),
581
%% X.691:10.9 Encoding of a length determinant
582
%%encode_small_length(undefined,Len) -> % null means no UpperBound
583
%% encode_small_number(Len).
587
encode_length(undefined,Len) -> % un-constrained
593
true -> % should be able to endode length >= 16384
594
exit({error,{asn1,{encode_length,{nyi,above_16k}}}})
597
encode_length({0,'MAX'},Len) ->
598
encode_length(undefined,Len);
599
encode_length(Vr={Lb,Ub},Len) when Ub =< 65535 ,Lb >= 0 -> % constrained
600
encode_constrained_number(Vr,Len);
601
encode_length({Lb,_Ub},Len) when integer(Lb), Lb >= 0 -> % Ub > 65535
602
encode_length(undefined,Len);
603
encode_length({Vr={Lb,Ub},Ext},Len)
604
when Ub =< 65535 ,Lb >= 0, Len=<Ub, is_list(Ext) ->
605
%% constrained extensible
606
[<<0:1>>,encode_constrained_number(Vr,Len)];
607
encode_length({{Lb,_Ub},Ext},Len) when is_list(Ext) ->
608
[<<1:1>>,encode_semi_constrained_number(Lb,Len)];
609
encode_length(SingleValue,_Len) when integer(SingleValue) ->
612
%% X.691 10.9.3.4 (only used for length of bitmap that prefixes extension
613
%% additions in a sequence or set
614
encode_small_length(Len) when Len =< 64 ->
616
encode_small_length(Len) ->
617
[<<1:1>>,encode_length(undefined,Len)].
620
decode_small_length(Buffer) ->
621
case getbit(Buffer) of
623
{Bits,Remain2} = getbits(Remain,6),
626
decode_length(Remain,undefined)
629
decode_length(Buffer) ->
630
decode_length(Buffer,undefined).
633
decode_length(<<0:1,Oct:7,Rest/bitstring>>,undefined) ->
635
decode_length(<<2:2,Val:14,Rest/bitstring>>,undefined) ->
637
decode_length(<<3:2,_:14,_Rest/bitstring>>,undefined) ->
638
exit({error,{asn1,{decode_length,{nyi,above_16k}}}});
640
decode_length(Buffer,{Lb,Ub}) when Ub =< 65535 ,Lb >= 0 -> % constrained
641
decode_constrained_number(Buffer,{Lb,Ub});
642
decode_length(Buffer,{Lb,_}) when integer(Lb), Lb >= 0 -> % Ub > 65535
643
decode_length(Buffer,undefined);
644
decode_length(Buffer,{VR={_Lb,_Ub},Ext}) when is_list(Ext) ->
645
{0,Buffer2} = getbit(Buffer),
646
decode_length(Buffer2, VR);
649
%When does this case occur with {_,_Lb,Ub} ??
651
decode_length(Bin,{_,_Lb,_Ub}) -> %when Len =< 127 -> % Unconstrained or large Ub NOTE! this case does not cover case when Ub > 65535
653
<<0:1,Val:7,Rest/bitstring>> ->
655
<<2:2,Val:14,Rest/bitstring>> ->
657
<<3:2,_:14,_Rest/bitstring>> ->
658
exit({error,{asn1,{decode_length,{nyi,length_above_64K}}}})
660
decode_length(Buffer,SingleValue) when integer(SingleValue) ->
661
{SingleValue,Buffer}.
665
encode_boolean(true) ->
667
encode_boolean(false) ->
669
encode_boolean({Name,Val}) when atom(Name) ->
671
encode_boolean(Val) ->
672
exit({error,{asn1,{encode_boolean,Val}}}).
674
decode_boolean(Buffer) -> %when record(Buffer,buffer)
675
case getbit(Buffer) of
676
{1,Remain} -> {true,Remain};
677
{0,Remain} -> {false,Remain}
681
%% ENUMERATED with extension marker
682
decode_enumerated(Buffer,C,{Ntup1,Ntup2}) when tuple(Ntup1), tuple(Ntup2) ->
683
{Ext,Buffer2} = getext(Buffer),
685
0 -> % not an extension value
686
{Val,Buffer3} = decode_integer(Buffer2,C),
687
case catch (element(Val+1,Ntup1)) of
688
NewVal when atom(NewVal) -> {NewVal,Buffer3};
689
_Error -> exit({error,{asn1,{decode_enumerated,{Val,[Ntup1,Ntup2]}}}})
691
1 -> % this an extension value
692
{Val,Buffer3} = decode_small_number(Buffer2),
693
case catch (element(Val+1,Ntup2)) of
694
NewVal when atom(NewVal) -> {NewVal,Buffer3};
695
_ -> {{asn1_enum,Val},Buffer3}
699
decode_enumerated(Buffer,C,NamedNumberTup) when tuple(NamedNumberTup) ->
700
{Val,Buffer2} = decode_integer(Buffer,C),
701
case catch (element(Val+1,NamedNumberTup)) of
702
NewVal when atom(NewVal) -> {NewVal,Buffer2};
703
_Error -> exit({error,{asn1,{decode_enumerated,{Val,NamedNumberTup}}}})
707
%%============================================================================
708
%%============================================================================
709
%% Bitstring value, ITU_T X.690 Chapter 8.5
710
%%============================================================================
711
%%============================================================================
713
%%============================================================================
714
%% encode bitstring value
715
%%============================================================================
719
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
720
%% bitstring NamedBitList
722
%% - [identifiers] where only named identifers are set to one,
723
%% the Constraint must then have some information of the
725
%% - [list of ones and zeroes] all bits
726
%% - integer value representing the bitlist
727
%% C is constraint Len, only valid when identifiers
730
%% when the value is a list of {Unused,BinBits}, where
731
%% Unused = integer(),
732
%% BinBits = binary().
734
encode_bit_string(C,Bin={Unused,BinBits},NamedBitList) when integer(Unused),
736
encode_bin_bit_string(get_constraint(C,'SizeConstraint'),Bin,NamedBitList);
738
encode_bit_string(C, BitListVal, NamedBitList) ->
739
encode_bit_string1(get_constraint(C,'SizeConstraint'), BitListVal, NamedBitList).
740
%% when the value is a list of named bits
741
encode_bit_string1(C, LoNB=[FirstVal | _RestVal], NamedBitList) when atom(FirstVal) ->
742
ToSetPos = get_all_bitposes(LoNB, NamedBitList, []),
743
BitList = make_and_set_list(ToSetPos,0),
744
encode_bit_string1(C,BitList,NamedBitList);
746
encode_bit_string1(C, BL=[{bit,_No} | _RestVal], NamedBitList) ->
747
ToSetPos = get_all_bitposes(BL, NamedBitList, []),
748
BitList = make_and_set_list(ToSetPos,0),
749
encode_bit_string1(C,BitList,NamedBitList);
750
%% when the value is a list of ones and zeroes
751
encode_bit_string1(Int, BitListValue, _)
752
when list(BitListValue),integer(Int) ->
753
%% The type is constrained by a single value size constraint
754
bit_list2bitstr(Int,BitListValue);
755
encode_bit_string1(no, BitListValue,[])
756
when list(BitListValue) ->
757
Len = length(BitListValue),
758
[encode_length(undefined,Len),bit_list2bitstr(Len,BitListValue)];
759
encode_bit_string1(C, BitListValue,[])
760
when list(BitListValue) ->
761
Len = length(BitListValue),
762
[encode_length(C,Len),bit_list2bitstr(Len,BitListValue)];
763
encode_bit_string1(no, BitListValue,_NamedBitList)
764
when list(BitListValue) ->
765
%% this case with an unconstrained BIT STRING can be made more efficient
766
%% if the complete driver can take a special code so the length field
768
NewBitLVal = lists:reverse(lists:dropwhile(fun(0)->true;(1)->false end,
769
lists:reverse(BitListValue))),
770
Len = length(NewBitLVal),
771
[encode_length(undefined,Len),bit_list2bitstr(Len,NewBitLVal)];
772
encode_bit_string1(C,BitListValue,_NamedBitList)
773
when list(BitListValue) ->% C = {_,'MAX'}
774
NewBitStr = bitstr_trailing_zeros(BitListValue,C),
775
[encode_length(C,bit_size(NewBitStr)),NewBitStr];
778
%% when the value is an integer
779
encode_bit_string1(C, IntegerVal, NamedBitList) when integer(IntegerVal)->
780
BitList = int_to_bitlist(IntegerVal),
781
encode_bit_string1(C,BitList,NamedBitList);
783
%% when the value is a tuple
784
encode_bit_string1(C,{Name,Val}, NamedBitList) when atom(Name) ->
785
encode_bit_string1(C,Val,NamedBitList).
787
bit_list2bitstr(Len,BitListValue) ->
788
case length(BitListValue) of
790
<< <<B:1>> ||B <- BitListValue>>;
791
L when L > Len -> % truncate
792
<< << <<B:1>> ||B <- BitListValue>> :Len/bitstring>>;
793
L -> % Len > L -> pad
794
<< << <<B:1>> ||B <- BitListValue>>/bitstring ,0:(Len-L)>>
797
adjust_trailing_zeros(Len,Bin) when Len == size(Bin) ->
799
adjust_trailing_zeros(Len,Bin) when Len > bit_size(Bin) ->
800
<<Bin/bitstring,0:(Len-bit_size(Bin))>>;
801
adjust_trailing_zeros(Len,Bin) ->
802
<<Bin:Len/bitstring>>.
804
bitstr_trailing_zeros(BitList,C) when integer(C) ->
805
bitstr_trailing_zeros1(BitList,C,C);
806
bitstr_trailing_zeros(BitList,{Lb,Ub}) when integer(Lb) ->
807
bitstr_trailing_zeros1(BitList,Lb,Ub);
808
bitstr_trailing_zeros(BitList,{{Lb,Ub},_}) when integer(Lb) ->
809
bitstr_trailing_zeros1(BitList,Lb,Ub);
810
bitstr_trailing_zeros(BitList,_) ->
811
bit_list2bitstr(length(BitList),BitList).
813
bitstr_trailing_zeros1(BitList,Lb,Ub) ->
814
case length(BitList) of
815
Lb -> bit_list2bitstr(Lb,BitList);
816
B when B<Lb -> bit_list2bitstr(Lb,BitList);
817
D -> F = fun(L,LB,LB,_,_)->bit_list2bitstr(LB,lists:reverse(L));
818
([0|R],L1,LB,UB,Fun)->Fun(R,L1-1,LB,UB,Fun);
819
(L,L1,_,UB,_)when L1 =< UB ->
820
bit_list2bitstr(L1,lists:reverse(L));
821
(_,_L1,_,_,_) ->exit({error,{list_length_BIT_STRING,
823
F(lists:reverse(BitList),D,Lb,Ub,F)
826
%% encode_bin_bit_string/3, when value is a tuple of Unused and BinBits.
827
%% Unused = integer(),i.e. number unused bits in least sign. byte of
828
%% BinBits = binary().
829
encode_bin_bit_string(C,{_,BinBits},_NamedBitList)
830
when integer(C),C=<16 ->
831
adjust_trailing_zeros(C,BinBits);
832
encode_bin_bit_string(C,{_Unused,BinBits},_NamedBitList)
834
adjust_trailing_zeros(C,BinBits);
835
encode_bin_bit_string(C,UnusedAndBin={_,_},NamedBitList) ->
836
%% removes all trailing bits if NamedBitList is not empty
837
BitStr = remove_trailing_bin(NamedBitList,UnusedAndBin),
839
{Lb,Ub} when integer(Lb),integer(Ub) ->
840
[encode_length({Lb,Ub},bit_size(BitStr)),BitStr];
842
[encode_length(undefined,bit_size(BitStr)),BitStr];
844
[encode_length(Sc,bit_size(BitStr)),BitStr]
848
remove_trailing_bin([], {Unused,Bin}) ->
849
BS = bit_size(Bin)-Unused,
850
<<BitStr:BS/bitstring,_:Unused>> = Bin,
852
remove_trailing_bin(_NamedNumberList,{_Unused,<<>>}) ->
854
remove_trailing_bin(NamedNumberList, {_Unused,Bin}) ->
856
<<Bfront:Size/binary, LastByte:8>> = Bin,
858
%% clear the Unused bits to be sure
859
Unused1 = trailingZeroesInNibble(LastByte band 15),
863
4 + trailingZeroesInNibble(LastByte bsr 4);
868
remove_trailing_bin(NamedNumberList,{0,Bfront});
870
BS = bit_size(Bin) - Unused2,
871
<<BitStr:BS/bitstring,_:Unused2>> = Bin,
875
trailingZeroesInNibble(0) ->
877
trailingZeroesInNibble(1) ->
879
trailingZeroesInNibble(2) ->
881
trailingZeroesInNibble(3) ->
883
trailingZeroesInNibble(4) ->
885
trailingZeroesInNibble(5) ->
887
trailingZeroesInNibble(6) ->
889
trailingZeroesInNibble(7) ->
891
trailingZeroesInNibble(8) ->
893
trailingZeroesInNibble(9) ->
895
trailingZeroesInNibble(10) ->
897
trailingZeroesInNibble(11) ->
899
trailingZeroesInNibble(12) -> %#1100
901
trailingZeroesInNibble(13) ->
903
trailingZeroesInNibble(14) ->
905
trailingZeroesInNibble(15) ->
909
%% The result is presented as a list of named bits (if possible)
910
%% else as a tuple {Unused,Bits}. Unused is the number of unused
911
%% bits, least significant bits in the last byte of Bits. Bits is
912
%% the BIT STRING represented as a binary.
914
decode_compact_bit_string(Buffer, C, NamedNumberList) ->
915
case get_constraint(C,'SizeConstraint') of
918
V when integer(V),V=<16 -> %fixed length 16 bits or less
919
compact_bit_string(Buffer,V,NamedNumberList);
920
V when integer(V),V=<65536 -> %fixed length > 16 bits
921
compact_bit_string(Buffer,V,NamedNumberList);
922
V when integer(V) -> % V > 65536 => fragmented value
923
{Bin,Buffer2} = decode_fragmented_bits(Buffer,V),
924
PadLen = (8 - (bit_size(Bin) rem 8)) rem 8,
925
{{PadLen,<<Bin/bitstring,0:PadLen>>},Buffer2};
926
%% {0,_} -> {{0,Bin},Buffer2};
927
%% {U,_} -> {{8-U,Bin},Buffer2}
928
{Lb,Ub} when integer(Lb),integer(Ub) ->
929
%% This case may demand decoding of fragmented length/value
930
{Len,Bytes2} = decode_length(Buffer,{Lb,Ub}),
931
compact_bit_string(Bytes2,Len,NamedNumberList);
933
%% This case may demand decoding of fragmented length/value
934
{Len,Bytes2} = decode_length(Buffer,undefined),
935
compact_bit_string(Bytes2,Len,NamedNumberList);
937
{Len,Bytes2} = decode_length(Buffer,Sc),
938
compact_bit_string(Bytes2,Len,NamedNumberList)
943
%% The result is presented as a list of named bits (if possible)
944
%% else as a list of 0 and 1.
946
decode_bit_string(Buffer, C, NamedNumberList) ->
947
case get_constraint(C,'SizeConstraint') of
948
{Lb,Ub} when integer(Lb),integer(Ub) ->
949
{Len,Bytes2} = decode_length(Buffer,{Lb,Ub}),
950
bit_list_or_named(Bytes2,Len,NamedNumberList);
952
{Len,Bytes2} = decode_length(Buffer,undefined),
953
bit_list_or_named(Bytes2,Len,NamedNumberList);
955
{[],Buffer}; % nothing to encode
956
V when integer(V),V=<16 -> % fixed length 16 bits or less
957
bit_list_or_named(Buffer,V,NamedNumberList);
958
V when integer(V),V=<65536 ->
959
bit_list_or_named(Buffer,V,NamedNumberList);
961
{BinBits,_} = decode_fragmented_bits(Buffer,V),
962
bit_list_or_named(BinBits,V,NamedNumberList);
963
Sc -> % extension marker
964
{Len,Bytes2} = decode_length(Buffer,Sc),
965
bit_list_or_named(Bytes2,Len,NamedNumberList)
969
%% if no named bits are declared we will return a
970
%% {Unused,Bits}. Unused = integer(),
972
compact_bit_string(Buffer,Len,[]) ->
973
{BitStr,Rest} = getbits_as_binary(Len,Buffer), % {{Unused,BinBits},NewBuffer}
974
PadLen = (8 - (bit_size(BitStr) rem 8)) rem 8,
975
{{PadLen,<<BitStr/bitstring,0:PadLen>>},Rest};
976
compact_bit_string(Buffer,Len,NamedNumberList) ->
977
bit_list_or_named(Buffer,Len,NamedNumberList).
980
%% if no named bits are declared we will return a
983
bit_list_or_named(Buffer,Len,[]) ->
984
getbits_as_list(Len,Buffer);
986
%% if there are named bits declared we will return a named
987
%% BitList where the names are atoms and unnamed bits represented
989
%% BitList = [atom() | {bit,Pos}]
992
bit_list_or_named(Buffer,Len,NamedNumberList) ->
993
{BitList,Rest} = getbits_as_list(Len,Buffer),
994
{bit_list_or_named1(0,BitList,NamedNumberList,[]), Rest}.
996
bit_list_or_named1(Pos,[0|Bt],Names,Acc) ->
997
bit_list_or_named1(Pos+1,Bt,Names,Acc);
998
bit_list_or_named1(Pos,[1|Bt],Names,Acc) ->
999
case lists:keysearch(Pos,2,Names) of
1001
bit_list_or_named1(Pos+1,Bt,Names,[Name|Acc]);
1003
bit_list_or_named1(Pos+1,Bt,Names,[{bit,Pos}|Acc])
1005
bit_list_or_named1(_,[],_,Acc) ->
1013
int_to_bitlist(Int) when integer(Int), Int > 0 ->
1014
[Int band 1 | int_to_bitlist(Int bsr 1)];
1015
int_to_bitlist(0) ->
1020
%% get_all_bitposes([list of named bits to set], named_bit_db, []) ->
1021
%% [sorted_list_of_bitpositions_to_set]
1023
get_all_bitposes([{bit,ValPos}|Rest], NamedBitList, Ack) ->
1024
get_all_bitposes(Rest, NamedBitList, [ValPos | Ack ]);
1026
get_all_bitposes([Val | Rest], NamedBitList, Ack) ->
1027
case lists:keysearch(Val, 1, NamedBitList) of
1028
{value, {_ValName, ValPos}} ->
1029
get_all_bitposes(Rest, NamedBitList, [ValPos | Ack]);
1031
exit({error,{asn1, {bitstring_namedbit, Val}}})
1033
get_all_bitposes([], _NamedBitList, Ack) ->
1037
%% make_and_set_list([list of positions to set to 1])->
1038
%% returns list with all in SetPos set.
1039
%% in positioning in list the first element is 0, the second 1 etc.., but
1042
make_and_set_list([XPos|SetPos], XPos) ->
1043
[1 | make_and_set_list(SetPos, XPos + 1)];
1044
make_and_set_list([Pos|SetPos], XPos) ->
1045
[0 | make_and_set_list([Pos | SetPos], XPos + 1)];
1046
make_and_set_list([], _) ->
1049
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1051
%% encode_octet_string(Constraint,Val)
1052
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1054
encode_octet_string(C,{_Name,Val}) ->
1055
encode_octet_string(C,Val);
1056
encode_octet_string(C,Val) ->
1057
case get_constraint(C,'SizeConstraint') of
1061
list_to_binary(Val);
1063
list_to_binary(Val);
1064
Sv when Sv =<65535, Sv == length(Val) -> % fixed length
1065
list_to_binary(Val);
1067
[encode_length(VR,length(Val)),list_to_binary(Val)];
1069
[encode_length({hd(Sv),lists:max(Sv)},length(Val)),list_to_binary(Val)];
1071
[encode_length(undefined,length(Val)),list_to_binary(Val)]
1074
decode_octet_string(Bytes,C) ->
1075
decode_octet_string1(Bytes,get_constraint(C,'SizeConstraint')).
1076
decode_octet_string1(<<B1,Bytes/bitstring>>,1) ->
1078
decode_octet_string1(<<B1,B2,Bytes/bitstring>>,2) ->
1080
decode_octet_string1(Bytes,Sv) when integer(Sv),Sv=<65535 ->
1081
getoctets_as_list(Bytes,Sv);
1082
decode_octet_string1(Bytes,Sv) when integer(Sv) ->
1083
decode_fragmented_octets(Bytes,Sv);
1084
decode_octet_string1(Bytes,{Lb,Ub}) ->
1085
{Len,Bytes2} = decode_length(Bytes,{Lb,Ub}),
1086
getoctets_as_list(Bytes2,Len);
1087
decode_octet_string1(Bytes,Sv) when list(Sv) ->
1088
{Len,Bytes2} = decode_length(Bytes,{hd(Sv),lists:max(Sv)}),
1089
getoctets_as_list(Bytes2,Len);
1090
decode_octet_string1(Bytes,no) ->
1091
{Len,Bytes2} = decode_length(Bytes,undefined),
1092
getoctets_as_list(Bytes2,Len).
1096
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1097
%% Restricted char string types
1098
%% (NumericString, PrintableString,VisibleString,IA5String,BMPString,UniversalString)
1099
%% X.691:26 and X.680:34-36
1100
%%encode_restricted_string('BMPString',Constraints,Extension,Val)
1103
encode_restricted_string({Name,Val}) when atom(Name) ->
1104
encode_restricted_string(Val);
1106
encode_restricted_string(Val) when list(Val)->
1107
[encode_length(undefined,length(Val)),list_to_binary(Val)].
1109
encode_known_multiplier_string(StringType,C,{Name,Val}) when atom(Name) ->
1110
encode_known_multiplier_string(StringType,C,Val);
1112
encode_known_multiplier_string(StringType,C,Val) ->
1113
Result = chars_encode(C,StringType,Val),
1114
NumBits = get_NumBits(C,StringType),
1115
case get_constraint(C,'SizeConstraint') of
1116
Ub when integer(Ub), Ub*NumBits =< 16 ->
1120
Ub when integer(Ub),Ub =<65535 -> % fixed length
1123
[encode_length({Ub,Lb},length(Val)),Result];
1125
[encode_length({lists:min(Vl),lists:max(Vl)},length(Val)),Result];
1127
[encode_length(undefined,length(Val)),Result]
1130
decode_restricted_string(Bytes) ->
1131
{Len,Bytes2} = decode_length(Bytes,undefined),
1132
getoctets_as_list(Bytes2,Len).
1134
decode_known_multiplier_string(Bytes,StringType,C,_Ext) ->
1135
NumBits = get_NumBits(C,StringType),
1136
case get_constraint(C,'SizeConstraint') of
1137
Ub when integer(Ub), Ub*NumBits =< 16 ->
1138
chars_decode(Bytes,NumBits,StringType,C,Ub);
1139
Ub when integer(Ub),Ub =<65535 -> % fixed length
1140
chars_decode(Bytes,NumBits,StringType,C,Ub);
1144
{Len,Bytes1} = decode_length(Bytes,{hd(Vl),lists:max(Vl)}),
1145
chars_decode(Bytes1,NumBits,StringType,C,Len);
1147
{Len,Bytes1} = decode_length(Bytes,undefined),
1148
chars_decode(Bytes1,NumBits,StringType,C,Len);
1150
{Len,Bytes1} = decode_length(Bytes,{Lb,Ub}),
1151
chars_decode(Bytes1,NumBits,StringType,C,Len)
1155
encode_NumericString(C,Val) ->
1156
encode_known_multiplier_string('NumericString',C,Val).
1157
decode_NumericString(Bytes,C) ->
1158
decode_known_multiplier_string(Bytes,'NumericString',C,false).
1160
encode_PrintableString(C,Val) ->
1161
encode_known_multiplier_string('PrintableString',C,Val).
1162
decode_PrintableString(Bytes,C) ->
1163
decode_known_multiplier_string(Bytes,'PrintableString',C,false).
1165
encode_VisibleString(C,Val) -> % equivalent with ISO646String
1166
encode_known_multiplier_string('VisibleString',C,Val).
1167
decode_VisibleString(Bytes,C) ->
1168
decode_known_multiplier_string(Bytes,'VisibleString',C,false).
1170
encode_IA5String(C,Val) ->
1171
encode_known_multiplier_string('IA5String',C,Val).
1172
decode_IA5String(Bytes,C) ->
1173
decode_known_multiplier_string(Bytes,'IA5String',C,false).
1175
encode_BMPString(C,Val) ->
1176
encode_known_multiplier_string('BMPString',C,Val).
1177
decode_BMPString(Bytes,C) ->
1178
decode_known_multiplier_string(Bytes,'BMPString',C,false).
1180
encode_UniversalString(C,Val) ->
1181
encode_known_multiplier_string('UniversalString',C,Val).
1182
decode_UniversalString(Bytes,C) ->
1183
decode_known_multiplier_string(Bytes,'UniversalString',C,false).
1186
%% end of known-multiplier strings for which PER visible constraints are
1189
encode_GeneralString(_C,Val) ->
1190
encode_restricted_string(Val).
1191
decode_GeneralString(Bytes,_C) ->
1192
decode_restricted_string(Bytes).
1194
encode_GraphicString(_C,Val) ->
1195
encode_restricted_string(Val).
1196
decode_GraphicString(Bytes,_C) ->
1197
decode_restricted_string(Bytes).
1199
encode_ObjectDescriptor(_C,Val) ->
1200
encode_restricted_string(Val).
1201
decode_ObjectDescriptor(Bytes) ->
1202
decode_restricted_string(Bytes).
1204
encode_TeletexString(_C,Val) -> % equivalent with T61String
1205
encode_restricted_string(Val).
1206
decode_TeletexString(Bytes,_C) ->
1207
decode_restricted_string(Bytes).
1209
encode_VideotexString(_C,Val) ->
1210
encode_restricted_string(Val).
1211
decode_VideotexString(Bytes,_C) ->
1212
decode_restricted_string(Bytes).
1217
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1218
%% getBMPChars(Bytes,Len) ->{BMPcharList,RemainingBytes}
1220
getBMPChars(Bytes,1) ->
1221
{O1,Bytes2} = getbits(Bytes,8),
1222
{O2,Bytes3} = getbits(Bytes2,8),
1227
{[{0,0,O1,O2}],Bytes3}
1229
getBMPChars(Bytes,Len) ->
1230
getBMPChars(Bytes,Len,[]).
1232
getBMPChars(Bytes,0,Acc) ->
1233
{lists:reverse(Acc),Bytes};
1234
getBMPChars(Bytes,Len,Acc) ->
1235
{Octs,Bytes1} = getoctets_as_list(Bytes,2),
1238
getBMPChars(Bytes1,Len-1,[O2|Acc]);
1240
getBMPChars(Bytes1,Len-1,[{0,0,O1,O2}|Acc])
1244
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1245
%% chars_encode(C,StringType,Value) -> ValueList
1247
%% encodes chars according to the per rules taking the constraint PermittedAlphabet
1249
%% This function does only encode the value part and NOT the length
1251
chars_encode(C,StringType,Value) ->
1252
case {StringType,get_constraint(C,'PermittedAlphabet')} of
1253
{'UniversalString',{_,_Sv}} ->
1254
exit({error,{asn1,{'not implemented',"UniversalString with PermittedAlphabet constraint"}}});
1255
{'BMPString',{_,_Sv}} ->
1256
exit({error,{asn1,{'not implemented',"BMPString with PermittedAlphabet constraint"}}});
1258
{NumBits,CharOutTab} = {get_NumBits(C,StringType),get_CharOutTab(C,StringType)},
1259
chars_encode2(Value,NumBits,CharOutTab)
1262
chars_encode2([H|T],NumBits,{Min,Max,notab}) when H =< Max, H >= Min ->
1263
%%[{bits,NumBits,H-Min}|chars_encode2(T,NumBits,{Min,Max,notab})];
1264
[<<(H-Min):NumBits>>|chars_encode2(T,NumBits,{Min,Max,notab})];
1265
chars_encode2([H|T],NumBits,{Min,Max,Tab}) when H =< Max, H >= Min ->
1266
%% [{bits,NumBits,exit_if_false(H,element(H-Min+1,Tab))}|chars_encode2(T,NumBits,{Min,Max,Tab})];
1267
Ch = exit_if_false(H,element(H-Min+1,Tab)),
1268
[<<Ch:NumBits>>|chars_encode2(T,NumBits,{Min,Max,Tab})];
1269
chars_encode2([{A,B,C,D}|T],NumBits,{Min,Max,notab}) ->
1270
%% no value range check here (ought to be, but very expensive)
1271
%% [{bits,NumBits,((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min}|chars_encode2(T,NumBits,{Min,Max,notab})];
1272
Ch = ((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min,
1273
[<<Ch:NumBits>>|chars_encode2(T,NumBits,{Min,Max,notab})];
1274
chars_encode2([{A,B,C,D}|T],NumBits,{Min,Max,Tab}) ->
1275
%% no value range check here (ought to be, but very expensive)
1276
%% [{bits,NumBits,exit_if_false({A,B,C,D},element(((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min,Tab))}|chars_encode2(T,NumBits,{Min,Max,notab})];
1277
Ch = exit_if_false({A,B,C,D},element(((((((A bsl 8)+B) bsl 8)+C) bsl 8)+D)-Min,Tab)),
1278
[<<Ch:NumBits>>|chars_encode2(T,NumBits,{Min,Max,notab})];
1279
chars_encode2([H|_T],_,{_,_,_}) ->
1280
exit({error,{asn1,{illegal_char_value,H}}});
1281
chars_encode2([],_,_) ->
1284
exit_if_false(V,false)->
1285
exit({error,{asn1,{"illegal value according to Permitted alphabet constraint",V}}});
1286
exit_if_false(_,V) ->V.
1289
get_NumBits(C,StringType) ->
1290
case get_constraint(C,'PermittedAlphabet') of
1291
{'SingleValue',Sv} ->
1292
charbits(length(Sv));
1296
charbits(128); % 16#00..16#7F
1298
charbits(95); % 16#20..16#7E
1299
'PrintableString' ->
1300
charbits(74); % [$\s,$',$(,$),$+,$,,$-,$.,$/,"0123456789",$:,$=,$?,$A..$Z,$a..$z
1302
charbits(11); % $ ,"0123456789"
1303
'UniversalString' ->
1310
get_CharOutTab(C,StringType) ->
1311
get_CharTab(C,StringType,out).
1313
get_CharInTab(C,StringType) ->
1314
get_CharTab(C,StringType,in).
1316
get_CharTab(C,StringType,InOut) ->
1317
case get_constraint(C,'PermittedAlphabet') of
1318
{'SingleValue',Sv} ->
1319
get_CharTab2(C,StringType,hd(Sv),lists:max(Sv),Sv,InOut);
1325
get_CharTab2(C,StringType,16#20,16#7F,notab,InOut);
1326
'PrintableString' ->
1328
" '()+,-./0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"),
1329
get_CharTab2(C,StringType,hd(Chars),lists:max(Chars),Chars,InOut);
1331
get_CharTab2(C,StringType,16#20,$9," 0123456789",InOut);
1332
'UniversalString' ->
1333
{0,16#FFFFFFFF,notab};
1339
get_CharTab2(C,StringType,Min,Max,Chars,InOut) ->
1340
BitValMax = (1 bsl get_NumBits(C,StringType))-1,
1347
{Min,Max,create_char_tab(Min,Chars)};
1349
{Min,Max,list_to_tuple(Chars)}
1353
create_char_tab(Min,L) ->
1354
list_to_tuple(create_char_tab(Min,L,0)).
1355
create_char_tab(Min,[Min|T],V) ->
1356
[V|create_char_tab(Min+1,T,V+1)];
1357
create_char_tab(_Min,[],_V) ->
1359
create_char_tab(Min,L,V) ->
1360
[false|create_char_tab(Min+1,L,V)].
1362
%% See Table 20.3 in Dubuisson
1363
charbits(NumOfChars) when NumOfChars =< 2 -> 1;
1364
charbits(NumOfChars) when NumOfChars =< 4 -> 2;
1365
charbits(NumOfChars) when NumOfChars =< 8 -> 3;
1366
charbits(NumOfChars) when NumOfChars =< 16 -> 4;
1367
charbits(NumOfChars) when NumOfChars =< 32 -> 5;
1368
charbits(NumOfChars) when NumOfChars =< 64 -> 6;
1369
charbits(NumOfChars) when NumOfChars =< 128 -> 7;
1370
charbits(NumOfChars) when NumOfChars =< 256 -> 8;
1371
charbits(NumOfChars) when NumOfChars =< 512 -> 9;
1372
charbits(NumOfChars) when NumOfChars =< 1024 -> 10;
1373
charbits(NumOfChars) when NumOfChars =< 2048 -> 11;
1374
charbits(NumOfChars) when NumOfChars =< 4096 -> 12;
1375
charbits(NumOfChars) when NumOfChars =< 8192 -> 13;
1376
charbits(NumOfChars) when NumOfChars =< 16384 -> 14;
1377
charbits(NumOfChars) when NumOfChars =< 32768 -> 15;
1378
charbits(NumOfChars) when NumOfChars =< 65536 -> 16;
1379
charbits(NumOfChars) when integer(NumOfChars) ->
1380
16 + charbits1(NumOfChars bsr 16).
1384
charbits1(NumOfChars) ->
1385
1 + charbits1(NumOfChars bsr 1).
1388
chars_decode(Bytes,_,'BMPString',C,Len) ->
1389
case get_constraint(C,'PermittedAlphabet') of
1391
getBMPChars(Bytes,Len);
1395
"BMPString with PermittedAlphabet constraint"}}})
1397
chars_decode(Bytes,NumBits,StringType,C,Len) ->
1398
CharInTab = get_CharInTab(C,StringType),
1399
chars_decode2(Bytes,CharInTab,NumBits,Len).
1402
chars_decode2(Bytes,CharInTab,NumBits,Len) ->
1403
chars_decode2(Bytes,CharInTab,NumBits,Len,[]).
1405
chars_decode2(Bytes,_CharInTab,_NumBits,0,Acc) ->
1406
{lists:reverse(Acc),Bytes};
1407
chars_decode2(Bytes,{Min,Max,notab},NumBits,Len,Acc) when NumBits > 8 ->
1408
{Char,Bytes2} = getbits(Bytes,NumBits),
1413
list_to_tuple(binary_to_list(<<Char:32>>))
1415
chars_decode2(Bytes2,{Min,Max,notab},NumBits,Len -1,[Result|Acc]);
1416
chars_decode2(Bytes,{Min,Max,notab},NumBits,Len,Acc) ->
1417
{Char,Bytes2} = getbits(Bytes,NumBits),
1418
chars_decode2(Bytes2,{Min,Max,notab},NumBits,Len -1,[Char+Min|Acc]);
1420
%% BMPString and UniversalString with PermittedAlphabet is currently not supported
1421
chars_decode2(Bytes,{Min,Max,CharInTab},NumBits,Len,Acc) ->
1422
{Char,Bytes2} = getbits(Bytes,NumBits),
1423
chars_decode2(Bytes2,{Min,Max,CharInTab},NumBits,Len -1,[element(Char+1,CharInTab)|Acc]).
1427
encode_UTF8String(Val) when binary(Val) ->
1428
[encode_length(undefined,size(Val)),Val];
1429
encode_UTF8String(Val) ->
1430
Bin = list_to_binary(Val),
1431
encode_UTF8String(Bin).
1433
decode_UTF8String(Bytes) ->
1434
{Len,Bytes2} = decode_length(Bytes,undefined),
1435
getoctets_as_bin(Bytes2,Len).
1439
encode_null(_) -> []. % encodes to nothing
1441
decode_null(Bytes) ->
1444
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1445
%% encode_object_identifier(Val) -> CompleteList
1446
%% encode_object_identifier({Name,Val}) -> CompleteList
1447
%% Val -> {Int1,Int2,...,IntN} % N >= 2
1449
%% Int1 -> integer(0..2)
1450
%% Int2 -> integer(0..39) when Int1 (0..1) else integer()
1451
%% Int3-N -> integer()
1452
%% CompleteList -> [binary()|bitstring()|list()]
1454
encode_object_identifier({Name,Val}) when atom(Name) ->
1455
encode_object_identifier(Val);
1456
encode_object_identifier(Val) ->
1457
OctetList = e_object_identifier(Val),
1458
Octets = list_to_binary(OctetList), % performs a flatten at the same time
1459
[encode_length(undefined,size(Octets)),Octets].
1461
%% This code is copied from asn1_encode.erl (BER) and corrected and modified
1463
e_object_identifier({'OBJECT IDENTIFIER',V}) ->
1464
e_object_identifier(V);
1465
e_object_identifier({Cname,V}) when atom(Cname),tuple(V) ->
1466
e_object_identifier(tuple_to_list(V));
1467
e_object_identifier({Cname,V}) when atom(Cname),list(V) ->
1468
e_object_identifier(V);
1469
e_object_identifier(V) when tuple(V) ->
1470
e_object_identifier(tuple_to_list(V));
1472
%% E1 = 0|1|2 and (E2 < 40 when E1 = 0|1)
1473
e_object_identifier([E1,E2|Tail]) when E1 >= 0, E1 < 2, E2 < 40 ; E1==2 ->
1474
Head = 40*E1 + E2, % weird
1475
e_object_elements([Head|Tail],[]);
1476
e_object_identifier(Oid=[_,_|_Tail]) ->
1477
exit({error,{asn1,{'illegal_value',Oid}}}).
1479
e_object_elements([],Acc) ->
1481
e_object_elements([H|T],Acc) ->
1482
e_object_elements(T,[e_object_element(H)|Acc]).
1484
e_object_element(Num) when Num < 128 ->
1486
e_object_element(Num) ->
1487
[e_o_e(Num bsr 7)|[Num band 2#1111111]].
1488
e_o_e(Num) when Num < 128 ->
1491
[e_o_e(Num bsr 7)|[(Num band 2#1111111) bor 2#10000000]].
1495
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1496
%% decode_object_identifier(Bytes) -> {ObjId,RemainingBytes}
1497
%% ObjId -> {integer(),integer(),...} % at least 2 integers
1498
%% RemainingBytes -> [integer()] when integer() (0..255)
1499
decode_object_identifier(Bytes) ->
1500
{Len,Bytes2} = decode_length(Bytes,undefined),
1501
{Octs,Bytes3} = getoctets_as_list(Bytes2,Len),
1502
[First|Rest] = dec_subidentifiers(Octs,0,[]),
1507
[1,First - 40|Rest];
1511
{list_to_tuple(Idlist),Bytes3}.
1513
dec_subidentifiers([H|T],Av,Al) when H >=16#80 ->
1514
dec_subidentifiers(T,(Av bsl 7) + (H band 16#7F),Al);
1515
dec_subidentifiers([H|T],Av,Al) ->
1516
dec_subidentifiers(T,0,[(Av bsl 7) + H |Al]);
1517
dec_subidentifiers([],_Av,Al) ->
1520
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1521
%% encode_relative_oid(Val) -> CompleteList
1522
%% encode_relative_oid({Name,Val}) -> CompleteList
1523
encode_relative_oid({Name,Val}) when is_atom(Name) ->
1524
encode_relative_oid(Val);
1525
encode_relative_oid(Val) when is_tuple(Val) ->
1526
encode_relative_oid(tuple_to_list(Val));
1527
encode_relative_oid(Val) when is_list(Val) ->
1528
Octets = list_to_binary([e_object_element(X)||X <- Val]),
1529
[encode_length(undefined,size(Octets)),Octets].
1532
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1533
%% decode_relative_oid(Val) -> CompleteList
1534
%% decode_relative_oid({Name,Val}) -> CompleteList
1535
decode_relative_oid(Bytes) ->
1536
{Len,Bytes2} = decode_length(Bytes,undefined),
1537
{Octs,Bytes3} = getoctets_as_list(Bytes2,Len),
1538
ObjVals = dec_subidentifiers(Octs,0,[]),
1539
{list_to_tuple(ObjVals),Bytes3}.
1542
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1543
%% encode_real(Val) -> CompleteList
1544
%% encode_real({Name,Val}) -> CompleteList
1545
encode_real({Name,Val}) when is_atom(Name) ->
1547
encode_real(Real) ->
1548
{EncVal,Len} = ?RT_COMMON:encode_real([],Real),
1549
[encode_length(undefined,Len),EncVal].
1552
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1553
%% decode_real(Val) -> {REALvalue,Rest}
1554
%% decode_real({Name,Val}) -> {REALvalue,Rest}
1555
decode_real(Bytes) ->
1556
{Len,Bytes2} = decode_length(Bytes,undefined),
1557
<<Bytes3:Len/binary,Rest/bitstring>> = Bytes2,
1558
{RealVal,Rest,Len} = ?RT_COMMON:decode_real(Bytes3,Len),
1562
get_constraint([{Key,V}],Key) ->
1564
get_constraint([],_Key) ->
1566
get_constraint(C,Key) ->
1567
case lists:keysearch(Key,1,C) of
1574
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1575
%% complete(InList) -> ByteList
1576
%% Takes a coded list with bits and bytes and converts it to a list of bytes
1577
%% Should be applied as the last step at encode of a complete ASN.1 type
1579
complete(InList) when is_list(InList) ->
1580
case complete1(InList) of
1584
case bit_size(Res) band 7 of
1586
Bits -> <<Res/bitstring,0:(8-Bits)>>
1589
complete(InList) when is_binary(InList) ->
1591
complete(InList) when is_bitstring(InList) ->
1592
PadLen = 8 - (bit_size(InList) band 7),
1593
<<InList/bitstring,0:PadLen>>.
1595
complete1(L) when is_list(L) ->
1596
list_to_bitstring(L).
1598
%% Special version of complete that does not align the completed message.
1599
complete_NFP(InList) when is_list(InList) ->
1600
list_to_bitstring(InList);
1601
complete_NFP(InList) when is_bitstring(InList) ->
1604
%% unaligned helpers
1607
num_bits(R) when R =< 4 ->
1609
num_bits(R) when R =< 8 ->
1611
num_bits(R) when R =< 16 ->
1613
num_bits(R) when R =< 32 ->
1615
num_bits(R) when R =< 64 ->
1617
num_bits(R) when R =< 128 ->
1619
num_bits(R) when R =< 255 ->
1621
num_bits(R) when R =< 511 ->
1623
num_bits(R) when R =< 1023 ->
1626
1+num_bits(R bsr 1).