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 + -
显示快捷键?