1%% ``Licensed under the Apache License, Version 2.0 (the "License"); 2%% you may not use this file except in compliance with the License. 3%% You may obtain a copy of the License at 4%% 5%% http://www.apache.org/licenses/LICENSE-2.0 6%% 7%% Unless required by applicable law or agreed to in writing, software 8%% distributed under the License is distributed on an "AS IS" BASIS, 9%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10%% See the License for the specific language governing permissions and 11%% limitations under the License. 12%% 13%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. 14%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings 15%% AB. All Rights Reserved.'' 16%% 17%% $Id: asn1ct_constructed_ber_bin_v2.erl,v 1.1 2008/12/17 09:53:29 mikpe Exp $ 18-module(asn1ct_constructed_ber_bin_v2). 19 20-export([gen_encode_sequence/3]). 21-export([gen_decode_sequence/3]). 22-export([gen_encode_set/3]). 23-export([gen_decode_set/3]). 24-export([gen_encode_sof/4]). 25-export([gen_decode_sof/4]). 26-export([gen_encode_choice/3]). 27-export([gen_decode_choice/3]). 28 29 30-include("asn1_records.hrl"). 31 32-import(asn1ct_gen, [emit/1,demit/1]). 33-import(asn1ct_constructed_ber,[match_tag/2]). 34 35-define(ASN1CT_GEN_BER,asn1ct_gen_ber_bin_v2). 36 37% the encoding of class of tag bits 8 and 7 38-define(UNIVERSAL, 0). 39-define(APPLICATION, 16#40). 40-define(CONTEXT, 16#80). 41-define(PRIVATE, 16#C0). 42 43% primitive or constructed encoding % bit 6 44-define(PRIMITIVE, 0). 45-define(CONSTRUCTED, 2#00100000). 46 47 48 49 50%%=============================================================================== 51%%=============================================================================== 52%%=============================================================================== 53%% Encode/decode SEQUENCE (and SET) 54%%=============================================================================== 55%%=============================================================================== 56%%=============================================================================== 57 58gen_encode_sequence(Erules,Typename,D) when record(D,type) -> 59 asn1ct_name:start(), 60 asn1ct_name:new(term), 61 asn1ct_name:new(bytes), 62 63 %% if EXTERNAL type the input value must be transformed to 64 %% ASN1 1990 format 65 ValName = 66 case Typename of 67 ['EXTERNAL'] -> 68 emit([indent(4), 69 "NewVal = asn1rt_check:transform_to_EXTERNAL1990(Val),", 70 nl]), 71 "NewVal"; 72 _ -> 73 "Val" 74 end, 75 76 {SeqOrSet,TableConsInfo,CompList} = 77 case D#type.def of 78 #'SEQUENCE'{tablecinf=TCI,components=CL} -> 79 {'SEQUENCE',TCI,CL}; 80 #'SET'{tablecinf=TCI,components=CL} -> 81 {'SET',TCI,CL} 82 end, 83 Ext = extensible(CompList), 84 CompList1 = case CompList of 85 {Rl,El} -> Rl ++ El; 86 _ -> CompList 87 end, 88 89%% don't match recordname for now, because of compatibility reasons 90%% emit(["{'",asn1ct_gen:list2rname(Typename),"'"]), 91 emit(["{_"]), 92 case length(CompList1) of 93 0 -> 94 true; 95 CompListLen -> 96 emit([","]), 97 mkcindexlist([Tc || Tc <- lists:seq(1,CompListLen)]) 98 end, 99 emit(["} = ",ValName,",",nl]), 100 EncObj = 101 case TableConsInfo of 102 #simpletableattributes{usedclassfield=Used, 103 uniqueclassfield=Unique} when Used /= Unique -> 104 false; 105 %% ObjectSet, name of the object set in constraints 106 %% 107 #simpletableattributes{objectsetname=ObjectSet, 108 c_name=AttrN, 109 c_index=N, 110 usedclassfield=UniqueFieldName, 111 uniqueclassfield=UniqueFieldName, 112 valueindex=ValueIndex} -> %% N is index of attribute that determines constraint 113 OSDef = 114 case ObjectSet of 115 {Module,OSName} -> 116 asn1_db:dbget(Module,OSName); 117 OSName -> 118 asn1_db:dbget(get(currmod),OSName) 119 end, 120% io:format("currmod: ~p~nOSName: ~p~nAttrN: ~p~nN: ~p~nUniqueFieldName: ~p~n", 121% [get(currmod),OSName,AttrN,N,UniqueFieldName]), 122 case (OSDef#typedef.typespec)#'ObjectSet'.gen of 123 true -> 124 ObjectEncode = 125 asn1ct_gen:un_hyphen_var(lists:concat(['Obj', 126 AttrN])), 127 emit([ObjectEncode," = ",nl]), 128 emit([" 'getenc_",ObjectSet,"'(",{asis,UniqueFieldName}, 129 ", ",nl]), 130 ValueMatch = value_match(ValueIndex, 131 lists:concat(["Cindex",N])), 132 emit([indent(35),ValueMatch,"),",nl]), 133 {AttrN,ObjectEncode}; 134 _ -> 135 false 136 end; 137 _ -> 138 case D#type.tablecinf of 139 [{objfun,_}|_] -> 140 %% when the simpletableattributes was at an outer 141 %% level and the objfun has been passed through the 142 %% function call 143 {"got objfun through args","ObjFun"}; 144 _ -> 145 false 146 end 147 end, 148 149 gen_enc_sequence_call(Erules,Typename,CompList1,1,Ext,EncObj), 150 151 emit([nl," BytesSoFar = "]), 152 case SeqOrSet of 153 'SET' when (D#type.def)#'SET'.sorted == dynamic -> 154 emit("?RT_BER:dynamicsort_SET_components(["), 155 mkvlist(asn1ct_name:all(encBytes)), 156 emit(["]),",nl]); 157 _ -> 158 emit("["), 159 mkvlist(asn1ct_name:all(encBytes)), 160 emit(["],",nl]) 161 end, 162 emit("LenSoFar = "), 163 case asn1ct_name:all(encLen) of 164 [] -> emit("0"); 165 AllLengths -> 166 mkvplus(AllLengths) 167 end, 168 emit([",",nl]), 169 emit(["?RT_BER:encode_tags(TagIn, BytesSoFar, LenSoFar)." 170 ,nl]). 171 172gen_decode_sequence(Erules,Typename,D) when record(D,type) -> 173 asn1ct_name:start(), 174 asn1ct_name:new(tag), 175 #'SEQUENCE'{tablecinf=TableConsInfo,components=CList} = D#type.def, 176 Ext = extensible(CList), 177 CompList = case CList of 178 {Rl,El} -> Rl ++ El; 179 _ -> CList 180 end, 181 182 emit([" %%-------------------------------------------------",nl]), 183 emit([" %% decode tag and length ",nl]), 184 emit([" %%-------------------------------------------------",nl]), 185 186 asn1ct_name:new(tlv), 187 case CompList of 188 EmptyCL when EmptyCL == [];EmptyCL == {[],[]}-> % empty sequence 189 true; 190 _ -> 191 emit([{curr,tlv}," = "]) 192 end, 193 emit(["?RT_BER:match_tags(",{prev,tlv},",TagIn), ",nl]), 194 asn1ct_name:new(tlv), 195 asn1ct_name:new(v), 196 197 {DecObjInf,UniqueFName,ValueIndex} = 198 case TableConsInfo of 199 #simpletableattributes{objectsetname=ObjectSet, 200 c_name=AttrN, 201 usedclassfield=UniqueFieldName, 202 uniqueclassfield=UniqueFieldName, 203 valueindex=ValIndex} -> 204% {ObjectSet,AttrN,_N,UniqueFieldName} ->%% N is index of attribute that determines constraint 205 F = fun(#'ComponentType'{typespec=CT})-> 206 case {CT#type.constraint,CT#type.tablecinf} of 207 {[],[{objfun,_}|_]} -> true; 208 _ -> false 209 end 210 end, 211 case lists:any(F,CompList) of 212 true -> % when component relation constraint establish 213 %% relation from a component to another components 214 %% subtype component 215 {{AttrN,{deep,ObjectSet,UniqueFieldName,ValIndex}}, 216 UniqueFieldName,ValIndex}; 217 false -> 218 {{AttrN,ObjectSet},UniqueFieldName,ValIndex} 219 end; 220 _ -> 221% case D#type.tablecinf of 222% [{objfun,_}|_] -> 223% {{"got objfun through args","ObjFun"},false,false}; 224% _ -> 225 {false,false,false} 226% end 227 end, 228 case gen_dec_sequence_call(Erules,Typename,CompList,Ext,DecObjInf) of 229 no_terms -> % an empty sequence 230 emit([nl,nl]), 231 demit(["Result = "]), %dbg 232 %% return value as record 233 asn1ct_name:new(rb), 234 emit([" {'",asn1ct_gen:list2rname(Typename),"'}.",nl,nl]); 235 {LeadingAttrTerm,PostponedDecArgs} -> 236 emit([com,nl,nl]), 237 case {LeadingAttrTerm,PostponedDecArgs} of 238 {[],[]} -> 239 ok; 240 {_,[]} -> 241 ok; 242 {[{ObjSet,LeadingAttr,Term}],PostponedDecArgs} -> 243 DecObj = asn1ct_gen:un_hyphen_var(lists:concat(['DecObj',LeadingAttr,Term])), 244 ValueMatch = value_match(ValueIndex,Term), 245 emit([DecObj," =",nl," 'getdec_",ObjSet,"'(", 246 {asis,UniqueFName},", ",ValueMatch,"),",nl]), 247 gen_dec_postponed_decs(DecObj,PostponedDecArgs) 248 end, 249 demit(["Result = "]), %dbg 250 %% return value as record 251 case Ext of 252 {ext,_,_} -> 253 emit(["case ",{prev,tlv}," of [] -> true; _ -> true end, % ... extra fields skipped",nl]); 254 noext -> 255 emit(["case ",{prev,tlv}," of",nl, 256 "[] -> true;", 257 "_ -> exit({error,{asn1, {unexpected,",{prev,tlv}, 258 "}}}) % extra fields not allowed",nl, 259 "end,",nl]) 260 end, 261 asn1ct_name:new(rb), 262 case Typename of 263 ['EXTERNAL'] -> 264 emit([" OldFormat={'",asn1ct_gen:list2rname(Typename), 265 "', "]), 266 mkvlist(asn1ct_name:all(term)), 267 emit(["},",nl]), 268 emit([" asn1rt_check:transform_to_EXTERNAL1994", 269 "(OldFormat).",nl]); 270 _ -> 271 emit([" {'",asn1ct_gen:list2rname(Typename),"', "]), 272 mkvlist(asn1ct_name:all(term)), 273 emit(["}.",nl,nl]) 274 end 275 end. 276 277gen_dec_postponed_decs(_,[]) -> 278 emit(nl); 279gen_dec_postponed_decs(DecObj,[{_Cname,{FirstPFN,PFNList},Term, 280 TmpTerm,_Tag,OptOrMand}|Rest]) -> 281 282 asn1ct_name:new(tmpterm), 283 asn1ct_name:new(reason), 284 asn1ct_name:new(tmptlv), 285 286 emit([Term," = ",nl]), 287 N = case OptOrMand of 288 mandatory -> 0; 289 'OPTIONAL' -> 290 emit_opt_or_mand_check(asn1_NOVALUE,TmpTerm), 291 6; 292 {'DEFAULT',Val} -> 293 emit_opt_or_mand_check(Val,TmpTerm), 294 6 295 end, 296 emit([indent(N+3),"case (catch ",DecObj,"(",{asis,FirstPFN}, 297 ", ",TmpTerm,", ",{asis,PFNList},")) of",nl]), 298 emit([indent(N+6),"{'EXIT', ",{curr,reason},"} ->",nl]), 299 emit([indent(N+9),"exit({'Type not compatible with table constraint',", 300 {curr,reason},"});",nl]), 301 emit([indent(N+6),{curr,tmpterm}," ->",nl]), 302 emit([indent(N+9),{curr,tmpterm},nl]), 303 304 case OptOrMand of 305 mandatory -> emit([indent(N+3),"end,",nl]); 306 _ -> 307 emit([indent(N+3),"end",nl, 308 indent(3),"end,",nl]) 309 end, 310 gen_dec_postponed_decs(DecObj,Rest). 311 312emit_opt_or_mand_check(Value,TmpTerm) -> 313 emit([indent(3),"case ",TmpTerm," of",nl, 314 indent(6),{asis,Value}," ->",{asis,Value},";",nl, 315 indent(6),"_ ->",nl]). 316 317%%============================================================================ 318%% Encode/decode SET 319%% 320%%============================================================================ 321 322gen_encode_set(Erules,Typename,D) when record(D,type) -> 323 gen_encode_sequence(Erules,Typename,D). 324 325gen_decode_set(Erules,Typename,D) when record(D,type) -> 326 asn1ct_name:start(), 327 asn1ct_name:new(term), 328 asn1ct_name:new(tag), 329 #'SET'{tablecinf=TableConsInfo,components=TCompList} = D#type.def, 330 Ext = extensible(TCompList), 331 CompList = case TCompList of 332 {Rl,El} -> Rl ++ El; 333 _ -> TCompList 334 end, 335 336 asn1ct_name:clear(), 337 asn1ct_name:new(tlv), 338 case CompList of 339 EmptyCL when EmptyCL == [];EmptyCL == {[],[]}-> % empty sequence 340 true; 341 _ -> 342 emit([{curr,tlv}," = "]) 343 end, 344 emit(["?RT_BER:match_tags(",{prev,tlv},",TagIn), ",nl]), 345 asn1ct_name:new(v), 346 347 348 {DecObjInf,UniqueFName} = 349 case TableConsInfo of 350 {ObjectSet,AttrN,_N,UniqueFieldName} ->%% N is index of attribute that determines constraint 351 F = fun(#'ComponentType'{typespec=CT})-> 352 case {CT#type.constraint,CT#type.tablecinf} of 353 {[],[{objfun,_}|_]} -> true; 354 _ -> false 355 end 356 end, 357 case lists:any(F,CompList) of 358 true -> % when component relation constraint establish 359 %% relation from a component to another components 360 %% subtype component 361 {{AttrN,{deep,ObjectSet,UniqueFieldName}}, 362 UniqueFieldName}; 363 false -> 364 {{AttrN,ObjectSet},UniqueFieldName} 365 end; 366 _ -> 367 {false,false} 368 end, 369 370 case CompList of 371 [] -> % empty set 372 true; 373 _ -> 374 emit(["SetFun = fun(FunTlv) ->", nl]), 375 emit(["case FunTlv of ",nl]), 376 NextNum = gen_dec_set_cases(Erules,Typename,CompList,1), 377 emit([indent(6), {curr,else}," -> ",nl, 378 indent(9),"{",NextNum,", ",{curr,else},"}",nl]), 379 emit([indent(3),"end",nl]), 380 emit([indent(3),"end,",nl]), 381 382 emit(["PositionList = [SetFun(TempTlv)|| TempTlv <- ",{curr,tlv},"],",nl]), 383 asn1ct_name:new(tlv), 384 emit([{curr,tlv}," = [Stlv || {_,Stlv} <- lists:sort(PositionList)],",nl]), 385 asn1ct_name:new(tlv) 386 387 end, 388 case gen_dec_sequence_call(Erules,Typename,CompList,Ext,DecObjInf) of 389 no_terms -> % an empty sequence 390 emit([nl,nl]), 391 demit(["Result = "]), %dbg 392 %% return value as record 393 emit([" {'",asn1ct_gen:list2rname(Typename),"'}.",nl]); 394 {LeadingAttrTerm,PostponedDecArgs} -> 395 emit([com,nl,nl]), 396 case {LeadingAttrTerm,PostponedDecArgs} of 397 {[],[]} -> 398 ok; 399 {_,[]} -> 400 ok; 401 {[{ObjSet,LeadingAttr,Term}],PostponedDecArgs} -> 402 DecObj = lists:concat(['DecObj',LeadingAttr,Term]), 403 emit([DecObj," =",nl," 'getdec_",ObjSet,"'(", 404 {asis,UniqueFName},", ",Term,"),",nl]), 405 gen_dec_postponed_decs(DecObj,PostponedDecArgs) 406 end, 407 demit(["Result = "]), %dbg 408 %% return value as record 409 case Ext of 410 {ext,_,_} -> 411 emit(["case ",{prev,tlv}," of [] -> true; _ -> true end, % ... extra fields skipped",nl]); 412 noext -> 413 emit(["case ",{prev,tlv}," of",nl, 414 "[] -> true;", 415 "_ -> exit({error,{asn1, {unexpected,",{prev,tlv}, 416 "}}}) % extra fields not allowed",nl, 417 "end,",nl]) 418 end, 419 emit([" {'",asn1ct_gen:list2rname(Typename),"', "]), 420 mkvlist(asn1ct_name:all(term)), 421 emit(["}.",nl]) 422 end. 423 424 425%%=============================================================================== 426%%=============================================================================== 427%%=============================================================================== 428%% Encode/decode SEQUENCE OF and SET OF 429%%=============================================================================== 430%%=============================================================================== 431%%=============================================================================== 432 433gen_encode_sof(Erules,Typename,_InnerTypename,D) when record(D,type) -> 434 asn1ct_name:start(), 435 {SeqOrSetOf, Cont} = D#type.def, 436 437 Objfun = case D#type.tablecinf of 438 [{objfun,_}|_R] -> 439 ", ObjFun"; 440 _ -> 441 "" 442 end, 443 444 emit([" {EncBytes,EncLen} = 'enc_",asn1ct_gen:list2name(Typename), 445 "_components'(Val",Objfun,",[],0),",nl]), 446 447 emit([" ?RT_BER:encode_tags(TagIn, EncBytes, EncLen).",nl,nl]), 448 449 gen_encode_sof_components(Erules,Typename,SeqOrSetOf,Cont). 450 451 452gen_decode_sof(Erules,TypeName,_InnerTypeName,D) when record(D,type) -> 453 asn1ct_name:start(), 454 {SeqOrSetOf, _TypeTag, Cont} = 455 case D#type.def of 456 {'SET OF',_Cont} -> {'SET OF','SET',_Cont}; 457 {'SEQUENCE OF',_Cont} -> {'SEQUENCE OF','SEQUENCE',_Cont} 458 end, 459 TypeNameSuffix = asn1ct_gen:constructed_suffix(SeqOrSetOf,Cont#type.def), 460 461 emit([" %%-------------------------------------------------",nl]), 462 emit([" %% decode tag and length ",nl]), 463 emit([" %%-------------------------------------------------",nl]), 464 465 asn1ct_name:new(tlv), 466 emit([{curr,tlv}, 467 " = ?RT_BER:match_tags(",{prev,tlv},",TagIn), ",nl]), 468 asn1ct_name:new(v), 469 470 emit(["["]), 471 472 InnerType = asn1ct_gen:get_inner(Cont#type.def), 473 ContName = case asn1ct_gen:type(InnerType) of 474 Atom when atom(Atom) -> Atom; 475 _ -> TypeNameSuffix 476 end, 477%% fix me 478 ObjFun = 479 case D#type.tablecinf of 480 [{objfun,_}|_R] -> 481 ", ObjFun"; 482 _ -> 483 [] 484 end, 485 gen_dec_line(Erules,TypeName,ContName,[],Cont,mandatory,ObjFun), 486 %% gen_dec_line_sof(Erules,Typename,ContName,Cont,ObjFun), 487 emit([" || ",{curr,v}," <- ",{curr,tlv},"].",nl,nl,nl]). 488 489 490gen_encode_sof_components(Erules,Typename,SeqOrSetOf,Cont) 491 when record(Cont,type)-> 492 493 {Objfun,Objfun_novar,EncObj} = 494 case Cont#type.tablecinf of 495 [{objfun,_}|_R] -> 496 {", ObjFun",", _",{no_attr,"ObjFun"}}; 497 _ -> 498 {"","",false} 499 end, 500 emit(["'enc_",asn1ct_gen:list2name(Typename), 501 "_components'([]",Objfun_novar,", AccBytes, AccLen) -> ",nl]), 502 503 case catch lists:member(der,get(encoding_options)) of 504 true -> 505 emit([indent(3), 506 "{?RT_BER:dynamicsort_SETOF(AccBytes),AccLen};",nl,nl]); 507 _ -> 508 emit([indent(3),"{lists:reverse(AccBytes),AccLen};",nl,nl]) 509 end, 510 emit(["'enc_",asn1ct_gen:list2name(Typename), 511 "_components'([H|T]",Objfun,",AccBytes, AccLen) ->",nl]), 512 TypeNameSuffix = asn1ct_gen:constructed_suffix(SeqOrSetOf,Cont#type.def), 513 gen_enc_line(Erules,Typename,TypeNameSuffix,Cont,"H",3, 514 mandatory,"{EncBytes,EncLen} = ",EncObj), 515 emit([",",nl]), 516 emit([indent(3),"'enc_",asn1ct_gen:list2name(Typename), 517 "_components'(T",Objfun,","]), 518 emit(["[EncBytes|AccBytes], AccLen + EncLen).",nl,nl]). 519 520%%============================================================================ 521%% Encode/decode CHOICE 522%% 523%%============================================================================ 524 525gen_encode_choice(Erules,Typename,D) when record(D,type) -> 526 ChoiceTag = D#type.tag, 527 {'CHOICE',CompList} = D#type.def, 528 Ext = extensible(CompList), 529 CompList1 = case CompList of 530 {Rl,El} -> Rl ++ El; 531 _ -> CompList 532 end, 533 gen_enc_choice(Erules,Typename,ChoiceTag,CompList1,Ext), 534 emit([nl,nl]). 535 536gen_decode_choice(Erules,Typename,D) when record(D,type) -> 537 asn1ct_name:start(), 538 asn1ct_name:new(bytes), 539 ChoiceTag = D#type.tag, 540 {'CHOICE',CompList} = D#type.def, 541 Ext = extensible(CompList), 542 CompList1 = case CompList of 543 {Rl,El} -> Rl ++ El; 544 _ -> CompList 545 end, 546 gen_dec_choice(Erules,Typename,ChoiceTag,CompList1,Ext), 547 emit([".",nl]). 548 549 550%%============================================================================ 551%% Encode SEQUENCE 552%% 553%%============================================================================ 554 555gen_enc_sequence_call(Erules,TopType,[#'ComponentType'{name=Cname,typespec=Type,prop=Prop}|Rest],Pos,Ext,EncObj) -> 556 asn1ct_name:new(encBytes), 557 asn1ct_name:new(encLen), 558 Element = 559 case TopType of 560 ['EXTERNAL'] -> 561 io_lib:format("Cindex~w",[Pos]); 562 _ -> 563 io_lib:format("Cindex~w",[Pos]) 564 end, 565 InnerType = asn1ct_gen:get_inner(Type#type.def), 566 print_attribute_comment(InnerType,Pos,Cname,Prop), 567 gen_enc_line(Erules,TopType,Cname,Type,Element,3,Prop,EncObj), 568 emit([com,nl]), 569 gen_enc_sequence_call(Erules,TopType,Rest,Pos+1,Ext,EncObj); 570 571gen_enc_sequence_call(_Erules,_TopType,[],_Num,_,_) -> 572 true. 573 574%%============================================================================ 575%% Decode SEQUENCE 576%% 577%%============================================================================ 578 579gen_dec_sequence_call(Erules,TopType,CompList,Ext,DecObjInf) -> 580 gen_dec_sequence_call1(Erules,TopType, CompList, 1, Ext,DecObjInf,[],[]). 581 582 583gen_dec_sequence_call1(Erules,TopType,[#'ComponentType'{name=Cname,typespec=Type,prop=Prop,tags=Tags}|Rest],Num,Ext,DecObjInf,LeadingAttrAcc,ArgsAcc) -> 584 {LA,PostponedDec} = 585 gen_dec_component(Erules,TopType,Cname,Tags,Type,Num,Prop, 586 Ext,DecObjInf), 587 case Rest of 588 [] -> 589 {LA ++ LeadingAttrAcc,PostponedDec ++ ArgsAcc}; 590 _ -> 591 emit([com,nl]), 592 asn1ct_name:new(bytes), 593 gen_dec_sequence_call1(Erules,TopType,Rest,Num+1,Ext,DecObjInf, 594 LA++LeadingAttrAcc,PostponedDec++ArgsAcc) 595 end; 596 597gen_dec_sequence_call1(_Erules,_TopType,[],1,_,_,_,_) -> 598 no_terms. 599 600 601%%---------------------------- 602%%SEQUENCE mandatory 603%%---------------------------- 604 605gen_dec_component(Erules,TopType,Cname,CTags,Type,Pos,Prop,Ext,DecObjInf) -> 606 InnerType = 607 case Type#type.def of 608 #'ObjectClassFieldType'{type=OCFTType} -> OCFTType; 609 _ -> asn1ct_gen:get_inner(Type#type.def) 610 end, 611% case asn1ct_gen:get_constraint(Type#type.constraint, 612% tableconstraint_info) of 613% no -> 614% asn1ct_gen:get_inner(Type#type.def); 615% _ -> 616% Type#type.def 617% end, 618 Prop1 = case {Prop,Ext} of 619 {mandatory,{ext,Epos,_}} when Pos >= Epos -> 620 'OPTIONAL'; 621 _ -> 622 Prop 623 end, 624 print_attribute_comment(InnerType,Pos,Cname,Prop1), 625 asn1ct_name:new(term), 626 emit_term_tlv(Prop1,InnerType,DecObjInf), 627 asn1ct_name:new(rb), 628 PostponedDec = 629 gen_dec_line(Erules,TopType,Cname,CTags,Type,Prop1,DecObjInf), 630 asn1ct_name:new(v), 631 asn1ct_name:new(tlv), 632 asn1ct_name:new(form), 633 PostponedDec. 634 635 636emit_term_tlv({'DEFAULT',_},InnerType,DecObjInf) -> 637 emit_term_tlv(opt_or_def,InnerType,DecObjInf); 638emit_term_tlv('OPTIONAL',InnerType,DecObjInf) -> 639 emit_term_tlv(opt_or_def,InnerType,DecObjInf); 640emit_term_tlv(Prop,{typefield,_},DecObjInf) -> 641 emit_term_tlv(Prop,type_or_object_field,DecObjInf); 642emit_term_tlv(Prop,{objectfield,_,_},DecObjInf) -> 643 emit_term_tlv(Prop,type_or_object_field,DecObjInf); 644emit_term_tlv(opt_or_def,type_or_object_field,_) -> 645 asn1ct_name:new(tmpterm), 646 emit(["{",{curr,tmpterm},",",{curr,tlv},"} = "]); 647emit_term_tlv(opt_or_def,_,_) -> 648 emit(["{",{curr,term},",",{curr,tlv},"} = "]); 649emit_term_tlv(_,type_or_object_field,false) -> 650 emit(["[",{curr,v},"|",{curr,tlv},"] = ",{prev,tlv},", ",nl, 651 {curr,term}," = "]); 652emit_term_tlv(_,type_or_object_field,_) -> 653 asn1ct_name:new(tmpterm), 654 emit(["[",{curr,v},"|",{curr,tlv},"] = ",{prev,tlv},", ",nl]), 655 emit([nl," ",{curr,tmpterm}," = "]); 656emit_term_tlv(mandatory,_,_) -> 657 emit(["[",{curr,v},"|",{curr,tlv},"] = ",{prev,tlv},", ",nl, 658 {curr,term}," = "]). 659 660 661gen_dec_set_cases(_Erules,_TopType,[],Pos) -> 662 Pos; 663gen_dec_set_cases(Erules,TopType,[Comp|RestComps],Pos) -> 664 Name = Comp#'ComponentType'.name, 665 Type = Comp#'ComponentType'.typespec, 666 CTags = Comp#'ComponentType'.tags, 667 668 emit([indent(6),"%",Name,nl]), 669 Tags = case Type#type.tag of 670 [] -> % this is a choice without explicit tag 671 [(?ASN1CT_GEN_BER:decode_class(T1class) bsl 10) + T1number|| 672 {T1class,T1number} <- CTags]; 673 [FirstTag|_] -> 674 [(?ASN1CT_GEN_BER:decode_class(FirstTag#tag.class) bsl 10) + FirstTag#tag.number] 675 end, 676% emit([indent(6),"%Tags: ",Tags,nl]), 677% emit([indent(6),"%Type#type.tag: ",Type#type.tag,nl]), 678 CaseFun = fun(TagList=[H|T],Fun,N) -> 679 Semicolon = case TagList of 680 [_Tag1,_|_] -> [";",nl]; 681 _ -> "" 682 end, 683 emit(["TTlv = {",H,",_} ->",nl]), 684 emit([indent(4),"{",Pos,", TTlv}",Semicolon]), 685 Fun(T,Fun,N+1); 686 ([],_,0) -> 687 true; 688 ([],_,_) -> 689 emit([";",nl]) 690 end, 691 CaseFun(Tags,CaseFun,0), 692%% emit([";",nl]), 693 gen_dec_set_cases(Erules,TopType,RestComps,Pos+1). 694 695 696 697%%--------------------------------------------- 698%% Encode CHOICE 699%%--------------------------------------------- 700%% for BER we currently do care (a little) if the choice has an EXTENSIONMARKER 701 702 703gen_enc_choice(Erules,TopType,Tag,CompList,_Ext) -> 704 gen_enc_choice1(Erules,TopType,Tag,CompList,_Ext). 705 706gen_enc_choice1(Erules,TopType,_Tag,CompList,_Ext) -> 707 asn1ct_name:clear(), 708 emit([" {EncBytes,EncLen} = case element(1,Val) of",nl]), 709 gen_enc_choice2(Erules,TopType,CompList), 710 emit([nl," end,",nl,nl]), 711 712 emit(["?RT_BER:encode_tags(TagIn, EncBytes, EncLen).",nl]). 713 714 715gen_enc_choice2(Erules,TopType,[H1|T]) when record(H1,'ComponentType') -> 716 Cname = H1#'ComponentType'.name, 717 Type = H1#'ComponentType'.typespec, 718 emit([" ",{asis,Cname}," ->",nl]), 719 {Encobj,Assign} = 720 case {Type#type.def,asn1ct_gen:get_constraint(Type#type.constraint, 721 componentrelation)} of 722 {#'ObjectClassFieldType'{},{componentrelation,_,_}} -> 723 asn1ct_name:new(tmpBytes), 724 asn1ct_name:new(encBytes), 725 asn1ct_name:new(encLen), 726 Emit = ["{",{curr,tmpBytes},", _} = "], 727 {{no_attr,"ObjFun"},Emit}; 728 _ -> 729 {false,[]} 730 end, 731% case asn1ct_gen:get_constraint(Type#type.constraint, 732% tableconstraint_info) of 733% no -> 734% {false,[]}; 735% _ -> 736% asn1ct_name:new(tmpBytes), 737% asn1ct_name:new(encBytes), 738% asn1ct_name:new(encLen), 739% Emit = ["{",{curr,tmpBytes},", _} = "], 740% {{no_attr,"ObjFun"},Emit} 741% end, 742 gen_enc_line(Erules,TopType,Cname,Type,"element(2,Val)",9, 743 mandatory,Assign,Encobj), 744 case Encobj of 745 false -> ok; 746 _ -> 747 emit([",",nl,indent(9),"{",{curr,encBytes},", ", 748 {curr,encLen},"}"]) 749 end, 750 emit([";",nl]), 751 case T of 752 [] -> 753 emit([indent(6), "Else -> ",nl, 754 indent(9),"exit({error,{asn1,{invalid_choice_type,Else}}})"]); 755 _ -> 756 true 757 end, 758 gen_enc_choice2(Erules,TopType,T); 759 760gen_enc_choice2(_Erules,_TopType,[]) -> 761 true. 762 763 764 765 766%%-------------------------------------------- 767%% Decode CHOICE 768%%-------------------------------------------- 769 770gen_dec_choice(Erules,TopType, _ChTag, CompList, Ext) -> 771 asn1ct_name:clear(), 772 asn1ct_name:new(tlv), 773 emit([{curr,tlv}, 774 " = ?RT_BER:match_tags(",{prev,tlv},",TagIn), ",nl]), 775 asn1ct_name:new(tlv), 776 asn1ct_name:new(v), 777 emit(["case (case ",{prev,tlv}, 778 " of [Ctemp",{prev,tlv},"] -> Ctemp",{prev,tlv}, 779 "; _ -> ",{prev,tlv}," end)"," of",nl]), 780 asn1ct_name:new(tagList), 781 asn1ct_name:new(choTags), 782 asn1ct_name:new(res), 783 gen_dec_choice_cases(Erules,TopType,CompList), 784 emit([indent(6), {curr,else}," -> ",nl]), 785 case Ext of 786 noext -> 787 emit([indent(9),"exit({error,{asn1,{invalid_choice_tag,", 788 {curr,else},"}}})",nl]); 789 _ -> 790 emit([indent(9),"{asn1_ExtAlt, ?RT_BER:encode(",{curr,else},")}",nl]) 791 end, 792 emit([indent(3),"end",nl]), 793 asn1ct_name:new(tag), 794 asn1ct_name:new(else). 795 796 797gen_dec_choice_cases(_Erules,_TopType, []) -> 798 ok; 799gen_dec_choice_cases(Erules,TopType, [H|T]) -> 800 Cname = H#'ComponentType'.name, 801 Type = H#'ComponentType'.typespec, 802 Prop = H#'ComponentType'.prop, 803 Tags = Type#type.tag, 804 Fcases = fun([{T1class,T1number}|Tail],Fun) -> 805 emit([indent(4),{curr,v}," = {", 806 (?ASN1CT_GEN_BER:decode_class(T1class) bsl 10) + 807 T1number,",_} -> ",nl]), 808 emit([indent(8),"{",{asis,Cname},", "]), 809 gen_dec_line(Erules,TopType,Cname,[],Type,Prop,false), 810 emit(["};",nl,nl]), 811 Fun(Tail,Fun); 812 ([],_) -> 813 ok 814 end, 815 emit([nl,"%% '",Cname,"'",nl]), 816 case {Tags,asn1ct:get_gen_state_field(namelist)} of 817 {[],_} -> % choice without explicit tags 818 Fcases(H#'ComponentType'.tags,Fcases); 819 {[FirstT|_RestT],[{Cname,undecoded}|Names]} -> 820 DecTag=(?ASN1CT_GEN_BER:decode_class(FirstT#tag.class) bsl 10) + 821 FirstT#tag.number, 822 asn1ct:add_generated_refed_func({[Cname|TopType],undecoded, 823 [DecTag],Type}), 824 asn1ct:update_gen_state(namelist,Names), 825 emit([indent(4),{curr,res}," = ", 826 match_tag(ber_bin,{FirstT#tag.class,FirstT#tag.number}), 827 " -> ",nl]), 828 emit([indent(8),"{",{asis,Cname},", {'", 829 asn1ct_gen:list2name([Cname|TopType]),"',", 830 {curr,res},"}};",nl,nl]); 831 {[FirstT|RestT],_} -> 832 emit([indent(4),"{", 833 (?ASN1CT_GEN_BER:decode_class(FirstT#tag.class) bsl 10) + 834 FirstT#tag.number,", ",{curr,v},"} -> ",nl]), 835 emit([indent(8),"{",{asis,Cname},", "]), 836 gen_dec_line(Erules,TopType,Cname,[],Type#type{tag=RestT},Prop,false), 837 emit(["};",nl,nl]) 838 end, 839 gen_dec_choice_cases(Erules,TopType, T). 840 841 842 843%%--------------------------------------- 844%% Generate the encode/decode code 845%%--------------------------------------- 846 847gen_enc_line(Erules,TopType,Cname, 848 Type=#type{constraint=[{componentrelation,_,_}], 849 def=#'ObjectClassFieldType'{type={typefield,_}}}, 850 Element,Indent,OptOrMand=mandatory,EncObj) 851 when list(Element) -> 852 asn1ct_name:new(tmpBytes), 853 gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand, 854 ["{",{curr,tmpBytes},",_} = "],EncObj); 855gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand,EncObj) 856 when list(Element) -> 857 gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand, 858 ["{",{curr,encBytes},",",{curr,encLen},"} = "],EncObj). 859 860gen_enc_line(Erules,TopType,Cname,Type,Element,Indent,OptOrMand,Assign,EncObj) 861 when list(Element) -> 862 IndDeep = indent(Indent), 863 Tag = lists:reverse([?ASN1CT_GEN_BER:encode_tag_val( 864 ?ASN1CT_GEN_BER:decode_class(X#tag.class), 865 X#tag.form, 866 X#tag.number) 867 || X <- Type#type.tag]), 868 InnerType = asn1ct_gen:get_inner(Type#type.def), 869 WhatKind = asn1ct_gen:type(InnerType), 870 emit(IndDeep), 871 emit(Assign), 872 gen_optormand_case(OptOrMand,Erules,TopType,Cname,Type,InnerType,WhatKind, 873 Element), 874 case {Type,asn1ct_gen:get_constraint(Type#type.constraint, 875 componentrelation)} of 876% #type{constraint=[{tableconstraint_info,RefedFieldName}], 877% def={typefield,_}} -> 878 {#type{def=#'ObjectClassFieldType'{type={typefield,_}, 879 fieldname=RefedFieldName}}, 880 {componentrelation,_,_}} -> 881 {_LeadingAttrName,Fun} = EncObj, 882 case RefedFieldName of 883 {notype,T} -> 884 throw({error,{notype,type_from_object,T}}); 885 {Name,RestFieldNames} when atom(Name) -> 886 case OptOrMand of 887 mandatory -> ok; 888 _ -> 889% emit(["{",{curr,tmpBytes},",",{curr,tmpLen}, 890 emit(["{",{curr,tmpBytes},",_ } = "]) 891% "} = "]) 892 end, 893 emit([Fun,"(",{asis,Name},", ",Element,", ", 894 {asis,RestFieldNames},"),",nl]), 895 emit(IndDeep), 896 case OptOrMand of 897 mandatory -> 898 emit(["{",{curr,encBytes},",",{curr,encLen}, 899 "} = "]), 900 emit(["?RT_BER:encode_open_type(",{curr,tmpBytes}, 901 ",",{asis,Tag},")"]); 902 _ -> 903% emit(["{",{next,tmpBytes},", _} = "]), 904 emit(["{",{next,tmpBytes},",",{curr,tmpLen}, 905 "} = "]), 906 emit(["?RT_BER:encode_open_type(",{curr,tmpBytes}, 907 ",",{asis,Tag},"),",nl]), 908 emit(IndDeep), 909 emit(["{",{next,tmpBytes},", ",{curr,tmpLen},"}"]) 910 end; 911 _ -> 912 throw({asn1,{'internal error'}}) 913 end; 914 {{#'ObjectClassFieldType'{type={objectfield,PrimFieldName1, 915 PFNList}},_}, 916 {componentrelation,_,_}} -> 917 %% this is when the dotted list in the FieldName has more 918 %% than one element 919 {_LeadingAttrName,Fun} = EncObj, 920 emit(["?RT_BER:encode_open_type(",Fun,"(",{asis,PrimFieldName1}, 921 ", ",Element,", ",{asis,PFNList},"))"]); 922 _ -> 923 case WhatKind of 924 {primitive,bif} -> 925 EncType = 926 case Type#type.def of 927 #'ObjectClassFieldType'{type={fixedtypevaluefield,_,Btype}} -> 928 Btype; 929 _ -> 930 Type 931 end, 932 ?ASN1CT_GEN_BER:gen_encode_prim(ber,EncType,{asis,Tag}, 933 Element); 934 {notype,_} -> 935 emit(["'enc_",InnerType,"'(",Element,", ",{asis,Tag},")"]); 936 'ASN1_OPEN_TYPE' -> 937 case Type#type.def of 938 #'ObjectClassFieldType'{} -> %Open Type 939 ?ASN1CT_GEN_BER:gen_encode_prim(ber,#type{def='ASN1_OPEN_TYPE'},{asis,Tag},Element); 940 _ -> 941 ?ASN1CT_GEN_BER:gen_encode_prim(ber,Type, 942 {asis,Tag}, 943 Element) 944 end; 945 _ -> 946 {EncFunName, _EncMod, _EncFun} = 947 mkfuncname(TopType,Cname,WhatKind,"enc_"), 948 case {WhatKind,Type#type.tablecinf,EncObj} of 949 {{constructed,bif},[{objfun,_}|_R],{_,Fun}} -> 950 emit([EncFunName,"(",Element,", ",{asis,Tag}, 951 ", ",Fun,")"]); 952 _ -> 953 emit([EncFunName,"(",Element,", ",{asis,Tag},")"]) 954 end 955 end 956 end, 957 case OptOrMand of 958 mandatory -> true; 959 _ -> 960 emit([nl,indent(7),"end"]) 961 end. 962 963gen_optormand_case(mandatory,_Erules,_TopType,_Cname,_Type,_InnerType,_WhatKind, 964 _Element) -> 965 ok; 966gen_optormand_case('OPTIONAL',Erules,_TopType,_Cname,_Type,_InnerType,_WhatKind, 967 Element) -> 968 emit([" case ",Element," of",nl]), 969 emit([indent(9),"asn1_NOVALUE -> {", 970 empty_lb(Erules),",0};",nl]), 971 emit([indent(9),"_ ->",nl,indent(12)]); 972gen_optormand_case({'DEFAULT',DefaultValue},Erules,TopType,Cname,Type, 973 InnerType,WhatKind,Element) -> 974 CurrMod = get(currmod), 975 case catch lists:member(der,get(encoding_options)) of 976 true -> 977 emit(" case catch "), 978 asn1ct_gen:gen_check_call(TopType,Cname,Type,InnerType, 979 WhatKind,{asis,DefaultValue}, 980 Element), 981 emit([" of",nl]), 982 emit([indent(12),"true -> {[],0};",nl]); 983 _ -> 984 emit([" case ",Element," of",nl]), 985 emit([indent(9),"asn1_DEFAULT -> {", 986 empty_lb(Erules), 987 ",0};",nl]), 988 case DefaultValue of 989 #'Externalvaluereference'{module=CurrMod, 990 value=V} -> 991 emit([indent(9),"?",{asis,V}," -> {", 992 empty_lb(Erules),",0};",nl]); 993 _ -> 994 emit([indent(9),{asis, 995 DefaultValue}," -> {", 996 empty_lb(Erules),",0};",nl]) 997 end 998 end, 999 emit([indent(9),"_ ->",nl,indent(12)]). 1000 1001 1002 1003gen_dec_line(Erules,TopType,Cname,CTags,Type,OptOrMand,DecObjInf) -> 1004 BytesVar = asn1ct_gen:mk_var(asn1ct_name:curr(v)), 1005 Tag = 1006 [(?ASN1CT_GEN_BER:decode_class(X#tag.class) bsl 10) + X#tag.number || 1007 X <- Type#type.tag], 1008 ChoiceTags = 1009 [(?ASN1CT_GEN_BER:decode_class(Class) bsl 10) + Number|| 1010 {Class,Number} <- CTags], 1011 InnerType = 1012 case Type#type.def of 1013 #'ObjectClassFieldType'{type=OCFTType} -> 1014 OCFTType; 1015 _ -> 1016 asn1ct_gen:get_inner(Type#type.def) 1017 end, 1018 PostpDec = 1019 case OptOrMand of 1020 mandatory -> 1021 gen_dec_call(InnerType,Erules,TopType,Cname,Type, 1022 BytesVar,Tag, 1023 mandatory,", mandatory, ",DecObjInf,OptOrMand); 1024 _ -> %optional or default or a mandatory component after an extensionmark 1025 {FirstTag,RestTag} = 1026 case Tag of 1027 [] -> 1028 {ChoiceTags,[]}; 1029 [Ft|Rt] -> 1030 {Ft,Rt} 1031 end, 1032 emit(["case ",{prev,tlv}," of",nl]), 1033 PostponedDec = 1034 case Tag of 1035 [] when length(ChoiceTags) > 0 -> % a choice without explicit tag 1036 Fcases = 1037 fun(FirstTag1) -> 1038 emit(["[",{curr,v}," = {",{asis,FirstTag1}, 1039 ",_}|Temp", 1040 {curr,tlv}, 1041 "] ->",nl]), 1042 emit([indent(4),"{"]), 1043 Pdec= 1044 gen_dec_call(InnerType,Erules, 1045 TopType,Cname,Type, 1046 BytesVar,RestTag, 1047 mandatory, 1048 ", mandatory, ", 1049 DecObjInf,OptOrMand), 1050 1051 emit([", Temp",{curr,tlv},"}"]), 1052 emit([";",nl]), 1053 Pdec 1054 end, 1055 hd([Fcases(TmpTag)|| TmpTag <- FirstTag]); 1056 1057 [] -> % an open type without explicit tag 1058 emit(["[",{curr,v},"|Temp",{curr,tlv},"] ->",nl]), 1059 emit([indent(4),"{"]), 1060 Pdec= 1061 gen_dec_call(InnerType,Erules,TopType,Cname, 1062 Type,BytesVar,RestTag,mandatory, 1063 ", mandatory, ",DecObjInf, 1064 OptOrMand), 1065 1066 emit([", Temp",{curr,tlv},"}"]), 1067 emit([";",nl]), 1068 Pdec; 1069 1070 _ -> 1071 emit(["[{",{asis,FirstTag}, 1072 ",",{curr,v},"}|Temp", 1073 {curr,tlv}, 1074 "] ->",nl]), 1075 emit([indent(4),"{"]), 1076 Pdec= 1077 gen_dec_call(InnerType,Erules,TopType,Cname, 1078 Type,BytesVar,RestTag,mandatory, 1079 ", mandatory, ",DecObjInf, 1080 OptOrMand), 1081 1082 emit([", Temp",{curr,tlv},"}"]), 1083 emit([";",nl]), 1084 Pdec 1085 end, 1086 1087 emit([indent(4),"_ ->",nl]), 1088 case OptOrMand of 1089 {'DEFAULT', Def} -> 1090 emit([indent(8),"{",{asis,Def},",",{prev,tlv},"}",nl]); 1091 'OPTIONAL' -> 1092 emit([indent(8),"{ asn1_NOVALUE, ",{prev,tlv},"}",nl]) 1093 end, 1094 emit(["end"]), 1095 PostponedDec 1096 end, 1097 case DecObjInf of 1098 {Cname,ObjSet} -> % this must be the component were an object is 1099 %% chosen from the object set according to the table 1100 %% constraint. 1101 {[{ObjSet,Cname,asn1ct_gen:mk_var(asn1ct_name:curr(term))}], 1102 PostpDec}; 1103 _ -> {[],PostpDec} 1104 end. 1105 1106gen_dec_call({typefield,_},_,_,_Cname,Type,BytesVar,Tag,_,_,false,_) -> 1107 %% this in case of a choice with typefield components 1108 asn1ct_name:new(reason), 1109 asn1ct_name:new(opendec), 1110 asn1ct_name:new(tmpterm), 1111 asn1ct_name:new(tmptlv), 1112 1113 {FirstPFName,RestPFName} = 1114% asn1ct_gen:get_constraint(Type#type.constraint, 1115% tableconstraint_info), 1116 (Type#type.def)#'ObjectClassFieldType'.fieldname, 1117 emit([nl,indent(6),"begin",nl]), 1118% emit([indent(9),{curr,opendec}," = ?RT_BER:decode_open_type(", 1119 emit([indent(9),{curr,tmptlv}," = ?RT_BER:decode_open_type(", 1120 BytesVar,",",{asis,Tag},"),",nl]), 1121% emit([indent(9),"{",{curr,tmptlv},",_} = ?RT_BER:decode(", 1122% {curr,opendec},"),",nl]), 1123 1124 emit([indent(9),"case (catch ObjFun(",{asis,FirstPFName}, 1125 ", ",{curr,tmptlv},", ",{asis,RestPFName}, 1126 ")) of", nl]),%% ??? What about Tag 1127 emit([indent(12),"{'EXIT',",{curr,reason},"} ->",nl]), 1128 emit([indent(15),"exit({'Type not ", 1129 "compatible with table constraint', ",{curr,reason},"});",nl]), 1130 emit([indent(12),{curr,tmpterm}," ->",nl]), 1131 emit([indent(15),{curr,tmpterm},nl]), 1132 emit([indent(9),"end",nl,indent(6),"end",nl]), 1133 []; 1134gen_dec_call({typefield,_},_,_,Cname,Type,BytesVar,Tag,_,_,_DecObjInf,OptOrMandComp) -> 1135 emit(["?RT_BER:decode_open_type(",BytesVar,",",{asis,Tag},")"]), 1136 RefedFieldName = 1137% asn1ct_gen:get_constraint(Type#type.constraint, 1138% tableconstraint_info), 1139 (Type#type.def)#'ObjectClassFieldType'.fieldname, 1140 [{Cname,RefedFieldName,asn1ct_gen:mk_var(asn1ct_name:curr(term)), 1141 asn1ct_gen:mk_var(asn1ct_name:curr(tmpterm)),Tag,OptOrMandComp}]; 1142gen_dec_call({objectfield,PrimFieldName,PFNList},_,_,Cname,_,BytesVar,Tag,_,_,_,OptOrMandComp) -> 1143 emit(["?RT_BER:decode_open_type(",BytesVar,",",{asis,Tag},")"]), 1144 [{Cname,{PrimFieldName,PFNList},asn1ct_gen:mk_var(asn1ct_name:curr(term)), 1145 asn1ct_gen:mk_var(asn1ct_name:curr(tmpterm)),Tag,OptOrMandComp}]; 1146gen_dec_call(InnerType,Erules,TopType,Cname,Type,BytesVar,Tag,PrimOptOrMand, 1147 OptOrMand,DecObjInf,_) -> 1148 WhatKind = asn1ct_gen:type(InnerType), 1149 gen_dec_call1(WhatKind,InnerType,Erules,TopType,Cname,Type,BytesVar,Tag, 1150 PrimOptOrMand,OptOrMand), 1151 case DecObjInf of 1152 {Cname,{_,OSet,UniqueFName,ValIndex}} -> 1153 Term = asn1ct_gen:mk_var(asn1ct_name:curr(term)), 1154 ValueMatch = value_match(ValIndex,Term), 1155 emit([",",nl,"ObjFun = 'getdec_",OSet,"'(", 1156% {asis,UniqueFName},", ",{curr,term},")"]); 1157 {asis,UniqueFName},", ",ValueMatch,")"]); 1158 _ -> 1159 ok 1160 end, 1161 []. 1162gen_dec_call1({primitive,bif},InnerType,Erules,TopType,Cname,Type,BytesVar, 1163 Tag,OptOrMand,_) -> 1164 case {asn1ct:get_gen_state_field(namelist),InnerType} of 1165 {[{Cname,undecoded}|Rest],_} -> 1166 asn1ct:add_generated_refed_func({[Cname|TopType],undecoded, 1167 Tag,Type}), 1168 asn1ct:update_gen_state(namelist,Rest), 1169% emit(["?RT_BER:match_tags(",BytesVar,",",{asis,Tag},")"]); 1170 emit(["{'",asn1ct_gen:list2name([Cname|TopType]),"',", 1171 BytesVar,"}"]); 1172 {_,{fixedtypevaluefield,_,Btype}} -> 1173 ?ASN1CT_GEN_BER:gen_dec_prim(Erules,Btype,BytesVar,Tag,[], 1174 ?PRIMITIVE,OptOrMand); 1175 _ -> 1176 ?ASN1CT_GEN_BER:gen_dec_prim(Erules,Type,BytesVar,Tag,[], 1177 ?PRIMITIVE,OptOrMand) 1178 end; 1179gen_dec_call1('ASN1_OPEN_TYPE',_InnerType,Erules,TopType,Cname,Type,BytesVar, 1180 Tag,OptOrMand,_) -> 1181 case {asn1ct:get_gen_state_field(namelist),Type#type.def} of 1182 {[{Cname,undecoded}|Rest],_} -> 1183 asn1ct:add_generated_refed_func({[Cname|TopType],undecoded, 1184 Tag,Type}), 1185 asn1ct:update_gen_state(namelist,Rest), 1186 emit(["{'",asn1ct_gen:list2name([Cname|TopType]),"',", 1187 BytesVar,"}"]); 1188% emit(["?RT_BER:match_tags(",BytesVar,",",{asis,Tag},")"]); 1189 {_,#'ObjectClassFieldType'{type=OpenType}} -> 1190 ?ASN1CT_GEN_BER:gen_dec_prim(Erules,#type{def=OpenType}, 1191 BytesVar,Tag,[], 1192 ?PRIMITIVE,OptOrMand); 1193 _ -> 1194 ?ASN1CT_GEN_BER:gen_dec_prim(Erules,Type,BytesVar,Tag,[], 1195 ?PRIMITIVE,OptOrMand) 1196 end; 1197gen_dec_call1(WhatKind,_,_Erules,TopType,Cname,Type,BytesVar, 1198 Tag,_,_OptOrMand) -> 1199 case asn1ct:get_gen_state_field(namelist) of 1200 [{Cname,undecoded}|Rest] -> 1201 asn1ct:add_generated_refed_func({[Cname|TopType],undecoded, 1202 Tag,Type}), 1203 asn1ct:update_gen_state(namelist,Rest), 1204 emit(["{'",asn1ct_gen:list2name([Cname|TopType]),"',", 1205 BytesVar,"}"]); 1206 _ -> 1207% {DecFunName, _DecMod, _DecFun} = 1208% case {asn1ct:get_gen_state_field(namelist),WhatKind} of 1209 EmitDecFunCall = 1210 fun(FuncName) -> 1211 case {WhatKind,Type#type.tablecinf} of 1212 {{constructed,bif},[{objfun,_}|_Rest]} -> 1213 emit([FuncName,"(",BytesVar,", ",{asis,Tag}, 1214 ", ObjFun)"]); 1215 _ -> 1216 emit([FuncName,"(",BytesVar,", ",{asis,Tag},")"]) 1217 end 1218 end, 1219 case asn1ct:get_gen_state_field(namelist) of 1220 [{Cname,List}|Rest] when list(List) -> 1221 case WhatKind of 1222 #'Externaltypereference'{} -> 1223 %%io:format("gen_dec_call1 1:~n~p~n~n",[WhatKind]), 1224 asn1ct:add_tobe_refed_func({WhatKind,List}); 1225 _ -> 1226 %%io:format("gen_dec_call1 2:~n~p~n~n",[[Cname|TopType]]), 1227 asn1ct:add_tobe_refed_func({[Cname|TopType], 1228 List}) 1229 end, 1230 asn1ct:update_gen_state(namelist,Rest), 1231 Prefix=asn1ct:get_gen_state_field(prefix), 1232 {DecFunName,_,_}= 1233 mkfuncname(TopType,Cname,WhatKind,Prefix), 1234 EmitDecFunCall(DecFunName); 1235 [{Cname,parts}|Rest] -> 1236 asn1ct:update_gen_state(namelist,Rest), 1237 asn1ct:get_gen_state_field(prefix), 1238 %% This is to prepare SEQUENCE OF value in 1239 %% partial incomplete decode for a later 1240 %% part-decode, i.e. skip %% the tag. 1241 asn1ct:add_generated_refed_func({[Cname|TopType], 1242 parts, 1243 [],Type}), 1244 emit(["{'",asn1ct_gen:list2name([Cname|TopType]),"',"]), 1245 EmitDecFunCall("?RT_BER:match_tags"), 1246 emit("}"); 1247 _ -> 1248 {DecFunName,_,_}= 1249 mkfuncname(TopType,Cname,WhatKind,"dec_"), 1250 EmitDecFunCall(DecFunName) 1251 end 1252% case {WhatKind,Type#type.tablecinf} of 1253% {{constructed,bif},[{objfun,_}|_Rest]} -> 1254% emit([DecFunName,"(",BytesVar,", ",{asis,Tag}, 1255% ", ObjFun)"]); 1256% _ -> 1257% emit([DecFunName,"(",BytesVar,", ",{asis,Tag},")"]) 1258% end 1259 end. 1260 1261 1262%%------------------------------------------------------ 1263%% General and special help functions (not exported) 1264%%------------------------------------------------------ 1265 1266 1267indent(N) -> 1268 lists:duplicate(N,32). % 32 = space 1269 1270mkcindexlist([H,T1|T], Sep) -> % Sep is a string e.g ", " or "+ " 1271 emit(["Cindex",H,Sep]), 1272 mkcindexlist([T1|T], Sep); 1273mkcindexlist([H|T], Sep) -> 1274 emit(["Cindex",H]), 1275 mkcindexlist(T, Sep); 1276mkcindexlist([], _) -> 1277 true. 1278 1279mkcindexlist(L) -> 1280 mkcindexlist(L,", "). 1281 1282 1283mkvlist([H,T1|T], Sep) -> % Sep is a string e.g ", " or "+ " 1284 emit([{var,H},Sep]), 1285 mkvlist([T1|T], Sep); 1286mkvlist([H|T], Sep) -> 1287 emit([{var,H}]), 1288 mkvlist(T, Sep); 1289mkvlist([], _) -> 1290 true. 1291 1292mkvlist(L) -> 1293 mkvlist(L,", "). 1294 1295mkvplus(L) -> 1296 mkvlist(L," + "). 1297 1298extensible(CompList) when list(CompList) -> 1299 noext; 1300extensible({RootList,ExtList}) -> 1301 {ext,length(RootList)+1,length(ExtList)}. 1302 1303 1304print_attribute_comment(InnerType,Pos,Cname,Prop) -> 1305 CommentLine = "%%-------------------------------------------------", 1306 emit([nl,CommentLine]), 1307 case InnerType of 1308 {typereference,_,Name} -> 1309 emit([nl,"%% attribute ",Cname,"(",Pos,") with type ",Name]); 1310 {'Externaltypereference',_,XModule,Name} -> 1311 emit([nl,"%% attribute ",Cname,"(",Pos,") External ",XModule,":",Name]); 1312 _ -> 1313 emit([nl,"%% attribute ",Cname,"(",Pos,") with type ",InnerType]) 1314 end, 1315 case Prop of 1316 mandatory -> 1317 continue; 1318 {'DEFAULT', Def} -> 1319 emit([" DEFAULT = ",{asis,Def}]); 1320 'OPTIONAL' -> 1321 emit([" OPTIONAL"]) 1322 end, 1323 emit([nl,CommentLine,nl]). 1324 1325 1326 1327mkfuncname(TopType,Cname,WhatKind,Prefix) -> 1328 CurrMod = get(currmod), 1329 case WhatKind of 1330 #'Externaltypereference'{module=CurrMod,type=EType} -> 1331 F = lists:concat(["'",Prefix,EType,"'"]), 1332 {F, "?MODULE", F}; 1333 #'Externaltypereference'{module=Mod,type=EType} -> 1334 {lists:concat(["'",Mod,"':'",Prefix,EType,"'"]),Mod, 1335 lists:concat(["'",Prefix,EType,"'"])}; 1336 {constructed,bif} -> 1337 F = lists:concat(["'",Prefix,asn1ct_gen:list2name([Cname|TopType]),"'"]), 1338 {F, "?MODULE", F} 1339 end. 1340 1341empty_lb(ber) -> 1342 "[]"; 1343empty_lb(ber_bin) -> 1344 "<<>>"; 1345empty_lb(ber_bin_v2) -> 1346 "<<>>". 1347 1348value_match(Index,Value) when atom(Value) -> 1349 value_match(Index,atom_to_list(Value)); 1350value_match([],Value) -> 1351 Value; 1352value_match([{VI,_}|VIs],Value) -> 1353 value_match1(Value,VIs,lists:concat(["element(",VI,","]),1). 1354value_match1(Value,[],Acc,Depth) -> 1355 Acc ++ Value ++ lists:concat(lists:duplicate(Depth,")")); 1356value_match1(Value,[{VI,_}|VIs],Acc,Depth) -> 1357 value_match1(Value,VIs,Acc++lists:concat(["element(",VI,","]),Depth+1). 1358