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_per.erl,v 1.1 2008/12/17 09:53:29 mikpe Exp $ 18%% 19-module(asn1ct_constructed_per). 20 21-export([gen_encode_sequence/3]). 22-export([gen_decode_sequence/3]). 23-export([gen_encode_set/3]). 24-export([gen_decode_set/3]). 25-export([gen_encode_sof/4]). 26-export([gen_decode_sof/4]). 27-export([gen_encode_choice/3]). 28-export([gen_decode_choice/3]). 29 30-include("asn1_records.hrl"). 31%-compile(export_all). 32 33-import(asn1ct_gen, [emit/1,demit/1]). 34 35 36%% ENCODE GENERATOR FOR SEQUENCE TYPE ** ********** 37 38 39gen_encode_set(Erules,TypeName,D) -> 40 gen_encode_constructed(Erules,TypeName,D). 41 42gen_encode_sequence(Erules,TypeName,D) -> 43 gen_encode_constructed(Erules,TypeName,D). 44 45gen_encode_constructed(Erules,Typename,D) when record(D,type) -> 46 asn1ct_name:start(), 47 asn1ct_name:new(term), 48 asn1ct_name:new(bytes), 49 {CompList,TableConsInfo} = 50 case D#type.def of 51 #'SEQUENCE'{tablecinf=TCI,components=CL} -> 52 {CL,TCI}; 53 #'SET'{tablecinf=TCI,components=CL} -> 54 {CL,TCI} 55 end, 56 case Typename of 57 ['EXTERNAL'] -> 58 emit({{var,asn1ct_name:next(val)}, 59 " = asn1rt_check:transform_to_EXTERNAL1990(", 60 {var,asn1ct_name:curr(val)},"),",nl}), 61 asn1ct_name:new(val); 62 _ -> 63 ok 64 end, 65 case {Optionals = optionals(CompList),CompList} of 66 {[],EmptyCL} when EmptyCL == {[],[]};EmptyCL == [] -> 67 emit(["%%Variable setting just to eliminate ", 68 "compiler warning for unused vars!",nl, 69 "_Val = ",{var,asn1ct_name:curr(val)},",",nl]); 70 {[],_} -> 71 emit([{var,asn1ct_name:next(val)}," = ?RT_PER:list_to_record("]), 72 emit(["'",asn1ct_gen:list2rname(Typename),"'"]), 73 emit([", ",{var,asn1ct_name:curr(val)},"),",nl]); 74 _ -> 75 Fixoptcall = 76 case Erules of 77 per -> ",Opt} = ?RT_PER:fixoptionals2("; 78 _ -> ",Opt} = ?RT_PER:fixoptionals(" 79 end, 80 emit({"{",{var,asn1ct_name:next(val)},Fixoptcall, 81 {asis,Optionals},",",length(Optionals), 82 ",",{var,asn1ct_name:curr(val)},"),",nl}) 83 end, 84 asn1ct_name:new(val), 85 Ext = extensible(CompList), 86 case Ext of 87 {ext,_,NumExt} when NumExt > 0 -> 88 emit(["Extensions = ?RT_PER:fixextensions(",{asis,Ext}, 89 ", ",{curr,val},"),",nl]); 90 _ -> true 91 end, 92 EncObj = 93 case TableConsInfo of 94 #simpletableattributes{usedclassfield=Used, 95 uniqueclassfield=Unique} when Used /= Unique -> 96 false; 97 %% ObjectSet, name of the object set in constraints 98 %% 99 %%{ObjectSet,AttrN,N,UniqueFieldName} -> %% N is index of attribute that determines constraint 100 #simpletableattributes{objectsetname=ObjectSet, 101 c_name=AttrN, 102 c_index=N, 103 usedclassfield=UniqueFieldName, 104 uniqueclassfield=UniqueFieldName, 105 valueindex=ValueIndex 106 } -> %% N is index of attribute that determines constraint 107 OSDef = 108 case ObjectSet of 109 {Module,OSName} -> 110 asn1_db:dbget(Module,OSName); 111 OSName -> 112 asn1_db:dbget(get(currmod),OSName) 113 end, 114 case (OSDef#typedef.typespec)#'ObjectSet'.gen of 115 true -> 116 ObjectEncode = 117 asn1ct_gen:un_hyphen_var(lists:concat(['Obj',AttrN])), 118 emit([ObjectEncode," = ",nl]), 119 emit([" 'getenc_",ObjectSet,"'(", 120 {asis,UniqueFieldName},", ",nl]), 121 El = make_element(N+1,asn1ct_gen:mk_var(asn1ct_name:curr(val)),AttrN), 122 Indent = 12 + length(atom_to_list(ObjectSet)), 123 case ValueIndex of 124 [] -> 125 emit([indent(Indent),El,"),",nl]); 126 _ -> 127 emit([indent(Indent),"value_match(", 128 {asis,ValueIndex},",",El,")),",nl]), 129 notice_value_match() 130 end, 131 {AttrN,ObjectEncode}; 132 _ -> 133 false 134 end; 135 _ -> 136 case D#type.tablecinf of 137 [{objfun,_}|_] -> 138 %% when the simpletableattributes was at an outer 139 %% level and the objfun has been passed through the 140 %% function call 141 {"got objfun through args","ObjFun"}; 142 _ -> 143 false 144 end 145 end, 146 emit({"[",nl}), 147 MaybeComma1 = 148 case Ext of 149 {ext,_Pos,NumExt2} when NumExt2 > 0 -> 150 emit({"?RT_PER:setext(Extensions =/= [])"}), 151 ", "; 152 {ext,_Pos,_} -> 153 emit({"?RT_PER:setext(false)"}), 154 ", "; 155 _ -> 156 "" 157 end, 158 MaybeComma2 = 159 case optionals(CompList) of 160 [] -> MaybeComma1; 161 _ -> 162 emit(MaybeComma1), 163 emit("Opt"), 164 {",",nl} 165 end, 166 gen_enc_components_call(Typename,CompList,MaybeComma2,EncObj,Ext), 167 emit({"].",nl}). 168 169 170%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 171%% generate decode function for SEQUENCE and SET 172%% 173gen_decode_set(Erules,Typename,D) -> 174 gen_decode_constructed(Erules,Typename,D). 175 176gen_decode_sequence(Erules,Typename,D) -> 177 gen_decode_constructed(Erules,Typename,D). 178 179gen_decode_constructed(_Erules,Typename,D) when record(D,type) -> 180 asn1ct_name:start(), 181 {CompList,TableConsInfo} = 182 case D#type.def of 183 #'SEQUENCE'{tablecinf=TCI,components=CL} -> 184 {CL,TCI}; 185 #'SET'{tablecinf=TCI,components=CL} -> 186 {CL,TCI} 187 end, 188 Ext = extensible(CompList), 189 MaybeComma1 = case Ext of 190 {ext,_Pos,_NumExt} -> 191 gen_dec_extension_value("Bytes"), 192 {",",nl}; 193 _ -> 194 "" 195 end, 196 Optionals = optionals(CompList), 197 MaybeComma2 = case Optionals of 198 [] -> MaybeComma1; 199 _ -> 200 Bcurr = asn1ct_name:curr(bytes), 201 Bnext = asn1ct_name:next(bytes), 202 emit(MaybeComma1), 203 GetoptCall = "} = ?RT_PER:getoptionals2(", 204 emit({"{Opt,",{var,Bnext},GetoptCall, 205 {var,Bcurr},",",{asis,length(Optionals)},")"}), 206 asn1ct_name:new(bytes), 207 ", " 208 end, 209 {DecObjInf,UniqueFName,ValueIndex} = 210 case TableConsInfo of 211%% {ObjectSet,AttrN,N,UniqueFieldName} ->%% N is index of attribute that determines constraint 212 #simpletableattributes{objectsetname=ObjectSet, 213 c_name=AttrN, 214 usedclassfield=UniqueFieldName, 215 uniqueclassfield=UniqueFieldName, 216 valueindex=ValIndex} -> 217%% {AttrN,ObjectSet}; 218 F = fun(#'ComponentType'{typespec=CT})-> 219 case {CT#type.constraint,CT#type.tablecinf} of 220 {[],[{objfun,_}|_R]} -> true; 221 _ -> false 222 end 223 end, 224 case lists:any(F,CompList) of 225 true -> % when component relation constraint establish 226 %% relation from a component to another components 227 %% subtype component 228 {{AttrN,{deep,ObjectSet,UniqueFieldName,ValIndex}}, 229 UniqueFieldName,ValIndex}; 230 false -> 231 {{AttrN,ObjectSet},UniqueFieldName,ValIndex} 232 end; 233 _ -> 234 case D#type.tablecinf of 235 [{objfun,_}|_] -> 236 {{"got objfun through args","ObjFun"},false,false}; 237 _ -> 238 {false,false,false} 239 end 240 end, 241 {AccTerm,AccBytes} = 242 gen_dec_components_call(Typename,CompList,MaybeComma2,DecObjInf,Ext,length(Optionals)), 243 case asn1ct_name:all(term) of 244 [] -> emit(MaybeComma2); % no components at all 245 _ -> emit({com,nl}) 246 end, 247 case {AccTerm,AccBytes} of 248 {[],[]} -> 249 ok; 250 {_,[]} -> 251 ok; 252 {[{ObjSet,LeadingAttr,Term}],ListOfOpenTypes} -> 253 DecObj = asn1ct_gen:un_hyphen_var(lists:concat(['DecObj',LeadingAttr,Term])), 254 ValueMatch = value_match(ValueIndex,Term), 255 emit({DecObj," =",nl," 'getdec_",ObjSet,"'(", 256% {asis,UniqueFName},", ",Term,"),",nl}), 257 {asis,UniqueFName},", ",ValueMatch,"),",nl}), 258 gen_dec_listofopentypes(DecObj,ListOfOpenTypes,false) 259 end, 260 %% we don't return named lists any more Cnames = mkcnamelist(CompList), 261 demit({"Result = "}), %dbg 262 %% return value as record 263 case Typename of 264 ['EXTERNAL'] -> 265 emit({" OldFormat={'",asn1ct_gen:list2rname(Typename), 266 "'"}), 267 mkvlist(asn1ct_name:all(term)), 268 emit({"},",nl}), 269 emit({" ASN11994Format =",nl, 270 " asn1rt_check:transform_to_EXTERNAL1994", 271 "(OldFormat),",nl}), 272 emit(" {ASN11994Format,"); 273 _ -> 274 emit(["{{'",asn1ct_gen:list2rname(Typename),"'"]), 275 mkvlist(asn1ct_name:all(term)), 276 emit("},") 277 end, 278 emit({{var,asn1ct_name:curr(bytes)},"}"}), 279 emit({".",nl,nl}). 280 281gen_dec_listofopentypes(_,[],_) -> 282 emit(nl); 283gen_dec_listofopentypes(DecObj,[{_Cname,{FirstPFN,PFNList},Term,TmpTerm,Prop}|Rest],_Update) -> 284 285% asn1ct_name:new(term), 286 asn1ct_name:new(tmpterm), 287 asn1ct_name:new(reason), 288 289 emit([Term," = ",nl]), 290 291 N = case Prop of 292 mandatory -> 0; 293 'OPTIONAL' -> 294 emit_opt_or_mand_check(asn1_NOVALUE,TmpTerm), 295 6; 296 {'DEFAULT',Val} -> 297 emit_opt_or_mand_check(Val,TmpTerm), 298 6 299 end, 300 301 emit([indent(N+3),"case (catch ",DecObj,"(", 302 {asis,FirstPFN},", ",TmpTerm,", telltype,",{asis,PFNList},")) of",nl]), 303 emit([indent(N+6),"{'EXIT', ",{curr,reason},"} ->",nl]), 304%% emit({indent(9),"throw({runtime_error,{","'Type not compatible with table constraint'",",",Term,"}});",nl}), 305 emit([indent(N+9),"exit({'Type not compatible with table constraint',", 306 {curr,reason},"});",nl]), 307 emit([indent(N+6),"{",{curr,tmpterm},",_} ->",nl]), 308 emit([indent(N+9),{curr,tmpterm},nl]), 309 310 case Prop of 311 mandatory -> 312 emit([indent(N+3),"end,",nl]); 313 _ -> 314 emit([indent(N+3),"end",nl, 315 indent(3),"end,",nl]) 316 end, 317 gen_dec_listofopentypes(DecObj,Rest,true). 318 319 320emit_opt_or_mand_check(Val,Term) -> 321 emit([indent(3),"case ",Term," of",nl, 322 indent(6),{asis,Val}," ->",{asis,Val},";",nl, 323 indent(6),"_ ->",nl]). 324 325%% ENCODE GENERATOR FOR THE CHOICE TYPE ******* 326%% assume Val = {Alternative,AltType} 327%% generate 328%%[ 329%% ?RT_PER:set_choice(element(1,Val),Altnum,Altlist,ext), 330%%case element(1,Val) of 331%% alt1 -> 332%% encode_alt1(element(2,Val)); 333%% alt2 -> 334%% encode_alt2(element(2,Val)) 335%%end 336%%]. 337 338gen_encode_choice(_Erules,Typename,D) when record(D,type) -> 339 {'CHOICE',CompList} = D#type.def, 340 emit({"[",nl}), 341 Ext = extensible(CompList), 342 gen_enc_choice(Typename,CompList,Ext), 343 emit({nl,"].",nl}). 344 345gen_decode_choice(_Erules,Typename,D) when record(D,type) -> 346 asn1ct_name:start(), 347 asn1ct_name:new(bytes), 348 {'CHOICE',CompList} = D#type.def, 349 Ext = extensible(CompList), 350 gen_dec_choice(Typename,CompList,Ext), 351 emit({".",nl}). 352 353%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 354% Encode generator for SEQUENCE OF type 355 356 357gen_encode_sof(_Erules,Typename,SeqOrSetOf,D) when record(D,type) -> 358 asn1ct_name:start(), 359% Val = [Component] 360% ?RT_PER:encode_length(length(Val)), 361% lists: 362 {_SeqOrSetOf,ComponentType} = D#type.def, 363 emit({"[",nl}), 364 SizeConstraint = 365 case asn1ct_gen:get_constraint(D#type.constraint, 366 'SizeConstraint') of 367 no -> undefined; 368 Range -> Range 369 end, 370 ObjFun = 371 case D#type.tablecinf of 372 [{objfun,_}|_R] -> 373 ", ObjFun"; 374 _-> 375 "" 376 end, 377 emit({nl,indent(3),"?RT_PER:encode_length(", 378 {asis,SizeConstraint}, 379 ",length(Val)),",nl}), 380 emit({indent(3),"'enc_",asn1ct_gen:list2name(Typename), 381 "_components'(Val",ObjFun,", [])"}), 382 emit({nl,"].",nl}), 383 NewComponentType = 384 case ComponentType#type.def of 385 {'ENUMERATED',_,Component}-> 386 ComponentType#type{def={'ENUMERATED',Component}}; 387 _ -> ComponentType 388 end, 389 gen_encode_sof_components(Typename,SeqOrSetOf,NewComponentType). 390 391gen_decode_sof(_Erules,Typename,SeqOrSetOf,D) when record(D,type) -> 392 asn1ct_name:start(), 393% Val = [Component] 394% ?RT_PER:encode_length(length(Val)), 395% lists: 396 {_SeqOrSetOf,ComponentType} = D#type.def, 397 SizeConstraint = 398 case asn1ct_gen:get_constraint(D#type.constraint, 399 'SizeConstraint') of 400 no -> undefined; 401 Range -> Range 402 end, 403 ObjFun = 404 case D#type.tablecinf of 405 [{objfun,_}|_R] -> 406 ", ObjFun"; 407 _ -> 408 "" 409 end, 410 emit({nl,"{Num,Bytes1} = ?RT_PER:decode_length(Bytes,",{asis,SizeConstraint},"),",nl}), 411 emit({"'dec_",asn1ct_gen:list2name(Typename), 412 "_components'(Num, Bytes1, telltype",ObjFun,", []).",nl}), 413 NewComponentType = 414 case ComponentType#type.def of 415 {'ENUMERATED',_,Component}-> 416 ComponentType#type{def={'ENUMERATED',Component}}; 417 _ -> ComponentType 418 end, 419 gen_decode_sof_components(Typename,SeqOrSetOf,NewComponentType). 420 421gen_encode_sof_components(Typename,SeqOrSetOf,Cont) -> 422 {ObjFun,ObjFun_Var} = 423 case Cont#type.tablecinf of 424 [{objfun,_}|_R] -> 425 {", ObjFun",", _"}; 426 _ -> 427 {"",""} 428 end, 429 emit({"'enc_",asn1ct_gen:list2name(Typename),"_components'([]", 430 ObjFun_Var,", Acc) -> lists:reverse(Acc);",nl,nl}), 431 emit({"'enc_",asn1ct_gen:list2name(Typename),"_components'([H|T]", 432 ObjFun,", Acc) ->",nl}), 433 emit({"'enc_",asn1ct_gen:list2name(Typename),"_components'(T"}), 434 emit({ObjFun,", ["}), 435 %% the component encoder 436 Constructed_Suffix = asn1ct_gen:constructed_suffix(SeqOrSetOf, 437 Cont#type.def), 438 439 Conttype = asn1ct_gen:get_inner(Cont#type.def), 440 Currmod = get(currmod), 441 Ctgenmod = list_to_atom(lists:concat(["asn1ct_gen_",per, 442 asn1ct_gen:rt2ct_suffix()])), 443 case asn1ct_gen:type(Conttype) of 444 {primitive,bif} -> 445 gen_encode_prim_wrapper(Ctgenmod,per,Cont,false,"H"); 446% Ctgenmod:gen_encode_prim(per,Cont,false,"H"); 447 {constructed,bif} -> 448 NewTypename = [Constructed_Suffix|Typename], 449 emit({"'enc_",asn1ct_gen:list2name(NewTypename),"'(H", 450 ObjFun,")",nl,nl}); 451 #'Externaltypereference'{module=Currmod,type=Ename} -> 452 emit({"'enc_",Ename,"'(H)",nl,nl}); 453 #'Externaltypereference'{module=EMod,type=EType} -> 454 emit({"'",EMod,"':'enc_",EType,"'(H)",nl,nl}); 455 _ -> 456 emit({"'enc_",Conttype,"'(H)",nl,nl}) 457 end, 458 emit({" | Acc]).",nl}). 459 460gen_decode_sof_components(Typename,SeqOrSetOf,Cont) -> 461 {ObjFun,ObjFun_Var} = 462 case Cont#type.tablecinf of 463 [{objfun,_}|_R] -> 464 {", ObjFun",", _"}; 465 _ -> 466 {"",""} 467 end, 468 emit({"'dec_",asn1ct_gen:list2name(Typename), 469 "_components'(0, Bytes, _",ObjFun_Var,", Acc) ->",nl, 470 indent(3),"{lists:reverse(Acc), Bytes};",nl}), 471 emit({"'dec_",asn1ct_gen:list2name(Typename), 472 "_components'(Num, Bytes, _",ObjFun,", Acc) ->",nl}), 473 emit({indent(3),"{Term,Remain} = "}), 474 Constructed_Suffix = asn1ct_gen:constructed_suffix(SeqOrSetOf, 475 Cont#type.def), 476 Conttype = asn1ct_gen:get_inner(Cont#type.def), 477 Ctgenmod = list_to_atom(lists:concat(["asn1ct_gen_",per, 478 asn1ct_gen:rt2ct_suffix()])), 479 case asn1ct_gen:type(Conttype) of 480 {primitive,bif} -> 481 Ctgenmod:gen_dec_prim(per,Cont,"Bytes"), 482 emit({com,nl}); 483 {constructed,bif} -> 484 NewTypename = [Constructed_Suffix|Typename], 485 emit({"'dec_",asn1ct_gen:list2name(NewTypename), 486 "'(Bytes, telltype",ObjFun,"),",nl}); 487 #typereference{val=Dname} -> 488 emit({"'dec_",Dname,"'(Bytes,telltype),",nl}); 489 #'Externaltypereference'{module=EMod,type=EType} -> 490 emit({"'",EMod,"':'dec_",EType,"'(Bytes,telltype),",nl}); 491 _ -> 492 emit({"'dec_",Conttype,"'(Bytes,telltype),",nl}) 493 end, 494 emit({indent(3),"'dec_",asn1ct_gen:list2name(Typename), 495 "_components'(Num-1, Remain, telltype",ObjFun,", [Term|Acc]).",nl}). 496 497 498%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 499% General and special help functions (not exported) 500 501mkvlist([H|T]) -> 502 emit(","), 503 mkvlist2([H|T]); 504mkvlist([]) -> 505 true. 506mkvlist2([H,T1|T]) -> 507 emit({{var,H},","}), 508 mkvlist2([T1|T]); 509mkvlist2([H|T]) -> 510 emit({{var,H}}), 511 mkvlist2(T); 512mkvlist2([]) -> 513 true. 514 515extensible(CompList) when list(CompList) -> 516 noext; 517extensible({RootList,ExtList}) -> 518 {ext,length(RootList)+1,length(ExtList)}. 519 520gen_dec_extension_value(_) -> 521 emit({"{Ext,",{next,bytes},"} = ?RT_PER:getext(",{curr,bytes},")"}), 522 asn1ct_name:new(bytes). 523 524%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 525%% Produce a list with positions (in the Value record) where 526%% there are optional components, start with 2 because first element 527%% is the record name 528 529optionals({L,_Ext}) -> optionals(L,[],2); 530optionals(L) -> optionals(L,[],2). 531 532optionals([{'EXTENSIONMARK',_,_}|Rest],Acc,Pos) -> 533 optionals(Rest,Acc,Pos); % optionals in extension are currently not handled 534optionals([#'ComponentType'{prop='OPTIONAL'}|Rest],Acc,Pos) -> 535 optionals(Rest,[Pos|Acc],Pos+1); 536optionals([#'ComponentType'{prop={'DEFAULT',_}}|Rest],Acc,Pos) -> 537 optionals(Rest,[Pos|Acc],Pos+1); 538optionals([#'ComponentType'{}|Rest],Acc,Pos) -> 539 optionals(Rest,Acc,Pos+1); 540optionals([],Acc,_) -> 541 lists:reverse(Acc). 542 543 544gen_enc_components_call(TopType,{CompList,ExtList},MaybeComma,DynamicEnc,Ext) -> 545 %% The type has extensionmarker 546 Rpos = gen_enc_components_call1(TopType,CompList,1,MaybeComma,DynamicEnc,noext), 547 case Ext of 548 {ext,_,ExtNum} when ExtNum > 0 -> 549 emit([nl, 550 ",Extensions",nl]); 551 _ -> true 552 end, 553 %handle extensions 554 gen_enc_components_call1(TopType,ExtList,Rpos,MaybeComma,DynamicEnc,Ext); 555gen_enc_components_call(TopType, CompList, MaybeComma, DynamicEnc, Ext) -> 556 %% The type has no extensionmarker 557 gen_enc_components_call1(TopType,CompList,1,MaybeComma,DynamicEnc,Ext). 558 559gen_enc_components_call1(TopType, 560 [C=#'ComponentType'{name=Cname,typespec=Type,prop=Prop}|Rest], 561 Tpos, 562 MaybeComma, DynamicEnc, Ext) -> 563 564 put(component_type,{true,C}), 565 %% information necessary in asn1ct_gen_per_rt2ct:gen_encode_prim 566 567 Pos = case Ext of 568 noext -> Tpos; 569 {ext,Epos,_Enum} -> Tpos - Epos + 1 570 end, 571 emit(MaybeComma), 572 case Prop of 573 'OPTIONAL' -> 574 gen_enc_component_optional(TopType,Cname,Type,Tpos,DynamicEnc,Ext); 575 {'DEFAULT',_DefVal} -> 576 gen_enc_component_default(TopType,Cname,Type,Tpos,DynamicEnc,Ext); 577 _ -> 578 case Ext of 579 {ext,ExtPos,_} when Tpos >= ExtPos -> 580 gen_enc_component_optional(TopType,Cname,Type,Tpos,DynamicEnc,Ext); 581 _ -> 582 gen_enc_component_mandatory(TopType,Cname,Type,Tpos,DynamicEnc,Ext) 583 end 584 end, 585 586 erase(component_type), 587 588 case Rest of 589 [] -> 590 Pos+1; 591 _ -> 592 emit({com,nl}), 593 gen_enc_components_call1(TopType,Rest,Tpos+1,"",DynamicEnc,Ext) 594 end; 595gen_enc_components_call1(_TopType,[],Pos,_,_,_) -> 596 Pos. 597 598gen_enc_component_default(TopType,Cname,Type,Pos,DynamicEnc,Ext) -> 599% Element = io_lib:format("?RT_PER:cindex(~w,Val1,~w)",[Pos+1,Cname]), 600 Element = make_element(Pos+1,"Val1",Cname), 601 emit({"case ",Element," of",nl}), 602% case Ext of 603% {ext,ExtPos,_} when Pos >= ExtPos -> 604% emit({"asn1_NOEXTVALUE -> [];",nl}); 605% _ -> 606 emit({"asn1_DEFAULT -> [];",nl}), 607% end, 608 asn1ct_name:new(tmpval), 609 emit({{curr,tmpval}," ->",nl}), 610 InnerType = asn1ct_gen:get_inner(Type#type.def), 611 emit({nl,"%% attribute number ",Pos," with type ", 612 InnerType,nl}), 613 NextElement = asn1ct_gen:mk_var(asn1ct_name:curr(tmpval)), 614 gen_enc_line(TopType,Cname,Type,NextElement, Pos,DynamicEnc,Ext), 615 emit({nl,"end"}). 616 617gen_enc_component_optional(TopType,Cname,Type,Pos,DynamicEnc,Ext) -> 618% Element = io_lib:format("?RT_PER:cindex(~w,Val1,~w)",[Pos+1,Cname]), 619 Element = make_element(Pos+1,"Val1",Cname), 620 emit({"case ",Element," of",nl}), 621% case Ext of 622% {ext,ExtPos,_} when Pos >= ExtPos -> 623% emit({"asn1_NOEXTVALUE -> [];",nl}); 624% _ -> 625 emit({"asn1_NOVALUE -> [];",nl}), 626% end, 627 asn1ct_name:new(tmpval), 628 emit({{curr,tmpval}," ->",nl}), 629 InnerType = asn1ct_gen:get_inner(Type#type.def), 630 emit({nl,"%% attribute number ",Pos," with type ", 631 InnerType,nl}), 632 NextElement = asn1ct_gen:mk_var(asn1ct_name:curr(tmpval)), 633 gen_enc_line(TopType,Cname,Type,NextElement, Pos,DynamicEnc,Ext), 634 emit({nl,"end"}). 635 636gen_enc_component_mandatory(TopType,Cname,Type,Pos,DynamicEnc,Ext) -> 637 InnerType = asn1ct_gen:get_inner(Type#type.def), 638 emit({nl,"%% attribute number ",Pos," with type ", 639 InnerType,nl}), 640 gen_enc_line(TopType,Cname,Type,[],Pos,DynamicEnc,Ext). 641 642gen_enc_line(TopType, Cname, Type, [], Pos,DynamicEnc,Ext) -> 643% Element = io_lib:format("?RT_PER:cindex(~w,~s,~w)",[Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val)),Cname]), 644 Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val)),Cname), 645 gen_enc_line(TopType,Cname,Type,Element, Pos,DynamicEnc,Ext); 646gen_enc_line(TopType,Cname,Type,Element, Pos,DynamicEnc,Ext) -> 647 Ctgenmod = list_to_atom(lists:concat(["asn1ct_gen_",per, 648 asn1ct_gen:rt2ct_suffix()])), 649 Atype = 650 case Type of 651 #type{def=#'ObjectClassFieldType'{type=InnerType}} -> 652 InnerType; 653 _ -> 654 asn1ct_gen:get_inner(Type#type.def) 655 end, 656% case asn1ct_gen:get_constraint(Type#type.constraint, 657% tableconstraint_info) of 658% no -> 659% asn1ct_gen:get_inner(Type#type.def); 660% _ -> 661% Type#type.def 662% end, 663 case Ext of 664 {ext,Ep1,_} when Pos >= Ep1 -> 665 emit(["?RT_PER:encode_open_type(dummy,?RT_PER:complete("]); 666 _ -> true 667 end, 668 case Atype of 669 {typefield,_} -> 670 case DynamicEnc of 671 {_LeadingAttrName,Fun} -> 672% case asn1ct_gen:get_constraint(Type#type.constraint, 673% componentrelation) of 674 case (Type#type.def)#'ObjectClassFieldType'.fieldname of 675 {notype,T} -> 676 throw({error,{notype,type_from_object,T}}); 677 {Name,RestFieldNames} when atom(Name) -> 678 emit({"?RT_PER:encode_open_type([],?RT_PER:complete(",nl}), 679 emit({" ",Fun,"(",{asis,Name},", ", 680 Element,", ",{asis,RestFieldNames},")))"}); 681 Other -> 682 throw({asn1,{'internal error',Other}}) 683 end 684 end; 685 {objectfield,PrimFieldName1,PFNList} -> 686 case DynamicEnc of 687 {_LeadingAttrName,Fun} -> 688 emit({"?RT_PER:encode_open_type([]," 689 "?RT_PER:complete(",nl}), 690 emit({" ",Fun,"(",{asis,PrimFieldName1}, 691 ", ",Element,", ",{asis,PFNList},")))"}) 692 end; 693 _ -> 694 CurrMod = get(currmod), 695 case asn1ct_gen:type(Atype) of 696 #'Externaltypereference'{module=Mod,type=EType} when 697 (CurrMod==Mod) -> 698 emit({"'enc_",EType,"'(",Element,")"}); 699 #'Externaltypereference'{module=Mod,type=EType} -> 700 emit({"'",Mod,"':'enc_", 701 EType,"'(",Element,")"}); 702 #typereference{val=Ename} -> 703 emit({"'enc_",Ename,"'(",Element,")"}); 704 {notype,_} -> 705 emit({"'enc_",Atype,"'(",Element,")"}); 706 {primitive,bif} -> 707 EncType = 708 case Atype of 709 {fixedtypevaluefield,_,Btype} -> 710 Btype; 711 _ -> 712 Type 713 end, 714 gen_encode_prim_wrapper(Ctgenmod,per,EncType, 715 false,Element); 716% Ctgenmod:gen_encode_prim(per,EncType, 717% false,Element); 718 'ASN1_OPEN_TYPE' -> 719 case Type#type.def of 720 #'ObjectClassFieldType'{type=OpenType} -> 721 gen_encode_prim_wrapper(Ctgenmod,per, 722 #type{def=OpenType}, 723 false,Element); 724 _ -> 725 gen_encode_prim_wrapper(Ctgenmod,per,Type, 726 false,Element) 727 end; 728% Ctgenmod:gen_encode_prim(per,Type, 729% false,Element); 730 {constructed,bif} -> 731 NewTypename = [Cname|TopType], 732 case {Type#type.tablecinf,DynamicEnc} of 733 {[{objfun,_}|_R],{_,EncFun}} -> 734%% emit({"?RT_PER:encode_open_type([],", 735%% "?RT_PER:complete(",nl}), 736 emit({"'enc_", 737 asn1ct_gen:list2name(NewTypename), 738 "'(",Element,", ",EncFun,")"}); 739 _ -> 740 emit({"'enc_", 741 asn1ct_gen:list2name(NewTypename), 742 "'(",Element,")"}) 743 end 744 end 745 end, 746 case Ext of 747 {ext,Ep2,_} when Pos >= Ep2 -> 748 emit(["))"]); 749 _ -> true 750 end. 751 752gen_dec_components_call(TopType,{CompList,ExtList},MaybeComma,DecInfObj,Ext,NumberOfOptionals) -> 753 %% The type has extensionmarker 754 {Rpos,AccTerm,AccBytes} = 755 gen_dec_components_call1(TopType, CompList, 1, 1, MaybeComma,DecInfObj, 756 noext,[],[],NumberOfOptionals), 757 emit([",",nl,"{Extensions,",{next,bytes},"} = "]), 758 emit(["?RT_PER:getextension(Ext,",{curr,bytes},"),",nl]), 759 asn1ct_name:new(bytes), 760 {_Epos,AccTermE,AccBytesE} = 761 gen_dec_components_call1(TopType,ExtList,Rpos, 1, "",DecInfObj,Ext,[],[],NumberOfOptionals), 762 case ExtList of 763 [] -> true; 764 _ -> emit([",",nl]) 765 end, 766 emit([{next,bytes},"= ?RT_PER:skipextensions(",{curr,bytes},",", 767 length(ExtList)+1,",Extensions)",nl]), 768 asn1ct_name:new(bytes), 769 {AccTerm++AccTermE,AccBytes++AccBytesE}; 770 771gen_dec_components_call(TopType,CompList,MaybeComma,DecInfObj,Ext,NumberOfOptionals) -> 772 %% The type has no extensionmarker 773 {_,AccTerm,AccBytes} = 774 gen_dec_components_call1(TopType, CompList, 1, 1,MaybeComma,DecInfObj,Ext,[],[],NumberOfOptionals), 775 {AccTerm,AccBytes}. 776 777 778gen_dec_components_call1(TopType, 779 [C=#'ComponentType'{name=Cname,typespec=Type,prop=Prop}|Rest], 780 Tpos,OptPos,MaybeComma,DecInfObj,Ext,AccTerm,AccBytes,NumberOfOptionals) -> 781 Pos = case Ext of 782 noext -> Tpos; 783 {ext,Epos,_Enum} -> Tpos - Epos + 1 784 end, 785 emit(MaybeComma), 786%% asn1ct_name:new(term), 787 InnerType = 788 case Type#type.def of 789 #'ObjectClassFieldType'{type=InType} -> 790 InType; 791 Def -> 792 asn1ct_gen:get_inner(Def) 793 end, 794% case asn1ct_gen:get_constraint(Type#type.constraint, 795% tableconstraint_info) of 796% no -> 797% asn1ct_gen:get_inner(Type#type.def); 798% _ -> 799% Type#type.def 800% end, 801 case InnerType of 802 #'Externaltypereference'{type=T} -> 803 emit({nl,"%% attribute number ",Tpos," with type ", 804 T,nl}); 805 IT when tuple(IT) -> 806 emit({nl,"%% attribute number ",Tpos," with type ", 807 element(2,IT),nl}); 808 _ -> 809 emit({nl,"%% attribute number ",Tpos," with type ", 810 InnerType,nl}) 811 end, 812 813 case InnerType of 814 {typefield,_} -> 815 asn1ct_name:new(term), 816 asn1ct_name:new(tmpterm), 817 emit({"{",{curr,tmpterm},", ",{next,bytes},"} = "}); 818 {objectfield,_,_} -> 819 asn1ct_name:new(term), 820 asn1ct_name:new(tmpterm), 821 emit({"{",{curr,tmpterm},", ",{next,bytes},"} = "}); 822 _ -> 823 asn1ct_name:new(term), 824 emit({"{",{curr,term},",",{next,bytes},"} = "}) 825 end, 826 827 NewOptPos = 828 case {Ext,Prop} of 829 {noext,mandatory} -> OptPos; % generate nothing 830 {noext,_} -> 831 Element = io_lib:format("Opt band (1 bsl ~w)",[NumberOfOptionals - OptPos]), 832 emit({"case ",Element," of",nl}), 833 emit({"_Opt",OptPos," when _Opt",OptPos," > 0 ->"}), 834 OptPos+1; 835 _ -> 836 emit(["case Extensions of",nl]), 837 emit(["_ when size(Extensions) >= ",Pos,",element(",Pos,",Extensions) == 1 ->",nl]) 838 end, 839 put(component_type,{true,C}), 840 {TermVar,BytesVar} = gen_dec_line(TopType,Cname,Type,Tpos,DecInfObj,Ext), 841 erase(component_type), 842 case {Ext,Prop} of 843 {noext,mandatory} -> true; % generate nothing 844 {noext,_} -> 845 emit([";",nl,"0 ->"]), 846 gen_dec_component_no_val(TopType,Cname,Type,Prop,Tpos,Ext); 847 _ -> 848 emit([";",nl,"_ ->",nl]), 849 gen_dec_component_no_val(TopType,Cname,Type,Prop,Tpos,Ext) 850 end, 851 case {Ext,Prop} of 852 {noext,mandatory} -> true; % generate nothing 853 {noext,_} -> 854 emit([nl,"end"]); 855 _ -> 856 emit([nl,"end"]) 857 858 end, 859 asn1ct_name:new(bytes), 860 case Rest of 861 [] -> 862 {Pos+1,AccTerm++TermVar,AccBytes++BytesVar}; 863 _ -> 864 emit({com,nl}), 865 gen_dec_components_call1(TopType,Rest,Tpos+1,NewOptPos,"",DecInfObj,Ext, 866 AccTerm++TermVar,AccBytes++BytesVar,NumberOfOptionals) 867 end; 868 869gen_dec_components_call1(_TopType,[],Pos,_OptPos,_,_,_,AccTerm,AccBytes,_NumberOfOptionals) -> 870 {Pos,AccTerm,AccBytes}. 871 872 873%%gen_dec_component_no_val(TopType,Cname,Type,_,Pos,{ext,Ep,Enum}) when Pos >= Ep -> 874%% emit({"{asn1_NOEXTVALUE,",{curr,bytes},"}",nl}); 875gen_dec_component_no_val(_,_,_,{'DEFAULT',DefVal},_,_) -> 876 emit(["{",{asis,DefVal},",",{curr,bytes},"}",nl]); 877gen_dec_component_no_val(_,_,_,'OPTIONAL',_,_) -> 878 emit({"{asn1_NOVALUE,",{curr,bytes},"}",nl}); 879gen_dec_component_no_val(_,_,_,mandatory,_,{ext,_,_}) -> 880 emit({"{asn1_NOVALUE,",{curr,bytes},"}",nl}). 881 882 883gen_dec_line(TopType,Cname,Type,Pos,DecInfObj,Ext) -> 884 Ctgenmod = list_to_atom(lists:concat(["asn1ct_gen_",per, 885 asn1ct_gen:rt2ct_suffix()])), 886 Atype = 887 case Type of 888 #type{def=#'ObjectClassFieldType'{type=InnerType}} -> 889 InnerType; 890 _ -> 891 asn1ct_gen:get_inner(Type#type.def) 892 end, 893% case asn1ct_gen:get_constraint(Type#type.constraint, 894% tableconstraint_info) of 895% no -> 896% asn1ct_gen:get_inner(Type#type.def); 897% _ -> 898% Type#type.def 899% end, 900 BytesVar0 = asn1ct_gen:mk_var(asn1ct_name:curr(bytes)), 901 BytesVar = case Ext of 902 {ext,Ep,_} when Pos >= Ep -> 903 emit(["begin",nl,"{TmpVal",Pos,",Trem",Pos, 904 "}=?RT_PER:decode_open_type(", 905 {curr,bytes},",[]),",nl, 906 "{TmpValx",Pos,",_}="]), 907 io_lib:format("TmpVal~p",[Pos]); 908 _ -> BytesVar0 909 end, 910 SaveBytes = 911 case Atype of 912 {typefield,_} -> 913 case DecInfObj of 914 false -> % This is in a choice with typefield components 915 {Name,RestFieldNames} = 916 (Type#type.def)#'ObjectClassFieldType'.fieldname, 917% asn1ct_gen:get_constraint(Type#type.constraint, 918% tableconstraint_info), 919 asn1ct_name:new(tmpterm), 920 asn1ct_name:new(reason), 921 emit([indent(2),"{",{curr,tmpterm},", ",{next,bytes}, 922 "} = ?RT_PER:decode_open_type(",{curr,bytes}, 923 ", []),",nl]), 924 emit([indent(2),"case (catch ObjFun(", 925 {asis,Name}, 926 ",",{curr,tmpterm},",telltype,", 927 {asis,RestFieldNames},")) of", nl]), 928 emit([indent(4),"{'EXIT',",{curr,reason},"} ->",nl]), 929 emit([indent(6),"exit({'Type not ", 930 "compatible with table constraint', ", 931 {curr,reason},"});",nl]), 932 asn1ct_name:new(tmpterm), 933 emit([indent(4),"{",{curr,tmpterm},", _} ->",nl]), 934 emit([indent(6),"{",Cname,", {",{curr,tmpterm},", ", 935 {next,bytes},"}}",nl]), 936 emit([indent(2),"end"]), 937 []; 938 {"got objfun through args","ObjFun"} -> 939 %% this is when the generated code gots the 940 %% objfun though arguments on function 941 %% invocation. 942 {Name,RestFieldNames} = 943 (Type#type.def)#'ObjectClassFieldType'.fieldname, 944 emit(["?RT_PER:decode_open_type(",{curr,bytes}, 945 ", []),",nl]), 946 emit([{curr,term}," =",nl, 947 " case (catch ObjFun(",{asis,Name},",", 948 {curr,tmpterm},",telltype,", 949 {asis,RestFieldNames},")) of", nl]), 950 emit([" {'EXIT',",{curr,reason},"} ->",nl]), 951 emit([indent(6),"exit({'Type not ", 952 "compatible with table constraint', ", 953 {curr,reason},"});",nl]), 954 asn1ct_name:new(tmpterm), 955 emit([indent(4),"{",{curr,tmpterm},", _} ->",nl]), 956 emit([indent(6),{curr,tmpterm},nl]), 957 emit([indent(2),"end"]), 958 []; 959 _ -> 960 emit({"?RT_PER:decode_open_type(",{curr,bytes}, 961 ", [])"}), 962 RefedFieldName = 963 (Type#type.def)#'ObjectClassFieldType'.fieldname, 964% asn1ct_gen:get_constraint(Type#type.constraint, 965% tableconstraint_info), 966 [{Cname,RefedFieldName, 967 asn1ct_gen:mk_var(asn1ct_name:curr(term)), 968 asn1ct_gen:mk_var(asn1ct_name:curr(tmpterm)), 969 get_components_prop()}] 970 end; 971 {objectfield,PrimFieldName1,PFNList} -> 972 emit({"?RT_PER:decode_open_type(",{curr,bytes},", [])"}), 973 [{Cname,{PrimFieldName1,PFNList}, 974 asn1ct_gen:mk_var(asn1ct_name:curr(term)), 975 asn1ct_gen:mk_var(asn1ct_name:curr(tmpterm)), 976 get_components_prop()}]; 977 _ -> 978 CurrMod = get(currmod), 979 case asn1ct_gen:type(Atype) of 980 #'Externaltypereference'{module=CurrMod,type=EType} -> 981 emit({"'dec_",EType,"'(",BytesVar,",telltype)"}); 982 #'Externaltypereference'{module=Mod,type=EType} -> 983 emit({"'",Mod,"':'dec_",EType,"'(",BytesVar, 984 ",telltype)"}); 985 {primitive,bif} -> 986 case Atype of 987 {fixedtypevaluefield,_,Btype} -> 988 Ctgenmod:gen_dec_prim(per,Btype, 989 BytesVar); 990 _ -> 991 Ctgenmod:gen_dec_prim(per,Type, 992 BytesVar) 993 end; 994 'ASN1_OPEN_TYPE' -> 995 case Type#type.def of 996 #'ObjectClassFieldType'{type=OpenType} -> 997 Ctgenmod:gen_dec_prim(per,#type{def=OpenType}, 998 BytesVar); 999 _ -> 1000 Ctgenmod:gen_dec_prim(per,Type, 1001 BytesVar) 1002 end; 1003 #typereference{val=Dname} -> 1004 emit({"'dec_",Dname,"'(",BytesVar,",telltype)"}); 1005 {notype,_} -> 1006 emit({"'dec_",Atype,"'(",BytesVar,",telltype)"}); 1007 {constructed,bif} -> 1008 NewTypename = [Cname|TopType], 1009 case Type#type.tablecinf of 1010 [{objfun,_}|_R] -> 1011 emit({"'dec_",asn1ct_gen:list2name(NewTypename), 1012 "'(",BytesVar,", telltype, ObjFun)"}); 1013 _ -> 1014 emit({"'dec_",asn1ct_gen:list2name(NewTypename), 1015 "'(",BytesVar,", telltype)"}) 1016 end 1017 end, 1018 case DecInfObj of 1019 {Cname,{_,OSet,UniqueFName,ValIndex}} -> 1020 Term = asn1ct_gen:mk_var(asn1ct_name:curr(term)), 1021 ValueMatch = value_match(ValIndex,Term), 1022 emit({",",nl,"ObjFun = 'getdec_",OSet,"'(", 1023 {asis,UniqueFName},", ",ValueMatch,")"}); 1024 _ -> 1025 ok 1026 end, 1027 [] 1028 end, 1029 case Ext of 1030 {ext,Ep2,_} when Pos >= Ep2 -> 1031 emit([", {TmpValx",Pos,",Trem",Pos,"}",nl,"end"]); 1032 _ -> true 1033 end, 1034 %% Prepare return value 1035 case DecInfObj of 1036 {Cname,ObjSet} -> 1037 {[{ObjSet,Cname,asn1ct_gen:mk_var(asn1ct_name:curr(term))}], 1038 SaveBytes}; 1039 _ -> 1040 {[],SaveBytes} 1041 end. 1042 1043gen_enc_choice(TopType,CompList,Ext) -> 1044 gen_enc_choice_tag(CompList, [], Ext), 1045 emit({com,nl}), 1046 emit({"case element(1,Val) of",nl}), 1047 gen_enc_choice2(TopType, CompList, Ext), 1048 emit({nl,"end"}). 1049 1050gen_enc_choice_tag({C1,C2},_,_) -> 1051 N1 = get_name_list(C1), 1052 N2 = get_name_list(C2), 1053 emit(["?RT_PER:set_choice(element(1,Val),", 1054 {asis,{N1,N2}},", ",{asis,{length(N1),length(N2)}},")"]); 1055gen_enc_choice_tag(C,_,_) -> 1056 N = get_name_list(C), 1057 emit(["?RT_PER:set_choice(element(1,Val),", 1058 {asis,N},", ",{asis,length(N)},")"]). 1059 1060get_name_list(L) -> 1061 get_name_list(L,[]). 1062 1063get_name_list([#'ComponentType'{name=Name}|T], Acc) -> 1064 get_name_list(T,[Name|Acc]); 1065get_name_list([], Acc) -> 1066 lists:reverse(Acc). 1067 1068%gen_enc_choice_tag([H|T],Acc,Ext) when record(H,'ComponentType') -> 1069% gen_enc_choice_tag(T,[H#'ComponentType'.name|Acc],Ext); 1070%gen_enc_choice_tag([H|T],Acc,Ext) -> % skip EXTENSIONMARK 1071% gen_enc_choice_tag(T,Acc,Ext); 1072%gen_enc_choice_tag([],Acc,Ext) -> 1073% Length = length(Acc), 1074% emit({"?RT_PER:set_choice(element(1,Val),",{asis,Length},",", 1075% {asis,lists:reverse(Acc)},",",{asis,Ext},")"}), 1076% Length. 1077 1078gen_enc_choice2(TopType, {L1,L2}, Ext) -> 1079 gen_enc_choice2(TopType, L1 ++ L2, 0, Ext); 1080gen_enc_choice2(TopType, L, Ext) -> 1081 gen_enc_choice2(TopType, L, 0, Ext). 1082 1083gen_enc_choice2(TopType,[H1,H2|T], Pos, Ext) 1084when record(H1,'ComponentType'), record(H2,'ComponentType') -> 1085 Cname = H1#'ComponentType'.name, 1086 Type = H1#'ComponentType'.typespec, 1087 EncObj = 1088% case asn1ct_gen:get_constraint(Type#type.constraint, 1089% tableconstraint_info) of 1090% no -> 1091% false; 1092% _ -> 1093% {no_attr,"ObjFun"} 1094% end, 1095 case asn1ct_gen:get_constraint(Type#type.constraint, 1096 componentrelation) of 1097 no -> false; 1098 _ -> {no_attr,"ObjFun"} 1099 end, 1100 emit({{asis,Cname}," ->",nl}), 1101 gen_enc_line(TopType,Cname,Type,"element(2,Val)", Pos+1,EncObj,Ext), 1102 emit({";",nl}), 1103 gen_enc_choice2(TopType,[H2|T], Pos+1, Ext); 1104gen_enc_choice2(TopType,[H1|T], Pos, Ext) when record(H1,'ComponentType') -> 1105 Cname = H1#'ComponentType'.name, 1106 Type = H1#'ComponentType'.typespec, 1107 EncObj = 1108% case asn1ct_gen:get_constraint(Type#type.constraint, 1109% tableconstraint_info) of 1110% no -> 1111% false; 1112% _ -> 1113% {no_attr,"ObjFun"} 1114% end, 1115 case asn1ct_gen:get_constraint(Type#type.constraint, 1116 componentrelation) of 1117 no -> false; 1118 _ -> {no_attr,"ObjFun"} 1119 end, 1120 emit({{asis,H1#'ComponentType'.name}," ->",nl}), 1121 gen_enc_line(TopType,Cname,Type,"element(2,Val)", Pos+1,EncObj,Ext), 1122 gen_enc_choice2(TopType,T, Pos+1, Ext); 1123gen_enc_choice2(_,[], _, _) -> 1124 true. 1125 1126gen_dec_choice(TopType,CompList,{ext,Pos,NumExt}) -> 1127 emit({"{Ext,",{curr,bytes},"} = ?RT_PER:getbit(Bytes),",nl}), 1128 asn1ct_name:new(bytes), 1129 gen_dec_choice1(TopType,CompList,{ext,Pos,NumExt}); 1130gen_dec_choice(TopType,CompList,noext) -> 1131 gen_dec_choice1(TopType,CompList,noext). 1132 1133gen_dec_choice1(TopType,CompList,noext) -> 1134 emit({"{Choice,",{curr,bytes}, 1135 "} = ?RT_PER:getchoice(",{prev,bytes},",", 1136 length(CompList),", 0),",nl}), 1137 emit({"{Cname,{Val,NewBytes}} = case Choice of",nl}), 1138 gen_dec_choice2(TopType,CompList,noext), 1139 emit({nl,"end,",nl}), 1140 emit({nl,"{{Cname,Val},NewBytes}"}); 1141gen_dec_choice1(TopType,{RootList,ExtList},Ext) -> 1142 NewList = RootList ++ ExtList, 1143 gen_dec_choice1(TopType, NewList, Ext); 1144gen_dec_choice1(TopType,CompList,{ext,ExtPos,ExtNum}) -> 1145 emit({"{Choice,",{curr,bytes}, 1146 "} = ?RT_PER:getchoice(",{prev,bytes},",", 1147 length(CompList)-ExtNum,",Ext ),",nl}), 1148 emit({"{Cname,{Val,NewBytes}} = case Choice + Ext*",ExtPos-1," of",nl}), 1149 gen_dec_choice2(TopType,CompList,{ext,ExtPos,ExtNum}), 1150 emit([";",nl,"_ -> {asn1_ExtAlt, ?RT_PER:decode_open_type(",{curr,bytes},",[])}"]), 1151 emit({nl,"end,",nl}), 1152 emit({nl,"{{Cname,Val},NewBytes}"}). 1153 1154 1155gen_dec_choice2(TopType,L,Ext) -> 1156 gen_dec_choice2(TopType,L,0,Ext). 1157 1158gen_dec_choice2(TopType,[H1,H2|T],Pos,Ext) 1159when record(H1,'ComponentType'), record(H2,'ComponentType') -> 1160 Cname = H1#'ComponentType'.name, 1161 Type = H1#'ComponentType'.typespec, 1162 case Type#type.def of 1163 #'ObjectClassFieldType'{type={typefield,_}} -> 1164 emit({Pos," -> ",nl}), 1165 wrap_gen_dec_line(H1,TopType,Cname,Type,Pos+1,false,Ext), 1166 emit({";",nl}); 1167 _ -> 1168 emit({Pos," -> {",{asis,Cname},",",nl}), 1169 wrap_gen_dec_line(H1,TopType,Cname,Type,Pos+1,false,Ext), 1170 emit({"};",nl}) 1171 end, 1172 gen_dec_choice2(TopType,[H2|T],Pos+1,Ext); 1173gen_dec_choice2(TopType,[H1,_H2|T],Pos,Ext) when record(H1,'ComponentType') -> 1174 gen_dec_choice2(TopType,[H1|T],Pos,Ext); % skip extensionmark 1175gen_dec_choice2(TopType,[H1|T],Pos,Ext) when record(H1,'ComponentType') -> 1176 Cname = H1#'ComponentType'.name, 1177 Type = H1#'ComponentType'.typespec, 1178 case Type#type.def of 1179 #'ObjectClassFieldType'{type={typefield,_}} -> 1180 emit({Pos," -> ",nl}), 1181 wrap_gen_dec_line(H1,TopType,Cname,Type,Pos+1,false,Ext); 1182 _ -> 1183 emit({Pos," -> {",{asis,Cname},",",nl}), 1184 wrap_gen_dec_line(H1,TopType,Cname,Type,Pos+1,false,Ext), 1185 emit("}") 1186 end, 1187 gen_dec_choice2(TopType,[T],Pos+1); 1188gen_dec_choice2(TopType,[_|T],Pos,Ext) -> 1189 gen_dec_choice2(TopType,T,Pos,Ext);% skip extensionmark 1190gen_dec_choice2(_,[],Pos,_) -> 1191 Pos. 1192 1193indent(N) -> 1194 lists:duplicate(N,32). % 32 = space 1195 1196gen_encode_prim_wrapper(CtgenMod,Erule,Cont,DoTag,Value) -> 1197% put(component_type,true), % add more info in component_type 1198 CtgenMod:gen_encode_prim(Erule,Cont,DoTag,Value). 1199% erase(component_type). 1200 1201make_element(I,Val,Cname) -> 1202 case lists:member(optimize,get(encoding_options)) of 1203 false -> 1204 io_lib:format("?RT_PER:cindex(~w,~s,~w)",[I,Val,Cname]); 1205 _ -> 1206 io_lib:format("element(~w,~s)",[I,Val]) 1207 end. 1208 1209wrap_gen_dec_line(C,TopType,Cname,Type,Pos,DIO,Ext) -> 1210 put(component_type,{true,C}), 1211 gen_dec_line(TopType,Cname,Type,Pos,DIO,Ext), 1212 erase(component_type). 1213 1214get_components_prop() -> 1215 case get(component_type) of 1216 undefined -> 1217 mandatory; 1218 {true,#'ComponentType'{prop=Prop}} -> Prop 1219 end. 1220 1221 1222value_match(Index,Value) when atom(Value) -> 1223 value_match(Index,atom_to_list(Value)); 1224value_match([],Value) -> 1225 Value; 1226value_match([{VI,_}|VIs],Value) -> 1227 value_match1(Value,VIs,lists:concat(["element(",VI,","]),1). 1228value_match1(Value,[],Acc,Depth) -> 1229 Acc ++ Value ++ lists:concat(lists:duplicate(Depth,")")); 1230value_match1(Value,[{VI,_}|VIs],Acc,Depth) -> 1231 value_match1(Value,VIs,Acc++lists:concat(["element(",VI,","]),Depth+1). 1232 1233notice_value_match() -> 1234 Module = get(currmod), 1235 put(value_match,{true,Module}). 1236