~clint-fewbar/ubuntu/precise/erlang/merge-15b

« back to all changes in this revision

Viewing changes to lib/dialyzer/test/r9c_SUITE_data/src/asn1/asn1ct_constructed_ber_bin_v2.erl

  • Committer: Package Import Robot
  • Author(s): Sergei Golovan
  • Date: 2011-12-15 19:20:10 UTC
  • mfrom: (1.1.18) (3.5.15 sid)
  • mto: (3.5.16 sid)
  • mto: This revision was merged to the branch mainline in revision 33.
  • Revision ID: package-import@ubuntu.com-20111215192010-jnxcfe3tbrpp0big
Tags: 1:15.b-dfsg-1
* New upstream release.
* Upload to experimental because this release breaks external drivers
  API along with ABI, so several applications are to be fixed.
* Removed SSL patch because the old SSL implementation is removed from
  the upstream distribution.
* Removed never used patch which added native code to erlang beam files.
* Removed the erlang-docbuilder binary package because the docbuilder
  application was dropped by upstream.
* Documented dropping ${erlang-docbuilder:Depends} substvar in
  erlang-depends(1) manpage.
* Made erlang-base and erlang-base-hipe provide virtual package
  erlang-abi-15.b (the number means the first erlang version, which
  provides current ABI).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
%% ``The contents of this file are subject to the Erlang Public License,
 
2
%% Version 1.1, (the "License"); you may not use this file except in
 
3
%% compliance with the License. You should have received a copy of the
 
4
%% Erlang Public License along with this software. If not, it can be
 
5
%% retrieved via the world wide web at http://www.erlang.org/.
 
6
%%
 
7
%% Software distributed under the License is distributed on an "AS IS"
 
8
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 
9
%% the License for the specific language governing rights and limitations
 
10
%% under the License.
 
11
%%
 
12
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
 
13
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
 
14
%% AB. All Rights Reserved.''
 
15
%%
 
16
%%     $Id: asn1ct_constructed_ber_bin_v2.erl,v 1.1 2008/12/17 09:53:29 mikpe Exp $
 
17
%%
 
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
 
 
58
gen_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
 
 
172
gen_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
 
 
277
gen_dec_postponed_decs(_,[]) ->
 
278
    emit(nl);
 
279
gen_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
 
 
312
emit_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
 
 
322
gen_encode_set(Erules,Typename,D) when record(D,type) ->
 
323
    gen_encode_sequence(Erules,Typename,D).
 
324
 
 
325
gen_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
 
 
433
gen_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
 
 
452
gen_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
 
 
490
gen_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
 
 
525
gen_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
 
 
536
gen_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
 
 
555
gen_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
 
 
571
gen_enc_sequence_call(_Erules,_TopType,[],_Num,_,_) ->
 
572
        true.
 
573
 
 
574
%%============================================================================
 
575
%%  Decode SEQUENCE
 
576
%%
 
577
%%============================================================================
 
578
 
 
579
gen_dec_sequence_call(Erules,TopType,CompList,Ext,DecObjInf) ->
 
580
    gen_dec_sequence_call1(Erules,TopType, CompList, 1, Ext,DecObjInf,[],[]).
 
581
 
 
582
 
 
583
gen_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
 
 
597
gen_dec_sequence_call1(_Erules,_TopType,[],1,_,_,_,_) ->
 
598
    no_terms.
 
599
 
 
600
 
 
601
%%----------------------------
 
602
%%SEQUENCE mandatory
 
603
%%----------------------------
 
604
 
 
605
gen_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
 
 
636
emit_term_tlv({'DEFAULT',_},InnerType,DecObjInf) ->
 
637
    emit_term_tlv(opt_or_def,InnerType,DecObjInf);
 
638
emit_term_tlv('OPTIONAL',InnerType,DecObjInf) ->
 
639
    emit_term_tlv(opt_or_def,InnerType,DecObjInf);
 
640
emit_term_tlv(Prop,{typefield,_},DecObjInf) ->
 
641
    emit_term_tlv(Prop,type_or_object_field,DecObjInf);
 
642
emit_term_tlv(Prop,{objectfield,_,_},DecObjInf) ->
 
643
    emit_term_tlv(Prop,type_or_object_field,DecObjInf);
 
644
emit_term_tlv(opt_or_def,type_or_object_field,_) ->
 
645
    asn1ct_name:new(tmpterm),
 
646
    emit(["{",{curr,tmpterm},",",{curr,tlv},"} = "]);
 
647
emit_term_tlv(opt_or_def,_,_) ->
 
648
    emit(["{",{curr,term},",",{curr,tlv},"} = "]);
 
