asn1ct_constructed_per.erl

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

ERL
1,251
字号
% ``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_per).-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").%-compile(export_all).-import(asn1ct_gen, [emit/1,demit/1]).%% ENCODE GENERATOR FOR SEQUENCE TYPE  ** **********gen_encode_set(Erules,TypeName,D) ->    gen_encode_constructed(Erules,TypeName,D).gen_encode_sequence(Erules,TypeName,D) ->    gen_encode_constructed(Erules,TypeName,D).gen_encode_constructed(_Erules,Typename,D) when record(D,type) ->    asn1ct_name:start(),    asn1ct_name:new(term),    asn1ct_name:new(bytes),    {CompList,TableConsInfo} = 	case D#type.def of	    #'SEQUENCE'{tablecinf=TCI,components=CL} ->		{CL,TCI};	    #'SET'{tablecinf=TCI,components=CL} ->		{CL,TCI}	end,    case Typename of	['EXTERNAL'] ->	    emit({{var,asn1ct_name:next(val)},		  " = asn1rt_check:transform_to_EXTERNAL1990(",		  {var,asn1ct_name:curr(val)},"),",nl}),	    asn1ct_name:new(val);	_ ->	    ok    end,    case {Optionals = optionals(CompList),CompList} of	{[],EmptyCL} when EmptyCL == {[],[]};EmptyCL == [] -> 	    emit(["%%Variable setting just to eliminate ",		  "compiler warning for unused vars!",nl,		  "_Val = ",{var,asn1ct_name:curr(val)},",",nl]);	{[],_} ->	    emit([{var,asn1ct_name:next(val)}," = ?RT_PER:list_to_record("]),	    emit(["'",asn1ct_gen:list2rname(Typename),"'"]),	    emit([", ",{var,asn1ct_name:curr(val)},"),",nl]);	_ ->	    Fixoptcall = ",Opt} = ?RT_PER:fixoptionals(",	    emit({"{",{var,asn1ct_name:next(val)},Fixoptcall,		  {asis,Optionals},",",length(Optionals),		  ",",{var,asn1ct_name:curr(val)},"),",nl})    end,    asn1ct_name:new(val),    Ext = extensible(CompList),    case Ext of	{ext,_,NumExt} when NumExt > 0 ->	    emit(["Extensions = ?RT_PER:fixextensions(",{asis,Ext},		  ", ",{curr,val},"),",nl]);	_ -> true    end,    EncObj =	case TableConsInfo of	    #simpletableattributes{usedclassfield=Used,				   uniqueclassfield=Unique} when Used /= Unique ->		false;	    %% ObjectSet, name of the object set in constraints	    %% 	    %%{ObjectSet,AttrN,N,UniqueFieldName} -> %% N is index of attribute that determines constraint	    #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,		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]),			El = make_element(N+1,asn1ct_gen:mk_var(asn1ct_name:curr(val)),AttrN),			Indent = 12 + length(atom_to_list(ObjectSet)), 			case ValueIndex of			    [] ->				emit([indent(Indent),El,"),",nl]);			    _ ->				emit([indent(Indent),"value_match(",				      {asis,ValueIndex},",",El,")),",nl]),				notice_value_match()			end,			{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,    emit({"[",nl}),    MaybeComma1 = 	case Ext of	    {ext,_Pos,NumExt2} when NumExt2 > 0 -> 		emit({"?RT_PER:setext(Extensions =/= [])"}),		", ";	    {ext,_Pos,_} -> 		emit({"?RT_PER:setext(false)"}),		", ";	    _ -> 		""	end,    MaybeComma2 = 	case optionals(CompList) of	    [] -> MaybeComma1;	    _ -> 		emit(MaybeComma1),		emit("Opt"),		{",",nl}	end,    gen_enc_components_call(Typename,CompList,MaybeComma2,EncObj,Ext),    emit({"].",nl}).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% generate decode function for SEQUENCE and SET%%gen_decode_set(Erules,Typename,D) ->    gen_decode_constructed(Erules,Typename,D).gen_decode_sequence(Erules,Typename,D) ->    gen_decode_constructed(Erules,Typename,D).gen_decode_constructed(Erules,Typename,D) when record(D,type) ->    asn1ct_name:start(),    {CompList,TableConsInfo} = 	case D#type.def of	    #'SEQUENCE'{tablecinf=TCI,components=CL} ->		{CL,TCI};	    #'SET'{tablecinf=TCI,components=CL} ->		{CL,TCI}	end,    Ext = extensible(CompList),    MaybeComma1 = case Ext of		      {ext,_Pos,_NumExt} -> 			  gen_dec_extension_value("Bytes"),			  {",",nl};		      _ -> 			  ""		  end,    Optionals = optionals(CompList),    MaybeComma2 = case Optionals of		      [] -> MaybeComma1;		      _ -> 			  Bcurr = asn1ct_name:curr(bytes),			  Bnext = asn1ct_name:next(bytes),			  emit(MaybeComma1),			  GetoptCall = "} = ?RT_PER:getoptionals2(",			  emit({"{Opt,",{var,Bnext},GetoptCall,				{var,Bcurr},",",{asis,length(Optionals)},")"}),			  asn1ct_name:new(bytes),			  ", "    		  end,    {DecObjInf,UniqueFName,ValueIndex} = 	case TableConsInfo of%%	    {ObjectSet,AttrN,N,UniqueFieldName} ->%% N is index of attribute that determines constraint	    #simpletableattributes{objectsetname=ObjectSet,				   c_name=AttrN,				   usedclassfield=UniqueFieldName,				   uniqueclassfield=UniqueFieldName,				   valueindex=ValIndex} ->%%		{AttrN,ObjectSet};		F = fun(#'ComponentType'{typespec=CT})->			    case {asn1ct_gen:get_constraint(CT#type.constraint,componentrelation),CT#type.tablecinf} of				{no,[{objfun,_}|_R]} -> 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,    {AccTerm,AccBytes} =	gen_dec_components_call(Erules,Typename,CompList,MaybeComma2,DecObjInf,Ext,length(Optionals)),    case asn1ct_name:all(term) of	[] -> emit(MaybeComma2); % no components at all	_ -> emit({com,nl})    end,    case {AccTerm,AccBytes} of	{[],[]} ->	    ok;	{_,[]} ->	    ok;	{[{ObjSet,LeadingAttr,Term}],ListOfOpenTypes} ->	    DecObj = asn1ct_gen:un_hyphen_var(lists:concat(['DecObj',LeadingAttr,Term])),	    ValueMatch = value_match(ValueIndex,Term),	    emit({DecObj," =",nl,"   'getdec_",ObjSet,"'(",%		  {asis,UniqueFName},", ",Term,"),",nl}),		  {asis,UniqueFName},", ",ValueMatch,"),",nl}),	    gen_dec_listofopentypes(DecObj,ListOfOpenTypes,false)    end,    %% we don't return named lists any more   Cnames = mkcnamelist(CompList),     demit({"Result = "}), %dbg    %% return value as record    case Typename of	['EXTERNAL'] ->	    emit({"   OldFormat={'",asn1ct_gen:list2rname(Typename),		  "'"}),	    mkvlist(asn1ct_name:all(term)),	    emit({"},",nl}),	    emit({"   ASN11994Format =",nl,		  "      asn1rt_check:transform_to_EXTERNAL1994",		  "(OldFormat),",nl}),	    emit("   {ASN11994Format,");	_ ->	    emit(["{{'",asn1ct_gen:list2rname(Typename),"'"]),	    mkvlist(asn1ct_name:all(term)),	    emit("},")    end,    emit({{var,asn1ct_name:curr(bytes)},"}"}),    emit({".",nl,nl}).gen_dec_listofopentypes(_,[],_) ->    emit(nl);gen_dec_listofopentypes(DecObj,[{_Cname,{FirstPFN,PFNList},Term,TmpTerm,Prop}|Rest],_Update) ->%    asn1ct_name:new(term),    asn1ct_name:new(tmpterm),    asn1ct_name:new(reason),    emit([Term," = ",nl]),    N = case Prop 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,", telltype,",{asis,PFNList},")) of",nl]),    emit([indent(N+6),"{'EXIT', ",{curr,reason},"} ->",nl]),%%    emit({indent(9),"throw({runtime_error,{","'Type not compatible with table constraint'",",",Term,"}});",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 Prop of	mandatory ->	    emit([indent(N+3),"end,",nl]);	_ ->	    emit([indent(N+3),"end",nl,		  indent(3),"end,",nl])    end,    gen_dec_listofopentypes(DecObj,Rest,true).emit_opt_or_mand_check(Val,Term) ->    emit([indent(3),"case ",Term," of",nl,	  indent(6),{asis,Val}," ->",{asis,Val},";",nl,	  indent(6),"_ ->",nl]).%% ENCODE GENERATOR FOR THE CHOICE TYPE *******%% assume Val = {Alternative,AltType}%% generate%%[%% ?RT_PER:set_choice(element(1,Val),Altnum,Altlist,ext),%%case element(1,Val) of%%    alt1 ->%%	encode_alt1(element(2,Val));%%    alt2 ->%%	encode_alt2(element(2,Val))%%end%%].gen_encode_choice(_Erules,Typename,D) when record(D,type) ->    {'CHOICE',CompList} = D#type.def,    emit({"[",nl}),    Ext = extensible(CompList),    gen_enc_choice(Typename,CompList,Ext),    emit({nl,"].",nl}).gen_decode_choice(Erules,Typename,D) when record(D,type) ->    asn1ct_name:start(),    asn1ct_name:new(bytes),    {'CHOICE',CompList} = D#type.def,    Ext = extensible(CompList),    gen_dec_choice(Erules,Typename,CompList,Ext),    emit({".",nl}).%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Encode generator for SEQUENCE OF typegen_encode_sof(_Erules,Typename,SeqOrSetOf,D) when record(D,type) ->    asn1ct_name:start(),% Val = [Component]% ?RT_PER:encode_length(length(Val)),% lists:    {_SeqOrSetOf,ComponentType} = D#type.def,    emit({"[",nl}),    SizeConstraint =	case asn1ct_gen:get_constraint(D#type.constraint,				       'SizeConstraint') of	    no -> undefined;	    Range -> Range	end,    ObjFun =	case D#type.tablecinf of	    [{objfun,_}|_R] ->		", ObjFun";	    _->		""	end,    emit({nl,indent(3),"?RT_PER:encode_length(",	  {asis,SizeConstraint},	  ",length(Val)),",nl}),    emit({indent(3),"'enc_",asn1ct_gen:list2name(Typename),	      "_components'(Val",ObjFun,", [])"}),    emit({nl,"].",nl}),    NewComponentType =	case ComponentType#type.def of	    {'ENUMERATED',_,Component}->		ComponentType#type{def={'ENUMERATED',Component}};	    _ -> ComponentType	end,    gen_encode_sof_components(Typename,SeqOrSetOf,NewComponentType).gen_decode_sof(Erules,Typename,SeqOrSetOf,D) when record(D,type) ->    asn1ct_name:start(),% Val = [Component]% ?RT_PER:encode_length(length(Val)),% lists:    {_SeqOrSetOf,ComponentType} = D#type.def,    SizeConstraint =	case asn1ct_gen:get_constraint(D#type.constraint,				       'SizeConstraint') of	    no -> undefined;	    Range -> Range	end,    ObjFun =	case D#type.tablecinf of	    [{objfun,_}|_R] ->		", ObjFun";	    _ ->		""	end,    emit({nl,"{Num,Bytes1} = ?RT_PER:decode_length(Bytes,",{asis,SizeConstraint},"),",nl}),    emit({"'dec_",asn1ct_gen:list2name(Typename),	      "_components'(Num, Bytes1, telltype",ObjFun,", []).",nl}),    NewComponentType =	case ComponentType#type.def of	    {'ENUMERATED',_,Component}->		ComponentType#type{def={'ENUMERATED',Component}};	    _ -> ComponentType	end,    gen_decode_sof_components(Erules,Typename,SeqOrSetOf,NewComponentType).gen_encode_sof_components(Typename,SeqOrSetOf,Cont) ->    {ObjFun,ObjFun_Var} =

⌨️ 快捷键说明

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