aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2014-04-15 08:24:51 +0200
committerBjörn Gustavsson <[email protected]>2014-04-29 06:24:19 +0200
commit1e8f50885a6faf95d8780cacd918b9084eba8b49 (patch)
tree5c6c589bbc8d8d4733878560fa17867314be25c8 /lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
parentc3c7dce82e3fd309f89e91a1e52109e5373ffd71 (diff)
downloadotp-1e8f50885a6faf95d8780cacd918b9084eba8b49.tar.gz
otp-1e8f50885a6faf95d8780cacd918b9084eba8b49.tar.bz2
otp-1e8f50885a6faf95d8780cacd918b9084eba8b49.zip
BER: Inline testing of constraints when decoding
Calling library routines for validation of constraints may cause dialyzer warnings if some type of constraints handled by the library routine are not used in a specific ASN.1 module. To avoid those warnings (and slightly speed up the decoding), inline the constraint checking.
Diffstat (limited to 'lib/asn1/src/asn1ct_gen_ber_bin_v2.erl')
-rw-r--r--lib/asn1/src/asn1ct_gen_ber_bin_v2.erl157
1 files changed, 109 insertions, 48 deletions
diff --git a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
index 09cb7c0628..6db31c5ea2 100644
--- a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
+++ b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl
@@ -492,6 +492,11 @@ gen_dec_prim(Att, BytesVar, DoTag) ->
'ObjectDescriptor'-> restricted_string;
'UTCTime' -> restricted_string;
'GeneralizedTime' -> restricted_string;
+ 'OCTET STRING' ->
+ case asn1ct:use_legacy_types() of
+ true -> restricted_string;
+ false -> Typename
+ end;
_ -> Typename
end,
TagStr = case DoTag of
@@ -502,26 +507,23 @@ gen_dec_prim(Att, BytesVar, DoTag) ->
'BOOLEAN'->
call(decode_boolean, [BytesVar,TagStr]);
'INTEGER' ->
- case IntConstr of
- [] ->
- call(decode_integer, [BytesVar,TagStr]);
- {_,_} ->
- call(decode_integer, [BytesVar,{asis,IntConstr},TagStr])
- end;
- {'INTEGER',NamedNumberList} ->
- case IntConstr of
- [] ->
- call(decode_named_integer,
- [BytesVar,
- {asis,NamedNumberList},
- TagStr]);
- {_,_} ->
- call(decode_named_integer,
- [BytesVar,
- {asis,IntConstr},
- {asis,NamedNumberList},
- TagStr])
- end;
+ check_constraint(decode_integer, [BytesVar,TagStr],
+ IntConstr,
+ identity,
+ identity);
+ {'INTEGER',NNL} ->
+ check_constraint(decode_integer,
+ [BytesVar,TagStr],
+ IntConstr,
+ identity,
+ fun(Val) ->
+ asn1ct_name:new(val),
+ emit([{curr,val}," = "]),
+ Val(),
+ emit([com,nl,
+ {call,ber,number2name,
+ [{curr,val},{asis,NNL}]}])
+ end);
{'ENUMERATED',NNL} ->
call(decode_enumerated, [BytesVar,{asis,NNL},TagStr]);
'REAL' ->
@@ -540,32 +542,25 @@ gen_dec_prim(Att, BytesVar, DoTag) ->
'RELATIVE-OID' ->
call(decode_relative_oid, [BytesVar,TagStr]);
'OCTET STRING' ->
- F = case asn1ct:use_legacy_types() of
- false -> decode_octet_string;
- true -> decode_restricted_string
- end,
- case Constraint of
- [] ->
- call(F, [BytesVar,TagStr]);
- _ ->
- call(F, [BytesVar,{asis,Constraint},TagStr])
- end;
+ check_constraint(decode_octet_string, [BytesVar,TagStr],
+ Constraint, {erlang,byte_size}, identity);
restricted_string ->
- case Constraint of
- [] ->
- call(decode_restricted_string,
- [BytesVar,TagStr]);
- _ ->
- call(decode_restricted_string,
- [BytesVar,{asis,Constraint},TagStr])
- end;
+ check_constraint(decode_restricted_string, [BytesVar,TagStr],
+ Constraint,
+ {erlang,byte_size},
+ fun(Val) ->
+ emit("binary_to_list("),
+ Val(),
+ emit(")")
+ end);
'UniversalString' ->
- call(decode_universal_string,
- [BytesVar,{asis,Constraint},TagStr]);
+ check_constraint(decode_universal_string, [BytesVar,TagStr],
+ Constraint, {erlang,length}, identity);
'UTF8String' ->
call(decode_UTF8_string, [BytesVar,TagStr]);
'BMPString' ->
- call(decode_BMP_string, [BytesVar,{asis,Constraint},TagStr]);
+ check_constraint(decode_BMP_string, [BytesVar,TagStr],
+ Constraint, {erlang,length}, identity);
'ASN1_OPEN_TYPE' ->
call(decode_open_type_as_binary, [BytesVar,TagStr])
end.
@@ -583,7 +578,7 @@ int_constr(C) ->
[{'ValueRange',{_,_}=Range}] ->
Range;
[{'SingleValue',Sv}] ->
- {Sv,Sv};
+ Sv;
[] ->
[]
end.
@@ -594,16 +589,82 @@ gen_dec_bit_string(BytesVar, _Constraint, [_|_]=NNL, TagStr) ->
gen_dec_bit_string(BytesVar, Constraint, [], TagStr) ->
case asn1ct:get_bit_string_format() of
compact ->
- call(decode_compact_bit_string,
- [BytesVar,{asis,Constraint},TagStr]);
+ check_constraint(decode_compact_bit_string,
+ [BytesVar,TagStr],
+ Constraint,
+ {ber,compact_bit_string_size},
+ identity);
legacy ->
- call(decode_legacy_bit_string,
- [BytesVar,{asis,Constraint},TagStr]);
+ check_constraint(decode_native_bit_string,
+ [BytesVar,TagStr],
+ Constraint,
+ {erlang,bit_size},
+ fun(Val) ->
+ asn1ct_name:new(val),
+ emit([{curr,val}," = "]),
+ Val(),
+ emit([com,nl,
+ {call,ber,native_to_legacy_bit_string,
+ [{curr,val}]}])
+ end);
bitstring ->
- call(decode_native_bit_string,
- [BytesVar,{asis,Constraint},TagStr])
+ check_constraint(decode_native_bit_string,
+ [BytesVar,TagStr],
+ Constraint,
+ {erlang,bit_size},
+ identity)
end.
+check_constraint(F, Args, Constr, PreConstr0, ReturnVal0) ->
+ PreConstr = case PreConstr0 of
+ identity ->
+ fun(V) -> V end;
+ {Mod,Name} ->
+ fun(V) ->
+ asn1ct_name:new(c),
+ emit([{curr,c}," = ",
+ {call,Mod,Name,[V]},com,nl]),
+ {curr,c}
+ end
+ end,
+ ReturnVal = case ReturnVal0 of
+ identity -> fun(Val) -> Val() end;
+ _ -> ReturnVal0
+ end,
+ case Constr of
+ [] when ReturnVal0 =:= identity ->
+ %% No constraint, no complications.
+ call(F, Args);
+ [] ->
+ %% No constraint, but the return value could consist
+ %% of more than one statement.
+ emit(["begin",nl]),
+ ReturnVal(fun() -> call(F, Args) end),
+ emit([nl,
+ "end",nl]);
+ _ ->
+ %% There is a constraint.
+ asn1ct_name:new(val),
+ emit(["begin",nl,
+ {curr,val}," = ",{call,ber,F,Args},com,nl]),
+ PreVal0 = asn1ct_gen:mk_var(asn1ct_name:curr(val)),
+ PreVal = PreConstr(PreVal0),
+ emit("if "),
+ case Constr of
+ {Min,Max} ->
+ emit([{asis,Min}," =< ",PreVal,", ",
+ PreVal," =< ",{asis,Max}]);
+ Sv when is_integer(Sv) ->
+ emit([PreVal," =:= ",{asis,Sv}])
+ end,
+ emit([" ->",nl]),
+ ReturnVal(fun() -> emit(PreVal0) end),
+ emit([";",nl,
+ "true ->",nl,
+ "exit({error,{asn1,bad_range}})",nl,
+ "end",nl,
+ "end"])
+ end.
%% Object code generating for encoding and decoding
%% ------------------------------------------------