asn1ct_constructed_ber_bin_v2.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,390 行 · 第 1/3 页

ERL
1,390
字号
    asn1ct_name:new(tlv),    emit([{curr,tlv},	  " = ?RT_BER:match_tags(",{prev,tlv},",TagIn), ",nl]),    asn1ct_name:new(v),    emit(["["]),    InnerType = asn1ct_gen:get_inner(Cont#type.def),    ContName = case asn1ct_gen:type(InnerType) of		   Atom when atom(Atom) -> Atom;		   _ -> TypeNameSuffix	       end,%% fix me    ObjFun =	case D#type.tablecinf of	    [{objfun,_}|_R] ->		", ObjFun";	    _ ->		[]	end,    gen_dec_line(Erules,TypeName,ContName,[],Cont,mandatory,ObjFun),    %%    gen_dec_line_sof(Erules,Typename,ContName,Cont,ObjFun),    emit([" || ",{curr,v}," <- ",{curr,tlv},"].",nl,nl,nl]).    gen_encode_sof_components(Erules,Typename,SeqOrSetOf,Cont)   when record(Cont,type)->    {Objfun,Objfun_novar,EncObj} = 	case Cont#type.tablecinf of	    [{objfun,_}|_R] ->		{", ObjFun",", _",{no_attr,"ObjFun"}};	    _ ->		{"","",false}	end,    emit(["'enc_",asn1ct_gen:list2name(Typename),	  "_components'([]",Objfun_novar,", AccBytes, AccLen) -> ",nl]),    case catch lists:member(der,get(encoding_options)) of	true when SeqOrSetOf=='SET OF'->	    emit([indent(3),		  "{asn1rt_check:dynamicsort_SETOF(AccBytes),AccLen};",nl,nl]);	_ ->	    emit([indent(3),"{lists:reverse(AccBytes),AccLen};",nl,nl])    end,    emit(["'enc_",asn1ct_gen:list2name(Typename),	  "_components'([H|T]",Objfun,",AccBytes, AccLen) ->",nl]),    TypeNameSuffix = asn1ct_gen:constructed_suffix(SeqOrSetOf,Cont#type.def),    gen_enc_line(Erules,Typename,TypeNameSuffix,Cont,"H",3,%		 mandatory,"{EncBytes,EncLen} = ",EncObj),		 mandatory,EncObj),    emit([",",nl]),    emit([indent(3),"'enc_",asn1ct_gen:list2name(Typename),	  "_components'(T",Objfun,","]),     emit(["[EncBytes|AccBytes], AccLen + EncLen).",nl,nl]).%%============================================================================%%  Encode/decode CHOICE%%%%============================================================================gen_encode_choice(Erules,Typename,D) when record(D,type) ->    ChoiceTag = D#type.tag,    {'CHOICE',CompList} = D#type.def,    Ext = extensible(CompList),    CompList1 = case CompList of		    {Rl,El} -> Rl ++ El;		    _ -> CompList		end,    gen_enc_choice(Erules,Typename,ChoiceTag,CompList1,Ext),    emit([nl,nl]).gen_decode_choice(Erules,Typename,D) when record(D,type) ->    asn1ct_name:start(),    asn1ct_name:new(bytes),    ChoiceTag = D#type.tag,    {'CHOICE',CompList} = D#type.def,    Ext = extensible(CompList),    CompList1 = case CompList of		    {Rl,El} -> Rl ++ El;		    _ -> CompList		end,    gen_dec_choice(Erules,Typename,ChoiceTag,CompList1,Ext),    emit([".",nl]).%%============================================================================%%  Encode SEQUENCE%%%%============================================================================gen_enc_sequence_call(Erules,TopType,[#'ComponentType'{name=Cname,typespec=Type,prop=Prop}|Rest],Pos,Ext,EncObj) ->    asn1ct_name:new(encBytes),    asn1ct_name:new(encLen),    Element = 	case TopType of	    ['EXTERNAL'] ->		io_lib:format("Cindex~w",[Pos]);	    _ ->		io_lib:format("Cindex~w",[Pos])	end,    InnerType = asn1ct_gen:get_inner(Type#type.def),    print_attribute_comment(InnerType,Pos,Cname,Prop),    gen_enc_line(Erules,TopType,Cname,Type,Element,3,Prop,EncObj),    emit([com,nl]),    gen_enc_sequence_call(Erules,TopType,Rest,Pos+1,Ext,EncObj);gen_enc_sequence_call(_Erules,_TopType,[],_Num,_,_) ->	true.%%============================================================================%%  Decode SEQUENCE%%%%============================================================================gen_dec_sequence_call(Erules,TopType,CompList,Ext,DecObjInf) ->    gen_dec_sequence_call1(Erules,TopType, CompList, 1, Ext,DecObjInf,[],[]).gen_dec_sequence_call1(Erules,TopType,[#'ComponentType'{name=Cname,typespec=Type,prop=Prop,tags=Tags}|Rest],Num,Ext,DecObjInf,LeadingAttrAcc,ArgsAcc) ->    {LA,PostponedDec} = 	gen_dec_component(Erules,TopType,Cname,Tags,Type,Num,Prop,			  Ext,DecObjInf),    case Rest of	[] ->	    {LA ++ LeadingAttrAcc,PostponedDec ++ ArgsAcc};	_ ->	    emit([com,nl]),	    asn1ct_name:new(bytes),	    gen_dec_sequence_call1(Erules,TopType,Rest,Num+1,Ext,DecObjInf,				   LA++LeadingAttrAcc,PostponedDec++ArgsAcc)    end;gen_dec_sequence_call1(_Erules,_TopType,[],1,_,_,_,_) ->    no_terms.%%----------------------------%%SEQUENCE mandatory%%----------------------------gen_dec_component(Erules,TopType,Cname,CTags,Type,Pos,Prop,Ext,DecObjInf) ->    InnerType = 	case Type#type.def of	    #'ObjectClassFieldType'{type=OCFTType} -> OCFTType;	    _ -> asn1ct_gen:get_inner(Type#type.def)	end,% 	case asn1ct_gen:get_constraint(Type#type.constraint,% 				       tableconstraint_info) of% 	    no ->% 		asn1ct_gen:get_inner(Type#type.def);% 	    _ ->% 		Type#type.def% 	end,    Prop1 = case {Prop,Ext} of		{mandatory,{ext,Epos,_}} when Pos >= Epos ->		    'OPTIONAL';		_ ->		    Prop	    end,    print_attribute_comment(InnerType,Pos,Cname,Prop1),    asn1ct_name:new(term),    emit_term_tlv(Prop1,InnerType,DecObjInf),    asn1ct_name:new(rb),    PostponedDec = 	gen_dec_line(Erules,TopType,Cname,CTags,Type,Prop1,DecObjInf),    asn1ct_name:new(v),    asn1ct_name:new(tlv),    asn1ct_name:new(form),    PostponedDec.emit_term_tlv({'DEFAULT',_},InnerType,DecObjInf) ->    emit_term_tlv(opt_or_def,InnerType,DecObjInf);emit_term_tlv('OPTIONAL',InnerType,DecObjInf) ->    emit_term_tlv(opt_or_def,InnerType,DecObjInf);emit_term_tlv(Prop,{typefield,_},DecObjInf) ->    emit_term_tlv(Prop,type_or_object_field,DecObjInf);emit_term_tlv(Prop,{objectfield,_,_},DecObjInf) ->    emit_term_tlv(Prop,type_or_object_field,DecObjInf);emit_term_tlv(opt_or_def,type_or_object_field,NotFalse)   when NotFalse /= false ->    asn1ct_name:new(tmpterm),    emit(["{",{curr,tmpterm},",",{curr,tlv},"} = "]);emit_term_tlv(opt_or_def,_,_) ->    emit(["{",{curr,term},",",{curr,tlv},"} = "]);emit_term_tlv(_,type_or_object_field,false) ->     emit(["[",{curr,v},"|",{curr,tlv},"] = ",{prev,tlv},", ",nl,	  {curr,term}," = "]);emit_term_tlv(_,type_or_object_field,_) ->    asn1ct_name:new(tmpterm),    emit(["[",{curr,v},"|",{curr,tlv},"] = ",{prev,tlv},", ",nl]),    emit([nl,"  ",{curr,tmpterm}," = "]);emit_term_tlv(mandatory,_,_) ->    emit(["[",{curr,v},"|",{curr,tlv},"] = ",{prev,tlv},", ",nl,	  {curr,term}," = "]).gen_dec_set_cases(_Erules,_TopType,[],Pos) ->    Pos;gen_dec_set_cases(Erules,TopType,[Comp|RestComps],Pos) ->    Name = Comp#'ComponentType'.name,    Type = Comp#'ComponentType'.typespec,    CTags = Comp#'ComponentType'.tags,        emit([indent(6),"%",Name,nl]),    Tags = case Type#type.tag of	       [] -> % this is a choice without explicit tag		   [(?ASN1CT_GEN_BER:decode_class(T1class) bsl 10) + T1number|| 		       {T1class,T1number} <- CTags];               [FirstTag|_] ->		   [(?ASN1CT_GEN_BER:decode_class(FirstTag#tag.class) bsl 10) + FirstTag#tag.number]	   end,%    emit([indent(6),"%Tags: ",Tags,nl]),%    emit([indent(6),"%Type#type.tag: ",Type#type.tag,nl]),    CaseFun = fun(TagList=[H|T],Fun,N) ->		      Semicolon = case TagList of				      [_Tag1,_|_] -> [";",nl];				      _ -> ""				  end,		      emit(["TTlv = {",H,",_} ->",nl]),		      emit([indent(4),"{",Pos,", TTlv}",Semicolon]),		      Fun(T,Fun,N+1);		 ([],_,0) ->		      true;		 ([],_,_) ->		      emit([";",nl])	      end,    CaseFun(Tags,CaseFun,0),%%    emit([";",nl]),    gen_dec_set_cases(Erules,TopType,RestComps,Pos+1).%%---------------------------------------------%%  Encode CHOICE%%---------------------------------------------%% for BER we currently do care (a little) if the choice has an EXTENSIONMARKERgen_enc_choice(Erules,TopType,Tag,CompList,_Ext) ->    gen_enc_choice1(Erules,TopType,Tag,CompList,_Ext).gen_enc_choice1(Erules,TopType,_Tag,CompList,_Ext) ->    asn1ct_name:clear(),    emit(["   {EncBytes,EncLen} = case element(1,Val) of",nl]),    gen_enc_choice2(Erules,TopType,CompList),    emit([nl,"   end,",nl,nl]),        emit(["?RT_BER:encode_tags(TagIn, EncBytes, EncLen).",nl]).gen_enc_choice2(Erules,TopType,[H1|T]) when record(H1,'ComponentType') ->    Cname = H1#'ComponentType'.name,    Type = H1#'ComponentType'.typespec,    emit(["      ",{asis,Cname}," ->",nl]),    {Encobj,Assign} =	case {Type#type.def,asn1ct_gen:get_constraint(Type#type.constraint,						      componentrelation)} of	    {#'ObjectClassFieldType'{},{componentrelation,_,_}} ->		asn1ct_name:new(tmpBytes),		asn1ct_name:new(encBytes),		asn1ct_name:new(encLen),		Emit = ["{",{curr,tmpBytes},", _} = "],		{{no_attr,"ObjFun"},Emit};	    _ ->		case Type#type.tablecinf of		    [{objfun,_}] -> {{no_attr,"ObjFun"},[]};		    _ -> {false,[]}		end	end,    gen_enc_line(Erules,TopType,Cname,Type,"element(2,Val)",9,		 mandatory,Assign,Encobj),    case {Type#type.def,Encobj} of	{#'ObjectClassFieldType'{},{no_attr,"ObjFun"}} ->	    emit([",",nl,indent(9),"{",{curr,encBytes},", ",		  {curr,encLen},"}"]);	_ -> ok    end,    emit([";",nl]),    case T of 	[] ->	    emit([indent(6), "Else -> ",nl,		  indent(9),"exit({error,{asn1,{invalid_choice_type,Else}}})"]);	_ ->	    true    end,    gen_enc_choice2(Erules,TopType,T);gen_enc_choice2(_Erules,_TopType,[])  ->    true.%%--------------------------------------------%%  Decode CHOICE%%--------------------------------------------gen_dec_choice(Erules,TopType, _ChTag, CompList, Ext) ->    asn1ct_name:clear(),    asn1ct_name:new(tlv),    emit([{curr,tlv},	  " = ?RT_BER:match_tags(",{prev,tlv},",TagIn), ",nl]),    asn1ct_name:new(tlv),    asn1ct_name:new(v),    emit(["case (case ",{prev,tlv},	  " of [Ctemp",{prev,tlv},"] -> Ctemp",{prev,tlv},	  "; _ -> ",{prev,tlv}," end)"," of",nl]),    asn1ct_name:new(tagList),    asn1ct_name:new(choTags),    asn1ct_name:new(res),    gen_dec_choice_cases(Erules,TopType,CompList),    emit([indent(6), {curr,else}," -> ",nl]),    case Ext of	noext ->	    emit([indent(9),"exit({error,{asn1,{invalid_choice_tag,",		  {curr,else},"}}})",nl]);	_ ->	    emit([indent(9),"{asn1_ExtAlt, ?RT_BER:encode(",{curr,else},")}",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]) ->    Cname = H#'ComponentType'.name,    Type = H#'ComponentType'.typespec,    Prop = H#'ComponentType'.prop,    Tags = Type#type.tag,    Fcases  = fun([{T1class,T1number}|Tail],Fun) ->		      		      emit([indent(4),{curr,v}," = {",			    (?ASN1CT_GEN_BER:decode_class(T1class) bsl 10) +			    T1number,",_} -> ",nl]),		      emit([indent(8),"{",{asis,Cname},", "]),		      gen_dec_line(Erules,TopType,Cname,[],Type,Prop,false),		      emit(["};",nl,nl]),		      Fun(Tail,Fun);		 ([],_) ->		      ok	      end,    emit([nl,"%% '",Cname,"'",nl]),    case {Tags,asn1ct:get_gen_state_field(namelist)} of	{[],_} -> % choice without explicit tags	    Fcases(H#'ComponentType'.tags,Fcases);	{[FirstT|_RestT],[{Cname,undecoded}|Names]} ->	    DecTag=(?ASN1CT_GEN_BER:decode_class(FirstT#tag.class) bsl 10) +		FirstT#tag.number,	    asn1ct:add_generated_refed_func({[Cname|TopType],undecoded,					     [DecTag],Type}),	    asn1ct:update_gen_state(namelist,Names),	    emit([indent(4),{curr,res}," = ",		  match_tag(ber_bin,{FirstT#tag.class,FirstT#tag.number}),		  " -> ",nl]),	    emit([indent(8),"{",{asis,Cname},", {'",		  asn1ct_gen:list2name([Cname|TopType]),"',",		  {curr,res},"}};",nl,nl]);	{[FirstT|RestT],_} ->	    emit([indent(4),"{",		  (?ASN1CT_GEN_BER:decode_class(FirstT#tag.class) bsl 10) +		  FirstT#tag.number,", ",{curr,v},"} -> ",nl]),	    emit([indent(8),"{",{asis,Cname},", "]),	    gen_dec_line(Erules,TopType,Cname,[],Type#type{tag=RestT},Prop,false),	    emit(["};",nl,nl])    end,    gen_dec_choice_cases(Erules,TopType, T).%%---------------------------------------%% Generate the encode/decode code %%---------------------------------------gen_enc_line(Erules,TopType,Cname,	     Type=#type{constraint=C,			def=#'ObjectClassFieldType'{type={typefield,_}}},	     Element,Indent,OptOrMand=mandatory,EncObj)   when list(Element) ->    case asn1ct_gen:get_constraint(C,componentrelation) of	{componentrelation,_,_} ->	    asn1ct_name:new(tmpBytes),	    gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand,			 ["{",{curr,tmpBytes},",_} = "],EncObj);	_ ->	    gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand,			 ["{",{curr,encBytes},",",{curr,encLen},"} = "],			 EncObj)    end;% gen_enc_line(Erules,TopType,Cname,% 	     Type=#type{constraint=[{componentrelation,_,_}],% 			def=#'ObjectClassFieldType'{type={typefield,_}}},% 	     Element,Indent,OptOrMand=mandatory,EncObj) %   when list(Element) ->%     asn1ct_name:new(tmpBytes),%     gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand,% 		 ["{",{curr,tmpBytes},",_} = "],EncObj);gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand,EncObj)   when list(Element) ->    gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand,		 ["{",{curr,encBytes},",",{curr,encLen},"} = "],EncObj).gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand,Assign,EncObj)  when list(Element) ->    IndDeep = indent(Indent),    Tag = lists:reverse([?ASN1CT_GEN_BER:encode_tag_val(			    ?ASN1CT_GEN_BER:decode_class(X#tag.class),			    X#tag.form,			    X#tag.number)			 || X <- Type#type.tag]),    InnerType = asn1ct_gen:get_inner(Type#type.def),    WhatKind = asn1ct_gen:type(InnerType),    emit(IndDeep),    emit(Assign),    gen_optormand_case(OptOrMand,Erules,TopType,Cname,Type,InnerType,WhatKind,		       Element),    case {Type,asn1ct_gen:get_constraint(Type#type.constraint,					 componentrelation)} of% 	#type{constraint=[{tableconstraint_info,RefedFieldName}],% 	      def={typefield,_}} ->	{#type{def=#'ObjectClassFieldType'{type={typefield,_},					   fieldname=RefedFieldName}},	 {componentrelation,_,_}} ->	    {_LeadingAttrName,Fun} = EncObj,	    case RefedFieldName of%% 		{notype,T} ->%% 		    throw({error,{notype,type_from_object,T}});		{Name,RestFieldNames} when atom(Name), Name =/= notype ->		    case OptOrMand of			mandatory -> ok;			_ ->%			    emit(["{",{curr,tmpBytes},",",{curr,tmpLen},			    emit(["{",{curr,tmpBytes},",_ } = "])%				  "} = "])		    end,		    emit([Fun,"(",{asis,Name},", ",Element,", ",			  {asis,RestFieldNames},"),",nl]),		    emit(IndDeep),		    case OptOrMand of			mandatory ->			    emit(["{",{curr,encBytes},",",{curr,encLen},				  "} = "]),			    emit(["?RT_BER:encode_open_type(",{curr,tmpBytes},				  ",",{asis,Tag},")"]);			_ ->%			    emit(["{",{next,tmpBytes},", _} = "]),			    emit(["{",{next,tmpBytes},",",{curr,tmpLen},				  "} = "]),			    emit(["?RT_BER:encode_open_type(",{curr,tmpBytes},				  ",",{asis,Tag},"),",nl]),			    emit(IndDeep),			    emit(["{",{next,tmpBytes},", ",{curr,tmpLen},"}"])		    end;		Err ->		    throw({asn1,{'internal error',Err}})	    end;%% 	{{#'ObjectClassFieldType'{type={objectfield,PrimFieldName1,%% 					PFNList}},_},%% 	 {componentrelation,_,_}} ->%% 	    %% this is when the dotted list in the FieldName has more%% 	    %% than one element%% 	    {_LeadingAttrName,Fun} = EncObj,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?