asn1ct_constructed_ber_bin_v2.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,390 行 · 第 1/3 页
ERL
1,390 行
%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %% $Id$%%-module(asn1ct_constructed_ber_bin_v2).-export([gen_encode_sequence/3]).-export([gen_decode_sequence/3]).-export([gen_encode_set/3]).-export([gen_decode_set/3]).-export([gen_encode_sof/4]).-export([gen_decode_sof/4]).-export([gen_encode_choice/3]).-export([gen_decode_choice/3]).-include("asn1_records.hrl").-import(asn1ct_gen, [emit/1,demit/1]).-import(asn1ct_constructed_ber,[match_tag/2]).-define(ASN1CT_GEN_BER,asn1ct_gen_ber_bin_v2).% the encoding of class of tag bits 8 and 7-define(UNIVERSAL, 0).-define(APPLICATION, 16#40).-define(CONTEXT, 16#80).-define(PRIVATE, 16#C0).% primitive or constructed encoding % bit 6-define(PRIMITIVE, 0).-define(CONSTRUCTED, 2#00100000).%%===============================================================================%%===============================================================================%%===============================================================================%% Encode/decode SEQUENCE (and SET)%%===============================================================================%%===============================================================================%%===============================================================================gen_encode_sequence(Erules,Typename,D) when record(D,type) -> asn1ct_name:start(), asn1ct_name:new(term), asn1ct_name:new(bytes), %% if EXTERNAL type the input value must be transformed to %% ASN1 1990 format ValName = case Typename of ['EXTERNAL'] -> emit([indent(4), "NewVal = asn1rt_check:transform_to_EXTERNAL1990(Val),", nl]), "NewVal"; _ -> "Val" end, {SeqOrSet,TableConsInfo,CompList} = case D#type.def of #'SEQUENCE'{tablecinf=TCI,components=CL} -> {'SEQUENCE',TCI,CL}; #'SET'{tablecinf=TCI,components=CL} -> {'SET',TCI,CL} end, Ext = extensible(CompList), CompList1 = case CompList of {Rl,El} -> Rl ++ El; _ -> CompList end, %% don't match recordname for now, because of compatibility reasons%% emit(["{'",asn1ct_gen:list2rname(Typename),"'"]), emit(["{_"]), case length(CompList1) of 0 -> true; CompListLen -> emit([","]), mkcindexlist([Tc || Tc <- lists:seq(1,CompListLen)]) end, emit(["} = ",ValName,",",nl]), EncObj = case TableConsInfo of #simpletableattributes{usedclassfield=Used, uniqueclassfield=Unique} when Used /= Unique -> false; %% ObjectSet, name of the object set in constraints %% #simpletableattributes{objectsetname=ObjectSet, c_name=AttrN, c_index=N, usedclassfield=UniqueFieldName, uniqueclassfield=UniqueFieldName, valueindex=ValueIndex} -> %% N is index of attribute that determines constraint OSDef = case ObjectSet of {Module,OSName} -> asn1_db:dbget(Module,OSName); OSName -> asn1_db:dbget(get(currmod),OSName) end,% io:format("currmod: ~p~nOSName: ~p~nAttrN: ~p~nN: ~p~nUniqueFieldName: ~p~n",% [get(currmod),OSName,AttrN,N,UniqueFieldName]), case (OSDef#typedef.typespec)#'ObjectSet'.gen of true -> ObjectEncode = asn1ct_gen:un_hyphen_var(lists:concat(['Obj', AttrN])), emit([ObjectEncode," = ",nl]), emit([" 'getenc_",ObjectSet,"'(",{asis,UniqueFieldName}, ", ",nl]), ValueMatch = value_match(ValueIndex, lists:concat(["Cindex",N])), emit([indent(35),ValueMatch,"),",nl]), {AttrN,ObjectEncode}; _ -> false end; _ -> case D#type.tablecinf of [{objfun,_}|_] -> %% when the simpletableattributes was at an outer %% level and the objfun has been passed through the %% function call {"got objfun through args","ObjFun"}; _ -> false end end, gen_enc_sequence_call(Erules,Typename,CompList1,1,Ext,EncObj), emit([nl," BytesSoFar = "]), case SeqOrSet of 'SET' when (D#type.def)#'SET'.sorted == dynamic -> emit("asn1rt_check:dynamicsort_SET_components(["), mkvlist(asn1ct_name:all(encBytes)), emit(["]),",nl]); _ -> emit("["), mkvlist(asn1ct_name:all(encBytes)), emit(["],",nl]) end, emit("LenSoFar = "), case asn1ct_name:all(encLen) of [] -> emit("0"); AllLengths -> mkvplus(AllLengths) end, emit([",",nl]), emit(["?RT_BER:encode_tags(TagIn, BytesSoFar, LenSoFar)." ,nl]).gen_decode_sequence(Erules,Typename,D) when record(D,type) -> asn1ct_name:start(), asn1ct_name:new(tag), #'SEQUENCE'{tablecinf=TableConsInfo,components=CList} = D#type.def, Ext = extensible(CList), CompList = case CList of {Rl,El} -> Rl ++ El; _ -> CList end, emit([" %%-------------------------------------------------",nl]), emit([" %% decode tag and length ",nl]), emit([" %%-------------------------------------------------",nl]), asn1ct_name:new(tlv), case CompList of EmptyCL when EmptyCL == [];EmptyCL == {[],[]}-> % empty sequence true; _ -> emit([{curr,tlv}," = "]) end, emit(["?RT_BER:match_tags(",{prev,tlv},",TagIn), ",nl]), asn1ct_name:new(tlv), asn1ct_name:new(v), {DecObjInf,UniqueFName,ValueIndex} = case TableConsInfo of #simpletableattributes{objectsetname=ObjectSet, c_name=AttrN, usedclassfield=UniqueFieldName, uniqueclassfield=UniqueFieldName, valueindex=ValIndex} ->% {ObjectSet,AttrN,_N,UniqueFieldName} ->%% N is index of attribute that determines constraint F = fun(#'ComponentType'{typespec=CT})-> case {asn1ct_gen:get_constraint(CT#type.constraint,componentrelation),CT#type.tablecinf} of {no,[{objfun,_}|_]} -> true; _ -> false end end, case lists:any(F,CompList) of true -> % when component relation constraint establish %% relation from a component to another components %% subtype component {{AttrN,{deep,ObjectSet,UniqueFieldName,ValIndex}}, UniqueFieldName,ValIndex}; false -> {{AttrN,ObjectSet},UniqueFieldName,ValIndex} end; _ ->% case D#type.tablecinf of% [{objfun,_}|_] ->% {{"got objfun through args","ObjFun"},false,false};% _ -> {false,false,false}% end end, case gen_dec_sequence_call(Erules,Typename,CompList,Ext,DecObjInf) of no_terms -> % an empty sequence emit([nl,nl]), demit(["Result = "]), %dbg %% return value as record asn1ct_name:new(rb), emit([" {'",asn1ct_gen:list2rname(Typename),"'}.",nl,nl]); {LeadingAttrTerm,PostponedDecArgs} -> emit([com,nl,nl]), case {LeadingAttrTerm,PostponedDecArgs} of {[],[]} -> ok; {_,[]} -> ok; {[{ObjSet,LeadingAttr,Term}],PostponedDecArgs} -> DecObj = asn1ct_gen:un_hyphen_var(lists:concat(['DecObj',LeadingAttr,Term])), ValueMatch = value_match(ValueIndex,Term), emit([DecObj," =",nl," 'getdec_",ObjSet,"'(", {asis,UniqueFName},", ",ValueMatch,"),",nl]), gen_dec_postponed_decs(DecObj,PostponedDecArgs) end, demit(["Result = "]), %dbg %% return value as record case Ext of {ext,_,_} -> emit(["case ",{prev,tlv}," of [] -> true; _ -> true end, % ... extra fields skipped",nl]); noext -> emit(["case ",{prev,tlv}," of",nl, "[] -> true;", "_ -> exit({error,{asn1, {unexpected,",{prev,tlv}, "}}}) % extra fields not allowed",nl, "end,",nl]) end, asn1ct_name:new(rb), case Typename of ['EXTERNAL'] -> emit([" OldFormat={'",asn1ct_gen:list2rname(Typename), "', "]), mkvlist(asn1ct_name:all(term)), emit(["},",nl]), emit([" asn1rt_check:transform_to_EXTERNAL1994", "(OldFormat).",nl]); _ -> emit([" {'",asn1ct_gen:list2rname(Typename),"', "]), mkvlist(asn1ct_name:all(term)), emit(["}.",nl,nl]) end end.gen_dec_postponed_decs(_,[]) -> emit(nl);gen_dec_postponed_decs(DecObj,[{_Cname,{FirstPFN,PFNList},Term, TmpTerm,_Tag,OptOrMand}|Rest]) -> asn1ct_name:new(tmpterm), asn1ct_name:new(reason), asn1ct_name:new(tmptlv), emit([Term," = ",nl]), N = case OptOrMand of mandatory -> 0; 'OPTIONAL' -> emit_opt_or_mand_check(asn1_NOVALUE,TmpTerm), 6; {'DEFAULT',Val} -> emit_opt_or_mand_check(Val,TmpTerm), 6 end, emit([indent(N+3),"case (catch ",DecObj,"(",{asis,FirstPFN}, ", ",TmpTerm,", ",{asis,PFNList},")) of",nl]), emit([indent(N+6),"{'EXIT', ",{curr,reason},"} ->",nl]), emit([indent(N+9),"exit({'Type not compatible with table constraint',", {curr,reason},"});",nl]), emit([indent(N+6),{curr,tmpterm}," ->",nl]), emit([indent(N+9),{curr,tmpterm},nl]), case OptOrMand of mandatory -> emit([indent(N+3),"end,",nl]); _ -> emit([indent(N+3),"end",nl, indent(3),"end,",nl]) end, gen_dec_postponed_decs(DecObj,Rest).emit_opt_or_mand_check(Value,TmpTerm) -> emit([indent(3),"case ",TmpTerm," of",nl, indent(6),{asis,Value}," ->",{asis,Value},";",nl, indent(6),"_ ->",nl]).%%============================================================================%% Encode/decode SET%%%%============================================================================gen_encode_set(Erules,Typename,D) when record(D,type) -> gen_encode_sequence(Erules,Typename,D).gen_decode_set(Erules,Typename,D) when record(D,type) -> asn1ct_name:start(), asn1ct_name:new(term), asn1ct_name:new(tag), #'SET'{tablecinf=TableConsInfo,components=TCompList} = D#type.def, Ext = extensible(TCompList), CompList = case TCompList of {Rl,El} -> Rl ++ El; _ -> TCompList end, asn1ct_name:clear(), asn1ct_name:new(tlv), case CompList of EmptyCL when EmptyCL == [];EmptyCL == {[],[]}-> % empty sequence true; _ -> emit([{curr,tlv}," = "]) end, emit(["?RT_BER:match_tags(",{prev,tlv},",TagIn), ",nl]), asn1ct_name:new(v), {DecObjInf,UniqueFName} = case TableConsInfo of {ObjectSet,AttrN,_N,UniqueFieldName} ->%% N is index of attribute that determines constraint F = fun(#'ComponentType'{typespec=CT})-> case {CT#type.constraint,CT#type.tablecinf} of {[],[{objfun,_}|_]} -> true; _ -> false end end, case lists:any(F,CompList) of true -> % when component relation constraint establish %% relation from a component to another components %% subtype component {{AttrN,{deep,ObjectSet,UniqueFieldName}}, UniqueFieldName}; false -> {{AttrN,ObjectSet},UniqueFieldName} end; _ -> {false,false} end, case CompList of [] -> % empty set true; _ -> emit(["SetFun = fun(FunTlv) ->", nl]), emit(["case FunTlv of ",nl]), NextNum = gen_dec_set_cases(Erules,Typename,CompList,1), emit([indent(6), {curr,else}," -> ",nl, indent(9),"{",NextNum,", ",{curr,else},"}",nl]), emit([indent(3),"end",nl]), emit([indent(3),"end,",nl]), emit(["PositionList = [SetFun(TempTlv)|| TempTlv <- ",{curr,tlv},"],",nl]), asn1ct_name:new(tlv), emit([{curr,tlv}," = [Stlv || {_,Stlv} <- lists:sort(PositionList)],",nl]), asn1ct_name:new(tlv) end, case gen_dec_sequence_call(Erules,Typename,CompList,Ext,DecObjInf) of no_terms -> % an empty sequence emit([nl,nl]), demit(["Result = "]), %dbg %% return value as record emit([" {'",asn1ct_gen:list2rname(Typename),"'}.",nl]); {LeadingAttrTerm,PostponedDecArgs} -> emit([com,nl,nl]), case {LeadingAttrTerm,PostponedDecArgs} of {[],[]} -> ok; {_,[]} -> ok; {[{ObjSet,LeadingAttr,Term}],PostponedDecArgs} -> DecObj = lists:concat(['DecObj',LeadingAttr,Term]), emit([DecObj," =",nl," 'getdec_",ObjSet,"'(", {asis,UniqueFName},", ",Term,"),",nl]), gen_dec_postponed_decs(DecObj,PostponedDecArgs) end, demit(["Result = "]), %dbg %% return value as record case Ext of {ext,_,_} -> emit(["case ",{prev,tlv}," of [] -> true; _ -> true end, % ... extra fields skipped",nl]); noext -> emit(["case ",{prev,tlv}," of",nl, "[] -> true;", "_ -> exit({error,{asn1, {unexpected,",{prev,tlv}, "}}}) % extra fields not allowed",nl, "end,",nl]) end, emit([" {'",asn1ct_gen:list2rname(Typename),"', "]), mkvlist(asn1ct_name:all(term)), emit(["}.",nl]) end.%%===============================================================================%%===============================================================================%%===============================================================================%% Encode/decode SEQUENCE OF and SET OF%%===============================================================================%%===============================================================================%%===============================================================================gen_encode_sof(Erules,Typename,_InnerTypename,D) when record(D,type) -> asn1ct_name:start(), {SeqOrSetOf, Cont} = D#type.def, Objfun = case D#type.tablecinf of [{objfun,_}|_R] -> ", ObjFun"; _ -> "" end, emit([" {EncBytes,EncLen} = 'enc_",asn1ct_gen:list2name(Typename), "_components'(Val",Objfun,",[],0),",nl]), emit([" ?RT_BER:encode_tags(TagIn, EncBytes, EncLen).",nl,nl]), gen_encode_sof_components(Erules,Typename,SeqOrSetOf,Cont). gen_decode_sof(Erules,TypeName,_InnerTypeName,D) when record(D,type) -> asn1ct_name:start(), {SeqOrSetOf, _TypeTag, Cont} = case D#type.def of {'SET OF',_Cont} -> {'SET OF','SET',_Cont}; {'SEQUENCE OF',_Cont} -> {'SEQUENCE OF','SEQUENCE',_Cont} end, TypeNameSuffix = asn1ct_gen:constructed_suffix(SeqOrSetOf,Cont#type.def), emit([" %%-------------------------------------------------",nl]), emit([" %% decode tag and length ",nl]), emit([" %%-------------------------------------------------",nl]),
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?