aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1/src
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2011-08-02 11:52:53 +0200
committerLukas Larsson <[email protected]>2011-08-02 11:52:53 +0200
commitb16af6d09ef2a5843e1fb491114906780f3f970d (patch)
tree484e6102aedf6a70ed8523ad59a7a29478b48c44 /lib/asn1/src
parent97f867992aaf98eac44c8fcd17df3a15e4aa3eab (diff)
parentf2490767798cbc3ea94d603afb75be2eb65fe564 (diff)
downloadotp-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.erl4
-rw-r--r--lib/asn1/src/asn1ct_gen_ber_bin_v2.erl17
-rw-r--r--lib/asn1/src/asn1rt_ber_bin_v2.erl78
-rw-r--r--lib/asn1/src/asn1rt_nif.erl8
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}).