4
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
4
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
6
6
%% The contents of this file are subject to the Erlang Public License,
7
7
%% Version 1.1, (the "License"); you may not use this file except in
8
8
%% compliance with the License. You should have received a copy of the
9
9
%% Erlang Public License along with this software. If not, it can be
10
10
%% retrieved online at http://www.erlang.org/.
12
12
%% Software distributed under the License is distributed on an "AS IS"
13
13
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
14
%% the License for the specific language governing rights and limitations
15
15
%% under the License.
46
46
asn1ct_name:start(),
47
47
asn1ct_name:new(term),
48
48
asn1ct_name:new(bytes),
49
{CompList,TableConsInfo} =
49
{ExtAddGroup,TmpCompList,TableConsInfo} =
51
#'SEQUENCE'{tablecinf=TCI,components=CL} ->
51
#'SEQUENCE'{tablecinf=TCI,components=CL,extaddgroup=ExtAddGroup0} ->
52
{ExtAddGroup0,CL,TCI};
53
53
#'SET'{tablecinf=TCI,components=CL} ->
57
CompList = case ExtAddGroup of
60
_ when is_integer(ExtAddGroup) ->
61
%% This is a fake SEQUENCE representing an ExtensionAdditionGroup
62
%% Reset the textual order so we get the right
63
%% index of the components
64
[Comp#'ComponentType'{textual_order=undefined}||
58
emit({{var,asn1ct_name:next(val)},
59
70
" = asn1rt_check:transform_to_EXTERNAL1990(",
60
{var,asn1ct_name:curr(val)},"),",nl}),
61
72
asn1ct_name:new(val);
66
77
{[],EmptyCL} when EmptyCL == {[],[],[]};EmptyCL == {[],[]};EmptyCL == [] ->
67
78
emit(["%%Variable setting just to eliminate ",
68
79
"compiler warning for unused vars!",nl,
69
"_Val = ",{var,asn1ct_name:curr(val)},",",nl]);
80
"_Val = ",{curr,val},",",nl]);
71
emit([{var,asn1ct_name:next(val)}," = ?RT_PER:list_to_record("]),
82
emit([{next,val}," = ?RT_PER:list_to_record("]),
72
83
emit(["'",asn1ct_gen:list2rname(Typename),"'"]),
73
emit([", ",{var,asn1ct_name:curr(val)},"),",nl]);
84
emit([", ",{curr,val},"),",nl]);
75
86
Fixoptcall = ",Opt} = ?RT_PER:fixoptionals(",
76
emit({"{",{var,asn1ct_name:next(val)},Fixoptcall,
87
emit({"{",{next,val},Fixoptcall,
77
88
{asis,Optionals},",",length(Optionals),
78
",",{var,asn1ct_name:curr(val)},"),",nl})
89
",",{curr,val},"),",nl})
80
91
asn1ct_name:new(val),
81
Ext = extensible(CompList),
92
Ext = extensible_enc(CompList),
83
94
{ext,_,NumExt} when NumExt > 0 ->
84
emit(["Extensions = ?RT_PER:fixextensions(",{asis,Ext},
85
", ",{curr,val},"),",nl]);
95
case extgroup_pos_and_length(CompList) of
96
{extgrouppos,ExtGroupPos,ExtGroupLen} ->
97
Elements = make_elements(ExtGroupPos+1,
98
"Val1",lists:seq(1,ExtGroupLen)),
100
{next,val}," = case [X || X <- [",Elements,
101
"],X =/= asn1_NOVALUE] of",nl,
102
"[] -> ",{curr,val},";",nl,
103
"_ -> setelement(",{asis,ExtGroupPos+1},",",
105
"{extaddgroup,", Elements,"})",nl,
107
asn1ct_name:new(val);
108
_ -> % no extensionAdditionGroup
111
asn1ct_name:new(tmpval),
112
emit(["Extensions = ?RT_PER:fixextensions(",{asis,Ext},",",
113
{curr,val},"),",nl]);
188
216
#'SEQUENCE'{tablecinf=TCI,components=CL} ->
189
217
{add_textual_order(CL),TCI};
190
218
#'SET'{tablecinf=TCI,components=CL} ->
191
{add_textual_order(CL),TCI}
219
%% {add_textual_order(CL),TCI}
220
{CL,TCI} % the textual order is already taken care of
193
Ext = extensible(CompList),
222
Ext = extensible_dec(CompList),
194
223
MaybeComma1 = case Ext of
195
224
{ext,_Pos,_NumExt} ->
196
225
gen_dec_extension_value("Bytes"),
243
272
{false,false,false}
275
NewCompList = wrap_compList(CompList),
246
276
{AccTerm,AccBytes} =
247
gen_dec_components_call(Erules,Typename,CompList,MaybeComma2,DecObjInf,Ext,length(Optionals)),
277
gen_dec_components_call(Erules,Typename,NewCompList,MaybeComma2,DecObjInf,Ext,length(Optionals)),
248
278
case asn1ct_name:all(term) of
249
279
[] -> emit(MaybeComma2); % no components at all
250
280
_ -> emit({com,nl})
284
314
emit(" {ASN11994Format,");
286
316
emit(["{{'",RecordName,"'"]),
287
mkvlist(textual_order(CompList,asn1ct_name:all(term))),
317
%% CompList is used here because we don't want
318
%% ExtensionAdditionGroups to be wrapped in SEQUENCES when
319
%% we are ordering the fields according to textual order
320
mkvlist(textual_order(to_encoding_order(CompList),asn1ct_name:all(term))),
290
emit({{var,asn1ct_name:curr(bytes)},"}"}),
323
emit({{curr,bytes},"}"}),
291
324
emit({".",nl,nl}).
293
326
textual_order([#'ComponentType'{textual_order=undefined}|_],TermList) ->
295
328
textual_order(CompList,TermList) when is_list(CompList) ->
296
TermTuple = list_to_tuple(TermList), %% ['Term1','Term2',...'TermN']
297
%% OrderList is ordered by canonical order of tags
298
TmpTuple = TermTuple,
299
OrderList = [Ix||#'ComponentType'{textual_order=Ix} <- CompList],
300
Fun = fun(X,{Tpl,Ix}) ->
302
{setelement(X,Tpl,element(Ix,TermTuple)),Ix+1}
304
{Ret,_} = lists:foldl(Fun,{TmpTuple,1},OrderList),
305
%% io:format("TermTuple: ~p~nOrderList: ~p~nRet: ~p~n",[TermTuple,OrderList,tuple_to_list(Ret)]),
329
OrderList = [Ix||#'ComponentType'{textual_order=Ix} <- CompList],
331
lists:sort(lists:zip(OrderList,
332
lists:sublist(TermList,length(OrderList))))];
333
%% sublist is just because Termlist can sometimes be longer than
334
%% OrderList, which it really shouldn't
307
335
textual_order({Root,Ext},TermList) ->
308
textual_order(Root ++ Ext,TermList);
309
textual_order({Root1,Ext,Root2},TermList) ->
310
textual_order(Root1 ++ Ext ++ Root2, TermList).
336
textual_order(Root ++ Ext,TermList).
312
338
to_textual_order({Root,Ext}) ->
313
339
{to_textual_order(Root),Ext};
561
extensible(CompList) when is_list(CompList) ->
563
extensible({RootList,ExtList}) ->
564
{ext,length(RootList)+1,length(ExtList)};
565
extensible({Rl1,Ext,_Rl2}) ->
566
{ext,length(Rl1)+1,length(Ext)}.
588
extensible_dec(CompList) when is_list(CompList) ->
590
extensible_dec({RootList,ExtList}) ->
591
{ext,length(RootList)+1,ext_length(ExtList)};
592
extensible_dec({Rl1,Ext,Rl2}) ->
593
{ext,length(Rl1)+length(Rl2)+1,ext_length(Ext)}.
595
extensible_enc(CompList) when is_list(CompList) ->
597
extensible_enc({RootList,ExtList}) ->
598
{ext,length(RootList)+1,ext_length(ExtList)};
599
extensible_enc({Rl1,Ext,_Rl2}) ->
600
{ext,length(Rl1)+1,ext_length(Ext)}.
602
ext_length(ExtList) -> ext_length(ExtList,normal,0).
603
ext_length([{'ExtensionAdditionGroup',_Num}|T],_,Acc)->
604
ext_length(T,group,Acc);
605
ext_length(['ExtensionAdditionGroupEnd'|T],group,Acc) ->
606
ext_length(T,normal,Acc+1);
607
ext_length([#'ComponentType'{}|T],State=group,Acc) ->
608
ext_length(T,State,Acc);
609
ext_length([#'ComponentType'{}|T],State=normal,Acc) ->
610
ext_length(T,State,Acc+1);
611
ext_length([],_,Acc) ->
614
extgroup_pos_and_length(CompList) when is_list(CompList) ->
616
extgroup_pos_and_length({RootList,ExtList}) ->
617
extgrouppos(ExtList,length(RootList)+1);
618
extgroup_pos_and_length({Rl1,Ext,_Rl2}) ->
619
extgrouppos(Ext,length(Rl1)+1).
621
extgrouppos([{'ExtensionAdditionGroup',_Num}|T],Pos) ->
622
extgrouppos(T,Pos,0);
623
extgrouppos([_|T],Pos) ->
624
extgrouppos(T,Pos+1);
628
extgrouppos(['ExtensionAdditionGroupEnd'|_T],Pos,Len) ->
629
{extgrouppos,Pos,Len};
630
extgrouppos([_|T],Pos,Len) ->
631
extgrouppos(T,Pos,Len+1).
568
635
gen_dec_extension_value(_) ->
569
636
emit({"{Ext,",{next,bytes},"} = ?RT_PER:getext(",{curr,bytes},")"}),
574
641
%% there are optional components, start with 2 because first element
575
642
%% is the record name
577
optionals({L1,_Ext,L2}) -> optionals(L1++L2,[],2);
644
optionals({L1,Ext,L2}) ->
645
Opt1 = optionals(L1,[],2),
646
ExtComps = length([C||C = #'ComponentType'{}<-Ext]),
647
Opt2 = optionals(L2,[],2+length(L1)+ExtComps),
578
649
optionals({L,_Ext}) -> optionals(L,[],2);
579
650
optionals(L) -> optionals(L,[],2).
629
707
{NewExt,Num2} = add_textual_order1(Ext,Num1),
630
708
{NewR2,_} = add_textual_order1(R2,Num2),
631
709
{NewR1,NewExt,NewR2}.
632
add_textual_order1(Cs=[#'ComponentType'{textual_order=Int}|_],I)
633
when is_integer(Int) ->
710
%%add_textual_order1(Cs=[#'ComponentType'{textual_order=Int}|_],I)
711
%% when is_integer(Int) ->
635
713
add_textual_order1(Cs,NumIn) ->
636
lists:mapfoldl(fun(C,Num) ->
714
lists:mapfoldl(fun(C=#'ComponentType'{},Num) ->
637
715
{C#'ComponentType'{textual_order=Num},
642
722
gen_enc_components_call(Erule,TopType,{Root1,ExtList,Root2},MaybeComma,DynamicEnc,Ext) ->
643
Rpos = gen_enc_components_call1(Erule,TopType,Root1,1,MaybeComma,DynamicEnc,noext),
645
{ext,_,ExtNum} when ExtNum > 0 ->
650
Rpos2 = gen_enc_components_call1(Erule,TopType,ExtList,Rpos,MaybeComma,DynamicEnc,Ext),
651
gen_enc_components_call1(Erule,TopType,Root2,Rpos2,MaybeComma,DynamicEnc,noext);
723
gen_enc_components_call(Erule,TopType,{Root1++Root2,ExtList},MaybeComma,DynamicEnc,Ext);
652
724
gen_enc_components_call(Erule,TopType,{CompList,ExtList},MaybeComma,DynamicEnc,Ext) ->
653
725
%% The type has extensionmarker
654
726
Rpos = gen_enc_components_call1(Erule,TopType,CompList,1,MaybeComma,DynamicEnc,noext),
661
733
%handle extensions
662
gen_enc_components_call1(Erule,TopType,ExtList,Rpos,MaybeComma,DynamicEnc,Ext);
734
NewExtList = wrap_extensionAdditionGroups(ExtList),
735
gen_enc_components_call1(Erule,TopType,NewExtList,Rpos,MaybeComma,DynamicEnc,Ext);
663
736
gen_enc_components_call(Erule,TopType, CompList, MaybeComma, DynamicEnc, Ext) ->
664
737
%% The type has no extensionmarker
665
738
gen_enc_components_call1(Erule,TopType,CompList,1,MaybeComma,DynamicEnc,Ext).
708
781
gen_enc_component_default(Erule,TopType,Cname,Type,Pos,DynamicEnc,Ext,DefaultVal) ->
709
Element = make_element(Pos+1,"Val1",Cname),
782
Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val)),Cname),
710
783
emit({"case ",Element," of",nl}),
711
784
% emit({"asn1_DEFAULT -> [];",nl}),
712
785
emit({"DFLT when DFLT == asn1_DEFAULT; DFLT == ",{asis,DefaultVal}," -> [];",nl}),
719
792
NextElement = asn1ct_gen:mk_var(asn1ct_name:curr(tmpval)),
720
793
gen_enc_line(Erule,TopType,Cname,Type,NextElement, Pos,DynamicEnc,Ext),
721
794
emit({nl,"end"}).
796
gen_enc_component_optional(Erule,TopType,Cname,
797
Type=#type{def=#'SEQUENCE'{
799
components=_ExtGroupCompList}},
800
Pos,DynamicEnc,Ext) when is_integer(Number) ->
802
Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val)),Cname),
803
emit({"case ",Element," of",nl}),
805
emit({"asn1_NOVALUE -> [];",nl}),
806
asn1ct_name:new(tmpval),
807
emit({{curr,tmpval}," ->",nl}),
808
InnerType = asn1ct_gen:get_inner(Type#type.def),
809
emit({nl,"%% attribute number ",Pos," with type ",
811
NextElement = asn1ct_gen:mk_var(asn1ct_name:curr(tmpval)),
812
gen_enc_line(Erule,TopType,Cname,Type,NextElement, Pos,DynamicEnc,Ext),
722
814
gen_enc_component_optional(Erule,TopType,Cname,Type,Pos,DynamicEnc,Ext) ->
723
Element = make_element(Pos+1,"Val1",Cname),
815
Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val)),Cname),
724
816
emit({"case ",Element," of",nl}),
726
818
emit({"asn1_NOVALUE -> [];",nl}),
836
928
gen_dec_components_call(Erule,TopType,{Root1,ExtList,Root2},MaybeComma,DecInfObj,Ext,NumberOfOptionals) ->
837
%% The type has extensionmarker
838
OptTable = create_optionality_table(Root1 ++ Root2),
839
{Rpos,AccTerm,AccBytes} =
840
gen_dec_components_call1(Erule,TopType, Root1, 1, OptTable,
841
MaybeComma,DecInfObj, noext,[],[],
843
emit([",",nl,"{Extensions,",{next,bytes},"} = "]),
844
emit(["?RT_PER:getextension(Ext,",{curr,bytes},"),",nl]),
845
asn1ct_name:new(bytes),
846
{Epos,AccTermE,AccBytesE} =
847
gen_dec_components_call1(Erule,TopType,ExtList,Rpos, OptTable, "",
848
DecInfObj,Ext,[],[],NumberOfOptionals),
853
emit([{next,bytes},"= ?RT_PER:skipextensions(",{curr,bytes},",",
854
length(ExtList)+1,",Extensions),",nl]),
855
asn1ct_name:new(bytes),
856
{_RPos2,AccTerm2,AccBytes2} =
857
gen_dec_components_call1(Erule,TopType,Root2,Epos,OptTable,
858
"",DecInfObj,noext,[],[],NumberOfOptionals),
859
{AccTerm++AccTermE++AccTerm2,AccBytes++AccBytesE++AccBytes2};
929
gen_dec_components_call(Erule,TopType,{Root1++Root2,ExtList},MaybeComma,DecInfObj,Ext,NumberOfOptionals);
860
930
gen_dec_components_call(Erule,TopType,{CompList,ExtList},MaybeComma,
861
931
DecInfObj,Ext,NumberOfOptionals) ->
862
932
%% The type has extensionmarker
868
938
emit([",",nl,"{Extensions,",{next,bytes},"} = "]),
869
939
emit(["?RT_PER:getextension(Ext,",{curr,bytes},"),",nl]),
870
940
asn1ct_name:new(bytes),
941
NewExtList = wrap_extensionAdditionGroups(ExtList),
871
942
{_Epos,AccTermE,AccBytesE} =
872
gen_dec_components_call1(Erule,TopType,ExtList,Rpos, OptTable,
943
gen_dec_components_call1(Erule,TopType,NewExtList,Rpos, OptTable,
873
944
"",DecInfObj,Ext,[],[],NumberOfOptionals),
942
1013
asn1ct_name:new(tmpterm),
943
1014
emit({"{",{curr,tmpterm},", ",{next,bytes},"} = "});
945
asn1ct_name:new(term),
946
emit({"{",{curr,term},",",{next,bytes},"} = "})
1017
#type{def=#'SEQUENCE'{
1018
extaddgroup=Number1,
1019
components=ExtGroupCompList1}} when is_integer(Number1)->
1021
emit_extaddgroupTerms(term,ExtGroupCompList1),
1024
asn1ct_name:new(term),
1025
emit({"{",{curr,term}})
1027
emit({",",{next,bytes},"} = "})
949
1030
case {Ext,Prop,is_optimized(Erule)} of
967
1048
{noext,mandatory} -> true; % generate nothing
969
1050
emit([";",nl,"0 ->"]),
970
gen_dec_component_no_val(TopType,Cname,Type,Prop,Tpos,Ext),
1052
gen_dec_component_no_val(Ext,Prop),
1053
emit({",",{curr,bytes},"}",nl}),
971
1054
emit([nl,"end"]);
973
1056
emit([";",nl,"_ ->",nl]),
974
gen_dec_component_no_val(TopType,Cname,Type,Prop,Tpos,Ext),
1059
#type{def=#'SEQUENCE'{
1060
extaddgroup=Number2,
1061
components=ExtGroupCompList2}} when is_integer(Number2)->
1062
emit({"{extAddGroup,"}),
1063
gen_dec_extaddGroup_no_val(Ext,ExtGroupCompList2),
1066
gen_dec_component_no_val(Ext,Prop)
1068
emit({",",{curr,bytes},"}",nl}),
975
1069
emit([nl,"end"])
977
1071
asn1ct_name:new(bytes),
988
1082
gen_dec_components_call1(_,_TopType,[],Pos,_OptTable,_,_,_,AccTerm,AccBytes,_NumberOfOptionals) ->
989
1083
{Pos,AccTerm,AccBytes}.
1085
gen_dec_extaddGroup_no_val(Ext,[#'ComponentType'{prop=Prop}])->
1086
gen_dec_component_no_val(Ext,Prop),
1088
gen_dec_extaddGroup_no_val(Ext,[#'ComponentType'{prop=Prop}|Rest])->
1089
gen_dec_component_no_val(Ext,Prop),
1091
gen_dec_extaddGroup_no_val(Ext,Rest);
1092
gen_dec_extaddGroup_no_val(_, []) ->
992
gen_dec_component_no_val(_,_,_,{'DEFAULT',DefVal},_,_) ->
993
emit(["{",{asis,DefVal},",",{curr,bytes},"}",nl]);
994
gen_dec_component_no_val(_,_,_,'OPTIONAL',_,_) ->
995
emit({"{asn1_NOVALUE,",{curr,bytes},"}",nl});
996
gen_dec_component_no_val(_,_,_,mandatory,_,{ext,_,_}) ->
997
emit({"{asn1_NOVALUE,",{curr,bytes},"}",nl}).
1095
gen_dec_component_no_val(_,{'DEFAULT',DefVal}) ->
1096
emit([{asis,DefVal}]);
1097
gen_dec_component_no_val(_,'OPTIONAL') ->
1098
emit({"asn1_NOVALUE"});
1099
gen_dec_component_no_val({ext,_,_},mandatory) ->
1100
emit({"asn1_NOVALUE"}).
1000
1103
gen_dec_line(Erule,TopType,Cname,Type,Pos,DecInfObj,Ext,Prop) ->
1192
1295
N2 = get_name_list(C2),
1193
1296
emit(["?RT_PER:set_choice(element(1,Val),",
1194
1297
{asis,{N1,N2}},", ",{asis,{length(N1),length(N2)}},")"]);
1299
gen_enc_choice_tag({C1,C2,C3},_,_) ->
1300
N1 = get_name_list(C1),
1301
N2 = get_name_list(C2),
1302
N3 = get_name_list(C3),
1304
emit(["?RT_PER:set_choice(element(1,Val),",
1305
{asis,{Root,N2}},", ",{asis,{length(Root),length(N2)}},")"]);
1195
1306
gen_enc_choice_tag(C,_,_) ->
1196
1307
N = get_name_list(C),
1197
1308
emit(["?RT_PER:set_choice(element(1,Val),",
1209
1320
gen_enc_choice2(Erule,TopType, {L1,L2}, Ext) ->
1210
1321
gen_enc_choice2(Erule,TopType, L1 ++ L2, 0, Ext);
1322
gen_enc_choice2(Erule,TopType, {L1,L2,L3}, Ext) ->
1323
gen_enc_choice2(Erule,TopType, L1 ++ L3 ++ L2, 0, Ext);
1211
1324
gen_enc_choice2(Erule,TopType, L, Ext) ->
1212
1325
gen_enc_choice2(Erule,TopType, L, 0, Ext).
1279
1392
gen_dec_choice1(Erule,TopType,{RootList,ExtList},Ext) ->
1280
1393
NewList = RootList ++ ExtList,
1281
1394
gen_dec_choice1(Erule,TopType, NewList, Ext);
1395
gen_dec_choice1(Erule,TopType,{RootList,ExtList,RootList2},Ext) ->
1396
NewList = RootList ++ RootList2 ++ ExtList,
1397
gen_dec_choice1(Erule,TopType, NewList, Ext);
1282
1398
gen_dec_choice1(Erule,TopType,CompList,{ext,ExtPos,ExtNum}) ->
1283
1399
emit({"{Choice,",{curr,bytes},
1284
1400
"} = ?RT_PER:getchoice(",{prev,bytes},",",
1347
1463
CtgenMod:gen_encode_prim(Erule,Cont,DoTag,Value).
1348
1464
% erase(component_type).
1466
make_elements(I,Val,ExtCnames) ->
1467
make_elements(I,Val,ExtCnames,[]).
1469
make_elements(I,Val,[ExtCname],Acc)-> % the last one, no comma needed
1470
Element = make_element(I,Val,ExtCname),
1471
make_elements(I+1,Val,[],[Element|Acc]);
1472
make_elements(I,Val,[ExtCname|Rest],Acc)->
1473
Element = make_element(I,Val,ExtCname),
1474
make_elements(I+1,Val,Rest,[", ",Element|Acc]);
1475
make_elements(_I,_,[],Acc) ->
1350
1478
make_element(I,Val,Cname) ->
1351
1479
case tuple_notation_allowed() of
1355
1483
io_lib:format("element(~w,~s)",[I,Val])
1486
emit_extaddgroupTerms(VarSeries,[_]) ->
1487
asn1ct_name:new(VarSeries),
1488
emit({curr,VarSeries}),
1490
emit_extaddgroupTerms(VarSeries,[_|Rest]) ->
1491
asn1ct_name:new(VarSeries),
1492
emit({{curr,VarSeries},","}),
1493
emit_extaddgroupTerms(VarSeries,Rest);
1494
emit_extaddgroupTerms(_,[]) ->
1496
wrap_compList({Root1,Ext,Root2}) ->
1497
{Root1,wrap_extensionAdditionGroups(Ext),Root2};
1498
wrap_compList({Root1,Ext}) ->
1499
{Root1,wrap_extensionAdditionGroups(Ext)};
1500
wrap_compList(CompList) ->
1502
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1503
%% Will convert all componentTypes following 'ExtensionAdditionGroup'
1504
%% up to the matching 'ExtensionAdditionGroupEnd' into one componentType
1505
%% of type SEQUENCE with the componentTypes as components
1507
wrap_extensionAdditionGroups(ExtCompList) ->
1508
wrap_extensionAdditionGroups(ExtCompList,[],0).
1510
wrap_extensionAdditionGroups([{'ExtensionAdditionGroup',_Number}|Rest],Acc,0) ->
1512
[#'ComponentType'{textual_order=TextPos}|_],
1513
['ExtensionAdditionGroupEnd'|Rest2]} =
1514
lists:splitwith(fun(#'ComponentType'{}) -> true;
1518
wrap_extensionAdditionGroups(Rest2,
1520
name='ExtAddGroup', % FIXME: handles ony one ExtAddGroup
1521
typespec=#type{def=#'SEQUENCE'{
1522
extaddgroup=1,% FIXME: handles only one
1523
components=ExtGroupCompList}},
1524
textual_order = TextPos,
1525
prop='OPTIONAL'}|Acc],length(ExtGroupCompList)-1);
1526
wrap_extensionAdditionGroups([H=#'ComponentType'{textual_order=Tord}|T],Acc,ExtAddGroupDiff) when is_integer(Tord) ->
1527
wrap_extensionAdditionGroups(T,[H#'ComponentType'{
1528
textual_order=Tord - ExtAddGroupDiff}|Acc],ExtAddGroupDiff);
1529
wrap_extensionAdditionGroups([H|T],Acc,ExtAddGroupDiff) ->
1530
wrap_extensionAdditionGroups(T,[H|Acc],ExtAddGroupDiff);
1531
wrap_extensionAdditionGroups([],Acc,_) ->
1358
1535
tuple_notation_allowed() ->
1359
1536
Options = get(encoding_options),
1360
1537
not (lists:member(optimize,Options) orelse lists:member(uper_bin,Options)).