From 79c59e5d6199ca3410d97aac47bac3be4f5d3089 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Mon, 21 Jan 2013 16:04:39 +0100 Subject: per,uper: Optimize decoding of the string data types --- lib/asn1/src/asn1ct_gen_per.erl | 39 +++++----- lib/asn1/src/asn1ct_gen_per_rt2ct.erl | 75 +++++-------------- lib/asn1/src/asn1ct_imm.erl | 97 ++++++++++++++++++++++++- lib/asn1/src/asn1rtt_per.erl | 64 ---------------- lib/asn1/src/asn1rtt_per_common.erl | 31 +++++++- lib/asn1/src/asn1rtt_uper.erl | 133 +++------------------------------- 6 files changed, 176 insertions(+), 263 deletions(-) diff --git a/lib/asn1/src/asn1ct_gen_per.erl b/lib/asn1/src/asn1ct_gen_per.erl index b38af3306a..25b0d46295 100644 --- a/lib/asn1/src/asn1ct_gen_per.erl +++ b/lib/asn1/src/asn1ct_gen_per.erl @@ -1131,6 +1131,22 @@ gen_dec_imm_1({'INTEGER',NamedNumberList}, Constraint, Aligned) -> asn1ct_imm:per_dec_named_integer(Constraint, NamedNumberList, Aligned); +gen_dec_imm_1('BMPString'=Type, Constraint, Aligned) -> + gen_dec_k_m_string(Type, Constraint, Aligned); +gen_dec_imm_1('NumericString'=Type, Constraint, Aligned) -> + gen_dec_k_m_string(Type, Constraint, Aligned); +gen_dec_imm_1('PrintableString'=Type, Constraint, Aligned) -> + gen_dec_k_m_string(Type, Constraint, Aligned); +gen_dec_imm_1('VisibleString'=Type, Constraint, Aligned) -> + gen_dec_k_m_string(Type, Constraint, Aligned); +gen_dec_imm_1('IA5String'=Type, Constraint, Aligned) -> + gen_dec_k_m_string(Type, Constraint, Aligned); +gen_dec_imm_1('UniversalString'=Type, Constraint, Aligned) -> + gen_dec_k_m_string(Type, Constraint, Aligned); +gen_dec_imm_1('UTCTime', Constraint, Aligned) -> + gen_dec_k_m_string('VisibleString', Constraint, Aligned); +gen_dec_imm_1('GeneralizedTime', Constraint, Aligned) -> + gen_dec_k_m_string('VisibleString', Constraint, Aligned); gen_dec_imm_1('OCTET STRING', Constraint, Aligned) -> SzConstr = get_constraint(Constraint, 'SizeConstraint'), Imm = asn1ct_imm:per_dec_octet_string(SzConstr, Aligned), @@ -1151,6 +1167,9 @@ gen_dec_copy_bitstring(Imm) -> end, {call,D,Imm}. +gen_dec_k_m_string(Type, Constraint, Aligned) -> + asn1ct_imm:per_dec_k_m_string(Type, Constraint, Aligned). + gen_dec_prim(Erule, Type, BytesVar) -> case gen_dec_imm(Erule, Type) of no -> @@ -1171,9 +1190,6 @@ gen_dec_prim_1(Erule, call(Erule, decode_relative_oid, [BytesVar]); 'ObjectDescriptor' -> call(Erule, decode_ObjectDescriptor, [BytesVar]); - 'NumericString' -> - call(Erule, decode_NumericString, - [BytesVar,{asis,Constraint}]); TString when TString == 'TeletexString'; TString == 'T61String' -> call(Erule, decode_TeletexString, @@ -1181,27 +1197,10 @@ gen_dec_prim_1(Erule, 'VideotexString' -> call(Erule, decode_VideotexString, [BytesVar,{asis,Constraint}]); - 'UTCTime' -> - call(Erule, decode_VisibleString, [BytesVar,{asis,Constraint}]); - 'GeneralizedTime' -> - call(Erule, decode_VisibleString, [BytesVar,{asis,Constraint}]); 'GraphicString' -> call(Erule, decode_GraphicString,[BytesVar,{asis,Constraint}]); - 'VisibleString' -> - call(Erule, decode_VisibleString, [BytesVar,{asis,Constraint}]); 'GeneralString' -> call(Erule, decode_GeneralString, [BytesVar,{asis,Constraint}]); - 'PrintableString' -> - call(Erule, decode_PrintableString, - [BytesVar,{asis,Constraint}]); - 'IA5String' -> - call(Erule, decode_IA5String, [BytesVar,{asis,Constraint}]); - 'BMPString' -> - call(Erule, decode_BMPString, - [BytesVar,{asis,Constraint}]); - 'UniversalString' -> - call(Erule, decode_UniversalString, - [BytesVar,{asis,Constraint}]); 'UTF8String' -> call(Erule, decode_UTF8String, [BytesVar]); #'ObjectClassFieldType'{} -> diff --git a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl index bf08494c5c..b6be3a1a8f 100644 --- a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl +++ b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl @@ -263,54 +263,26 @@ emit_enc_k_m_string(SizeC, NumBits, CharOutTab, Value) -> call(per, encode_known_multiplier_string, [{asis,SizeC},NumBits,{asis,CharOutTab},Value]). -emit_dec_known_multiplier_string(StringType,C,BytesVar) -> - SizeC = get_constraint(C,'SizeConstraint'), - PAlphabC = get_constraint(C,'PermittedAlphabet'), - case {StringType,PAlphabC} of - {'BMPString',{_,_}} -> - exit({error,{asn1, - {'not implemented', - "BMPString with PermittedAlphabet " - "constraint"}}}); - _ -> - ok - end, - NumBits = get_NumBits(C,StringType), - CharInTab = get_CharInTab(C,StringType), - case SizeC of - 0 -> - emit({"{[],",BytesVar,"}"}); - _ -> - call(per, decode_known_multiplier_string, - [{asis,StringType},{asis,SizeC},NumBits, - {asis,CharInTab},BytesVar]) - end. - %% copied from run time module -get_CharOutTab(C,StringType) -> - get_CharTab(C,StringType,out). - -get_CharInTab(C,StringType) -> - get_CharTab(C,StringType,in). - -get_CharTab(C,StringType,InOut) -> +get_CharOutTab(C, StringType) -> case get_constraint(C,'PermittedAlphabet') of {'SingleValue',Sv} -> - get_CharTab2(C,StringType,hd(Sv),lists:max(Sv),Sv,InOut); + get_CharTab2(C, StringType, hd(Sv), lists:max(Sv), Sv); no -> case StringType of 'IA5String' -> {0,16#7F,notab}; 'VisibleString' -> - get_CharTab2(C,StringType,16#20,16#7F,notab,InOut); + get_CharTab2(C, StringType, 16#20, 16#7F, notab); 'PrintableString' -> Chars = lists:sort( " '()+,-./0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), - get_CharTab2(C,StringType,hd(Chars),lists:max(Chars),Chars,InOut); + get_CharTab2(C, StringType, hd(Chars), + lists:max(Chars), Chars); 'NumericString' -> - get_CharTab2(C,StringType,16#20,$9," 0123456789",InOut); + get_CharTab2(C, StringType, 16#20, $9, " 0123456789"); 'UniversalString' -> {0,16#FFFFFFFF,notab}; 'BMPString' -> @@ -318,18 +290,13 @@ get_CharTab(C,StringType,InOut) -> end end. -get_CharTab2(C,StringType,Min,Max,Chars,InOut) -> +get_CharTab2(C, StringType, Min, Max, Chars) -> BitValMax = (1 bsl get_NumBits(C,StringType))-1, if Max =< BitValMax -> {0,Max,notab}; true -> - case InOut of - out -> - {Min,Max,create_char_tab(Min,Chars)}; - in -> - {Min,Max,list_to_tuple(Chars)} - end + {Min,Max,create_char_tab(Min,Chars)} end. create_char_tab(Min,L) -> @@ -1401,7 +1368,6 @@ gen_decode_user(Erules,D) when is_record(D,typedef) -> gen_dec_prim(Erules,Att,BytesVar) -> Typename = Att#type.def, - Constraint = Att#type.constraint, case Typename of 'INTEGER' -> asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar); @@ -1429,8 +1395,7 @@ gen_dec_prim(Erules,Att,BytesVar) -> asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar); 'NumericString' -> - emit_dec_known_multiplier_string('NumericString', - Constraint,BytesVar); + asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar); TString when TString == 'TeletexString'; TString == 'T61String' -> asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar); @@ -1439,32 +1404,30 @@ gen_dec_prim(Erules,Att,BytesVar) -> asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar); 'UTCTime' -> - emit_dec_known_multiplier_string('VisibleString', - Constraint,BytesVar); + asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar); + 'GeneralizedTime' -> - emit_dec_known_multiplier_string('VisibleString', - Constraint,BytesVar); + asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar); + 'GraphicString' -> asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar); 'VisibleString' -> - emit_dec_known_multiplier_string('VisibleString', - Constraint,BytesVar); + asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar); + 'GeneralString' -> asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar); 'PrintableString' -> - emit_dec_known_multiplier_string('PrintableString', - Constraint,BytesVar); + asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar); 'IA5String' -> - emit_dec_known_multiplier_string('IA5String',Constraint,BytesVar); + asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar); 'BMPString' -> - emit_dec_known_multiplier_string('BMPString',Constraint,BytesVar); + asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar); 'UniversalString' -> - emit_dec_known_multiplier_string('UniversalString', - Constraint,BytesVar); + asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar); 'UTF8String' -> asn1ct_gen_per:gen_dec_prim(Erules, Att, BytesVar); diff --git a/lib/asn1/src/asn1ct_imm.erl b/lib/asn1/src/asn1ct_imm.erl index d0459ae60b..fca85fd778 100644 --- a/lib/asn1/src/asn1ct_imm.erl +++ b/lib/asn1/src/asn1ct_imm.erl @@ -21,7 +21,8 @@ -export([per_dec_raw_bitstring/2, per_dec_boolean/0,per_dec_enumerated/2,per_dec_enumerated/3, per_dec_extension_map/1, - per_dec_integer/2,per_dec_length/3,per_dec_named_integer/3, + per_dec_integer/2,per_dec_k_m_string/3, + per_dec_length/3,per_dec_named_integer/3, per_dec_octet_string/2,per_dec_open_type/1,per_dec_real/1]). -export([optimize_alignment/1,optimize_alignment/2, dec_slim_cg/2,dec_code_gen/2]). @@ -109,6 +110,13 @@ per_dec_named_integer(Constraint, NamedList0, Aligned) -> NamedList = [{K,V} || {V,K} <- NamedList0] ++ [integer_default], {map,Int,NamedList}. +per_dec_k_m_string(StringType, Constraint, Aligned) -> + SzConstr = get_constraint(Constraint, 'SizeConstraint'), + N = string_num_bits(StringType, Constraint, Aligned), + Imm = dec_string(SzConstr, N, Aligned), + Chars = char_tab(Constraint, StringType, N), + convert_string(N, Chars, Imm). + per_dec_octet_string(Constraint, Aligned) -> dec_string(Constraint, 8, Aligned). @@ -259,6 +267,93 @@ matched_range({get_bits,Bits0,[U|Flags]}) when is_integer(U) -> end; matched_range(_Op) -> unknown. +string_num_bits(StringType, Constraint, Aligned) -> + case get_constraint(Constraint, 'PermittedAlphabet') of + {'SingleValue',Sv} -> + charbits(length(Sv), Aligned); + no -> + case StringType of + 'IA5String' -> + charbits(128, Aligned); + 'VisibleString' -> + charbits(95, Aligned); + 'PrintableString' -> + charbits(74, Aligned); + 'NumericString' -> + charbits(11, Aligned); + 'UniversalString' -> + 32; + 'BMPString' -> + 16 + end + end. + +charbits(NumChars, false) -> + uper_num_bits(NumChars); +charbits(NumChars, true) -> + 1 bsl uper_num_bits(uper_num_bits(NumChars)). + +convert_string(8, notab, Imm) -> + {convert,binary_to_list,Imm}; +convert_string(NumBits, notab, Imm) when NumBits < 8 -> + Dec = fun(V, Buf) -> + emit(["{",{call,per_common,decode_chars, + [V,NumBits]},com,Buf,"}"]) + end, + {call,Dec,Imm}; +convert_string(NumBits, notab, Imm) when NumBits =:= 16 -> + Dec = fun(V, Buf) -> + emit(["{",{call,per_common,decode_chars_16bit, + [V]},com,Buf,"}"]) + end, + {call,Dec,Imm}; +convert_string(NumBits, notab, Imm) -> + Dec = fun(V, Buf) -> + emit(["{",{call,per_common,decode_big_chars, + [V,NumBits]},com,Buf,"}"]) + end, + {call,Dec,Imm}; +convert_string(NumBits, Chars, Imm) -> + Dec = fun(V, Buf) -> + emit(["{",{call,per_common,decode_chars, + [V,NumBits,{asis,Chars}]},com,Buf,"}"]) + end, + {call,Dec,Imm}. + +char_tab(C, StringType, NumBits) -> + case get_constraint(C, 'PermittedAlphabet') of + {'SingleValue',Sv} -> + char_tab_1(Sv, NumBits); + no -> + case StringType of + 'IA5String' -> + notab; + 'VisibleString' -> + notab; + 'PrintableString' -> + Chars = " '()+,-./0123456789:=?" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz", + char_tab_1(Chars, NumBits); + 'NumericString' -> + char_tab_1(" 0123456789", NumBits); + 'UniversalString' -> + notab; + 'BMPString' -> + notab + end + end. + +char_tab_1(Chars, NumBits) -> + Max = lists:max(Chars), + BitValMax = (1 bsl NumBits) - 1, + if + Max =< BitValMax -> + notab; + true -> + list_to_tuple(lists:sort(Chars)) + end. + %%% %%% Remove unnecessary aligning to octet boundaries. %%% diff --git a/lib/asn1/src/asn1rtt_per.erl b/lib/asn1/src/asn1rtt_per.erl index 7903dcf9e9..bcd74d9da7 100644 --- a/lib/asn1/src/asn1rtt_per.erl +++ b/lib/asn1/src/asn1rtt_per.erl @@ -38,7 +38,6 @@ encode_UTF8String/1,decode_UTF8String/1, encode_octet_string/3, encode_known_multiplier_string/4, - decode_known_multiplier_string/5, octets_to_complete/2]). -define('16K',16384). @@ -871,27 +870,6 @@ decode_restricted_string(Bytes,aligned) -> {Len,Bytes2} = decode_length(Bytes,undefined), getoctets_as_list(Bytes2,Len). -decode_known_multiplier_string(StringType,SizeC,NumBits,CharInTab,Bytes) -> - case SizeC of - Ub when is_integer(Ub), Ub*NumBits =< 16 -> - chars_decode(Bytes,NumBits,StringType,CharInTab,Ub); - Ub when is_integer(Ub),Ub =<65535 -> % fixed length - Bytes1 = align(Bytes), - chars_decode(Bytes1,NumBits,StringType,CharInTab,Ub); - Vl when is_list(Vl) -> - {Len,Bytes1} = decode_length(Bytes,{hd(Vl),lists:max(Vl)}), - Bytes2 = align(Bytes1), - chars_decode(Bytes2,NumBits,StringType,CharInTab,Len); - no -> - {Len,Bytes1} = decode_length(Bytes,undefined), - Bytes2 = align(Bytes1), - chars_decode(Bytes2,NumBits,StringType,CharInTab,Len); - {Lb,Ub}-> - {Len,Bytes1} = decode_length(Bytes,{Lb,Ub}), - Bytes2 = align(Bytes1), - chars_decode(Bytes2,NumBits,StringType,CharInTab,Len) - end. - encode_GeneralString(_C,Val) -> encode_restricted_string(Val). decode_GeneralString(Bytes,_C) -> @@ -918,18 +896,6 @@ decode_VideotexString(Bytes,_C) -> decode_restricted_string(Bytes,aligned). - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% getBMPChars(Bytes,Len) ->{BMPcharList,RemainingBytes} -%% -getBMPChars(<>, 0, Acc) -> - {lists:reverse(Acc),T}; -getBMPChars(<<0,O2,Bytes1/bitstring>>, Len, Acc) -> - getBMPChars(Bytes1,Len-1,[O2|Acc]); -getBMPChars(<>, Len, Acc) -> - getBMPChars(Bytes1,Len-1,[{0,0,O1,O2}|Acc]). - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% chars_encode(C,StringType,Value) -> ValueList %% @@ -970,36 +936,6 @@ pre_complete_bits(NumBits,Val) when NumBits =< 2040 -> % 255 * 8 [30,Unused,Len div 8,<<(Val bsl Unused):Len>>]. -chars_decode(Bytes,_,'BMPString',_,Len) -> - getBMPChars(Bytes,Len,[]); -chars_decode(Bytes,NumBits,_StringType,CharInTab,Len) -> - chars_decode2(Bytes,CharInTab,NumBits,Len). - - -chars_decode2(Bytes,CharInTab,NumBits,Len) -> - chars_decode2(Bytes,CharInTab,NumBits,Len,[]). - -chars_decode2(Bytes,_CharInTab,_NumBits,0,Acc) -> - {lists:reverse(Acc),Bytes}; -chars_decode2(Bytes,{Min,Max,notab},NumBits,Len,Acc) when NumBits > 8 -> - {Char,Bytes2} = getbits(Bytes,NumBits), - Result = - if - Char < 256 -> Char; - true -> - list_to_tuple(binary_to_list(<>)) - end, - chars_decode2(Bytes2,{Min,Max,notab},NumBits,Len -1,[Result|Acc]); -chars_decode2(Bytes,{Min,Max,notab},NumBits,Len,Acc) -> - {Char,Bytes2} = getbits(Bytes,NumBits), - chars_decode2(Bytes2,{Min,Max,notab},NumBits,Len -1,[Char+Min|Acc]); - -%% BMPString and UniversalString with PermittedAlphabet is currently not supported -chars_decode2(Bytes,{Min,Max,CharInTab},NumBits,Len,Acc) -> - {Char,Bytes2} = getbits(Bytes,NumBits), - chars_decode2(Bytes2,{Min,Max,CharInTab},NumBits,Len -1,[element(Char+1,CharInTab)|Acc]). - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% encode_UTF8String(Val) -> CompleteList %% Val -> <> diff --git a/lib/asn1/src/asn1rtt_per_common.erl b/lib/asn1/src/asn1rtt_per_common.erl index 2edd240baf..cd6e9e2c99 100644 --- a/lib/asn1/src/asn1rtt_per_common.erl +++ b/lib/asn1/src/asn1rtt_per_common.erl @@ -24,7 +24,10 @@ -export([decode_fragmented/3, decode_compact_bit_string/1, decode_legacy_bit_string/1, - decode_named_bit_string/2]). + decode_named_bit_string/2, + decode_chars/2,decode_chars/3, + decode_chars_16bit/1, + decode_big_chars/2]). -define('16K',16384). @@ -58,6 +61,20 @@ decode_compact_bit_string(Val) -> PadLen = (8 - (bit_size(Val) band 7)) band 7, {PadLen,<>}. +decode_chars(Val, N) -> + [C || <> <= Val]. + +decode_chars(Val, N, Chars) -> + [element(C+1, Chars) || <> <= Val]. + +decode_chars_16bit(Val) -> + Cs = [C || <> <= Val], + decode_chars_16bit_1(Cs). + +decode_big_chars(Val, N) -> + decode_big_chars_1(decode_chars(Val, N)). + + %%% %%% Internal functions. %%% @@ -73,3 +90,15 @@ decode_named_bit_string_1(Pos, [1|Bt], Names, Acc) -> end; decode_named_bit_string_1(_Pos, [], _Names, Acc) -> lists:reverse(Acc). + +decode_chars_16bit_1([H|T]) when H < 256 -> + [H|decode_chars_16bit_1(T)]; +decode_chars_16bit_1([H|T]) -> + [{0,0,H bsr 8,H band 255}|decode_chars_16bit_1(T)]; +decode_chars_16bit_1([]) -> []. + +decode_big_chars_1([H|T]) when H < 256 -> + [H|decode_big_chars_1(T)]; +decode_big_chars_1([H|T]) -> + [list_to_tuple(binary_to_list(<>))|decode_big_chars_1(T)]; +decode_big_chars_1([]) -> []. diff --git a/lib/asn1/src/asn1rtt_uper.erl b/lib/asn1/src/asn1rtt_uper.erl index 2d91e0df24..92c8d44402 100644 --- a/lib/asn1/src/asn1rtt_uper.erl +++ b/lib/asn1/src/asn1rtt_uper.erl @@ -34,17 +34,17 @@ -export([encode_open_type/1]). - -export([encode_UniversalString/2, decode_UniversalString/2, - encode_PrintableString/2, decode_PrintableString/2, + -export([encode_UniversalString/2, + encode_PrintableString/2, encode_GeneralString/2, decode_GeneralString/2, encode_GraphicString/2, decode_GraphicString/2, encode_TeletexString/2, decode_TeletexString/2, encode_VideotexString/2, decode_VideotexString/2, - encode_VisibleString/2, decode_VisibleString/2, + encode_VisibleString/2, encode_UTF8String/1, decode_UTF8String/1, - encode_BMPString/2, decode_BMPString/2, - encode_IA5String/2, decode_IA5String/2, - encode_NumericString/2, decode_NumericString/2, + encode_BMPString/2, + encode_IA5String/2, + encode_NumericString/2, encode_ObjectDescriptor/2, decode_ObjectDescriptor/1 ]). @@ -799,56 +799,23 @@ decode_restricted_string(Bytes) -> {Len,Bytes2} = decode_length(Bytes, undefined), getoctets_as_list(Bytes2,Len). -decode_known_multiplier_string(Bytes, StringType, C, _Ext) -> - NumBits = get_NumBits(C, StringType), - case get_constraint(C, 'SizeConstraint') of - Ub when is_integer(Ub), Ub*NumBits =< 16 -> - chars_decode(Bytes, NumBits, StringType, C, Ub); - Ub when is_integer(Ub), Ub =<65535 -> % fixed length - chars_decode(Bytes,NumBits,StringType,C,Ub); - 0 -> - {[],Bytes}; - Vl when is_list(Vl) -> - {Len,Bytes1} = decode_length(Bytes,{hd(Vl),lists:max(Vl)}), - chars_decode(Bytes1,NumBits,StringType,C,Len); - no -> - {Len,Bytes1} = decode_length(Bytes,undefined), - chars_decode(Bytes1,NumBits,StringType,C,Len); - {Lb,Ub}-> - {Len,Bytes1} = decode_length(Bytes,{Lb,Ub}), - chars_decode(Bytes1,NumBits,StringType,C,Len) - end. - - encode_NumericString(C,Val) -> encode_known_multiplier_string('NumericString',C,Val). -decode_NumericString(Bytes,C) -> - decode_known_multiplier_string(Bytes,'NumericString',C,false). encode_PrintableString(C,Val) -> encode_known_multiplier_string('PrintableString',C,Val). -decode_PrintableString(Bytes,C) -> - decode_known_multiplier_string(Bytes,'PrintableString',C,false). encode_VisibleString(C,Val) -> % equivalent with ISO646String encode_known_multiplier_string('VisibleString',C,Val). -decode_VisibleString(Bytes,C) -> - decode_known_multiplier_string(Bytes,'VisibleString',C,false). encode_IA5String(C,Val) -> encode_known_multiplier_string('IA5String',C,Val). -decode_IA5String(Bytes,C) -> - decode_known_multiplier_string(Bytes,'IA5String',C,false). encode_BMPString(C,Val) -> encode_known_multiplier_string('BMPString',C,Val). -decode_BMPString(Bytes,C) -> - decode_known_multiplier_string(Bytes,'BMPString',C,false). encode_UniversalString(C,Val) -> encode_known_multiplier_string('UniversalString',C,Val). -decode_UniversalString(Bytes,C) -> - decode_known_multiplier_string(Bytes,'UniversalString',C,false). %% end of known-multiplier strings for which PER visible constraints are @@ -880,33 +847,6 @@ decode_VideotexString(Bytes,_C) -> decode_restricted_string(Bytes). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% getBMPChars(Bytes, Len) -> {BMPcharList,RemainingBytes} -%% -getBMPChars(Bytes, 1) -> - {O1,Bytes2} = getbits(Bytes, 8), - {O2,Bytes3} = getbits(Bytes2, 8), - if - O1 == 0 -> - {[O2],Bytes3}; - true -> - {[{0,0,O1,O2}],Bytes3} - end; -getBMPChars(Bytes, Len) -> - getBMPChars(Bytes, Len, []). - -getBMPChars(Bytes, 0, Acc) -> - {lists:reverse(Acc),Bytes}; -getBMPChars(Bytes, Len, Acc) -> - {Octs,Bytes1} = getoctets_as_list(Bytes,2), - case Octs of - [0,O2] -> - getBMPChars(Bytes1, Len-1, [O2|Acc]); - [O1,O2]-> - getBMPChars(Bytes1, Len-1, [{0,0,O1,O2}|Acc]) - end. - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% chars_encode(C,StringType,Value) -> ValueList %% @@ -970,27 +910,21 @@ get_NumBits(C,StringType) -> end. get_CharOutTab(C,StringType) -> - get_CharTab(C,StringType,out). - -get_CharInTab(C,StringType) -> - get_CharTab(C,StringType,in). - -get_CharTab(C,StringType,InOut) -> case get_constraint(C,'PermittedAlphabet') of {'SingleValue',Sv} -> - get_CharTab2(C,StringType,hd(Sv),lists:max(Sv),Sv,InOut); + get_CharTab2(C,StringType,hd(Sv),lists:max(Sv),Sv); no -> case StringType of 'IA5String' -> {0,16#7F,notab}; 'VisibleString' -> - get_CharTab2(C,StringType,16#20,16#7F,notab,InOut); + get_CharTab2(C,StringType,16#20,16#7F,notab); 'PrintableString' -> Chars = lists:sort( " '()+,-./0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), - get_CharTab2(C,StringType,hd(Chars),lists:max(Chars),Chars,InOut); + get_CharTab2(C,StringType,hd(Chars),lists:max(Chars),Chars); 'NumericString' -> - get_CharTab2(C,StringType,16#20,$9," 0123456789",InOut); + get_CharTab2(C,StringType,16#20,$9," 0123456789"); 'UniversalString' -> {0,16#FFFFFFFF,notab}; 'BMPString' -> @@ -998,18 +932,13 @@ get_CharTab(C,StringType,InOut) -> end end. -get_CharTab2(C,StringType,Min,Max,Chars,InOut) -> +get_CharTab2(C,StringType,Min,Max,Chars) -> BitValMax = (1 bsl get_NumBits(C,StringType))-1, if Max =< BitValMax -> {0,Max,notab}; true -> - case InOut of - out -> - {Min,Max,create_char_tab(Min,Chars)}; - in -> - {Min,Max,list_to_tuple(Chars)} - end + {Min,Max,create_char_tab(Min,Chars)} end. create_char_tab(Min,L) -> @@ -1047,44 +976,6 @@ charbits1(NumOfChars) -> 1 + charbits1(NumOfChars bsr 1). -chars_decode(Bytes,_,'BMPString',C,Len) -> - case get_constraint(C,'PermittedAlphabet') of - no -> - getBMPChars(Bytes,Len); - _ -> - exit({error,{asn1, - {'not implemented', - "BMPString with PermittedAlphabet constraint"}}}) - end; -chars_decode(Bytes,NumBits,StringType,C,Len) -> - CharInTab = get_CharInTab(C,StringType), - chars_decode2(Bytes,CharInTab,NumBits,Len). - - -chars_decode2(Bytes,CharInTab,NumBits,Len) -> - chars_decode2(Bytes,CharInTab,NumBits,Len,[]). - -chars_decode2(Bytes,_CharInTab,_NumBits,0,Acc) -> - {lists:reverse(Acc),Bytes}; -chars_decode2(Bytes,{Min,Max,notab},NumBits,Len,Acc) when NumBits > 8 -> - {Char,Bytes2} = getbits(Bytes,NumBits), - Result = - if - Char < 256 -> Char; - true -> - list_to_tuple(binary_to_list(<>)) - end, - chars_decode2(Bytes2,{Min,Max,notab},NumBits,Len -1,[Result|Acc]); -chars_decode2(Bytes,{Min,Max,notab},NumBits,Len,Acc) -> - {Char,Bytes2} = getbits(Bytes,NumBits), - chars_decode2(Bytes2,{Min,Max,notab},NumBits,Len -1,[Char+Min|Acc]); - -%% BMPString and UniversalString with PermittedAlphabet is currently not supported -chars_decode2(Bytes,{Min,Max,CharInTab},NumBits,Len,Acc) -> - {Char,Bytes2} = getbits(Bytes,NumBits), - chars_decode2(Bytes2,{Min,Max,CharInTab},NumBits,Len -1,[element(Char+1,CharInTab)|Acc]). - - %% UTF8String encode_UTF8String(Val) when is_binary(Val) -> [encode_length(byte_size(Val)),Val]; -- cgit v1.2.3