aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1/src
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2013-09-30 10:09:16 +0200
committerBjörn Gustavsson <[email protected]>2013-09-30 10:09:16 +0200
commitb4f5a3a238cc726b215c6c34484d4cb5299aff33 (patch)
tree78ce067f01ae9a2e4ecdfa25f5bcd49f9738bbd4 /lib/asn1/src
parent8f8c00f77779f5d47642e6decddf298d2f8e2254 (diff)
parent0f430abcb189988a7faf55386557b2b74afa6f56 (diff)
downloadotp-b4f5a3a238cc726b215c6c34484d4cb5299aff33.tar.gz
otp-b4f5a3a238cc726b215c6c34484d4cb5299aff33.tar.bz2
otp-b4f5a3a238cc726b215c6c34484d4cb5299aff33.zip
Merge branch 'maint'
* maint: Teach the ASN.1 compiler the no_ok_wrapper option Optimize the generated decode/2 function
Diffstat (limited to 'lib/asn1/src')
-rw-r--r--lib/asn1/src/asn1ct_gen.erl157
1 files changed, 76 insertions, 81 deletions
diff --git a/lib/asn1/src/asn1ct_gen.erl b/lib/asn1/src/asn1ct_gen.erl
index c526c28b70..3452d29085 100644
--- a/lib/asn1/src/asn1ct_gen.erl
+++ b/lib/asn1/src/asn1ct_gen.erl
@@ -909,49 +909,45 @@ pgen_dispatcher(Erules,_Module,{[],_Values,_,_,_Objects,_ObjectSets}) ->
pgen_dispatcher(Erules,_Module,{Types,_Values,_,_,_Objects,_ObjectSets}) ->
emit(["-export([encode/2,decode/2]).",nl,nl]),
gen_info_functions(Erules),
- NoFinalPadding = lists:member(no_final_padding,get(encoding_options)),
- {Call,BytesAsBinary} =
- case Erules of
- per ->
- asn1ct_func:need({Erules,complete,1}),
- {["complete(encode_disp(Type, Data))"],"Bytes"};
- ber ->
- {"encode_disp(Type,Data)","iolist_to_binary(Bytes)"};
- uper when NoFinalPadding == true ->
- asn1ct_func:need({Erules,complete_NFP,1}),
- {"complete_NFP(encode_disp(Type, Data))","Bytes"};
- uper ->
- asn1ct_func:need({Erules,complete,1}),
- {["complete(encode_disp(Type, Data))"],"Bytes"}
- end,
- emit(["encode(Type,Data) ->",nl,
- "try ",Call," of",nl,
- case erule(Erules) of
- ber ->
- [" {Bytes,_Len} ->",nl,
- " {ok,",BytesAsBinary,"}",nl];
- per ->
- [" Bytes ->",nl,
- " {ok,",BytesAsBinary,"}",nl]
- end,
- " catch",nl,
- " Class:Exception when Class =:= error; Class =:= exit ->",nl,
- " case Exception of",nl,
- " {error,Reason}=Error ->",nl,
- " Error;",nl,
- " Reason ->",nl,
- " {error,{asn1,Reason}}",nl,
- " end",nl,
- "end.",nl,nl]),
-
- Return_rest = lists:member(undec_rest,get(encoding_options)),
+
+ Options = get(encoding_options),
+ NoFinalPadding = lists:member(no_final_padding, Options),
+ NoOkWrapper = proplists:get_bool(no_ok_wrapper, Options),
+
+ Call = case Erules of
+ per ->
+ asn1ct_func:need({Erules,complete,1}),
+ "complete(encode_disp(Type, Data))";
+ ber ->
+ "iolist_to_binary(element(1, encode_disp(Type, Data)))";
+ uper when NoFinalPadding == true ->
+ asn1ct_func:need({Erules,complete_NFP,1}),
+ "complete_NFP(encode_disp(Type, Data))";
+ uper ->
+ asn1ct_func:need({Erules,complete,1}),
+ "complete(encode_disp(Type, Data))"
+ end,
+
+ emit(["encode(Type, Data) ->",nl]),
+ case NoOkWrapper of
+ true ->
+ emit([" ",Call,"."]);
+ false ->
+ emit(["try ",Call," of",nl,
+ " Bytes ->",nl,
+ " {ok,Bytes}",nl,
+ try_catch()])
+ end,
+ emit([nl,nl]),
+
+ Return_rest = proplists:get_bool(undec_rest, Options),
Data = case {Erules,Return_rest} of
{ber,true} -> "Data0";
_ -> "Data"
end,
emit(["decode(Type,",Data,") ->",nl]),
- DecAnonymous =
+ DecWrap =
case {Erules,Return_rest} of
{ber,false} ->
asn1ct_func:need({ber,ber_decode_nif,1}),
@@ -963,49 +959,26 @@ pgen_dispatcher(Erules,_Module,{Types,_Values,_,_,_Objects,_ObjectSets}) ->
_ ->
"Data"
end,
- DecWrap = case Erules of
- ber ->
- DecAnonymous;
- _ -> "Data"
- end,
-
- emit(["case catch decode_disp(Type,",DecWrap,") of",nl,
- " {'EXIT',{error,Reason}} ->",nl,
- " {error,Reason};",nl,
- " {'EXIT',Reason} ->",nl,
- " {error,{asn1,Reason}};",nl]),
- case {Erules,Return_rest} of
- {ber,false} ->
- emit([" Result ->",nl,
- " {ok,Result}",nl]);
- {ber,true} ->
- emit([" Result ->",nl,
- " {ok,Result,Rest}",nl]);
- {_,false} ->
- emit([" {X,_Rest} ->",nl,
- " {ok,X};",nl,
- " {X,_Rest,_Len} ->",nl,
- " {ok,X}",nl]);
- {per,true} ->
- emit([" {X,{_,Rest}} ->",nl,
- " {ok,X,Rest};",nl,
- " {X,{_,Rest},_Len} ->",nl,
- " {ok,X,Rest};",nl,
- " {X,Rest} ->",nl,
- " {ok,X,Rest};",nl,
- " {X,Rest,_Len} ->",nl,
- " {ok,X,Rest}",nl]);
- {uper,true} ->
- emit([" {X,{_,Rest}} ->",nl,
- " {ok,X,Rest};",nl,
- " {X,{_,Rest},_Len} ->",nl,
- " {ok,X,Rest};",nl,
- " {X,Rest} ->",nl,
- " {ok,X,Rest};",nl,
- " {X,Rest,_Len} ->",nl,
- " {ok,X,Rest}",nl])
+ emit([case NoOkWrapper of
+ false -> "try";
+ true -> "case"
+ end, " decode_disp(Type, ",DecWrap,") of",nl]),
+ case erule(Erules) of
+ ber ->
+ emit([" Result ->",nl]);
+ per ->
+ emit([" {Result,Rest} ->",nl])
+ end,
+ case Return_rest of
+ false -> result_line(NoOkWrapper, ["Result"]);
+ true -> result_line(NoOkWrapper, ["Result","Rest"])
+ end,
+ case NoOkWrapper of
+ false ->
+ emit([nl,try_catch(),nl,nl]);
+ true ->
+ emit([nl,"end.",nl,nl])
end,
- emit(["end.",nl,nl]),
gen_decode_partial_incomplete(Erules),
@@ -1018,8 +991,30 @@ pgen_dispatcher(Erules,_Module,{Types,_Values,_,_,_Objects,_ObjectSets}) ->
gen_dispatcher(Types,"encode_disp","enc_",""),
gen_dispatcher(Types,"decode_disp","dec_","")
end,
- emit([nl]),
- emit({nl,nl}).
+ emit([nl,nl]).
+
+result_line(NoOkWrapper, Items) ->
+ S = [" "|case NoOkWrapper of
+ false -> result_line_1(["ok"|Items]);
+ true -> result_line_1(Items)
+ end],
+ emit(lists:flatten(S)).
+
+result_line_1([SingleItem]) ->
+ SingleItem;
+result_line_1(Items) ->
+ ["{",string:join(Items, ","),"}"].
+
+try_catch() ->
+ [" catch",nl,
+ " Class:Exception when Class =:= error; Class =:= exit ->",nl,
+ " case Exception of",nl,
+ " {error,Reason}=Error ->",nl,
+ " Error;",nl,
+ " Reason ->",nl,
+ " {error,{asn1,Reason}}",nl,
+ " end",nl,
+ "end."].
gen_info_functions(Erules) ->
emit(["encoding_rule() -> ",