asn1ct_gen.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,973 行 · 第 1/4 页
ERL
1,973 行
gen_part_decode_funcs({constructed,bif},TypeName, {_Name,undecoded,Tag,_Type}) -> emit([" 'dec_",TypeName,"'(Data,",{asis,Tag},")"]);gen_part_decode_funcs({primitive,bif},_TypeName, {_Name,undecoded,Tag,Type}) -> % Argument no 6 is 0, i.e. bit 6 for primitive encoding. asn1ct_gen_ber_bin_v2:gen_dec_prim(ber_bin_v2,Type,"Data",Tag,[],0,", mandatory, ");gen_part_decode_funcs(WhatKind,_TypeName,{_,Directive,_,_}) -> throw({error,{asn1,{"Not implemented yet",WhatKind," partial incomplete directive:",Directive}}}). gen_types(Erules,Tname,{RootList,ExtList}) when list(RootList) -> gen_types(Erules,Tname,RootList), gen_types(Erules,Tname,ExtList);gen_types(Erules,Tname,[{'EXTENSIONMARK',_,_}|Rest]) -> gen_types(Erules,Tname,Rest);gen_types(Erules,Tname,[ComponentType|Rest]) -> Rtmod = list_to_atom(lists:concat(["asn1ct_gen_",erule(Erules), rt2ct_suffix(Erules)])), asn1ct_name:clear(), Rtmod:gen_encode(Erules,Tname,ComponentType), asn1ct_name:clear(), Rtmod:gen_decode(Erules,Tname,ComponentType), gen_types(Erules,Tname,Rest);gen_types(_,_,[]) -> true;gen_types(Erules,Tname,Type) when record(Type,type) -> Rtmod = list_to_atom(lists:concat(["asn1ct_gen_",erule(Erules), rt2ct_suffix(Erules)])), asn1ct_name:clear(), Rtmod:gen_encode(Erules,Tname,Type), asn1ct_name:clear(), Rtmod:gen_decode(Erules,Tname,Type).gen_value_match(Module) -> case get(value_match) of {true,Module} -> emit(["value_match([{Index,Cname}|Rest],Value) ->",nl, " Value2 =",nl, " case element(Index,Value) of",nl, " {Cname,Val2} -> Val2;",nl, " X -> X",nl, " end,",nl, " value_match(Rest,Value2);",nl, "value_match([],Value) ->",nl, " Value.",nl]); _ -> ok end, put(value_match,undefined).gen_check_defaultval(Erules,Module,[{Name,Type}|Rest]) -> gen_check_func(Name,Type), gen_check_defaultval(Erules,Module,Rest);gen_check_defaultval(_,_,[]) -> ok.gen_check_func(Name,FType = #type{def=Def}) -> emit({Name,"(V,asn1_DEFAULT) ->",nl," true;",nl}), emit({Name,"(V,V) ->",nl," true;",nl}), emit({Name,"(V,{_,V}) ->",nl," true;",nl}), case Def of {'SEQUENCE OF',Type} -> gen_check_sof(Name,'SEQOF',Type); {'SET OF',Type} -> gen_check_sof(Name,'SETOF',Type); #'SEQUENCE'{components=Components} -> gen_check_sequence(Name,Components); #'SET'{components=Components} -> gen_check_sequence(Name,Components); {'CHOICE',Components} -> gen_check_choice(Name,Components); #'Externaltypereference'{type=T} -> emit({Name,"(DefaultValue,Value) ->",nl}), emit({" ",list2name([T,check]),"(DefaultValue,Value).",nl}); MaybePrim -> InnerType = get_inner(MaybePrim), case type(InnerType) of {primitive,bif} -> emit({Name,"(DefaultValue,Value) ->",nl," "}), gen_prim_check_call(InnerType,"DefaultValue","Value", FType), emit({".",nl,nl}); _ -> throw({asn1_error,{unknown,type,MaybePrim}}) end end.gen_check_sof(Name,SOF,Type) -> NewName = list2name([sorted,Name]), emit({Name,"(V1,V2) ->",nl}), emit({" ",NewName,"(lists:sort(V1),lists:sort(V2)).",nl,nl}), emit({NewName,"([],[]) ->",nl," true;",nl}), emit({NewName,"([DV|DVs],[V|Vs]) ->",nl," "}), InnerType = get_inner(Type#type.def), case type(InnerType) of {primitive,bif} -> gen_prim_check_call(InnerType,"DV","V",Type), emit({",",nl}); {constructed,bif} -> emit({list2name([SOF,Name]),"(DV, V),",nl}); #'Externaltypereference'{type=T} -> emit({list2name([T,check]),"(DV,V),",nl}) end, emit({" ",NewName,"(DVs,Vs).",nl,nl}).gen_check_sequence(Name,Components) -> emit({Name,"(DefaultValue,Value) ->",nl}), gen_check_sequence(Name,Components,1).gen_check_sequence(Name,[#'ComponentType'{name=N,typespec=Type}|Cs],Num) -> InnerType = get_inner(Type#type.def),% NthDefV = lists:concat(["lists:nth(",Num,",DefaultValue)"]), NthDefV = ["element(",Num+1,",DefaultValue)"],% NthV = lists:concat(["lists:nth(",Num,",Value)"]), NthV = ["element(",Num+1,",Value)"], gen_check_func_call(Name,Type,InnerType,NthDefV,NthV,N), case Cs of [] -> emit({".",nl,nl}); _ -> emit({",",nl}), gen_check_sequence(Name,Cs,Num+1) end;gen_check_sequence(_,[],_) -> ok.gen_check_choice(Name,CList=[#'ComponentType'{}|_Cs]) -> emit({Name,"({Id,DefaultValue},{Id,Value}) ->",nl}), emit({" case Id of",nl}), gen_check_choice_components(Name,CList,1).gen_check_choice_components(_,[],_)-> ok;gen_check_choice_components(Name,[#'ComponentType'{name=N,typespec=Type}| Cs],Num) -> Ind6 = " ", InnerType = get_inner(Type#type.def),% DefVal = ["element(2,lists:nth(",Num,",DefaultValue))"], emit({Ind6,N," ->",nl,Ind6}), gen_check_func_call(Name,Type,InnerType,{var,"defaultValue"}, {var,"value"},N), case Cs of [] -> emit({nl," end.",nl,nl}); _ -> emit({";",nl}), gen_check_choice_components(Name,Cs,Num+1) end.gen_check_func_call(Name,Type,InnerType,DefVal,Val,N) -> case type(InnerType) of {primitive,bif} -> emit(" "), gen_prim_check_call(InnerType,DefVal,Val,Type); #'Externaltypereference'{type=T} -> emit({" ",list2name([T,check]),"(",DefVal,",",Val,")"}); _ -> emit({" ",list2name([N,Name]),"(",DefVal,",",Val,")"}) end. %% VARIOUS GENERATOR STUFF %% *************************************************%%**************************************************mk_var(X) when atom(X) -> list_to_atom(mk_var(atom_to_list(X)));mk_var([H|T]) -> [H-32|T].%% Since hyphens are allowed in ASN.1 names, it may occur in a%% variable to. Turn a hyphen into a under-score sign.un_hyphen_var(X) when atom(X) -> list_to_atom(un_hyphen_var(atom_to_list(X)));un_hyphen_var([45|T]) -> [95|un_hyphen_var(T)];un_hyphen_var([H|T]) -> [H|un_hyphen_var(T)];un_hyphen_var([]) -> [].%% Generate value functions ***************%% ****************************************%% Generates a function 'V'/0 for each Value V defined in the ASN.1 module%% the function returns the value in an Erlang representation which can be%% used as input to the runtime encode functionsgen_value(Value) when record(Value,valuedef) ->%% io:format(" ~w ",[Value#valuedef.name]), emit({"'",Value#valuedef.name,"'() ->",nl}), V = Value#valuedef.value, emit([{asis,V},".",nl,nl]).gen_encode_constructed(Erules,Typename,InnerType,D) when record(D,type) -> Rtmod = list_to_atom(lists:concat(["asn1ct_constructed_",erule(Erules)])), case InnerType of 'SET' -> Rtmod:gen_encode_set(Erules,Typename,D), #'SET'{components=Components} = D#type.def, gen_types(Erules,Typename,Components); 'SEQUENCE' -> Rtmod:gen_encode_sequence(Erules,Typename,D), #'SEQUENCE'{components=Components} = D#type.def, gen_types(Erules,Typename,Components); 'CHOICE' -> Rtmod:gen_encode_choice(Erules,Typename,D), {_,Components} = D#type.def, gen_types(Erules,Typename,Components); 'SEQUENCE OF' -> Rtmod:gen_encode_sof(Erules,Typename,InnerType,D), {_,Type} = D#type.def, NameSuffix = asn1ct_gen:constructed_suffix(InnerType,Type#type.def), gen_types(Erules,[NameSuffix|Typename],Type); 'SET OF' -> Rtmod:gen_encode_sof(Erules,Typename,InnerType,D), {_,Type} = D#type.def, NameSuffix = asn1ct_gen:constructed_suffix(InnerType,Type#type.def), gen_types(Erules,[NameSuffix|Typename],Type); _ -> exit({nyi,InnerType}) end;gen_encode_constructed(Erules,Typename,InnerType,D) when record(D,typedef) -> gen_encode_constructed(Erules,Typename,InnerType,D#typedef.typespec).gen_decode_constructed(Erules,Typename,InnerType,D) when record(D,type) -> Rtmod = list_to_atom(lists:concat(["asn1ct_constructed_",erule(Erules)])), asn1ct:step_in_constructed(), %% updates namelist for exclusive decode case InnerType of 'SET' -> Rtmod:gen_decode_set(Erules,Typename,D); 'SEQUENCE' -> Rtmod:gen_decode_sequence(Erules,Typename,D); 'CHOICE' -> Rtmod:gen_decode_choice(Erules,Typename,D); 'SEQUENCE OF' -> Rtmod:gen_decode_sof(Erules,Typename,InnerType,D); 'SET OF' -> Rtmod:gen_decode_sof(Erules,Typename,InnerType,D); _ -> exit({nyi,InnerType}) end;gen_decode_constructed(Erules,Typename,InnerType,D) when record(D,typedef) -> gen_decode_constructed(Erules,Typename,InnerType,D#typedef.typespec).pgen_exports(Erules,_Module,{Types,Values,_,_,Objects,ObjectSets}) -> emit({"-export([encoding_rule/0]).",nl}), case Types of [] -> ok; _ -> emit({"-export([",nl}), case Erules of ber -> gen_exports1(Types,"enc_",2); ber_bin -> gen_exports1(Types,"enc_",2); ber_bin_v2 -> gen_exports1(Types,"enc_",2); _ -> gen_exports1(Types,"enc_",1) end, emit({"-export([",nl}), gen_exports1(Types,"dec_",2), case Erules of ber -> emit({"-export([",nl}), gen_exports1(Types,"dec_",3); ber_bin -> emit({"-export([",nl}), gen_exports1(Types,"dec_",3);% ber_bin_v2 ->% emit({"-export([",nl}),% gen_exports1(Types,"dec_",2); _ -> ok end end, case Values of [] -> ok; _ -> emit({"-export([",nl}), gen_exports1(Values,"",0) end, case Objects of [] -> ok; _ -> case erule(Erules) of per -> emit({"-export([",nl}), gen_exports1(Objects,"enc_",3), emit({"-export([",nl}), gen_exports1(Objects,"dec_",4); ber_bin_v2 -> emit({"-export([",nl}), gen_exports1(Objects,"enc_",3), emit({"-export([",nl}), gen_exports1(Objects,"dec_",3); _ -> emit({"-export([",nl}), gen_exports1(Objects,"enc_",4), emit({"-export([",nl}), gen_exports1(Objects,"dec_",4) end end, case ObjectSets of [] -> ok; _ -> emit({"-export([",nl}), gen_exports1(ObjectSets,"getenc_",2), emit({"-export([",nl}), gen_exports1(ObjectSets,"getdec_",2) end, emit({"-export([info/0]).",nl}), gen_partial_inc_decode_exports(), gen_selected_decode_exports(), emit({nl,nl}).gen_exports1([F1,F2|T],Prefix,Arity) -> emit({"'",Prefix,F1,"'/",Arity,com,nl}), gen_exports1([F2|T],Prefix,Arity);gen_exports1([Flast|_T],Prefix,Arity) -> emit({"'",Prefix,Flast,"'/",Arity,nl,"]).",nl,nl}).gen_partial_inc_decode_exports() -> case {asn1ct:read_config_data(partial_incomplete_decode), asn1ct:get_gen_state_field(inc_type_pattern)} of {undefined,_} -> ok; {_,undefined} -> ok; {Data,_} -> gen_partial_inc_decode_exports(Data), emit(["-export([decode_part/2]).",nl]) end.gen_partial_inc_decode_exports([]) -> ok;gen_partial_inc_decode_exports([{Name,_,_}|Rest]) -> emit(["-export([",Name,"/1"]), gen_partial_inc_decode_exports1(Rest);gen_partial_inc_decode_exports([_|Rest]) -> gen_partial_inc_decode_exports(Rest).gen_partial_inc_decode_exports1([]) -> emit(["]).",nl]);gen_partial_inc_decode_exports1([{Name,_,_}|Rest]) -> emit([", ",Name,"/1"]), gen_partial_inc_decode_exports1(Rest);gen_partial_inc_decode_exports1([_|Rest]) -> gen_partial_inc_decode_exports1(Rest).gen_selected_decode_exports() -> case asn1ct:get_gen_state_field(type_pattern) of undefined -> ok; L -> gen_selected_decode_exports(L) end.gen_selected_decode_exports([]) -> ok;gen_selected_decode_exports([{FuncName,_}|Rest]) -> emit(["-export([",FuncName,"/1"]), gen_selected_decode_exports1(Rest).gen_selected_decode_exports1([]) -> emit(["]).",nl,nl]);gen_selected_decode_exports1([{FuncName,_}|Rest]) -> emit([",",nl," ",FuncName,"/1"]), gen_selected_decode_exports1(Rest).pgen_dispatcher(Erules,_Module,{[],_Values,_,_,_Objects,_ObjectSets}) -> emit(["encoding_rule() ->",nl]), emit([{asis,Erules},".",nl,nl]);pgen_dispatcher(Erules,_Module,{Types,_Values,_,_,_Objects,_ObjectSets}) -> emit(["-export([encode/2,decode/2,encode_disp/2,decode_disp/2]).",nl,nl]), emit(["encoding_rule() ->",nl]), emit([" ",{asis,Erules},".",nl,nl]), Call = case Erules of per -> "?RT_PER:complete(encode_disp(Type,Data))"; per_bin -> "?RT_PER:complete(encode_disp(Type,Data))"; ber -> "encode_disp(Type,Data)"; ber_bin -> "encode_disp(Type,Data)"; ber_bin_v2 -> "encode_disp(Type,Data)" end, EncWrap = case Erules of ber -> "wrap_encode(Bytes)"; _ -> "Bytes" end, emit(["encode(Type,Data) ->",nl, "case catch ",Call," of",nl, " {'EXIT',{error,Reason}} ->",nl, " {error,Reason};",nl, " {'EXIT',Reason} ->",nl, " {error,{asn1,Reason}};",nl, " {Bytes,_Len} ->",nl, " {ok,",EncWrap,"};",nl]), case Erules of per -> emit([" Bytes when is_binary(Bytes) ->",nl, " {ok,binary_to_list(Bytes)};",nl, " Bytes ->",nl, " {ok,binary_to_list(list_to_binary(Bytes))}",nl, " end.",nl,nl]); _ -> emit([" Bytes ->",nl, " {ok,",EncWrap,"}",nl, "end.",nl,nl]) end,% case Erules of% ber_bin_v2 ->% emit(["decode(Type,Data0) ->",nl]),% emit(["{Data,_RestBin} = ?RT_BER:decode(Data0",driver_parameter(),"),",nl]);% _ ->% emit(["decode(Type,Data) ->",nl])% end, Return_rest = lists:member(undec_rest,get(encoding_options)), Data = case {Erules,Return_rest} of {ber_bin_v2,true} -> "Data0"; _ -> "Data" end, emit(["decode(Type,",Data,") ->",nl]), DecAnonymous = case {Erules,Return_rest} of {ber_bin_v2,false} -> io_lib:format("~s~s~s~n", ["element(1,?RT_BER:decode(Data", driver_parameter(),"))"]); {ber_bin_v2,true} -> emit(["{Data,Rest} = ?RT_BER:decode(Data0", driver_parameter(),"),",nl]), "Data"; _ -> "Data" end, DecWrap = case Erules of ber -> "wrap_decode(Data)"; ber_bin_v2 -> DecAnonymous; per -> "list_to_binary(Data)"; _ -> "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_bin_v2,false} -> emit([" Result ->",nl, " {ok,Result}",nl]); {ber_bin_v2,true} -> emit([" Result ->",nl, " {ok,Result,Rest}",nl]); {per,false} -> emit([" {X,_Rest} ->",nl, " {ok,if_binary2list(X)};",nl, " {X,_Rest,_Len} ->",nl, " {ok,if_binary2list(X)}",nl]); {_,false} -> emit([" {X,_Rest} ->",nl, " {ok,X};",nl, " {X,_Rest,_Len} ->",nl, " {ok,X}",nl]); {per,true} -> emit([" {X,{_,Rest}} ->",nl, " {ok,if_binary2list(X),Rest};",nl, " {X,{_,Rest},_Len} ->",nl, " {ok,if_binary2list(X),Rest};",nl, " {X,Rest} ->",nl, " {ok,if_binary2list(X),Rest};",nl, " {X,Rest,_Len} ->",nl, " {ok,if_binary2list(X),Rest}",nl]); {per_bin,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([" {X,Rest} ->",nl, " {ok,X,Rest};",nl, " {X,Rest,_Len} ->",nl, " {ok,X,Rest}",nl]) end, emit(["end.",nl,nl]),
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?