diff options
author | Lukas Larsson <[email protected]> | 2011-08-02 11:52:53 +0200 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2011-08-02 11:52:53 +0200 |
commit | b16af6d09ef2a5843e1fb491114906780f3f970d (patch) | |
tree | 484e6102aedf6a70ed8523ad59a7a29478b48c44 /lib/asn1/src | |
parent | 97f867992aaf98eac44c8fcd17df3a15e4aa3eab (diff) | |
parent | f2490767798cbc3ea94d603afb75be2eb65fe564 (diff) | |
download | otp-b16af6d09ef2a5843e1fb491114906780f3f970d.tar.gz otp-b16af6d09ef2a5843e1fb491114906780f3f970d.tar.bz2 otp-b16af6d09ef2a5843e1fb491114906780f3f970d.zip |
Merge branch 'lukas/asn1/ber_encode_nif/OTP-9441' into major
* lukas/asn1/ber_encode_nif/OTP-9441:
Update to use enif_alloc instead of malloc
Make performance code more generic and migrate per/ber NBAP perormance suites to use the generic code
Update code genaration to call nif/erlang depending on what is configured
Remove export_all and only export is_nif_loadable
Add documentation for ber encode nif optmization
Fix bug in counting length of empty composite types
Fix bug where composite types with more then one element would be encoded in reverse
Add pubkey performance tests
Update ber encode nif to use a linked list memry buffer
Create a nif for ber encode
Extract generic is_nif_loadable function from decode
Diffstat (limited to 'lib/asn1/src')
-rw-r--r-- | lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl | 4 | ||||
-rw-r--r-- | lib/asn1/src/asn1ct_gen_ber_bin_v2.erl | 17 | ||||
-rw-r--r-- | lib/asn1/src/asn1rt_ber_bin_v2.erl | 78 | ||||
-rw-r--r-- | lib/asn1/src/asn1rt_nif.erl | 8 |
4 files changed, 73 insertions, 34 deletions
diff --git a/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl b/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl index e16873c717..243ff234a7 100644 --- a/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl +++ b/lib/asn1/src/asn1ct_constructed_ber_bin_v2.erl @@ -877,13 +877,13 @@ gen_dec_choice(Erules,TopType, _ChTag, CompList, Ext) -> emit([indent(9),"exit({error,{asn1,{invalid_choice_tag,", {curr,else},"}}})",nl]); _ -> - emit([indent(9),"{asn1_ExtAlt, ?RT_BER:encode(",{curr,else},")}",nl]) + emit([indent(9),"{asn1_ExtAlt, ?RT_BER:encode(",{curr,else}, + asn1ct_gen:nif_parameter(),")}",nl]) end, emit([indent(3),"end",nl]), asn1ct_name:new(tag), asn1ct_name:new(else). - gen_dec_choice_cases(_Erules,_TopType, []) -> ok; gen_dec_choice_cases(Erules,TopType, [H|T]) -> diff --git a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl index e8a4ad0cf1..781271bae7 100644 --- a/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl +++ b/lib/asn1/src/asn1ct_gen_ber_bin_v2.erl @@ -728,13 +728,13 @@ gen_dec_prim(Erules,Att,BytesVar,DoTag,TagIn,Form,OptOrMand) -> {_,#'ObjectClassFieldType'{}} -> case asn1ct_gen:get_inner(Att#type.def) of 'ASN1_OPEN_TYPE' -> - emit([{asis,DoTag},")"]); + emit([{asis,DoTag},asn1ct_gen:nif_parameter(),")"]); _ -> ok end; {{string,TagStr},'ASN1_OPEN_TYPE'} -> - emit([TagStr,")"]); + emit([TagStr,asn1ct_gen:nif_parameter(),")"]); {_,'ASN1_OPEN_TYPE'} -> - emit([{asis,DoTag},")"]); + emit([{asis,DoTag},asn1ct_gen:nif_parameter(),")"]); {{string,TagStr},_} -> emit([TagStr,")"]); _ when is_list(DoTag) -> @@ -1502,13 +1502,14 @@ gen_objset_dec(Erules,ObjSetName,_UniqueName,['EXTENSIONMARK'],_ClName, _ClFields,_NthObj) -> emit(["'getdec_",ObjSetName,"'(_, _) ->",nl]), emit([indent(2),"fun(_,Bytes, _RestPrimFieldName) ->",nl]), + case Erules of ber_bin_v2 -> emit([indent(4),"case Bytes of",nl, indent(6),"Bin when is_binary(Bin) -> ",nl, indent(8),"Bin;",nl, indent(6),"_ ->",nl, - indent(8),"?RT_BER:encode(Bytes)",nl, + indent(8),"?RT_BER:encode(Bytes",driver_parameter(),")",nl, indent(4),"end",nl]); _ -> emit([indent(6),"Len = case Bytes of",nl,indent(9), @@ -1521,6 +1522,14 @@ gen_objset_dec(Erules,ObjSetName,_UniqueName,['EXTENSIONMARK'],_ClName, gen_objset_dec(_,_,_,[],_,_,_) -> ok. +driver_parameter() -> + Options = get(encoding_options), + case {lists:member(driver,Options),lists:member(nif,Options)} of + {true,_} -> ",nif"; + {_,true} -> ",nif"; + _ -> ",erlang" + end. + emit_default_getdec(ObjSetName,UniqueName) -> emit(["'getdec_",ObjSetName,"'(",{asis,UniqueName},", ErrV) ->",nl]), emit([indent(2), "fun(C,V,_) -> exit({{component,C},{value,V},{unique_name_and_value,",{asis,UniqueName},", ErrV}}) end"]). diff --git a/lib/asn1/src/asn1rt_ber_bin_v2.erl b/lib/asn1/src/asn1rt_ber_bin_v2.erl index 2df289e2b8..bef2216091 100644 --- a/lib/asn1/src/asn1rt_ber_bin_v2.erl +++ b/lib/asn1/src/asn1rt_ber_bin_v2.erl @@ -21,7 +21,7 @@ %% encoding / decoding of BER --export([decode/1, decode/2, match_tags/2, encode/1]). +-export([decode/1, decode/2, match_tags/2, encode/1, encode/2]). -export([fixoptionals/2, cindex/3, list_to_record/2, encode_tag_val/1, @@ -50,10 +50,13 @@ -export([encode_open_type/1,encode_open_type/2, decode_open_type/2,decode_open_type/3, - decode_open_type_as_binary/2]). + decode_open_type_as_binary/2, + decode_open_type_as_binary/3]). -export([decode_primitive_incomplete/2,decode_selective/2]). - + +-export([is_nif_loadable/0]). + -include("asn1_records.hrl"). % the encoding of class of tag bits 8 and 7 @@ -126,15 +129,28 @@ % encode(Tlv) -> % encode_constructed(Tlv). -encode([Tlv]) -> - encode(Tlv); -encode({TlvTag,TlvVal}) when is_list(TlvVal) -> +encode(Tlv) -> + encode(Tlv,erlang). + +encode(Tlv,_) when is_binary(Tlv) -> + Tlv; +encode([Tlv],Method) -> + encode(Tlv,Method); +encode(Tlv, nif) -> + case is_nif_loadable() of + true -> + asn1rt_nif:encode_ber_tlv(Tlv); + false -> + encode_erl(Tlv) + end; +encode(Tlv, _) -> + encode_erl(Tlv). + +encode_erl({TlvTag,TlvVal}) when is_list(TlvVal) -> %% constructed form of value encode_tlv(TlvTag,TlvVal,?CONSTRUCTED); -encode({TlvTag,TlvVal}) -> - encode_tlv(TlvTag,TlvVal,?PRIMITIVE); -encode(Bin) when is_binary(Bin) -> - Bin. +encode_erl({TlvTag,TlvVal}) -> + encode_tlv(TlvTag,TlvVal,?PRIMITIVE). encode_tlv(TlvTag,TlvVal,Form) -> Tag = encode_tlv_tag(TlvTag,Form), @@ -153,7 +169,7 @@ encode_tlv_val(Bin) -> {Bin,size(Bin)}. encode_tlv_list([Tlv|Tlvs],Acc) -> - EncTlv = encode(Tlv), + EncTlv = encode_erl(Tlv), encode_tlv_list(Tlvs,[EncTlv|Acc]); encode_tlv_list([],Acc) -> Bin=list_to_binary(lists:reverse(Acc)), @@ -164,28 +180,36 @@ decode(B) -> %% asn1-1.7 decode(B, nif) -> - case application:get_env(asn1, nif_loadable) of - {ok, true} -> + case is_nif_loadable() of + true -> case asn1rt_nif:decode_ber_tlv(B) of {error, Reason} -> handle_error(Reason, B); Else -> Else end; - {ok, false} -> - decode(B); - undefined -> - case catch code:load_file(asn1rt_nif) of - {module, asn1rt_nif} -> - application:set_env(asn1, nif_loadable, true); - _Else -> - application:set_env(asn1, nif_loadable, false) - end, - decode(B, nif) + false -> + decode(B) end; decode(B,erlang) when is_binary(B) -> decode_primitive(B); decode(Tlv,erlang) -> {Tlv,<<>>}. +%% Have to check this since asn1 is not guaranteed to be available +is_nif_loadable() -> + case application:get_env(asn1, nif_loadable) of + {ok,R} -> + R; + undefined -> + case catch code:load_file(asn1rt_nif) of + {module, asn1rt_nif} -> + application:set_env(asn1, nif_loadable, true), + true; + _Else -> + application:set_env(asn1, nif_loadable, false), + false + end + end. + handle_error([],_)-> exit({error,{asn1,{"memory allocation problem"}}}); handle_error({$1,_},L) -> % error in nif @@ -780,12 +804,14 @@ decode_open_type(Tlv, TagIn, Method) -> end. -decode_open_type_as_binary(Tlv,TagIn)-> +decode_open_type_as_binary(Tlv, TagIn) -> + decode_open_type_as_binary(Tlv, TagIn, erlang). +decode_open_type_as_binary(Tlv,TagIn, Method)-> case match_tags(Tlv,TagIn) of V when is_binary(V) -> V; - [Tlv2] -> encode(Tlv2); - Tlv2 -> encode(Tlv2) + [Tlv2] -> encode(Tlv2, Method); + Tlv2 -> encode(Tlv2, Method) end. %%=============================================================================== diff --git a/lib/asn1/src/asn1rt_nif.erl b/lib/asn1/src/asn1rt_nif.erl index 8580c70e6b..de1fb94816 100644 --- a/lib/asn1/src/asn1rt_nif.erl +++ b/lib/asn1/src/asn1rt_nif.erl @@ -22,7 +22,8 @@ %% Nif interface for asn1 -export([encode_per_complete/1, - decode_ber_tlv/1]). + decode_ber_tlv/1, + encode_ber_tlv/1]). -on_load(load_nif/0). @@ -76,8 +77,11 @@ load_nif() -> Status end. -encode_per_complete(_Binary) -> +encode_per_complete(_TagValueList) -> erlang:nif_error({nif_not_loaded,module,?MODULE,line,?LINE}). decode_ber_tlv(_Binary) -> erlang:nif_error({nif_not_loaded,module,?MODULE,line,?LINE}). + +encode_ber_tlv(_TagValueList) -> + erlang:nif_error({nif_not_loaded,module,?MODULE,line,?LINE}). |