diff options
author | Björn Gustavsson <[email protected]> | 2012-12-12 12:20:22 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2012-12-19 11:52:12 +0100 |
commit | b8c35cfdb858cc68a40d21e58b54e2362f3a456a (patch) | |
tree | 12714552a8430888c0957de67456967f8dc87c68 /lib/asn1/src | |
parent | 1749a097ef9871124e6d2eecf2c6644f0c133fcc (diff) | |
download | otp-b8c35cfdb858cc68a40d21e58b54e2362f3a456a.tar.gz otp-b8c35cfdb858cc68a40d21e58b54e2362f3a456a.tar.bz2 otp-b8c35cfdb858cc68a40d21e58b54e2362f3a456a.zip |
per: Slightly optimize encoding of fixed OCTET STRINGs
Do the following optimizations:
* Optimize construction of OCTET STRINGs of size 2 by using
the 45 opcode instead of the 10 opcode for each character.
* Use exact comparison (implicit by matching) instead of '=='.
* Use list literals when more than one integer is added to a
list (e.g. [[45,16,2],...] instead of [45,16,2,...]). Results
in fewer BEAM instructions and less garbage.
* Cons instead of building a nested list when possible. Example:
[20,TempLen|TmpVal] instead of [20,TempLen,TmpVal].
* Omit the "2" opcode (align to byte boundary) before the "20" and
"21" opcodes (because they imply alignment).
* Assign the value to be encoded to a temporary variable, to avoid
calling element/2 more than once.
Diffstat (limited to 'lib/asn1/src')
-rw-r--r-- | lib/asn1/src/asn1ct_gen_per_rt2ct.erl | 57 |
1 files changed, 34 insertions, 23 deletions
diff --git a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl index fa9c3645b3..e6ffc0fb47 100644 --- a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl +++ b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl @@ -405,35 +405,46 @@ emit_enc_octet_string(_Erules,Constraint,Value) -> asn1ct_name:new(tmpval), emit({" begin",nl}), emit({" [",{curr,tmpval},"] = ",Value,",",nl}), - emit({" [10,8,",{curr,tmpval},"]",nl}), + emit([" [[10,8],",{curr,tmpval},"]",nl]), emit(" end"); 2 -> asn1ct_name:new(tmpval), - emit({" begin",nl}), - emit({" [",{curr,tmpval},",",{next,tmpval},"] = ", - Value,",",nl}), - emit({" [[10,8,",{curr,tmpval},"],[10,8,", - {next,tmpval},"]]",nl}), - emit(" end"), - asn1ct_name:new(tmpval); - Sv when is_integer(Sv),Sv < 256 -> + emit([" begin",nl, + " ",{curr,tmpval}," = ",Value,",",nl, + " case length(",{curr,tmpval},") of",nl, + " 2 ->",nl, + " [[45,16,2]|",{curr,tmpval},"];",nl, + " _ ->",nl, + " exit({error,{value_out_of_bounds,", + {curr,tmpval},"}})",nl, + " end",nl, + " end"]); + Sv when is_integer(Sv), Sv < 256 -> asn1ct_name:new(tmpval), - emit({" begin",nl}), - emit({" case length(",Value,") of",nl}), - emit([" ",{curr,tmpval}," when ",{curr,tmpval}," == ",Sv," ->"]), - emit([" [2,20,",{curr,tmpval},",",Value,"];",nl]), - emit({" _ -> exit({error,{value_out_of_bounds,", - Value,"}})", nl," end",nl}), - emit(" end"); + asn1ct_name:new(tmplen), + emit([" begin",nl, + " ",{curr,tmpval}," = ",Value,",",nl, + " case length(",{curr,tmpval},") of",nl, + " ",Sv,"=",{curr,tmplen}," ->",nl, + " [20,",{curr,tmplen},"|",{curr,tmpval},"];",nl, + " _ ->",nl, + " exit({error,{value_out_of_bounds,", + {curr,tmpval},"}})",nl, + " end",nl, + " end"]); Sv when is_integer(Sv),Sv =< 65535 -> asn1ct_name:new(tmpval), - emit({" begin",nl}), - emit({" case length(",Value,") of",nl}), - emit([" ",{curr,tmpval}," when ",{curr,tmpval}," == ",Sv," ->"]), - emit([" [<<21,",{curr,tmpval},":16>>|",Value,"];",nl]), - emit({" _ -> exit({error,{value_out_of_bounds,", - Value,"}})",nl," end",nl}), - emit(" end"); + asn1ct_name:new(tmplen), + emit([" begin",nl, + " ",{curr,tmpval}," = ",Value,",",nl, + " case length(",{curr,tmpval},") of",nl, + " ",Sv,"=",{curr,tmplen}," ->",nl, + " [<<21,",{curr,tmplen},":16>>|",Value,"];",nl, + " _ ->",nl, + " exit({error,{value_out_of_bounds,", + {curr,tmpval},"}})",nl, + " end",nl, + " end"]); C -> emit({" ?RT_PER:encode_octet_string(",{asis,C},",false,",Value,")",nl}) end. |