asn1ct_constructed_ber.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,497 行 · 第 1/4 页
ERL
1,497 行
%% ``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).-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]).%%%% Application internal exports -export([match_tag/2]).-include("asn1_records.hrl").-import(asn1ct_gen, [emit/1,demit/1]).% 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%%===============================================================================%%===============================================================================%%===============================================================================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 case Typename of ['EXTERNAL'] -> emit([" NewVal = asn1rt_check:transform_to_EXTERNAL1990(Val),", nl]); _ -> ok 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, 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} #simpletableattributes{objectsetname=ObjectSet, c_name=AttrN, c_index=N, usedclassfield=UniqueFieldName, uniqueclassfield=UniqueFieldName, valueindex=ValueIndex } -> 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 ->% Val = lists:concat(["?RT_BER:cindex(",% N+1,",Val,"]), ObjectEncode = asn1ct_gen:un_hyphen_var(lists:concat(['Obj', AttrN])), emit({ObjectEncode," = ",nl}), emit({" 'getenc_",ObjectSet,"'(",{asis,UniqueFieldName}, ", ",nl}),% emit({indent(35),"?RT_BER:cindex(",N+1,", Val,",% {asis,AttrN},")),",nl}), emit([indent(10+length(atom_to_list(ObjectSet))), "value_match(",{asis,ValueIndex},",", "?RT_BER:cindex(",N+1,",Val,", {asis,AttrN},"))),",nl]), notice_value_match(), {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), MyTag = [X#tag{class=asn1ct_gen_ber:decode_class(X#tag.class)}|| X <- D#type.tag] ++ [#tag{class = asn1ct_gen_ber:decode_class('UNIVERSAL'), number = asn1ct_gen_ber:decode_type(SeqOrSet), form = ?CONSTRUCTED, type = 'IMPLICIT'}], 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(["{TagBytes,Len} = ?RT_BER:encode_tags(TagIn ++ ", emit([" ?RT_BER:encode_tags(TagIn ++ ", {asis,MyTag},", BytesSoFar, LenSoFar).",nl]).gen_decode_sequence(Erules,Typename,D) when record(D,type) -> asn1ct_name:start(),% asn1ct_name:new(term), 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(rb), MyTag = [X#tag{class=asn1ct_gen_ber:decode_class(X#tag.class)}|| X <- D#type.tag] ++ [#tag{class = asn1ct_gen_ber:decode_class('UNIVERSAL'), number = asn1ct_gen_ber:decode_type('SEQUENCE'), form = ?CONSTRUCTED, type = 'IMPLICIT'}], emit([" {{_,",asn1ct_gen_ber:unused_var("Len",D#type.def),"},",{next,bytes},",",{curr,rb}, "} = ?RT_BER:check_tags(TagIn ++ ",{asis,MyTag},", ", {curr,bytes},", OptOrMand), ",nl]), asn1ct_name:new(bytes), asn1ct_name:new(len), case CompList of [] -> true; _ -> emit({"{",{next,bytes}, ",RemBytes} = ?RT_BER:split_list(", {curr,bytes}, ",", {prev,len},"),",nl}), asn1ct_name:new(bytes) end, {DecObjInf,UniqueFName,ValueIndex} = case TableConsInfo of #simpletableattributes{objectsetname=ObjectSet, c_name=AttrN, usedclassfield=UniqueFieldName, uniqueclassfield=UniqueFieldName, valueindex=ValIndex } -> F = fun(#'ComponentType'{typespec=CT})-> case {asn1ct_gen:get_constraint(CT#type.constraint,componentrelation),CT#type.tablecinf} of% case {CT#type.constraint,CT#type.tablecinf} of {no,[{objfun,_}|_R]} -> true; _ -> false end end, case lists:any(F,CompList) of %%AttributeName = asn1ct_gen:un_hyphen_var(AttrN), 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; _ -> {false,false,false} 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),"'}, ",{curr,bytes},",",nl," "]), asn1ct_gen_ber:add_removed_bytes(), emit(["}.",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},", ",Term,"),",nl}), {asis,UniqueFName},", ",ValueMatch,"),",nl]), gen_dec_postponed_decs(DecObj,PostponedDecArgs) end, demit({"Result = "}), %dbg %% return value as record asn1ct_name:new(rb), asn1ct_name:new(bytes), ExtStatus = case Ext of {ext,_,_} -> ext; noext -> noext end, emit([" {",{next,bytes},",",{curr,rb},"} = ?RT_BER:restbytes2(RemBytes, ", {curr,bytes},",",ExtStatus,"),",nl]), asn1ct_name:new(rb), 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,",{next,bytes},", "]); _ -> emit([" {{'",asn1ct_gen:list2rname(Typename),"', "]), mkvlist(asn1ct_name:all(term)), emit(["}, ",{next,bytes},", "]) end, asn1ct_gen_ber:add_removed_bytes(), emit(["}.",nl]) end.gen_dec_postponed_decs(_,[]) -> emit(nl);gen_dec_postponed_decs(DecObj,[{_Cname,{FirstPFN,PFNList},Term,TmpTerm,_Tag,OptOrMand}|Rest]) ->% asn1ct_name:new(term), asn1ct_name:new(tmpterm), asn1ct_name:new(reason), 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,Tag},", ",{asis,PFNList},")) of",nl}), ", ",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,% emit({indent(3),"end,",nl}), 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'{components=TCompList} = D#type.def, Ext = extensible(TCompList), CompList = case TCompList of {Rl,El} -> Rl ++ El; _ -> TCompList end, emit([" %%-------------------------------------------------",nl]), emit([" %% decode tag and length ",nl]), emit([" %%-------------------------------------------------",nl]), asn1ct_name:new(rb), MyTag = [X#tag{class=asn1ct_gen_ber:decode_class(X#tag.class)}|| X <- D#type.tag] ++ [#tag{class = asn1ct_gen_ber:decode_class('UNIVERSAL'), number = asn1ct_gen_ber:decode_type('SET'), form = ?CONSTRUCTED, type = 'IMPLICIT'}], emit([" {{_,Len},",{next,bytes},",",{curr,rb}, "} = ?RT_BER:check_tags(TagIn ++ ",{asis,MyTag},", ", {curr,bytes},", OptOrMand), ",nl]), asn1ct_name:new(bytes), asn1ct_name:new(len), asn1ct_name:new(rb), emit([" {SetTerm, SetBytes, ",{curr,rb},"} = ?RT_BER:decode_set(0, Len, ", {curr,bytes},", OptOrMand, ", "fun 'dec_",asn1ct_gen:list2name(Typename),"_fun'/2, []),",nl]), asn1ct_name:new(rb),
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?