649
emit_term_tlv(_,type_or_object_field,false) ->
 
650
     emit(["[",{curr,v},"|",{curr,tlv},"] = ",{prev,tlv},", ",nl,
 
651
          {curr,term}," = "]);
 
652
emit_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}," = "]);
 
656
emit_term_tlv(mandatory,_,_) ->
 
657
    emit(["[",{curr,v},"|",{curr,tlv},"] = ",{prev,tlv},", ",nl,
 
658
          {curr,term}," = "]).
 
659
 
 
660
 
 
661
gen_dec_set_cases(_Erules,_TopType,[],Pos) ->
 
662
    Pos;
 
663
gen_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
 
 
703
gen_enc_choice(Erules,TopType,Tag,CompList,_Ext) ->
 
704
    gen_enc_choice1(Erules,TopType,Tag,CompList,_Ext).
 
705
 
 
706
gen_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
 
 
715
gen_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
 
 
760
gen_enc_choice2(_Erules,_TopType,[])  ->
 
761
    true.
 
762
 
 
763
 
 
764
 
 
765
 
 
766
%%--------------------------------------------
 
767
%%  Decode CHOICE
 
768
%%--------------------------------------------
 
769
 
 
770
gen_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
 
 
797
gen_dec_choice_cases(_Erules,_TopType, []) ->
 
798
    ok;
 
799
gen_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
 
 
847
gen_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);
 
855
gen_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
 
 
860
gen_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
 
 
963
gen_optormand_case(mandatory,_Erules,_TopType,_Cname,_Type,_InnerType,_WhatKind,
 
964
                   _Element) ->
 
965
    ok;
 
966
gen_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)]);
 
972
gen_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
 
 
1003
gen_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
            %% choosen 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
 
 
1106
gen_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
    [];
 
1134
gen_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}];
 
1142
gen_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}];
 
1146
gen_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
    [].
 
1162
gen_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;
 
1179
gen_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;
 
1197
gen_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
 
 
1267
indent(N) ->
 
1268
    lists:duplicate(N,32). % 32 = space
 
1269
 
 
1270
mkcindexlist([H,T1|T], Sep) -> % Sep is a string e.g ", " or "+ "
 
1271
    emit(["Cindex",H,Sep]),
 
1272
    mkcindexlist([T1|T], Sep);
 
1273
mkcindexlist([H|T], Sep) ->
 
1274
    emit(["Cindex",H]),
 
1275
    mkcindexlist(T, Sep);
 
1276
mkcindexlist([], _) ->
 
1277
    true.
 
1278
 
 
1279
mkcindexlist(L) ->
 
1280
    mkcindexlist(L,", ").
 
1281
 
 
1282
 
 
1283
mkvlist([H,T1|T], Sep) -> % Sep is a string e.g ", " or "+ "
 
1284
    emit([{var,H},Sep]),
 
1285
    mkvlist([T1|T], Sep);
 
1286
mkvlist([H|T], Sep) ->
 
1287
    emit([{var,H}]),
 
1288
    mkvlist(T, Sep);
 
1289
mkvlist([], _) ->
 
1290
    true.
 
1291
 
 
1292
mkvlist(L) ->
 
1293
    mkvlist(L,", ").
 
1294
 
 
1295
mkvplus(L) ->
 
1296
    mkvlist(L," + ").
 
1297
 
 
1298
extensible(CompList) when list(CompList) ->
 
1299
    noext;
 
1300
extensible({RootList,ExtList}) ->
 
1301
    {ext,length(RootList)+1,length(ExtList)}.
 
1302
 
 
1303
 
 
1304
print_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
 
 
1327
mkfuncname(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
 
 
1341
empty_lb(ber) ->
 
1342
    "[]";
 
1343
empty_lb(ber_bin) ->
 
1344
    "<<>>";
 
1345
empty_lb(ber_bin_v2) ->
 
1346
    "<<>>".
 
1347
 
 
1348
value_match(Index,Value) when atom(Value) ->
 
1349
    value_match(Index,atom_to_list(Value));
 
1350
value_match([],Value) ->
 
1351
    Value;
 
1352
value_match([{VI,_}|VIs],Value) ->
 
1353
    value_match1(Value,VIs,lists:concat(["element(",VI,","]),1).
 
1354
value_match1(Value,[],Acc,Depth) ->
 
1355
    Acc ++ Value ++ lists:concat(lists:duplicate(Depth,")"));
 
1356
value_match1(Value,[{VI,_}|VIs],Acc,Depth) ->
 
1357
    value_match1(Value,VIs,Acc++lists:concat(["element(",VI,","]),Depth+1).