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