1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
23 * Szabo, Janos Zoltan – initial implementation
26 ******************************************************************************/
28 #include "datatypes.h"
29 #include "../common/memory.h"
35 #include "ttcn3/compiler.h"
37 static void defEmptyRecordClass(const struct_def
*sdef
,
38 output_struct
*output
);
40 static void defEmptyRecordTemplate(const char *name
, const char *dispname
,
41 output_struct
*output
);
43 /** this is common code for both empty and non-empty cases, called from
44 * both functions for template generation */
45 static void defCommonRecordTemplate(const char *name
,
46 char **def
, char **src
);
48 /** code generation for original runtime */
49 static void defRecordClass1(const struct_def
*sdef
, output_struct
*output
);
50 static void defRecordTemplate1(const struct_def
*sdef
, output_struct
*output
);
51 /** code generation for alternative runtime (TITAN_RUNTIME_2) */
52 static void defRecordClass2(const struct_def
*sdef
, output_struct
*output
);
53 static void defRecordTemplate2(const struct_def
*sdef
, output_struct
*output
);
55 void defRecordClass(const struct_def
*sdef
, output_struct
*output
)
57 if (use_runtime_2
) defRecordClass2(sdef
, output
);
58 else defRecordClass1(sdef
, output
);
61 void defRecordTemplate(const struct_def
*sdef
, output_struct
*output
)
63 if (use_runtime_2
) defRecordTemplate2(sdef
, output
);
64 else defRecordTemplate1(sdef
, output
);
67 struct raw_option_struct
{
68 boolean lengthto
; /* indicates whether this field contains a length */
69 int lengthof
; /* how many length indicators this field counted in */
70 int *lengthoffield
; /* the list of length indicator field indices */
76 boolean delayed_decode
; /* indicates whether the field has to be decoded
77 out of order (later) */
78 int nof_dependent_fields
; /* list of fields that are to be decoded */
79 int *dependent_fields
; /* after this field */
82 static char *genRawFieldDecodeLimit(char *src
, const struct_def
*sdef
,
83 int i
, const struct raw_option_struct
*raw_options
);
85 static char *genRawDecodeRecordField(char *src
, const struct_def
*sdef
,
86 int i
, const struct raw_option_struct
*raw_options
, boolean delayed_decode
,
89 static void set_raw_options(const struct_def
*sdef
,
90 struct raw_option_struct
*raw_options
, boolean
* haslengthto
,
91 boolean
* haspointer
, boolean
* hascrosstag
, boolean
* has_ext_bit
);
93 static char *generate_raw_coding(char *src
,
94 const struct_def
*sdef
, struct raw_option_struct
*raw_options
,
95 boolean haspointer
, boolean hascrosstag
, boolean has_ext_bit
);
96 static char *generate_raw_coding_negtest(char *src
,
97 const struct_def
*sdef
, struct raw_option_struct
*raw_options
);
99 void set_raw_options(const struct_def
*sdef
,
100 struct raw_option_struct
*raw_options
, boolean
*haslengthto
,
101 boolean
*haspointer
, boolean
*hascrosstag
, boolean
*has_ext_bit
)
104 for (i
= 0; i
< sdef
->nElements
; i
++) {
105 raw_options
[i
].lengthto
= FALSE
;
106 raw_options
[i
].lengthof
= 0;
107 raw_options
[i
].lengthoffield
= NULL
;
108 raw_options
[i
].pointerto
= FALSE
;
109 raw_options
[i
].pointerof
= 0;
110 raw_options
[i
].ptrbase
= FALSE
;
111 raw_options
[i
].extbitgroup
= 0;
112 raw_options
[i
].tag_type
= 0;
113 raw_options
[i
].delayed_decode
= FALSE
;
114 raw_options
[i
].nof_dependent_fields
= 0;
115 raw_options
[i
].dependent_fields
= NULL
;
117 *haslengthto
= FALSE
;
119 *hascrosstag
= FALSE
;
120 *has_ext_bit
= sdef
->hasRaw
&& sdef
->raw
.extension_bit
!=XDEFNO
&&
121 sdef
->raw
.extension_bit
!=XDEFDEFAULT
;
122 for(i
=0;i
<sdef
->nElements
;i
++){
123 if(sdef
->elements
[i
].hasRaw
&&
124 sdef
->elements
[i
].raw
.crosstaglist
.nElements
){
129 if(sdef
->hasRaw
){ /* fill tag_type. 0-No tag, >0 index of the tag + 1 */
130 for(i
=0;i
<sdef
->raw
.taglist
.nElements
;i
++){
131 raw_options
[sdef
->raw
.taglist
.list
[i
].fieldnum
].tag_type
= i
+1;
133 for(i
=0;i
<sdef
->raw
.ext_bit_goup_num
;i
++){
135 for(k
=sdef
->raw
.ext_bit_groups
[i
].from
;
136 k
<=sdef
->raw
.ext_bit_groups
[i
].to
;k
++)
137 raw_options
[k
].extbitgroup
=i
+1;
140 for(i
=0;i
<sdef
->nElements
;i
++){
141 if (sdef
->elements
[i
].hasRaw
&& sdef
->elements
[i
].raw
.lengthto_num
> 0) {
144 raw_options
[i
].lengthto
= TRUE
;
145 for(j
= 0; j
< sdef
->elements
[i
].raw
.lengthto_num
; j
++) {
146 int field_index
= sdef
->elements
[i
].raw
.lengthto
[j
];
147 raw_options
[field_index
].lengthoffield
= (int*)
148 Realloc(raw_options
[field_index
].lengthoffield
,
149 (raw_options
[field_index
].lengthof
+ 1) * sizeof(int));
150 raw_options
[field_index
].lengthoffield
[
151 raw_options
[field_index
].lengthof
] = i
;
152 raw_options
[field_index
].lengthof
++;
155 if(sdef
->elements
[i
].hasRaw
&& sdef
->elements
[i
].raw
.pointerto
!=-1){
156 raw_options
[i
].pointerto
= TRUE
;
157 raw_options
[sdef
->elements
[i
].raw
.pointerto
].pointerof
=i
+1;
159 raw_options
[sdef
->elements
[i
].raw
.pointerbase
].ptrbase
= TRUE
;
162 if (sdef
->kind
== RECORD
&& *hascrosstag
) {
163 /* looking for fields that require delayed decoding because of
164 forward references in CROSSTAG */
165 for (i
= 0; i
< sdef
->nElements
; i
++) {
167 /* we are looking for a field index that is greater than i */
168 size_t max_index
= i
;
169 if (!sdef
->elements
[i
].hasRaw
) continue;
170 for (j
= 0; j
< sdef
->elements
[i
].raw
.crosstaglist
.nElements
; j
++) {
172 rawAST_coding_taglist
*crosstag
=
173 sdef
->elements
[i
].raw
.crosstaglist
.list
+ j
;
174 for (k
= 0; k
< crosstag
->nElements
; k
++) {
175 rawAST_coding_field_list
*keyid
= crosstag
->fields
+ k
;
176 if (keyid
->nElements
>= 1) {
177 int field_index
= keyid
->fields
[0].nthfield
;
178 if (field_index
> max_index
) max_index
= field_index
;
183 raw_options
[i
].delayed_decode
= TRUE
;
184 raw_options
[max_index
].nof_dependent_fields
++;
185 raw_options
[max_index
].dependent_fields
= (int*)
186 Realloc(raw_options
[max_index
].dependent_fields
,
187 raw_options
[max_index
].nof_dependent_fields
*
188 sizeof(*raw_options
[max_index
].dependent_fields
));
189 raw_options
[max_index
].dependent_fields
[
190 raw_options
[max_index
].nof_dependent_fields
- 1] = i
;
196 char* generate_raw_coding(char* src
,
197 const struct_def
*sdef
, struct raw_option_struct
*raw_options
,
198 boolean haspointer
, boolean hascrosstag
, boolean has_ext_bit
)
201 const char *name
= sdef
->name
;
203 if (sdef
->kind
== SET
) { /* set decoder start */
205 for (i
= 0; i
< sdef
->nElements
; i
++) {
206 if (!sdef
->elements
[i
].isOptional
) mand_num
++;
208 src
= mputprintf(src
, "int %s::RAW_decode(const TTCN_Typedescriptor_t& "
209 "p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, "
210 "boolean, int, boolean)\n"
212 "int prepaddlength = p_buf.increase_pos_padd(p_td.raw->prepadding);\n"
213 "limit -= prepaddlength;\n"
214 "int decoded_length = 0;\n"
215 "int field_map[%lu];\n"
216 "memset(field_map, 0, sizeof(field_map));\n",
217 name
, (unsigned long) sdef
->nElements
);
219 src
= mputstr(src
, "size_t nof_mand_fields = 0;\n");
220 for (i
= 0; i
< sdef
->nElements
; i
++) {
221 if (sdef
->elements
[i
].isOptional
)
222 src
= mputprintf(src
, "field_%s = OMIT_VALUE;\n",
223 sdef
->elements
[i
].name
);
226 "raw_order_t local_top_order;\n"
227 "if (p_td.raw->top_bit_order == TOP_BIT_INHERITED) "
228 "local_top_order = top_bit_ord;\n"
229 "else if (p_td.raw->top_bit_order == TOP_BIT_RIGHT) "
230 "local_top_order = ORDER_MSB;\n"
231 "else local_top_order = ORDER_LSB;\n"
232 "while (limit > 0) {\n"
233 "size_t fl_start_pos = p_buf.get_pos_bit();\n"
235 for (i
= 0; i
< sdef
->nElements
; i
++) { /* decoding fields with tag */
236 if (raw_options
[i
].tag_type
&&
237 sdef
->raw
.taglist
.list
[raw_options
[i
].tag_type
- 1].nElements
> 0) {
238 rawAST_coding_taglist
* cur_choice
=
239 sdef
->raw
.taglist
.list
+ raw_options
[i
].tag_type
- 1;
241 boolean has_fixed
= FALSE
, has_variable
= FALSE
, flag_needed
= FALSE
;
242 for (j
= 0; j
< cur_choice
->nElements
; j
++) {
243 if (cur_choice
->fields
[j
].start_pos
>= 0) {
244 if (has_fixed
|| has_variable
) flag_needed
= TRUE
;
247 if (has_fixed
) flag_needed
= TRUE
;
250 if (has_fixed
&& has_variable
) break;
252 src
= mputprintf(src
, "if (field_map[%lu] == 0) {\n",
255 src
= mputstr(src
, "boolean already_failed = FALSE;\n");
257 /* first check the fields we can precode
258 * try to decode those key variables whose position we know
259 * this way we might be able to step over bad values faster
261 boolean first_fixed
= TRUE
;
262 src
= mputstr(src
, "raw_order_t temporal_top_order;\n"
263 "int temporal_decoded_length;\n");
264 for (j
= 0; j
< cur_choice
->nElements
; j
++) {
266 rawAST_coding_field_list
*cur_field_list
= cur_choice
->fields
+ j
;
267 if (cur_field_list
->start_pos
< 0) continue;
268 if (!first_fixed
) src
= mputstr(src
, "if (!already_failed) {\n");
269 for (k
= cur_field_list
->nElements
- 1; k
> 0; k
--) {
270 src
= mputprintf(src
, "if (%s_descr_.raw->top_bit_order == "
271 "TOP_BIT_RIGHT) temporal_top_order = ORDER_MSB;\n"
272 "else if (%s_descr_.raw->top_bit_order == TOP_BIT_LEFT) "
273 "temporal_top_order = ORDER_LSB;\n"
274 "else ", cur_field_list
->fields
[k
- 1].typedescr
,
275 cur_field_list
->fields
[k
- 1].typedescr
);
277 src
= mputprintf(src
, "temporal_top_order = top_bit_ord;\n"
279 "p_buf.set_pos_bit(fl_start_pos + %d);\n"
280 "temporal_decoded_length = temporal_%lu.RAW_decode(%s_descr_, "
281 "p_buf, limit, temporal_top_order, TRUE);\n"
282 "p_buf.set_pos_bit(fl_start_pos);\n"
283 "if (temporal_decoded_length > 0 && temporal_%lu == %s) {\n"
284 "int decoded_field_length = field_%s%s.RAW_decode(%s_descr_, "
285 "p_buf, limit, local_top_order, TRUE);\n"
286 "if (decoded_field_length %s 0 && (",
287 cur_field_list
->fields
[cur_field_list
->nElements
- 1].type
,
288 (unsigned long) j
, cur_field_list
->start_pos
, (unsigned long) j
,
289 cur_field_list
->fields
[cur_field_list
->nElements
- 1].typedescr
,
290 (unsigned long) j
, cur_field_list
->value
,
291 sdef
->elements
[i
].name
,
292 sdef
->elements
[i
].isOptional
? "()" : "",
293 sdef
->elements
[i
].typedescrname
,
294 sdef
->elements
[i
].isOptional
? ">" : ">=");
295 src
= genRawFieldChecker(src
, cur_choice
, TRUE
);
296 src
= mputstr(src
, ")) {\n"
297 "decoded_length += decoded_field_length;\n"
298 "limit -= decoded_field_length;\n");
299 if (!sdef
->elements
[i
].isOptional
)
300 src
= mputstr(src
, "nof_mand_fields++;\n");
301 src
= mputprintf(src
, "field_map[%lu] = 1;\n"
304 "p_buf.set_pos_bit(fl_start_pos);\n", (unsigned long) i
);
305 if (sdef
->elements
[i
].isOptional
)
306 src
= mputprintf(src
, "field_%s = OMIT_VALUE;\n",
307 sdef
->elements
[i
].name
);
308 if (flag_needed
) src
= mputstr(src
, "already_failed = TRUE;\n");
309 src
= mputstr(src
, "}\n"
311 if (first_fixed
) first_fixed
= FALSE
;
312 else src
= mputstr(src
, "}\n");
316 /* if there is one tag key whose position we don't know
317 * and we couldn't decide yet if element can be decoded or not
318 * than we have to decode it.
320 if (flag_needed
) src
= mputstr(src
, "if (!already_failed) {\n");
321 src
= mputprintf(src
, "int decoded_field_length = "
322 "field_%s%s.RAW_decode(%s_descr_, p_buf, limit, "
323 "local_top_order, TRUE);\n"
324 "if (decoded_field_length %s 0 && (",
325 sdef
->elements
[i
].name
, sdef
->elements
[i
].isOptional
? "()" : "",
326 sdef
->elements
[i
].typedescrname
,
327 sdef
->elements
[i
].isOptional
? ">" : ">=");
328 src
= genRawFieldChecker(src
, cur_choice
, TRUE
);
329 src
= mputstr(src
, ")) {\n"
330 "decoded_length += decoded_field_length;\n"
331 "limit -= decoded_field_length;\n");
332 if (!sdef
->elements
[i
].isOptional
)
333 src
= mputstr(src
, "nof_mand_fields++;\n");
334 src
= mputprintf(src
, "field_map[%lu] = 1;\n"
337 "p_buf.set_pos_bit(fl_start_pos);\n", (unsigned long) i
);
338 if (sdef
->elements
[i
].isOptional
)
339 src
= mputprintf(src
, "field_%s = OMIT_VALUE;\n",
340 sdef
->elements
[i
].name
);
341 src
= mputstr(src
, "}\n");
342 if (flag_needed
) src
= mputstr(src
, "}\n");
344 src
= mputstr(src
, "}\n");
347 for (i
= 0; i
< sdef
->nElements
; i
++) {
348 /* decoding fields without TAG */
349 if (!raw_options
[i
].tag_type
) {
351 if (sdef
->elements
[i
].of_type
&& sdef
->elements
[i
].hasRaw
&&
352 sdef
->elements
[i
].raw
.repeatable
== XDEFYES
) repeatable
= TRUE
;
355 src
= mputprintf(src
, "if (field_map[%lu] == 0) ",
358 src
= mputprintf(src
, "{\n"
359 "int decoded_field_length = field_%s%s.RAW_decode(%s_descr_, "
360 "p_buf, limit, local_top_order, TRUE",
361 sdef
->elements
[i
].name
, sdef
->elements
[i
].isOptional
? "()" : "",
362 sdef
->elements
[i
].typedescrname
);
364 src
= mputprintf(src
, ", -1, field_map[%lu] == 0",
366 src
= mputprintf(src
, ");\n"
367 "if (decoded_field_length %s 0) {\n"
368 "decoded_length += decoded_field_length;\n"
369 "limit -= decoded_field_length;\n",
370 sdef
->elements
[i
].isOptional
? ">" : ">=");
372 if (!sdef
->elements
[i
].isOptional
) src
= mputprintf(src
,
373 "if (field_map[%lu] == 0) nof_mand_fields++;\n",
375 src
= mputprintf(src
, "field_map[%lu]++;\n", (unsigned long) i
);
377 if (!sdef
->elements
[i
].isOptional
)
378 src
= mputstr(src
, "nof_mand_fields++;\n");
379 src
= mputprintf(src
, "field_map[%lu] = 1;\n", (unsigned long) i
);
381 src
= mputstr(src
, "continue;\n"
383 "p_buf.set_pos_bit(fl_start_pos);\n");
384 if (sdef
->elements
[i
].isOptional
) {
386 src
= mputprintf(src
, "if (field_map[%lu] == 0) ",
388 src
= mputprintf(src
, "field_%s = OMIT_VALUE;\n",
389 sdef
->elements
[i
].name
);
391 src
= mputstr(src
, "}\n"
395 for (i
= 0; i
< sdef
->nElements
; i
++){
396 /* decoding fields with tag OTHERWISE */
397 if (raw_options
[i
].tag_type
&&
398 sdef
->raw
.taglist
.list
[raw_options
[i
].tag_type
-1].nElements
== 0) {
399 src
= mputprintf(src
, "if (field_map[%lu] == 0) {\n"
400 "int decoded_field_length = field_%s%s.RAW_decode(%s_descr_, "
401 "p_buf, limit, local_top_order, TRUE);\n"
402 "if (decoded_field_length %s 0) {\n"
403 "decoded_length += decoded_field_length;\n"
404 "limit -= decoded_field_length;\n", (unsigned long) i
,
405 sdef
->elements
[i
].name
, sdef
->elements
[i
].isOptional
? "()" : "",
406 sdef
->elements
[i
].typedescrname
,
407 sdef
->elements
[i
].isOptional
? ">" : ">=");
408 if (!sdef
->elements
[i
].isOptional
)
409 src
= mputstr(src
, "nof_mand_fields++;\n");
410 src
= mputprintf(src
, "field_map[%lu] = 1;\n"
413 "p_buf.set_pos_bit(fl_start_pos);\n", (unsigned long) i
);
414 if (sdef
->elements
[i
].isOptional
)
415 src
= mputprintf(src
, "field_%s = OMIT_VALUE;\n",
416 sdef
->elements
[i
].name
);
417 src
= mputstr(src
, "}\n"
421 src
= mputstr(src
, "break;\n" /* no field decoded successfully, quit */
423 if (mand_num
> 0) src
= mputprintf(src
,
424 "if (nof_mand_fields != %lu) return limit ? -1 : -TTCN_EncDec::ET_INCOMPL_MSG;\n",
425 (unsigned long) mand_num
);
426 /* If not all required fields were decoded and there are no bits left,
427 * that means that the last field was decoded successfully but used up
428 * the buffer. Signal "incomplete". If there were bits left, that means that
429 * no field could be decoded from them; signal an error.
431 src
= mputstr(src
, "return decoded_length + prepaddlength + "
432 "p_buf.increase_pos_padd(p_td.raw->padding);\n"
435 /* set decoder end, record decoder start */
436 int prev_ext_group
= 0;
437 src
= mputprintf(src
,
438 "int %s::RAW_decode(const TTCN_Typedescriptor_t& p_td, "
439 "TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, "
442 " int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);\n"
443 " limit-=prepaddlength;\n"
444 " size_t last_decoded_pos = p_buf.get_pos_bit();\n"
445 " int decoded_length = 0;\n"
446 " int decoded_field_length = 0;\n"
447 " raw_order_t local_top_order;\n"
450 src
= mputstr(src
, " int selected_field = -1;\n");
452 if (sdef
->raw
.ext_bit_goup_num
) {
453 src
=mputstr(src
, " int group_limit = 0;\n");
456 " if(p_td.raw->top_bit_order==TOP_BIT_INHERITED)"
457 "local_top_order=top_bit_ord;\n"
458 " else if(p_td.raw->top_bit_order==TOP_BIT_RIGHT)local_top_order"
460 " else local_top_order=ORDER_LSB;\n"
465 " cbyte* data=p_buf.get_read_data();\n"
467 " unsigned mask = 1 << (local_top_order==ORDER_LSB ? 0 : 7);\n"
468 " if(p_td.raw->extension_bit==EXT_BIT_YES){\n"
469 " while((data[count-1] & mask)==0 && count*8<(int)limit) count++;\n"
472 " while((data[count-1] & mask)!=0 && count*8<(int)limit) count++;\n"
474 " if(limit) limit=count*8;\n"
480 " int end_of_available_data=last_decoded_pos+limit;\n");
481 for(i
=0;i
<sdef
->nElements
;i
++){
482 if(raw_options
[i
].pointerof
)
484 " int start_of_field%lu=-1;\n"
487 if(raw_options
[i
].ptrbase
)
489 " int start_pos_of_field%lu=-1;\n"
492 if(raw_options
[i
].lengthto
)
494 " int value_of_length_field%lu = 0;\n"
498 for(i
=0;i
<sdef
->nElements
;i
++){ /* decoding fields */
499 if (raw_options
[i
].delayed_decode
) {
501 /* checking whether there are enough bits in the buffer to decode
503 src
= mputstr(src
, " if (");
504 src
= genRawFieldDecodeLimit(src
, sdef
, i
, raw_options
);
505 src
= mputprintf(src
, " < %d) return -TTCN_EncDec::ET_LEN_ERR;\n",
506 sdef
->elements
[i
].raw
.length
);
507 /* skipping over the field that has to be decoded later because of
508 forward referencing in CROSSTAG */
509 src
= mputprintf(src
,
510 " size_t start_of_field%lu = p_buf.get_pos_bit();\n"
511 " p_buf.set_pos_bit(start_of_field%lu + %d);\n"
512 " decoded_length += %d;\n"
513 " last_decoded_pos += %d;\n"
515 (unsigned long) i
, (unsigned long) i
, sdef
->elements
[i
].raw
.length
,
516 sdef
->elements
[i
].raw
.length
,
517 sdef
->elements
[i
].raw
.length
, sdef
->elements
[i
].raw
.length
);
518 for (j
= 0; j
< raw_options
[i
].lengthof
; j
++) {
519 src
= mputprintf(src
,
520 " value_of_length_field%d -= %d;\n",
521 raw_options
[i
].lengthoffield
[j
], sdef
->elements
[i
].raw
.length
);
524 src
= genRawDecodeRecordField(src
, sdef
, i
, raw_options
, FALSE
,
526 if (raw_options
[i
].nof_dependent_fields
> 0) {
528 for (j
= 0; j
< raw_options
[i
].nof_dependent_fields
; j
++) {
529 int dependent_field_index
= raw_options
[i
].dependent_fields
[j
];
530 /* seek to the beginning of the dependent field */
531 src
= mputprintf(src
,
532 " p_buf.set_pos_bit(start_of_field%d);\n",
533 dependent_field_index
);
534 /* decode the dependent field */
535 src
= genRawDecodeRecordField(src
, sdef
, dependent_field_index
,
536 raw_options
, TRUE
, &prev_ext_group
);
538 if (i
< sdef
->nElements
- 1) {
539 /* seek back if there are more regular fields to decode */
541 " p_buf.set_pos_bit(last_decoded_pos);\n");
545 } /* decoding fields*/
547 if(sdef
->hasRaw
&& sdef
->raw
.presence
.nElements
> 0)
549 src
= mputstr(src
, " if (");
550 src
= genRawFieldChecker(src
, &sdef
->raw
.presence
, FALSE
);
551 src
= mputstr(src
, ") return -1;\n");
555 " p_buf.set_pos_bit(last_decoded_pos);\n"
556 " return decoded_length+prepaddlength+"
557 "p_buf.increase_pos_padd(p_td.raw->padding);\n}\n\n");
558 } /* record decoder end */
560 src
= mputprintf(src
, /* encoder */
561 "int %s::RAW_encode(const TTCN_Typedescriptor_t&%s, "
562 "RAW_enc_tree& myleaf) const {\n", name
,
563 use_runtime_2
? " p_td" : "");
565 src
= mputstr(src
, " if (err_descr) return RAW_encode_negtest(err_descr, p_td, myleaf);\n");
567 src
= mputprintf(src
,
568 " if (!is_bound()) TTCN_EncDec_ErrorContext::error"
569 "(TTCN_EncDec::ET_UNBOUND, \"Encoding an unbound value.\");\n"
570 " int encoded_length = 0;\n"
571 " myleaf.isleaf = false;\n"
572 " myleaf.body.node.num_of_nodes = %lu;\n"
573 " myleaf.body.node.nodes = init_nodes_of_enc_tree(%lu);\n",
574 (unsigned long)sdef
->nElements
, (unsigned long)sdef
->nElements
);
576 for (i
= 0; i
< sdef
->nElements
; i
++) {
577 if (sdef
->elements
[i
].isOptional
) {
578 src
= mputprintf(src
,
579 " if (field_%s.ispresent()) {\n", sdef
->elements
[i
].name
);
581 src
= mputprintf(src
,
582 " myleaf.body.node.nodes[%lu] = new RAW_enc_tree(true, &myleaf, "
583 "&(myleaf.curr_pos), %lu, %s_descr_.raw);\n",
584 (unsigned long)i
, (unsigned long)i
, sdef
->elements
[i
].typedescrname
);
585 if (sdef
->elements
[i
].isOptional
) {
586 src
= mputprintf(src
,
588 " else myleaf.body.node.nodes[%lu] = NULL;\n", (unsigned long)i
);
591 for (i
= 0; i
< sdef
->raw
.ext_bit_goup_num
; i
++) {
592 if (sdef
->raw
.ext_bit_groups
[i
].ext_bit
!= XDEFNO
) {
593 src
= mputprintf(src
,
595 " int node_idx = %d;\n"
596 " while (node_idx <= %d && myleaf.body.node.nodes[node_idx] == NULL) node_idx++;\n"
597 " if (myleaf.body.node.nodes[node_idx]) {\n"
598 " myleaf.body.node.nodes[node_idx]->ext_bit_handling = 1;\n"
599 " myleaf.body.node.nodes[node_idx]->ext_bit = %s;\n }\n"
601 " while (node_idx >= %d && myleaf.body.node.nodes[node_idx] == NULL) node_idx--;\n"
602 " if (myleaf.body.node.nodes[node_idx]) myleaf.body.node.nodes[node_idx]"
603 "->ext_bit_handling += 2;\n"
605 sdef
->raw
.ext_bit_groups
[i
].from
,
606 sdef
->raw
.ext_bit_groups
[i
].to
,
607 sdef
->raw
.ext_bit_groups
[i
].ext_bit
== XDEFYES
? "EXT_BIT_YES" : "EXT_BIT_REVERSE",
608 sdef
->raw
.ext_bit_groups
[i
].to
,
609 sdef
->raw
.ext_bit_groups
[i
].from
);
612 for (i
= 0; i
< sdef
->nElements
; i
++) {
613 /* encoding fields */
614 if (sdef
->elements
[i
].isOptional
) {
615 src
= mputprintf(src
,
616 " if (field_%s.ispresent()) {\n", sdef
->elements
[i
].name
);
618 if (raw_options
[i
].lengthto
&& sdef
->elements
[i
].raw
.lengthindex
== NULL
619 && sdef
->elements
[i
].raw
.union_member_num
== 0) {
620 /* encoding of lenghto fields */
622 src
= mputprintf(src
,
623 " encoded_length += %d;\n"
624 " myleaf.body.node.nodes[%lu]->calc = CALC_LENGTH;\n"
625 " myleaf.body.node.nodes[%lu]->coding_descr = &%s_descr_;\n"
626 " myleaf.body.node.nodes[%lu]->calcof.lengthto.num_of_fields = %d;\n"
627 " myleaf.body.node.nodes[%lu]->calcof.lengthto.unit = %d;\n"
628 " myleaf.body.node.nodes[%lu]->calcof.lengthto.fields = "
629 "init_lengthto_fields_list(%d);\n"
630 " myleaf.body.node.nodes[%lu]->length = %d;\n",
631 sdef
->elements
[i
].raw
.fieldlength
, (unsigned long)i
,
632 (unsigned long)i
, sdef
->elements
[i
].typedescrname
,
633 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthto_num
,
634 (unsigned long)i
, sdef
->elements
[i
].raw
.unit
,
635 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthto_num
,
636 (unsigned long)i
, sdef
->elements
[i
].raw
.fieldlength
);
637 for (a
= 0; a
< sdef
->elements
[i
].raw
.lengthto_num
; a
++) {
638 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
639 src
= mputprintf(src
,
640 " if (field_%s.ispresent()) {\n",
641 sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].name
);
643 src
= mputprintf(src
,
644 " myleaf.body.node.nodes[%lu]->calcof.lengthto.fields[%d].level = "
645 "myleaf.body.node.nodes[%d]->curr_pos.level;\n"
646 " myleaf.body.node.nodes[%lu]->calcof.lengthto.fields[%d].pos = "
647 "myleaf.body.node.nodes[%d]->curr_pos.pos;\n",
648 (unsigned long)i
, a
, sdef
->elements
[i
].raw
.lengthto
[a
],
649 (unsigned long)i
, a
, sdef
->elements
[i
].raw
.lengthto
[a
]);
650 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
651 src
= mputprintf(src
,
653 " myleaf.body.node.nodes[%lu]->calcof.lengthto.fields[%d].level = 0;\n"
654 " myleaf.body.node.nodes[%lu]->calcof.lengthto.fields[%d].pos = 0;\n"
655 " }\n", (unsigned long)i
, a
, (unsigned long)i
, a
);
658 } else if (raw_options
[i
].pointerto
) {
659 /* encoding of pointerto fields */
660 if (sdef
->elements
[sdef
->elements
[i
].raw
.pointerto
].isOptional
) {
661 src
= mputprintf(src
,
662 " if (field_%s.ispresent()) {\n",
663 sdef
->elements
[sdef
->elements
[i
].raw
.pointerto
].name
);
665 src
= mputprintf(src
,
666 " encoded_length += %d;\n"
667 " myleaf.body.node.nodes[%lu]->calc = CALC_POINTER;\n"
668 " myleaf.body.node.nodes[%lu]->coding_descr = &%s_descr_;\n"
669 " myleaf.body.node.nodes[%lu]->calcof.pointerto.unit = %d;\n"
670 " myleaf.body.node.nodes[%lu]->calcof.pointerto.ptr_offset = %d;\n"
671 " myleaf.body.node.nodes[%lu]->calcof.pointerto.ptr_base = %d;\n"
672 " myleaf.body.node.nodes[%lu]->calcof.pointerto.target.level = "
673 "myleaf.body.node.nodes[%d]->curr_pos.level;\n"
674 " myleaf.body.node.nodes[%lu]->calcof.pointerto.target.pos = "
675 "myleaf.body.node.nodes[%d]->curr_pos.pos;\n"
676 " myleaf.body.node.nodes[%lu]->length = %d;\n",
677 sdef
->elements
[i
].raw
.fieldlength
,(unsigned long)i
,
678 (unsigned long)i
, sdef
->elements
[i
].typedescrname
,
679 (unsigned long)i
, sdef
->elements
[i
].raw
.unit
,
680 (unsigned long)i
, sdef
->elements
[i
].raw
.ptroffset
,
681 (unsigned long)i
, sdef
->elements
[i
].raw
.pointerbase
,
682 (unsigned long)i
, sdef
->elements
[i
].raw
.pointerto
,
683 (unsigned long)i
, sdef
->elements
[i
].raw
.pointerto
,
684 (unsigned long)i
, sdef
->elements
[i
].raw
.fieldlength
);
685 if (sdef
->elements
[sdef
->elements
[i
].raw
.pointerto
].isOptional
) {
686 src
= mputprintf(src
,
690 " encoded_length += atm.RAW_encode(%s_descr_"
691 ", *myleaf.body.node.nodes[%lu]);\n"
693 sdef
->elements
[i
].typedescrname
, (unsigned long)i
);
696 /* encoding of normal fields */
697 src
= mputprintf(src
,
698 " encoded_length += field_%s%s.RAW_encode(%s_descr_"
699 ", *myleaf.body.node.nodes[%lu]);\n",
700 sdef
->elements
[i
].name
, sdef
->elements
[i
].isOptional
? "()" : "",
701 sdef
->elements
[i
].typedescrname
, (unsigned long)i
);
703 if (sdef
->elements
[i
].isOptional
) {
704 src
= mputstr(src
, " }\n");
707 for (i
= 0; i
< sdef
->nElements
; i
++) {
708 /* fill presence, tag and crosstag */
709 if (raw_options
[i
].lengthto
&& sdef
->elements
[i
].raw
.lengthindex
) {
710 /* encoding of lenghto fields */
712 if (sdef
->elements
[i
].isOptional
) {
713 src
= mputprintf(src
,
714 " if (field_%s.ispresent()) {\n",
715 sdef
->elements
[i
].name
);
717 src
= mputprintf(src
,
718 " if (myleaf.body.node.nodes[%lu]->body.node.nodes[%d]) {\n"
719 " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]->"
720 "calc = CALC_LENGTH;\n"
721 " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]->"
722 "coding_descr = &%s_descr_;\n"
723 " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]->"
724 "calcof.lengthto.num_of_fields = %d;\n"
725 " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]->"
726 "calcof.lengthto.unit = %d;\n"
727 " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]->"
728 "calcof.lengthto.fields = "
729 "init_lengthto_fields_list(%d);\n",
730 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
731 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
732 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
733 sdef
->elements
[i
].raw
.lengthindex
->typedescr
,
734 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
735 sdef
->elements
[i
].raw
.lengthto_num
,
736 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
737 sdef
->elements
[i
].raw
.unit
,
738 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
739 sdef
->elements
[i
].raw
.lengthto_num
);
740 for (a
= 0; a
< sdef
->elements
[i
].raw
.lengthto_num
; a
++) {
741 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
742 src
= mputprintf(src
,
743 " if (field_%s.ispresent()) {\n",
744 sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].name
);
746 src
= mputprintf(src
,
747 " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]"
748 "->calcof.lengthto.fields[%d].level = "
749 "myleaf.body.node.nodes[%d]->curr_pos.level;\n"
750 " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]"
751 "->calcof.lengthto.fields[%d].pos = "
752 "myleaf.body.node.nodes[%d]->curr_pos.pos;\n",
753 (unsigned long)i
,sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
754 a
, sdef
->elements
[i
].raw
.lengthto
[a
],
755 (unsigned long)i
,sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
756 a
, sdef
->elements
[i
].raw
.lengthto
[a
]);
757 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
758 src
= mputprintf(src
,
760 " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]->"
761 "calcof.lengthto.fields[%d].level = 0;\n"
762 " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]->"
763 "calcof.lengthto.fields[%d].pos = 0;\n"
765 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
, a
,
766 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
, a
);
769 src
= mputstr(src
, " }\n");
770 if (sdef
->elements
[i
].isOptional
) {
771 src
= mputstr(src
, " }\n");
774 if (raw_options
[i
].lengthto
&& sdef
->elements
[i
].raw
.union_member_num
) {
775 /* encoding of lenghto fields */
777 if (sdef
->elements
[i
].isOptional
) {
778 src
= mputprintf(src
,
779 " if (field_%s.ispresent()) ", sdef
->elements
[i
].name
);
782 src
= mputprintf(src
,
784 " int sel_field = 0;\n"
785 " while (myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field] == NULL) "
787 " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]->"
788 "calc = CALC_LENGTH;\n"
789 " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]->"
790 "calcof.lengthto.num_of_fields = %d;\n"
791 " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]->"
792 "calcof.lengthto.unit = %d;\n"
793 " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]->"
794 "calcof.lengthto.fields = init_lengthto_fields_list(%d);\n",
795 (unsigned long)i
,(unsigned long)i
,
796 (unsigned long)i
,sdef
->elements
[i
].raw
.lengthto_num
,
797 (unsigned long)i
,sdef
->elements
[i
].raw
.unit
,
798 (unsigned long)i
,sdef
->elements
[i
].raw
.lengthto_num
);
799 for (a
= 0; a
< sdef
->elements
[i
].raw
.lengthto_num
; a
++) {
800 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
801 src
= mputprintf(src
,
802 " if (field_%s.ispresent()) {\n",
803 sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].name
);
805 src
= mputprintf(src
,
806 " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]"
807 "->calcof.lengthto.fields[%d].level = "
808 "myleaf.body.node.nodes[%d]->curr_pos.level;\n"
809 " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]"
810 "->calcof.lengthto.fields[%d].pos = "
811 "myleaf.body.node.nodes[%d]->curr_pos.pos;\n",
812 (unsigned long)i
, a
, sdef
->elements
[i
].raw
.lengthto
[a
],
813 (unsigned long)i
, a
, sdef
->elements
[i
].raw
.lengthto
[a
]);
814 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
815 src
= mputprintf(src
,
817 " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]"
818 "->calcof.lengthto.fields[%d].level = 0;\n"
819 " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]"
820 "->calcof.lengthto.fields[%d].pos = 0;\n"
823 (unsigned long)i
, a
);
829 if (raw_options
[i
].tag_type
&& sdef
->raw
.taglist
.list
[raw_options
[i
].tag_type
- 1].nElements
) {
831 rawAST_coding_taglist
*cur_choice
=
832 sdef
->raw
.taglist
.list
+ raw_options
[i
].tag_type
- 1;
833 src
= mputstr(src
, " if (");
834 if (sdef
->elements
[i
].isOptional
) {
835 src
= mputprintf(src
, "field_%s.ispresent() && (", sdef
->elements
[i
].name
);
837 src
= genRawFieldChecker(src
, cur_choice
, FALSE
);
838 if (sdef
->elements
[i
].isOptional
) src
= mputstr(src
, ")");
839 src
= mputstr(src
,") {\n");
840 src
= genRawTagChecker(src
, cur_choice
);
841 src
=mputstr(src
," }\n");
843 if (sdef
->elements
[i
].hasRaw
&& sdef
->elements
[i
].raw
.presence
.nElements
) {
845 src
= mputstr(src
, " if (");
846 if (sdef
->elements
[i
].isOptional
) {
847 src
= mputprintf(src
, "field_%s.ispresent() && (", sdef
->elements
[i
].name
);
849 src
= genRawFieldChecker(src
, &sdef
->elements
[i
].raw
.presence
, FALSE
);
850 if (sdef
->elements
[i
].isOptional
) src
= mputstr(src
, ")");
851 src
= mputstr(src
, ") {\n");
852 src
= genRawTagChecker(src
, &sdef
->elements
[i
].raw
.presence
);
853 src
= mputstr(src
," }\n");
855 if (sdef
->elements
[i
].hasRaw
&&
856 sdef
->elements
[i
].raw
.crosstaglist
.nElements
) {
859 if (sdef
->elements
[i
].isOptional
) {
860 src
= mputprintf(src
,
861 " if (field_%s.ispresent()) {\n",
862 sdef
->elements
[i
].name
);
864 src
= mputprintf(src
,
865 " switch (field_%s%s.get_selection()) {\n",
866 sdef
->elements
[i
].name
,sdef
->elements
[i
].isOptional
? "()" : "");
867 for (a
= 0; a
< sdef
->elements
[i
].raw
.crosstaglist
.nElements
; a
++) {
868 rawAST_coding_taglist
*cur_choice
=
869 sdef
->elements
[i
].raw
.crosstaglist
.list
+ a
;
870 if (cur_choice
->nElements
> 0) {
871 src
= mputprintf(src
, " case %s%s%s:\n"
872 " if (", sdef
->elements
[i
].type
,
873 "::ALT_", cur_choice
->fieldName
);
874 src
= genRawFieldChecker(src
, cur_choice
, FALSE
);
875 src
= mputstr(src
, ") {\n");
876 if (!strcmp(cur_choice
->fields
[0].value
, "OMIT_VALUE")) {
877 if (cur_choice
->fields
[0].nElements
!= 1)
878 NOTSUPP("omit value with multiple fields in CROSSTAG");
879 /* eliminating the corresponding encoded leaf, which will have
880 the same effect as if the referred field had been omit */
881 src
= mputprintf(src
,
882 " encoded_length -= myleaf.body.node.nodes[%d]->length;\n"
883 " delete myleaf.body.node.nodes[%d];\n"
884 " myleaf.body.node.nodes[%d] = NULL;\n",
885 cur_choice
->fields
[0].fields
[0].nthfield
,
886 cur_choice
->fields
[0].fields
[0].nthfield
,
887 cur_choice
->fields
[0].fields
[0].nthfield
);
890 src
= mputprintf(src
,
891 " RAW_enc_tr_pos pr_pos;\n"
892 " pr_pos.level = myleaf.curr_pos.level + %d;\n"
893 " int new_pos[] = { ",
894 cur_choice
->fields
[0].nElements
);
895 for (ll
= 0; ll
< cur_choice
->fields
[0].nElements
; ll
++) {
896 if (ll
> 0) src
= mputstr(src
, ", ");
897 src
= mputprintf(src
, "%d",
898 cur_choice
->fields
[0].fields
[ll
].nthfield
);
900 src
= mputprintf(src
, " };\n"
901 " pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, %d, "
903 cur_choice
->fields
[0].nElements
);
904 if (cur_choice
->fields
[0].value
[0] == ' ') {
905 /* the value is a string literal (the encoder can be called
906 on that object directly */
907 src
= mputprintf(src
,
908 " RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);\n"
909 " if (temp_leaf != NULL)\n"
910 " %s.RAW_encode(%s_descr_,*temp_leaf);\n"
912 " TTCN_EncDec_ErrorContext::error\n"
913 " (TTCN_EncDec::ET_OMITTED_TAG, \"Encoding a tagged,"
914 " but omitted value.\");\n",
915 cur_choice
->fields
[0].value
,
916 cur_choice
->fields
[0].fields
[
917 cur_choice
->fields
[0].nElements
- 1].typedescr
);
919 /* a temporary object needs to be created for encoding */
920 src
= mputprintf(src
,
922 " RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);\n"
923 " if (temp_leaf != NULL)\n"
924 " new_val.RAW_encode(%s_descr_,*temp_leaf);\n"
926 " TTCN_EncDec_ErrorContext::error\n"
927 " (TTCN_EncDec::ET_OMITTED_TAG, \"Encoding a tagged,"
928 " but omitted value.\");\n",
929 cur_choice
->fields
[0].fields
[
930 cur_choice
->fields
[0].nElements
- 1].type
,
931 cur_choice
->fields
[0].value
,
932 cur_choice
->fields
[0].fields
[
933 cur_choice
->fields
[0].nElements
- 1].typedescr
);
935 src
= mputstr(src
, " free_tree_pos(pr_pos.pos);\n");
937 src
= mputstr(src
, " }\n"
941 src
= mputstr(src
, " default:;\n"
943 if (sdef
->elements
[i
].isOptional
) src
= mputstr(src
, " }\n");
947 if (sdef
->hasRaw
&& sdef
->raw
.presence
.nElements
> 0) {
948 src
= mputstr(src
, " if (");
949 src
= genRawFieldChecker(src
, &sdef
->raw
.presence
, FALSE
);
950 src
= mputstr(src
,") {\n");
951 src
= genRawTagChecker(src
, &sdef
->raw
.presence
);
952 src
= mputstr(src
," }\n");
954 src
= mputstr(src
, " return myleaf.length = encoded_length;\n}\n\n");
957 src
= generate_raw_coding_negtest(src
, sdef
, raw_options
);
961 char *generate_raw_coding_negtest(char *src
, const struct_def
*sdef
,
962 struct raw_option_struct
*raw_options
)
965 const char *name
= sdef
->name
;
966 src
= mputprintf(src
,
967 /* Count the nodes and discover the new node order only. No node creation
969 "int %s::RAW_encode_negtest(const Erroneous_descriptor_t *p_err_descr, "
970 "const TTCN_Typedescriptor_t& /*p_td*/, RAW_enc_tree& myleaf) const\n"
972 " if (!is_bound()) TTCN_EncDec_ErrorContext::error"
973 "(TTCN_EncDec::ET_UNBOUND, \"Encoding an unbound value.\");\n"
974 " int idx_map[%lu];\n"
975 " for (int idx_map_idx = 0; idx_map_idx < %lu; ++idx_map_idx)\n"
976 " idx_map[idx_map_idx] = -1;\n"
978 " int encoded_length = 0;\n"
979 " int num_fields = get_count();\n"
980 " myleaf.isleaf = false;\n"
981 " myleaf.body.node.num_of_nodes = 0;\n"
982 " for (int field_idx = 0; field_idx < num_fields; ++field_idx) {\n"
983 " if ((p_err_descr->omit_before != -1) &&\n"
984 " (field_idx < p_err_descr->omit_before))\n"
986 " const Erroneous_values_t *err_vals = p_err_descr->get_field_err_values(field_idx);\n"
987 " const Erroneous_descriptor_t *emb_descr = p_err_descr->get_field_emb_descr(field_idx);\n"
988 " if (err_vals && err_vals->before)\n"
989 " ++myleaf.body.node.num_of_nodes;\n"
990 " if (err_vals && err_vals->value) {\n"
991 " if (err_vals->value->errval) {\n"
992 " // Field is modified, but it's still there. Otherwise, it's\n"
993 " // initialized to `-1'.\n"
994 " idx_map[field_idx] = -2;\n"
995 " ++myleaf.body.node.num_of_nodes;\n"
998 " if (emb_descr) idx_map[field_idx] = -2;\n"
999 " else idx_map[field_idx] = myleaf.body.node.num_of_nodes;\n"
1000 " ++myleaf.body.node.num_of_nodes;\n"
1002 " if (err_vals && err_vals->after)\n"
1003 " ++myleaf.body.node.num_of_nodes;\n"
1004 " if ((p_err_descr->omit_after != -1) &&\n"
1005 " (field_idx >= p_err_descr->omit_after))\n"
1008 name
, (unsigned long)sdef
->nElements
, (unsigned long)sdef
->nElements
);
1010 src
= mputprintf(src
,
1011 " myleaf.body.node.nodes =\n"
1012 " init_nodes_of_enc_tree(myleaf.body.node.num_of_nodes);\n"
1013 " TTCN_EncDec_ErrorContext e_c;\n"
1014 " int node_pos = 0;\n"
1015 " int next_optional_idx = 0;\n"
1016 " const int *my_optional_indexes = get_optional_indexes();\n"
1017 " for (int field_idx = 0; field_idx < num_fields; ++field_idx) {\n"
1018 " boolean is_optional_field = my_optional_indexes &&\n"
1019 " (my_optional_indexes[next_optional_idx] == field_idx);\n"
1020 " if ((p_err_descr->omit_before != -1) &&\n"
1021 " (field_idx < p_err_descr->omit_before)) {\n"
1022 " if (is_optional_field) ++next_optional_idx;\n"
1025 " const Erroneous_values_t *err_vals =\n"
1026 " p_err_descr->get_field_err_values(field_idx);\n"
1027 " if (err_vals && err_vals->before) {\n"
1028 " if (err_vals->before->errval == NULL)\n"
1029 " TTCN_error(\"internal error: erroneous before value missing\");\n"
1030 " if (err_vals->before->raw) {\n"
1031 " myleaf.body.node.nodes[node_pos] =\n"
1032 " new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos),\n"
1033 " node_pos, err_vals->before->errval"
1034 "->get_descriptor()->raw);\n"
1036 " if (err_vals->before->type_descr == NULL)\n"
1037 " TTCN_error(\"internal error: erroneous before typedescriptor "
1039 " myleaf.body.node.nodes[node_pos] =\n"
1040 " new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos),\n"
1041 " node_pos, err_vals->before->type_descr->raw);\n"
1045 " if (err_vals && err_vals->value) {\n"
1046 " if (err_vals->value->errval) {\n"
1047 " e_c.set_msg(\"'%%s'(erroneous value): \", fld_name(field_idx));\n"
1048 " if (err_vals->value->raw) {\n"
1049 " myleaf.body.node.nodes[node_pos] =\n"
1050 " new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos),\n"
1051 " node_pos, err_vals->value->errval"
1052 "->get_descriptor()->raw);\n"
1054 " if (err_vals->value->type_descr == NULL)\n"
1055 " TTCN_error(\"internal error: erroneous value typedescriptor "
1057 " myleaf.body.node.nodes[node_pos] =\n"
1058 " new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos),\n"
1059 " node_pos, err_vals->value->type_descr->raw);\n"
1064 " e_c.set_msg(\"'%%s': \", fld_name(field_idx));\n"
1065 " if (!is_optional_field || get_at(field_idx)->ispresent()) {\n"
1066 " myleaf.body.node.nodes[node_pos] =\n"
1067 " new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos),\n"
1068 " node_pos, fld_descr(field_idx)->raw);\n"
1070 " // `omitted' field.\n"
1071 " myleaf.body.node.nodes[node_pos] = NULL;\n"
1075 " if (err_vals && err_vals->after) {\n"
1076 " if (err_vals->after->errval == NULL)\n"
1077 " TTCN_error(\"internal error: erroneous before value missing\");\n"
1078 " if (err_vals->after->raw) {\n"
1079 " myleaf.body.node.nodes[node_pos] =\n"
1080 " new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos),\n"
1081 " node_pos, err_vals->after->errval"
1082 "->get_descriptor()->raw);\n"
1084 " if (err_vals->after->type_descr == NULL)\n"
1085 " TTCN_error(\"internal error: erroneous after typedescriptor "
1087 " myleaf.body.node.nodes[node_pos] =\n"
1088 " new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos),\n"
1089 " node_pos, err_vals->after->type_descr->raw);\n"
1093 " if (is_optional_field) ++next_optional_idx;\n"
1094 " if ((p_err_descr->omit_after != -1) &&\n"
1095 " (field_idx >= p_err_descr->omit_after))\n"
1098 /* Handling of the tricky attributes. A simple integer array will be used
1099 to track changes (field positions) in the record.
1100 int idx_map[n_fields] = {
1101 -1 (= field 0. was omitted),
1102 1 (= field 1. can be found at index 1.),
1103 -2 (= field 2. is still at index 2., but its value has changed) }; */
1104 for (i
= 0; i
< sdef
->raw
.ext_bit_goup_num
; i
++) {
1105 if (sdef
->raw
.ext_bit_groups
[i
].ext_bit
!= XDEFNO
) {
1106 src
= mputprintf(src
,
1108 " bool in_between_modified = false;\n"
1109 " for (int idx_map_idx = %d; idx_map_idx <= %d; ++idx_map_idx)\n"
1110 " if (idx_map[idx_map_idx] < 0) {\n"
1111 " in_between_modified = true;\n"
1114 " if (idx_map[%d] < 0 || idx_map[%d] < 0 ||\n"
1115 " %d != idx_map[%d] - idx_map[%d] || in_between_modified) {\n"
1116 " e_c.set_msg(\"Field #%d and/or #%d: \");\n"
1117 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1118 " \"Conflicting negative testing attributes, extension bit "
1119 "group #%d will be ignored\");\n"
1121 " int node_idx = idx_map[%d];\n"
1122 " while (node_idx <= idx_map[%d] &&\n"
1123 " myleaf.body.node.nodes[node_idx] == NULL)\n"
1125 " if (myleaf.body.node.nodes[node_idx]) {\n"
1126 " myleaf.body.node.nodes[node_idx]->ext_bit_handling = 1;\n"
1127 " myleaf.body.node.nodes[node_idx]->ext_bit = %s;\n"
1129 " node_idx = idx_map[%d];\n"
1130 " while (node_idx >= idx_map[%d] &&\n"
1131 " myleaf.body.node.nodes[node_idx] == NULL)\n"
1133 " if (myleaf.body.node.nodes[node_idx])\n"
1134 " myleaf.body.node.nodes[node_idx]->ext_bit_handling += 2;\n"
1137 sdef
->raw
.ext_bit_groups
[i
].from
,
1138 sdef
->raw
.ext_bit_groups
[i
].to
,
1139 sdef
->raw
.ext_bit_groups
[i
].from
,
1140 sdef
->raw
.ext_bit_groups
[i
].to
,
1141 sdef
->raw
.ext_bit_groups
[i
].to
- sdef
->raw
.ext_bit_groups
[i
].from
,
1142 sdef
->raw
.ext_bit_groups
[i
].to
,
1143 sdef
->raw
.ext_bit_groups
[i
].from
,
1144 sdef
->raw
.ext_bit_groups
[i
].from
,
1145 sdef
->raw
.ext_bit_groups
[i
].to
, i
,
1146 sdef
->raw
.ext_bit_groups
[i
].from
,
1147 sdef
->raw
.ext_bit_groups
[i
].to
,
1148 sdef
->raw
.ext_bit_groups
[i
].ext_bit
== XDEFYES
? "EXT_BIT_YES" : "EXT_BIT_REVERSE",
1149 sdef
->raw
.ext_bit_groups
[i
].to
,
1150 sdef
->raw
.ext_bit_groups
[i
].from
);
1153 for (i
= 0; i
< sdef
->nElements
; i
++) {
1154 if (sdef
->elements
[i
].isOptional
) {
1155 src
= mputprintf(src
,
1156 " if (field_%s.ispresent()) {\n",
1157 sdef
->elements
[i
].name
);
1159 if (raw_options
[i
].lengthto
&& sdef
->elements
[i
].raw
.lengthindex
== NULL
1160 && sdef
->elements
[i
].raw
.union_member_num
== 0) {
1161 /* Encoding of lenghto fields. */
1163 src
= mputprintf(src
,
1164 " if (idx_map[%lu] < 0) {\n"
1165 " e_c.set_msg(\"Field '%s': \");\n"
1166 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1167 " \"Conflicting negative testing attributes, LENGTHTO "
1168 "attribute will be ignored\");\n"
1170 " bool negtest_confl_lengthto = false;\n",
1171 (unsigned long)i
, sdef
->elements
[i
].name
);
1172 for (a
= 0; a
< sdef
->elements
[i
].raw
.lengthto_num
; a
++) {
1173 src
= mputprintf(src
,
1174 " if (idx_map[%lu] < 0) {\n"
1175 " negtest_confl_lengthto = true;\n"
1176 " e_c.set_msg(\"Field '%s': \");\n"
1177 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1178 " \"Conflicting negative testing attributes, LENGTHTO "
1179 "attribute will be ignored\");\n"
1181 (unsigned long)sdef
->elements
[i
].raw
.lengthto
[a
],
1182 sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].name
);
1184 src
= mputprintf(src
,
1185 " if (!negtest_confl_lengthto) {\n"
1186 " encoded_length += %d;\n"
1187 " myleaf.body.node.nodes[idx_map[%lu]]->calc = CALC_LENGTH;\n"
1188 " myleaf.body.node.nodes[idx_map[%lu]]->coding_descr = &%s_descr_;\n"
1189 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.lengthto.num_of_fields = %d;\n"
1190 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.lengthto.unit = %d;\n"
1191 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.lengthto.fields = "
1192 "init_lengthto_fields_list(%d);\n"
1193 " myleaf.body.node.nodes[idx_map[%lu]]->length = %d;\n",
1194 sdef
->elements
[i
].raw
.fieldlength
, (unsigned long)i
,
1195 (unsigned long)i
, sdef
->elements
[i
].typedescrname
,
1196 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthto_num
,
1197 (unsigned long)i
, sdef
->elements
[i
].raw
.unit
,
1198 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthto_num
,
1199 (unsigned long)i
, sdef
->elements
[i
].raw
.fieldlength
);
1200 for (a
= 0; a
< sdef
->elements
[i
].raw
.lengthto_num
; a
++) {
1201 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
1202 src
= mputprintf(src
,
1203 " if (field_%s.ispresent()) {\n",
1204 sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].name
);
1206 src
= mputprintf(src
,
1207 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.lengthto.fields[%lu].level = "
1208 "myleaf.body.node.nodes[idx_map[%lu]]->curr_pos.level;\n"
1209 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.lengthto.fields[%lu].pos = "
1210 "myleaf.body.node.nodes[idx_map[%lu]]->curr_pos.pos;\n",
1211 (unsigned long)i
, (unsigned long)a
,
1212 (unsigned long)sdef
->elements
[i
].raw
.lengthto
[a
],
1213 (unsigned long)i
, (unsigned long)a
,
1214 (unsigned long)sdef
->elements
[i
].raw
.lengthto
[a
]);
1215 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
1216 src
= mputprintf(src
,
1218 " myleaf.body.node.nodes[idx_map[%lu]]->"
1219 "calcof.lengthto.fields[%lu].level = 0;\n"
1220 " myleaf.body.node.nodes[idx_map[%lu]]->"
1221 "calcof.lengthto.fields[%lu].pos = 0;\n"
1223 (unsigned long)i
, (unsigned long)a
,
1224 (unsigned long)i
, (unsigned long)a
);
1227 /* Closing inner index check. */
1230 /* Closing outer index check. */
1233 } else if (raw_options
[i
].pointerto
) {
1234 /* Encoding of pointerto fields. */
1235 if (sdef
->elements
[sdef
->elements
[i
].raw
.pointerto
].isOptional
) {
1236 src
= mputprintf(src
,
1237 " if (field_%s.ispresent()) {\n",
1238 sdef
->elements
[sdef
->elements
[i
].raw
.pointerto
].name
);
1240 src
= mputprintf(src
,
1241 " bool in_between_modified_pointerto_%s = false;\n"
1242 " for (int idx_map_idx = %d; idx_map_idx <= %d; ++idx_map_idx) {\n"
1243 " if (idx_map[idx_map_idx] < 0) {\n"
1244 " in_between_modified_pointerto_%s = true;\n"
1248 " if (idx_map[%lu] < 0 || idx_map[%lu] < 0 ||\n"
1249 " %lu != idx_map[%lu] - idx_map[%lu] || in_between_modified_pointerto_%s) {\n"
1250 " e_c.set_msg(\"Field '%s' and/or '%s': \");\n"
1251 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1252 " \"Conflicting negative testing attributes, POINTERTO "
1253 "attribute will be ignored\");\n"
1255 " encoded_length += %d;\n"
1256 " myleaf.body.node.nodes[idx_map[%lu]]->calc = CALC_POINTER;\n"
1257 " myleaf.body.node.nodes[idx_map[%lu]]->coding_descr = &%s_descr_;\n"
1258 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.pointerto.unit = %d;\n"
1259 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.pointerto.ptr_offset = %d;\n"
1260 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.pointerto.ptr_base = %d;\n"
1261 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.pointerto.target.level = "
1262 "myleaf.body.node.nodes[%d]->curr_pos.level;\n"
1263 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.pointerto.target.pos = "
1264 "myleaf.body.node.nodes[%d]->curr_pos.pos;\n"
1265 " myleaf.body.node.nodes[idx_map[%lu]]->length = %d;\n"
1267 sdef
->elements
[i
].name
,
1268 i
, sdef
->elements
[i
].raw
.pointerto
,
1269 sdef
->elements
[i
].name
, (unsigned long)i
,
1270 (unsigned long)sdef
->elements
[i
].raw
.pointerto
,
1271 (unsigned long)sdef
->elements
[i
].raw
.pointerto
- (unsigned long)i
,
1272 (unsigned long)sdef
->elements
[i
].raw
.pointerto
, (unsigned long)i
,
1273 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
1274 sdef
->elements
[sdef
->elements
[i
].raw
.pointerto
].name
,
1275 sdef
->elements
[i
].raw
.fieldlength
, (unsigned long)i
,
1276 (unsigned long)i
, sdef
->elements
[i
].typedescrname
,
1277 (unsigned long)i
, sdef
->elements
[i
].raw
.unit
,
1278 (unsigned long)i
, sdef
->elements
[i
].raw
.ptroffset
,
1279 (unsigned long)i
, sdef
->elements
[i
].raw
.pointerbase
,
1280 (unsigned long)i
, sdef
->elements
[i
].raw
.pointerto
,
1281 (unsigned long)i
, sdef
->elements
[i
].raw
.pointerto
,
1282 (unsigned long)i
, sdef
->elements
[i
].raw
.fieldlength
);
1283 if (sdef
->elements
[sdef
->elements
[i
].raw
.pointerto
].isOptional
) {
1284 src
= mputprintf(src
,
1288 " encoded_length += atm.RAW_encode(%s_descr_, "
1289 "*myleaf.body.node.nodes[idx_map[%lu]]);\n"
1291 sdef
->elements
[i
].typedescrname
, (unsigned long)i
);
1294 /* Encoding of normal fields with no negative testing. Needed for the
1296 src
= mputprintf(src
,
1297 " if (idx_map[%lu] >= 0) "
1298 "encoded_length += field_%s%s.RAW_encode(%s_descr_, "
1299 "*myleaf.body.node.nodes[idx_map[%lu]]);\n",
1300 (unsigned long)i
, sdef
->elements
[i
].name
,
1301 sdef
->elements
[i
].isOptional
? "()" : "",
1302 sdef
->elements
[i
].typedescrname
, (unsigned long)i
);
1304 if (sdef
->elements
[i
].isOptional
) {
1309 for (i
= 0; i
< sdef
->nElements
; i
++) {
1310 /* Fill presence, tag and crosstag. */
1311 if (raw_options
[i
].lengthto
&& sdef
->elements
[i
].raw
.lengthindex
) {
1312 /* Encoding of lenghto fields with lengthindex. */
1314 if (sdef
->elements
[i
].isOptional
) {
1315 src
= mputprintf(src
,
1316 " if (field_%s.ispresent()) {\n",
1317 sdef
->elements
[i
].name
);
1319 src
= mputprintf(src
,
1320 " if (idx_map[%lu] < 0) {\n"
1321 " e_c.set_msg(\"Field '%s': \");\n"
1322 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1323 " \"Conflicting negative testing attributes, LENGTHTO/LENGTHINDEX "
1324 "attribute will be ignored\");\n"
1326 " if (myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]) {\n"
1327 " bool negtest_confl_lengthto = false;\n",
1328 (unsigned long)i
, sdef
->elements
[i
].name
, (unsigned long)i
,
1329 sdef
->elements
[i
].raw
.lengthindex
->nthfield
);
1330 for (a
= 0; a
< sdef
->elements
[i
].raw
.lengthto_num
; a
++) {
1331 src
= mputprintf(src
,
1332 " if (idx_map[%lu] < 0) {\n"
1333 " negtest_confl_lengthto = true;\n"
1334 " e_c.set_msg(\"Field '%s': \");\n"
1335 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1336 " \"Conflicting negative testing attributes, LENGTHTO/LENGTHINDEX "
1337 "attribute will be ignored\");\n"
1339 (unsigned long)sdef
->elements
[i
].raw
.lengthto
[a
],
1340 sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].name
);
1342 src
= mputprintf(src
,
1343 " if (!negtest_confl_lengthto) {\n"
1344 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]->"
1345 "calc = CALC_LENGTH;\n"
1346 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]->"
1347 "coding_descr = &%s_descr_;\n"
1348 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]->"
1349 "calcof.lengthto.num_of_fields = %d;\n"
1350 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]->"
1351 "calcof.lengthto.unit = %d;\n"
1352 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]->"
1353 "calcof.lengthto.fields = init_lengthto_fields_list(%d);\n",
1354 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
1355 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
1356 sdef
->elements
[i
].raw
.lengthindex
->typedescr
,
1357 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
1358 sdef
->elements
[i
].raw
.lengthto_num
,
1359 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
1360 sdef
->elements
[i
].raw
.unit
,
1361 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
1362 sdef
->elements
[i
].raw
.lengthto_num
);
1363 for (a
= 0; a
< sdef
->elements
[i
].raw
.lengthto_num
; a
++) {
1364 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
1365 src
= mputprintf(src
,
1366 " if (field_%s.ispresent()) {\n",
1367 sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].name
);
1369 src
= mputprintf(src
,
1370 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]"
1371 "->calcof.lengthto.fields[%d].level = "
1372 "myleaf.body.node.nodes[idx_map[%d]]->curr_pos.level;\n"
1373 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]"
1374 "->calcof.lengthto.fields[%d].pos = "
1375 "myleaf.body.node.nodes[idx_map[%d]]->curr_pos.pos;\n",
1376 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
, a
,
1377 sdef
->elements
[i
].raw
.lengthto
[a
], (unsigned long)i
,
1378 sdef
->elements
[i
].raw
.lengthindex
->nthfield
, a
,
1379 sdef
->elements
[i
].raw
.lengthto
[a
]);
1380 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
1381 src
= mputprintf(src
,
1383 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]->"
1384 "calcof.lengthto.fields[%d].level = 0;\n"
1385 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]->"
1386 "calcof.lengthto.fields[%d].pos = 0;\n"
1388 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
, a
,
1389 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
, a
);
1392 /* Closing index check. */
1395 src
= mputstr(src
, " }\n }\n");
1396 if (sdef
->elements
[i
].isOptional
) {
1397 src
= mputstr(src
, " }\n");
1400 if (raw_options
[i
].lengthto
&& sdef
->elements
[i
].raw
.union_member_num
) {
1401 /* Encoding of lenghto fields. */
1403 if (sdef
->elements
[i
].isOptional
) {
1404 src
= mputprintf(src
,
1405 " if (field_%s.ispresent()) ", sdef
->elements
[i
].name
);
1407 src
= mputprintf(src
,
1409 " if (idx_map[%lu] < 0) {\n"
1410 " e_c.set_msg(\"Field '%s': \");\n"
1411 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1412 " \"Conflicting negative testing attributes, LENGTHTO/LENGTHINDEX "
1413 "attribute will be ignored\");\n"
1415 " bool negtest_confl_lengthto = false;\n",
1416 (unsigned long)i
, sdef
->elements
[i
].name
);
1417 for (a
= 0; a
< sdef
->elements
[i
].raw
.lengthto_num
; a
++) {
1418 src
= mputprintf(src
,
1419 " if (idx_map[%lu] < 0) {\n"
1420 " negtest_confl_lengthto = true;\n"
1421 " e_c.set_msg(\"Field '%s': \");\n"
1422 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1423 " \"Conflicting negative testing attributes, LENGTHTO/LENGTHINDEX "
1424 "attribute will be ignored\");\n"
1426 (unsigned long)sdef
->elements
[i
].raw
.lengthto
[a
],
1427 sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].name
);
1429 src
= mputprintf(src
,
1430 " if (!negtest_confl_lengthto) {\n"
1431 " int sel_field = 0;\n"
1432 " while (myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[sel_field] == NULL) "
1433 "{ sel_field++; }\n"
1434 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[sel_field]->"
1435 "calc = CALC_LENGTH;\n"
1436 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[sel_field]->"
1437 "calcof.lengthto.num_of_fields = %d;\n"
1438 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[sel_field]->"
1439 "calcof.lengthto.unit = %d;\n"
1440 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[sel_field]->"
1441 "calcof.lengthto.fields = init_lengthto_fields_list(%d);\n",
1442 (unsigned long)i
, (unsigned long)i
,
1443 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthto_num
,
1444 (unsigned long)i
, sdef
->elements
[i
].raw
.unit
,
1445 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthto_num
);
1446 for (a
= 0; a
< sdef
->elements
[i
].raw
.lengthto_num
; a
++) {
1447 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
1448 src
= mputprintf(src
,
1449 " if (field_%s.ispresent()) {\n",
1450 sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].name
);
1452 src
= mputprintf(src
,
1453 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[sel_field]"
1454 "->calcof.lengthto.fields[%d].level = "
1455 "myleaf.body.node.nodes[%d]->curr_pos.level;\n"
1456 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[sel_field]"
1457 "->calcof.lengthto.fields[%d].pos = "
1458 "myleaf.body.node.nodes[%d]->curr_pos.pos;\n",
1459 (unsigned long)i
, a
, sdef
->elements
[i
].raw
.lengthto
[a
],
1460 (unsigned long)i
, a
, sdef
->elements
[i
].raw
.lengthto
[a
]);
1461 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
1462 src
= mputprintf(src
,
1464 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[sel_field]"
1465 "->calcof.lengthto.fields[%d].level = 0;\n"
1466 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[sel_field]"
1467 "->calcof.lengthto.fields[%d].pos = 0;\n"
1469 (unsigned long)i
, a
,
1470 (unsigned long)i
, a
);
1473 /* Closing inner index check. */
1476 /* Closing outer index check. */
1479 /* Closing ispresent or local block. */
1483 if (raw_options
[i
].tag_type
&&
1484 sdef
->raw
.taglist
.list
[raw_options
[i
].tag_type
- 1].nElements
) {
1485 /* Plain, old tag. */
1486 rawAST_coding_taglist
*cur_choice
=
1487 sdef
->raw
.taglist
.list
+ raw_options
[i
].tag_type
- 1;
1488 src
= mputprintf(src
,
1489 " bool negtest_confl_tag_%s = false;\n"
1490 " if (idx_map[%lu] < 0) {\n"
1491 " negtest_confl_tag_%s = true;\n"
1492 " e_c.set_msg(\"Field '%s': \");\n"
1493 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1494 " \"Conflicting negative testing attributes, TAG attribute will "
1497 sdef
->elements
[i
].name
, (unsigned long)i
, sdef
->elements
[i
].name
,
1498 sdef
->elements
[i
].name
);
1499 src
= mputprintf(src
, " if (!negtest_confl_tag_%s && (",
1500 sdef
->elements
[i
].name
);
1501 if (sdef
->elements
[i
].isOptional
) {
1502 src
= mputprintf(src
, "field_%s.ispresent() && (", sdef
->elements
[i
].name
);
1504 src
= genRawFieldChecker(src
, cur_choice
, FALSE
);
1505 if (sdef
->elements
[i
].isOptional
) src
= mputstr(src
, ")");
1506 src
= mputstr(src
,")) {\n");
1507 src
= genRawTagChecker(src
, cur_choice
);
1508 src
= mputstr(src
," }\n");
1510 if (sdef
->elements
[i
].hasRaw
&& sdef
->elements
[i
].raw
.presence
.nElements
) {
1511 /* Presence attribute for fields. */
1512 int taglist_idx
, field_idx
;
1513 /* The optional field itself. */
1514 src
= mputprintf(src
,
1515 " bool negtest_confl_presence_%s = false;\n"
1516 " if (idx_map[%lu] < 0) {\n"
1517 " negtest_confl_presence_%s = true;\n"
1518 " e_c.set_msg(\"Field '%s': \");\n"
1519 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1520 " \"Conflicting negative testing attributes, PRESENCE attribute "
1521 "will be ignored\");\n"
1523 sdef
->elements
[i
].name
, (unsigned long)i
, sdef
->elements
[i
].name
,
1524 sdef
->elements
[i
].name
);
1525 /* Check the referenced fields. */
1526 for (taglist_idx
= 0;
1527 taglist_idx
< sdef
->elements
[i
].raw
.presence
.nElements
; ++taglist_idx
) {
1528 rawAST_coding_field_list
*fields
=
1529 sdef
->elements
[i
].raw
.presence
.fields
+ taglist_idx
;
1530 for (field_idx
= 0; field_idx
< fields
->nElements
; ++field_idx
) {
1531 /* The top level field is enough. >0 index is for subrefs. */
1532 if (field_idx
== 0) {
1533 rawAST_coding_fields
*field
= fields
->fields
+ field_idx
;
1534 src
= mputprintf(src
,
1535 " if (idx_map[%d] < 0) {\n"
1536 " negtest_confl_presence_%s = true;\n"
1537 " e_c.set_msg(\"Field '%s': \");\n"
1538 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1539 " \"Conflicting negative testing attributes, PRESENCE attribute "
1540 "will be ignored\");\n"
1542 field
->nthfield
, sdef
->elements
[i
].name
, field
->nthfieldname
);
1549 src
= mputprintf(src
, " if (!negtest_confl_presence_%s && (",
1550 sdef
->elements
[i
].name
);
1551 if (sdef
->elements
[i
].isOptional
) {
1552 src
= mputprintf(src
, "field_%s.ispresent() && (", sdef
->elements
[i
].name
);
1554 src
= genRawFieldChecker(src
, &sdef
->elements
[i
].raw
.presence
, FALSE
);
1555 if (sdef
->elements
[i
].isOptional
) src
= mputstr(src
, ")");
1556 src
= mputstr(src
, ")) {\n");
1557 src
= genRawTagChecker(src
, &sdef
->elements
[i
].raw
.presence
);
1558 src
= mputstr(src
, " }\n");
1560 if (sdef
->elements
[i
].hasRaw
&&
1561 sdef
->elements
[i
].raw
.crosstaglist
.nElements
) {
1564 /* The union field itself. */
1565 src
= mputprintf(src
,
1566 " if (idx_map[%lu] < 0) {\n"
1567 " e_c.set_msg(\"Field '%s': \");\n"
1568 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1569 " \"Conflicting negative testing attributes, CROSSTAG attribute "
1570 "will be ignored\");\n"
1572 (unsigned long)i
, sdef
->elements
[i
].name
);
1573 if (sdef
->elements
[i
].isOptional
) {
1574 src
= mputprintf(src
,
1575 " if (field_%s.ispresent()) {\n",
1576 sdef
->elements
[i
].name
);
1578 src
= mputprintf(src
,
1579 " switch (field_%s%s.get_selection()) {\n",
1580 sdef
->elements
[i
].name
,sdef
->elements
[i
].isOptional
? "()" : "");
1581 for (a
= 0; a
< sdef
->elements
[i
].raw
.crosstaglist
.nElements
; a
++) {
1582 rawAST_coding_taglist
*cur_choice
=
1583 sdef
->elements
[i
].raw
.crosstaglist
.list
+ a
;
1584 if (cur_choice
->nElements
> 0) {
1585 int taglist_idx
, field_idx
;
1586 src
= mputprintf(src
,
1588 " bool negtest_confl_crosstag = false;\n",
1589 sdef
->elements
[i
].type
, "::ALT_",
1590 cur_choice
->fieldName
);
1591 for (taglist_idx
= 0;
1592 taglist_idx
< cur_choice
->nElements
; ++taglist_idx
) {
1593 rawAST_coding_field_list
*fields
= cur_choice
->fields
+ taglist_idx
;
1594 for (field_idx
= 0; field_idx
< fields
->nElements
; ++field_idx
) {
1595 rawAST_coding_fields
*field
= fields
->fields
+ field_idx
;
1596 if (field_idx
== 0) {
1597 src
= mputprintf(src
,
1598 " if (idx_map[%d] < 0) {\n"
1599 " negtest_confl_crosstag = true;\n"
1600 " e_c.set_msg(\"Field '%s': \");\n"
1601 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1602 " \"Conflicting negative testing attributes, CROSSTAG attribute "
1603 "will be ignored\");\n"
1605 field
->nthfield
, field
->nthfieldname
);
1611 src
= mputstr(src
, " if (!negtest_confl_crosstag && (");
1612 src
= genRawFieldChecker(src
, cur_choice
, FALSE
);
1613 src
= mputstr(src
, ")) {\n");
1614 if (!strcmp(cur_choice
->fields
[0].value
, "OMIT_VALUE")) {
1615 if (cur_choice
->fields
[0].nElements
!= 1)
1616 NOTSUPP("omit value with multiple fields in CROSSTAG");
1617 /* eliminating the corresponding encoded leaf, which will have
1618 the same effect as if the referred field had been omit */
1619 src
= mputprintf(src
,
1620 " encoded_length -= myleaf.body.node.nodes[%d]->length;\n"
1621 " delete myleaf.body.node.nodes[%d];\n"
1622 " myleaf.body.node.nodes[%d] = NULL;\n",
1623 cur_choice
->fields
[0].fields
[0].nthfield
,
1624 cur_choice
->fields
[0].fields
[0].nthfield
,
1625 cur_choice
->fields
[0].fields
[0].nthfield
);
1628 src
= mputprintf(src
,
1629 " RAW_enc_tr_pos pr_pos;\n"
1630 " pr_pos.level = myleaf.curr_pos.level + %d;\n"
1631 " int new_pos[] = { ",
1632 cur_choice
->fields
[0].nElements
);
1633 for (ll
= 0; ll
< cur_choice
->fields
[0].nElements
; ll
++) {
1634 if (ll
> 0) src
= mputstr(src
, ", ");
1635 src
= mputprintf(src
, "%d",
1636 cur_choice
->fields
[0].fields
[ll
].nthfield
);
1638 src
= mputprintf(src
, " };\n"
1639 " pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, %d, "
1641 cur_choice
->fields
[0].nElements
);
1642 if (cur_choice
->fields
[0].value
[0] == ' ') {
1643 /* the value is a string literal (the encoder can be called
1644 on that object directly */
1645 src
= mputprintf(src
,
1646 " RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);\n"
1647 " if (temp_leaf != NULL)\n"
1648 " %s.RAW_encode(%s_descr_, *temp_leaf);\n"
1650 " TTCN_EncDec_ErrorContext::error\n"
1651 " (TTCN_EncDec::ET_OMITTED_TAG, \"Encoding a tagged, "
1652 "but omitted value.\");\n",
1653 cur_choice
->fields
[0].value
,
1654 cur_choice
->fields
[0].fields
[
1655 cur_choice
->fields
[0].nElements
- 1].typedescr
);
1657 /* a temporary object needs to be created for encoding */
1658 src
= mputprintf(src
,
1659 " %s new_val(%s);\n"
1660 " RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);\n"
1661 " if (temp_leaf != NULL)\n"
1662 " new_val.RAW_encode(%s_descr_, *temp_leaf);\n"
1664 " TTCN_EncDec_ErrorContext::error\n"
1665 " (TTCN_EncDec::ET_OMITTED_TAG, \"Encoding a tagged, "
1666 "but omitted value.\");\n",
1667 cur_choice
->fields
[0].fields
[
1668 cur_choice
->fields
[0].nElements
- 1].type
,
1669 cur_choice
->fields
[0].value
,
1670 cur_choice
->fields
[0].fields
[
1671 cur_choice
->fields
[0].nElements
- 1].typedescr
);
1673 src
= mputstr(src
, " free_tree_pos(pr_pos.pos);\n");
1675 src
= mputstr(src
, " }\n"
1679 src
= mputstr(src
, " default:;\n"
1681 if (sdef
->elements
[i
].isOptional
) src
= mputstr(src
, " }\n");
1682 src
= mputstr(src
, " }\n");
1685 src
= mputprintf(src
,
1687 " next_optional_idx = 0;\n"
1688 " for (int field_idx = 0; field_idx < num_fields; ++field_idx) {\n"
1689 " boolean is_optional_field = my_optional_indexes &&\n"
1690 " (my_optional_indexes[next_optional_idx] == field_idx);\n"
1691 " if ((p_err_descr->omit_before != -1) &&\n"
1692 " (field_idx < p_err_descr->omit_before)) {\n"
1693 " if (is_optional_field) ++next_optional_idx;\n"
1696 " const Erroneous_values_t *err_vals = p_err_descr->get_field_err_values(field_idx);\n"
1697 " const Erroneous_descriptor_t *emb_descr = p_err_descr->get_field_emb_descr(field_idx);\n"
1698 " if (err_vals && err_vals->before) {\n"
1699 " if (err_vals->before->errval == NULL)\n"
1700 " TTCN_error(\"internal error: erroneous before value missing\");\n"
1701 " if (err_vals->before->raw) {\n"
1702 " encoded_length += err_vals->before->errval->"
1703 "RAW_encode_negtest_raw(*myleaf.body.node.nodes[node_pos++]);\n"
1705 " if (err_vals->before->type_descr == NULL)\n"
1706 " TTCN_error(\"internal error: erroneous before typedescriptor missing\");\n"
1707 " encoded_length += err_vals->before->errval->RAW_encode(*(err_vals->before->type_descr),\n"
1708 " *myleaf.body.node.nodes[node_pos++]);\n"
1711 " if (err_vals && err_vals->value) {\n"
1712 " if (err_vals->value->errval) {\n"
1713 " e_c.set_msg(\"'%%s'(erroneous value): \", fld_name(field_idx));\n"
1714 " if (err_vals->value->raw) {\n"
1715 " encoded_length += err_vals->value->errval->"
1716 "RAW_encode_negtest_raw(*myleaf.body.node.nodes[node_pos++]);\n"
1718 " if (err_vals->value->type_descr == NULL)\n"
1719 " TTCN_error(\"internal error: erroneous value typedescriptor missing\");\n"
1720 " encoded_length += err_vals->value->errval->"
1721 "RAW_encode(*(err_vals->value->type_descr), *myleaf.body.node.nodes[node_pos++]);\n"
1725 " e_c.set_msg(\"'%%s': \", fld_name(field_idx));\n"
1726 " if (!is_optional_field || get_at(field_idx)->ispresent()) {\n"
1727 " const Base_Type *curr_field = is_optional_field "
1728 "? get_at(field_idx)->get_opt_value() : get_at(field_idx);\n"
1729 " if (emb_descr) {\n"
1730 " encoded_length += curr_field\n"
1731 " ->RAW_encode_negtest(emb_descr, *fld_descr(field_idx),\n"
1732 " *myleaf.body.node.nodes[node_pos]);\n"
1735 " // `omitted' field.\n"
1736 " myleaf.body.node.nodes[node_pos] = NULL;\n"
1740 " if (err_vals && err_vals->after) {\n"
1741 " if (err_vals->after->errval == NULL)\n"
1742 " TTCN_error(\"internal error: erroneous before value missing\");\n"
1743 " if (err_vals->after->raw) {\n"
1744 " encoded_length += err_vals->after->errval->"
1745 "RAW_encode_negtest_raw(*myleaf.body.node.nodes[node_pos++]);\n"
1747 " if (err_vals->after->type_descr == NULL)\n"
1748 " TTCN_error(\"internal error: erroneous after typedescriptor missing\");\n"
1749 " encoded_length += err_vals->after->errval->"
1750 "RAW_encode(*(err_vals->after->type_descr), *myleaf.body.node.nodes[node_pos++]);\n"
1753 " if (is_optional_field) ++next_optional_idx;\n"
1754 " if ((p_err_descr->omit_after != -1) &&\n"
1755 " (field_idx >= p_err_descr->omit_after))\n"
1758 /* Presence for the whole record. */
1759 if (sdef
->hasRaw
&& sdef
->raw
.presence
.nElements
> 0) {
1760 /* Check the referenced fields. */
1761 int taglist_idx
, field_idx
;
1762 src
= mputstr(src
, " bool negtest_confl_presence = false;\n");
1763 for (taglist_idx
= 0; taglist_idx
< sdef
->raw
.presence
.nElements
; ++taglist_idx
) {
1764 rawAST_coding_field_list
*fields
=
1765 sdef
->raw
.presence
.fields
+ taglist_idx
;
1766 for (field_idx
= 0; field_idx
< fields
->nElements
; ++field_idx
) {
1767 if (field_idx
== 0) {
1768 rawAST_coding_fields
*field
= fields
->fields
+ field_idx
;
1769 src
= mputprintf(src
,
1770 " if (idx_map[%d] < 0) {\n"
1771 " negtest_confl_presence = true;\n"
1772 " e_c.set_msg(\"Field '%s': \");\n"
1773 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1774 " \"Conflicting negative testing attributes, PRESENCE attribute "
1775 "will be ignored\");\n"
1777 field
->nthfield
, field
->nthfieldname
);
1783 src
= mputstr(src
, " if (!negtest_confl_presence && (");
1784 src
= genRawFieldChecker(src
, &sdef
->raw
.presence
, FALSE
);
1785 src
= mputstr(src
,")) {\n");
1786 src
= genRawTagChecker(src
, &sdef
->raw
.presence
);
1787 src
= mputstr(src
," }\n");
1790 " return myleaf.length = encoded_length;\n"
1795 void gen_xer(const struct_def
*sdef
, char **pdef
, char **psrc
)
1796 { /* XERSTUFF codegen for record/SEQUENCE */
1798 char *def
= *pdef
, *src
= *psrc
;
1799 const char * const name
= sdef
->name
;
1802 * NOTE! Decisions based on the coding instructions of the components
1803 * (e.g. number of attributes) can be made at compile time.
1804 * Decisions on coding instructions of the record itself (e.g. D-F-E,
1805 * EMBED-VALUES, USE-NIL, USE-ORDER) __must__ be postponed to run-time,
1806 * because these can be applied to type references,
1807 * which will not be visible when the code is generated.
1810 /* Number of fields with ATTRIBUTE, includes ANY-ATTRIBUTES */
1811 size_t num_attributes
= 0;
1813 /* index of USE-ORDER member, which may be bumped into second place by EMBED-VALUES */
1814 size_t uo
= (sdef
->xerEmbedValuesPossible
!=0);
1816 /* start_at is the index of the first "real" member of the record */
1817 size_t start_at
= uo
+ (sdef
->xerUseOrderPossible
!= 0);
1819 /* Number of optional non-attributes */
1820 size_t n_opt_elements
= 0;
1822 const boolean want_namespaces
= !sdef
->isASN1
/* TODO remove this when ASN.1 gets EXER */;
1825 /* Find the number of attributes (compile time) */
1826 for (i
= 0; i
< sdef
->nElements
; ++i
) {
1827 if (sdef
->elements
[i
].xerAttribute
) {
1830 else if (sdef
->elements
[i
].xerAnyKind
& ANY_ATTRIB_BIT
) {
1831 ++num_attributes
; /* ANY-ATTRIBUTES also included with attributes */
1833 /* If the first member is ANY-ATTRIBUTES, then xerEmbedValuesPossible
1834 * is merely an illusion and USE-ORDER is not possible. */
1839 else /* not attribute */ if (sdef
->elements
[i
].isOptional
) {
1844 /* Write some helper functions */
1846 "char **collect_ns(const XERdescriptor_t& p_td, size_t& num_ns, bool& def_ns) const;\n");
1848 src
= mputprintf(src
,
1849 "char ** %s::collect_ns(const XERdescriptor_t& p_td, size_t& num_ns, bool& def_ns) const {\n"
1850 " size_t num_collected;\n"
1851 " char **collected_ns = Base_Type::collect_ns(p_td, num_collected, def_ns);\n"
1852 /* The above might throw but then nothing was allocated. */
1855 /* Collect namespaces from the "non-special" members (incl. attributes) */
1856 if (start_at
< sdef
->nElements
) src
= mputstr(src
,
1859 " size_t num_new;\n"
1860 " bool def_ns_1 = false;\n");
1861 for (i
= start_at
; i
< sdef
->nElements
; ++i
) {
1862 src
= mputprintf(src
,
1863 " new_ns = field_%s.collect_ns(%s_xer_, num_new, def_ns);\n"
1864 " merge_ns(collected_ns, num_collected, new_ns, num_new);\n"
1865 " def_ns = def_ns || def_ns_1;\n" /* alas, no ||= */
1866 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typegen
1869 if (sdef
->xerUseNilPossible
) {
1870 src
= mputprintf(src
,
1871 " if((p_td.xer_bits & USE_NIL) && !field_%s.ispresent()) {\n" /* "nil" attribute to be written*/
1872 " collected_ns = (char**)Realloc(collected_ns, sizeof(char*) * ++num_collected);\n"
1873 " const namespace_t *c_ns = p_td.my_module->get_controlns();\n"
1874 " collected_ns[num_collected-1] = mprintf(\" xmlns:%%s='%%s'\", c_ns->px, c_ns->ns);\n"
1876 , sdef
->elements
[sdef
->nElements
-1].name
1879 if (start_at
< sdef
->nElements
) src
= mputstr(src
,
1882 /* Probably a TC_Error thrown from field_%s->collect_ns() if e.g.
1883 * encoding an unbound value. */
1884 " while (num_collected > 0) Free(collected_ns[--num_collected]);\n"
1885 " Free(collected_ns);\n"
1891 " num_ns = num_collected;\n"
1892 " return collected_ns;\n"
1896 src
= mputprintf(src
,
1897 "boolean %s::can_start(const char *name, const char *uri, const XERdescriptor_t& xd, unsigned int flavor) {\n"
1898 " boolean e_xer = is_exer(flavor &= ~XER_RECOF);\n"
1899 " if (!e_xer || !((xd.xer_bits & UNTAGGED) || (flavor & (USE_NIL|XER_RECOF)))) return check_name(name, xd, e_xer) && (!e_xer || check_namespace(uri, xd));\n"
1902 for (i
= start_at
; i
< sdef
->nElements
; ++i
) {
1903 src
= mputprintf(src
,
1904 " else if (%s::can_start(name, uri, %s_xer_, flavor)) return true;\n"
1905 /* Here we know for sure it's exer */
1906 , sdef
->elements
[i
].type
1907 , sdef
->elements
[i
].typegen
1909 if (!sdef
->elements
[i
].isOptional
) break;
1910 /* The last component with which it can begin is the first non-optional.
1911 * Does that sentence makes sense to you ? */
1913 src
= mputstr(src
, " return false;\n}\n\n");
1915 /* * * * * * * * * * XER_encode * * * * * * * * * * * * * * */
1916 src
= mputprintf(src
,
1917 "int %s::XER_encode(const XERdescriptor_t& p_td, "
1918 "TTCN_Buffer& p_buf, unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const\n"
1920 " if (!is_bound()) TTCN_EncDec_ErrorContext::error"
1921 "(TTCN_EncDec::ET_UNBOUND, \"Encoding an unbound value.\");\n"
1922 " TTCN_EncDec_ErrorContext ec_0(\"Component '\");\n"
1923 " TTCN_EncDec_ErrorContext ec_1;\n"
1924 " int encoded_length=(int)p_buf.get_len();\n"
1925 " int e_xer = is_exer(p_flavor);\n"
1926 " const boolean omit_tag = e_xer && p_indent "
1927 "&& ((p_td.xer_bits & (UNTAGGED|XER_ATTRIBUTE)) || (p_flavor & (USE_NIL|USE_TYPE_ATTR)));\n"
1928 " if (e_xer && (p_td.xer_bits & EMBED_VALUES)) p_flavor |= XER_CANONICAL;\n"
1929 " int is_indented = !is_canonical(p_flavor);\n"
1932 if (want_namespaces
&& !(num_attributes
|sdef
->xerUseQName
)) src
= mputstr(src
,
1933 " const boolean need_control_ns = (p_td.xer_bits & (USE_NIL));\n");
1935 if (want_namespaces
&& (start_at
< sdef
->nElements
)) { /* there _are_ non-special members */
1937 " size_t num_collected = 0;\n"
1938 " char **collected_ns = NULL;\n"
1939 " bool def_ns = false;\n"
1941 " if (p_indent == 0) {\n" /* top-level */
1942 " collected_ns = collect_ns(p_td, num_collected, def_ns);\n" /* our own ns */
1944 " else if ((p_flavor & DEF_NS_SQUASHED) && p_td.my_module && p_td.ns_index != -1){\n"
1945 " const namespace_t * ns = p_td.my_module->get_ns(p_td.ns_index);\n"
1946 " if (*ns->px == '\\0') {\n"
1947 " collected_ns = Base_Type::collect_ns(p_td, num_collected, def_ns);\n"
1954 if (want_namespaces
) {
1956 " const boolean empty_ns_hack = e_xer && !omit_tag && (p_indent > 0)\n"
1957 " && (p_td.xer_bits & FORM_UNQUALIFIED)\n"
1958 " && p_td.my_module && p_td.ns_index != -1\n"
1959 " && *p_td.my_module->get_ns(p_td.ns_index)->px == '\\0';\n"
1962 src
= mputstr(src
, " boolean delay_close = e_xer");
1963 if (!(num_attributes
| sdef
->xerUseQName
)) {
1964 src
= mputprintf(src
, " && (need_control_ns%s || empty_ns_hack)",
1965 (start_at
< sdef
->nElements
) ? " || num_collected" : "");
1967 src
= mputstr(src
, ";\n");
1971 { /* write start tag */
1973 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND e_xer
1974 * lose the > if attributes are present (*) AND e_xer
1976 src
= mputprintf(src
,
1977 " size_t chopped_chars = 0;\n"
1978 " if (!omit_tag) {\n"
1979 " if (is_indented) do_indent(p_buf, p_indent);\n"
1980 " p_buf.put_c('<');\n"
1981 " if (e_xer) write_ns_prefix(p_td, p_buf);\n"
1982 " p_buf.put_s((size_t)p_td.namelens[e_xer]%s-(!is_indented%s), "
1983 "(cbyte*)p_td.names[e_xer]);\n"
1985 " else if (p_flavor & (USE_NIL|USE_TYPE_ATTR)) {\n"
1986 " size_t buf_len = p_buf.get_len();\n"
1987 " const unsigned char * const buf_data = p_buf.get_data();\n"
1988 " if (buf_data[buf_len-1-chopped_chars] == '\\n') ++chopped_chars;\n"
1989 " if (buf_data[buf_len-1-chopped_chars] == '>' ) ++chopped_chars;\n"
1990 " if (chopped_chars) {\n"
1991 " p_buf.increase_length(-chopped_chars);\n"
1995 , (want_namespaces
? "-(delay_close || (e_xer && (p_td.xer_bits & HAS_1UNTAGGED)))" : "")
1996 , (want_namespaces
? " || delay_close" : "")
1997 , (want_namespaces
? " delay_close = TRUE;\n" : ""));
2000 src
= mputprintf(src
,
2001 " int sub_len=0%s;\n"
2002 " p_flavor &= XER_MASK;\n",
2003 num_attributes
? ", tmp_len; (void)tmp_len" : "");
2005 if (sdef
->xerUseQName
) {
2006 src
= mputprintf(src
,
2007 " if (e_xer && (p_td.xer_bits & USE_QNAME)) {\n"
2008 " if (field_%s.is_value()) {\n"
2009 " p_buf.put_s(11, (cbyte*)\" xmlns:b0='\");\n"
2010 " field_%s.XER_encode(%s_xer_, p_buf, p_flavor | XER_LIST, p_indent+1, 0);\n"
2011 " p_buf.put_c('\\'');\n"
2013 " if (p_td.xer_bits & XER_ATTRIBUTE) begin_attribute(p_td, p_buf);\n"
2014 " else p_buf.put_c('>');\n"
2015 " if (field_%s.is_value()) {\n"
2016 " p_buf.put_s(3, (cbyte*)\"b0:\");\n"
2019 " sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor | XER_LIST, p_indent+1, 0);\n"
2020 " if (p_td.xer_bits & XER_ATTRIBUTE) p_buf.put_c('\\'');\n"
2021 " } else" /* no newline */
2022 , sdef
->elements
[0].name
2023 , sdef
->elements
[0].name
, sdef
->elements
[0].typegen
2024 , sdef
->elements
[0].name
2025 , sdef
->elements
[1].name
, sdef
->elements
[1].typegen
2028 src
= mputstr(src
, " { // !QN\n");
2030 /* First, the EMBED-VALUES member as an ordinary member if not doing EXER */
2031 if (sdef
->xerEmbedValuesPossible
) {
2032 src
= mputprintf(src
,
2033 " if (!e_xer && (p_td.xer_bits & EMBED_VALUES)) {\n"
2034 " ec_1.set_msg(\"%s': \");\n"
2035 " sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1, 0);\n"
2037 , sdef
->elements
[0].dispname
2038 , sdef
->elements
[0].name
, sdef
->elements
[0].typegen
2041 /* Then, the USE-ORDER member as an ordinary member when !EXER */
2042 if (sdef
->xerUseOrderPossible
) {
2043 src
= mputprintf(src
,
2044 " if (!e_xer && (p_td.xer_bits & USE_ORDER)) {\n"
2045 " sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1, 0);\n"
2047 , sdef
->elements
[uo
].name
, sdef
->elements
[uo
].typegen
2051 if (start_at
+num_attributes
> sdef
->nElements
) FATAL_ERROR("defRecordClass1");
2053 if (want_namespaces
&& (start_at
< sdef
->nElements
)) {
2055 " if (e_xer && num_collected) {\n"
2057 " for (num_ns = 0; num_ns < num_collected; ++num_ns) {\n"
2058 " p_buf.put_s(strlen(collected_ns[num_ns]), (cbyte*)collected_ns[num_ns]);\n"
2059 " Free(collected_ns[num_ns]);\n"
2061 " Free(collected_ns);\n"
2064 " p_flavor &= ~DEF_NS_SQUASHED;\n"
2065 " p_flavor |= DEF_NS_PRESENT;\n"
2067 " else if (empty_ns_hack) {\n"
2068 " p_buf.put_s(9, (cbyte*)\" xmlns=''\");\n"
2069 " p_flavor &= ~DEF_NS_PRESENT;\n"
2070 " p_flavor |= DEF_NS_SQUASHED;\n"
2074 /* Then, all the attributes (not added to sub_len) */
2075 for ( i
= start_at
; i
< start_at
+ num_attributes
; ++i
) {
2076 /* If the first component is a record-of with ANY-ATTRIBUTES,
2077 * it has been taken care of because it looked like an EMBED-VALUES */
2078 if (i
==0 && sdef
->xerEmbedValuesPossible
&& (sdef
->elements
[i
].xerAnyKind
& ANY_ATTRIB_BIT
)) continue ;
2079 src
= mputprintf(src
,
2080 " ec_1.set_msg(\"%s': \");\n"
2081 " tmp_len = field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1, 0);\n"
2082 " %ssub_len += tmp_len;\n" /* do not add if attribute and EXER */
2083 , sdef
->elements
[i
].dispname
2084 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typegen
2085 , sdef
->elements
[i
].xerAttribute
|| (sdef
->elements
[i
].xerAnyKind
& ANY_ATTRIB_BIT
) ? "if (!e_xer) " : ""
2089 if (sdef
->xerUseNilPossible
) {
2090 src
= mputprintf(src
,
2091 " bool nil_attribute = e_xer && (p_td.xer_bits & USE_NIL) && !field_%s.ispresent();\n"
2092 " if (nil_attribute) {\n"
2093 " const namespace_t *control_ns = p_td.my_module->get_controlns();\n"
2094 " p_buf.put_c(' ');\n"
2095 " p_buf.put_s(strlen(control_ns->px), (cbyte*)control_ns->px);\n"
2096 " p_buf.put_c(':');\n"
2097 " p_buf.put_s(10, (cbyte*)\"nil='true'\");\n"
2099 , sdef
->elements
[sdef
->nElements
-1].name
2103 if (want_namespaces
) {
2104 /* there were some attributes. close the start tag left open */
2105 src
= mputprintf(src
,
2106 " if (delay_close && (!omit_tag || chopped_chars)) p_buf.put_s(1%s, (cbyte*)\">\\n\");\n", /* close the start tag */
2107 (sdef
->xerUntaggedOne
/*|| sdef->xerUseNil*/) ? "" : "+is_indented"
2111 if (sdef
->xerEmbedValuesPossible
) {
2112 src
= mputprintf(src
,
2113 " ec_1.set_msg(\"%s': \");\n"
2114 " if (e_xer && (p_td.xer_bits & EMBED_VALUES)) {\n"
2115 /* write the first string (must come AFTER the attributes) */
2116 " if (%s%s%s field_%s%s.size_of() > 0) {\n"
2117 " sub_len += field_%s%s[0].XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n"
2120 , sdef
->elements
[0].dispname
2121 , sdef
->elements
[0].isOptional
? "field_" : ""
2122 , sdef
->elements
[0].isOptional
? sdef
->elements
[0].name
: ""
2123 , sdef
->elements
[0].isOptional
? ".ispresent() &&" : ""
2124 , sdef
->elements
[0].name
2125 , sdef
->elements
[0].isOptional
? "()" : "", sdef
->elements
[0].name
2126 , sdef
->elements
[0].isOptional
? "()" : "");
2127 if (want_namespaces
) { /* here's another chance */
2128 src
= mputprintf(src
,
2129 " else if ( !(p_td.xer_bits & EMBED_VALUES)) {\n"
2130 " %sfield_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1, 0);\n"
2132 , ((sdef
->elements
[0].xerAnyKind
& ANY_ATTRIB_BIT
) ? "" : "sub_len += " )
2133 , sdef
->elements
[0].name
, sdef
->elements
[0].typegen
2138 /* Then, all the non-attributes. Structuring the code like this depends on
2139 * all attributes appearing before all non-attributes (excluding
2140 * special members for EMBED-VALUES, USE-ORDER, etc.) */
2141 if (sdef
->xerEmbedValuesPossible
) {
2142 src
= mputprintf(src
,
2143 " embed_values_enc_struct_t* emb_val = 0;\n"
2144 " if (e_xer && (p_td.xer_bits & EMBED_VALUES) && "
2145 " %s%s%s field_%s%s.size_of() > 1) {\n"
2146 " emb_val = new embed_values_enc_struct_t;\n"
2147 /* If the first field is a record of ANY-ELEMENTs, then it won't be a pre-generated
2148 * record of universal charstring, so it needs a cast to avoid a compilation error */
2149 " emb_val->embval_array%s = (const PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING%s*)&field_%s%s;\n"
2150 " emb_val->embval_array%s = NULL;\n"
2151 " emb_val->embval_index = 1;\n"
2153 , sdef
->elements
[0].isOptional
? "field_" : ""
2154 , sdef
->elements
[0].isOptional
? sdef
->elements
[0].name
: ""
2155 , sdef
->elements
[0].isOptional
? ".ispresent() &&" : ""
2156 , sdef
->elements
[0].name
2157 , sdef
->elements
[0].isOptional
? "()" : ""
2158 , sdef
->elements
[0].optimizedMemAlloc
? "_opt" : "_reg"
2159 , sdef
->elements
[0].optimizedMemAlloc
? "__OPTIMIZED" : ""
2160 , sdef
->elements
[0].name
2161 , sdef
->elements
[0].isOptional
? "()" : ""
2162 , sdef
->elements
[0].optimizedMemAlloc
? "_reg" : "_opt");
2165 if (sdef
->xerUseOrderPossible
) {
2166 int max_ordered
= sdef
->nElements
- start_at
- num_attributes
;
2167 int min_ordered
= max_ordered
- n_opt_elements
;
2170 size_t limit
= sdef
->nElements
;
2171 /* base and limit are indexes into sdef->elements[] */
2172 src
= mputprintf(src
,
2173 " int dis_order = e_xer && (p_td.xer_bits & USE_ORDER);\n"
2174 " int to_send = field_%s.lengthof();\n"
2175 " int uo_limit = dis_order ? to_send : %lu;\n"
2176 , sdef
->elements
[start_at
-1].name
2177 , (unsigned long)(limit
- base
)
2179 if (sdef
->xerUseNilPossible
) { /* USE-NIL on top of USE-ORDER */
2180 base
= sdef
->nElements
;
2181 limit
= sdef
->totalElements
;
2182 min_ordered
= max_ordered
= limit
- base
;
2183 src
= mputprintf(src
,
2184 " if (!nil_attribute) {\n"
2186 " if (!e_xer) sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+!omit_tag, 0);\n"
2187 " else" /* no newline */
2188 , (sdef
->xerUseNilPossible
? " if (!(p_td.xer_bits & USE_ORDER)) p_flavor |= (p_td.xer_bits & USE_NIL);\n" : "")
2189 /* If USE-ORDER is on, the tag-removing effect of USE-NIL has been
2190 * performed by calling the sub-fields directly. */
2191 , sdef
->elements
[sdef
->nElements
-1].name
2192 , sdef
->elements
[sdef
->nElements
-1].typegen
2196 /* check incorrect data */
2197 src
= mputprintf(src
,
2199 " if (to_send < %d || to_send > %d) {\n"
2200 " ec_1.set_msg(\"%s': \");\n"
2201 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT, "
2202 "\"Wrong number of USE-ORDER, %%d instead of %d..%d\", to_send);\n"
2203 " uo_limit = -1;\n" /* squash the loop */
2205 " else {\n" /* check duplicates */
2206 " int *seen = new int [to_send];\n"
2207 " int num_seen = 0;\n"
2208 " for (int ei = 0; ei < to_send; ++ei) {\n"
2209 " int val = field_%s[ei];\n"
2210 " for (int x = 0; x < num_seen; ++x) {\n"
2211 " if (val == seen[x]) { // complain\n"
2212 " ec_1.set_msg(\"%s': \");\n"
2213 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,\n"
2214 " \"Duplicate value for USE-ORDER\");\n"
2215 " uo_limit = -1; // don't bother sending anything\n"
2219 " seen[num_seen++] = val;\n"
2225 , min_ordered
, max_ordered
2226 , sdef
->elements
[start_at
-1].dispname
2227 , min_ordered
, max_ordered
2228 , sdef
->elements
[start_at
-1].name
2229 , sdef
->elements
[start_at
-1].dispname
2232 src
= mputprintf(src
,
2233 " for (int i = 0; i < uo_limit; ++i) {\n"
2234 " switch (dis_order ? (int)field_%s[i] : i) {\n"
2235 , sdef
->elements
[start_at
-1].name
2237 for ( i
= base
; i
< limit
; ++i
) {
2238 src
= mputprintf(src
,
2240 " ec_1.set_msg(\"%s': \");\n"
2241 " sub_len += field_%s%s%s%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+!omit_tag, %s);\n"
2243 , (unsigned long)offset
++
2244 , sdef
->elements
[i
].dispname
2245 , (sdef
->xerUseNilPossible
? sdef
->elements
[sdef
->nElements
-1].name
: sdef
->elements
[i
].name
)
2246 , (sdef
->xerUseNilPossible
? "()." : "")
2247 , (sdef
->xerUseNilPossible
? sdef
->elements
[i
].name
: "")
2248 , (sdef
->xerUseNilPossible
? "()" : "")
2249 , sdef
->elements
[i
].typegen
2250 , sdef
->xerEmbedValuesPossible
? "emb_val" : "0"
2253 src
= mputstr(src
, " break;\n");
2254 } /* next element */
2257 " TTCN_error(\"Runaway value while encoding USE-ORDER\");\n"
2258 " break;\n" /* cannot happen, complain */
2261 if (sdef
->xerEmbedValuesPossible
) {
2262 src
= mputprintf(src
,
2263 " if (e_xer && (p_td.xer_bits & EMBED_VALUES) && 0 != emb_val &&\n"
2264 " %s%s%s emb_val->embval_index < field_%s%s.size_of()) { // embed-val\n"
2265 " field_%s%s[emb_val->embval_index].XER_encode(\n"
2266 " UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n"
2267 " ++emb_val->embval_index;\n"
2269 , sdef
->elements
[0].isOptional
? "field_" : ""
2270 , sdef
->elements
[0].isOptional
? sdef
->elements
[0].name
: ""
2271 , sdef
->elements
[0].isOptional
? ".ispresent() &&" : ""
2272 , sdef
->elements
[0].name
2273 , sdef
->elements
[0].isOptional
? "()" : "", sdef
->elements
[0].name
2274 , sdef
->elements
[0].isOptional
? "()" : "");
2279 " }\n" /* end of loop */
2281 if (sdef
->xerUseNilPossible
) {
2282 src
= mputstr(src
, " } // nil_attr\n");
2285 else /* not USE-ORDER */
2286 for ( /* continue with i */; i
< sdef
->nElements
; ++i
) {
2287 src
= mputprintf(src
,
2288 " ec_1.set_msg(\"%s': \");\n"
2289 , sdef
->elements
[i
].dispname
2291 src
= mputprintf(src
,
2292 " sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor%s, p_indent+!omit_tag, %s);\n"
2293 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typegen
2294 , sdef
->xerUseNilPossible
? "| (p_td.xer_bits & USE_NIL)" : ""
2295 , sdef
->xerEmbedValuesPossible
? "emb_val" : "0"
2298 if (sdef
->xerEmbedValuesPossible
) {
2299 src
= mputprintf(src
,
2300 " if (e_xer && (p_td.xer_bits & EMBED_VALUES) && 0 != emb_val &&\n"
2301 " %s%s%s emb_val->embval_index < field_%s%s.size_of()) {\n"
2302 " field_%s%s[emb_val->embval_index].XER_encode(\n"
2303 " UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n"
2304 " ++emb_val->embval_index;\n"
2306 , sdef
->elements
[0].isOptional
? "field_" : ""
2307 , sdef
->elements
[0].isOptional
? sdef
->elements
[0].name
: ""
2308 , sdef
->elements
[0].isOptional
? ".ispresent() &&" : ""
2309 , sdef
->elements
[0].name
2310 , sdef
->elements
[0].isOptional
? "()" : "", sdef
->elements
[0].name
2311 , sdef
->elements
[0].isOptional
? "()" : "");
2313 } /* next field when not USE-ORDER */
2315 if (sdef
->xerEmbedValuesPossible
) {
2316 src
= mputprintf(src
,
2317 " if (0 != emb_val) {\n"
2318 " if (%s%s%s emb_val->embval_index < field_%s%s.size_of()) {\n"
2319 " ec_1.set_msg(\"%s': \");\n"
2320 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,\n"
2321 " \"Too many EMBED-VALUEs specified: %%d (expected %%d or less)\",\n"
2322 " field_%s%s.size_of(), emb_val->embval_index);\n"
2324 " delete emb_val;\n"
2326 , sdef
->elements
[0].isOptional
? "field_" : ""
2327 , sdef
->elements
[0].isOptional
? sdef
->elements
[0].name
: ""
2328 , sdef
->elements
[0].isOptional
? ".ispresent() &&" : ""
2329 , sdef
->elements
[0].name
, sdef
->elements
[0].isOptional
? "()" : ""
2330 , sdef
->elements
[0].name
, sdef
->elements
[0].name
2331 , sdef
->elements
[0].isOptional
? "()" : "");
2334 src
= mputstr(src
, " } // QN?\n");
2337 src
= mputprintf(src
,
2338 " if (!omit_tag) {\n"
2339 " if (sub_len) {\n" /* something was written, now an end tag */
2340 " if (is_indented && !(e_xer && (p_td.xer_bits & (HAS_1UNTAGGED | USE_QNAME)))) {\n"
2341 " switch ((int)(e_xer && (p_td.xer_bits & USE_NIL))) {\n"
2343 " const unsigned char *buf_end = p_buf.get_data() + (p_buf.get_len()-1);\n"
2344 " if (buf_end[-1] != '>' || *buf_end != '\\n') break;\n"
2345 /* else fall through */
2348 " do_indent(p_buf, p_indent);\n"
2352 " p_buf.put_c('<');\n"
2353 " p_buf.put_c('/');\n"
2354 " if (e_xer) write_ns_prefix(p_td, p_buf);\n"
2355 " p_buf.put_s((size_t)p_td.namelens[e_xer]-!is_indented, (cbyte*)p_td.names[e_xer]);\n"
2356 " } else {\n" /* need to generate an empty element tag */
2357 " p_buf.increase_length(%s-1);\n" /* decrease length */
2358 " p_buf.put_s((size_t)2+is_indented, (cbyte*)\"/>\\n\");\n"
2360 , (sdef
->xerUntaggedOne
/*|| sdef->xerUseNil*/) ? "" : "-is_indented"
2364 " return (int)p_buf.get_len() - encoded_length;\n"
2368 src
= mputprintf(src
, "// %s has%s%s%s%s%s%s%s%s%s\n"
2369 "// written by %s in " __FILE__
" at %d\n"
2371 , (sdef
->xerUntagged
? " UNTAGGED" : "")
2372 , (sdef
->xerUntaggedOne
? "1" : "")
2373 , (sdef
->xerUseNilPossible
? " USE_NIL?" : "")
2374 , (sdef
->xerUseOrderPossible
? " USE_ORDER?" : "")
2375 , (sdef
->xerUseQName
? " USE_QNAME" : "")
2376 , (sdef
->xerUseTypeAttr
? " USE_TYPE_ATTR" : "")
2377 , (sdef
->xerUseUnion
? " USE-UNION" : "")
2378 , (sdef
->xerHasNamespaces
? " namespace" : "")
2379 , (sdef
->xerEmbedValuesPossible
? " EMBED?" : "")
2380 , __FUNCTION__
, __LINE__
2384 src
= mputprintf(src
, /* XERSTUFF decodegen for record/SEQUENCE*/
2385 "int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader,"
2386 " unsigned int p_flavor, unsigned int p_flavor2, embed_values_dec_struct_t*)\n"
2388 /* Remove XER_LIST, XER_RECOF from p_flavor. This is not required
2389 * for is_exer (which tests another bit), but for subsequent code. */
2390 " int e_xer = is_exer(p_flavor);\n"
2391 " int xerbits = p_td.xer_bits;\n"
2392 " if (p_flavor & XER_TOPLEVEL) xerbits &= ~UNTAGGED;\n"
2393 " const boolean omit_tag = e_xer && ((xerbits & (UNTAGGED|XER_ATTRIBUTE)) "
2394 "|| (p_flavor & (USE_NIL|USE_TYPE_ATTR)));\n"
2396 " const boolean parent_tag = e_xer && ((p_flavor & USE_TYPE_ATTR)|| (p_flavor2 & USE_NIL_PARENT_TAG));\n"
2397 " (void)parent_tag;\n"
2398 " p_flavor &= XER_MASK;\n" /* also removes "toplevel" bit */
2399 " p_flavor2 = XER_NONE;\n" /* Remove only bit: USE_NIL_PARENT_TAG (for now) */
2400 " int rd_ok, xml_depth=-1, type;\n"
2401 " {\n" /* scope for the error contexts */
2403 , (start_at
+ num_attributes
< sdef
->nElements
|| (sdef
->xerEmbedValuesPossible
&& num_attributes
==0)
2404 ? " boolean tag_closed = (p_flavor & PARENT_CLOSED) != 0;\n" : "")
2405 /* tag_closed needed for non-attribute normal members only,
2406 * or if EMBED-VALUES is possible, but isn't. */
2409 if (sdef
->xerUseNilPossible
) { src
= mputstr(src
,
2410 " boolean nil_attribute = FALSE;\n"
2411 " boolean already_processed = FALSE;\n");
2414 src
= mputprintf(src
,
2415 " TTCN_EncDec_ErrorContext ec_0(\"Component '\");\n"
2416 " TTCN_EncDec_ErrorContext ec_1;\n"
2417 " if (!omit_tag) for (rd_ok=p_reader.Ok(); rd_ok==1; rd_ok=p_reader.Read()) {\n"
2418 " type = p_reader.NodeType();\n"
2419 " if (type==XML_READER_TYPE_ELEMENT) {\n"
2420 " verify_name(p_reader, p_td, e_xer);\n"
2421 " xml_depth = p_reader.Depth();\n"
2426 , (start_at
+ num_attributes
< sdef
->nElements
|| (sdef
->xerEmbedValuesPossible
&& num_attributes
==0)
2427 ? " tag_closed = p_reader.IsEmptyElement();\n": "")
2431 if (sdef
->xerUseQName
) {
2432 src
= mputprintf(src
,
2433 " if (e_xer && (p_td.xer_bits & USE_QNAME)) {\n"
2434 " if (p_td.xer_bits & XER_ATTRIBUTE) rd_ok = 1;\n"
2435 " else for (rd_ok = p_reader.Read(); rd_ok == 1; rd_ok = p_reader.Read()) {\n"
2436 " type = p_reader.NodeType();\n"
2437 " if (type == XML_READER_TYPE_TEXT) break;\n"
2439 " if (rd_ok==1) {\n"
2440 " xmlChar *new_val = p_reader.NewValue();\n"
2441 " xmlChar *v_npfx = (xmlChar*)strchr((char*)new_val, ':');\n"
2442 " xmlChar *v_pfx;\n"
2443 " if (v_npfx != NULL) {\n"
2444 " *v_npfx++ = '\\0';\n"
2445 " v_pfx = new_val;\n"
2448 " v_npfx = new_val;\n"
2451 " xmlChar *q_ns = p_reader.LookupNamespace(v_pfx);\n"
2452 " if (q_ns) field_%s = (const char*)q_ns;\n"
2453 " else field_%s = OMIT_VALUE;\n"
2454 " field_%s = (const char*)v_npfx;\n"
2456 " xmlFree(new_val);\n"
2459 , sdef
->elements
[0].name
2460 , sdef
->elements
[0].name
2461 , sdef
->elements
[1].name
2465 if (num_attributes
|| sdef
->xerEmbedValuesPossible
|| sdef
->xerUseOrderPossible
) {
2466 src
= mputstr(src
, "if (e_xer) {\n");
2469 /* ********************************************************************
2471 ***************************/
2472 if (num_attributes
|| sdef
->xerUseNilPossible
/* maybe QNAME too ? */) {
2475 /* Prepare for attributes not present in the XML.
2476 * Set all attributes with defaultForEmpty to the D-F-E value.
2477 * Set all optional components with ATTRIBUTE to omit.
2479 * If EMBED-VALUES is possible, the first component can't be optional.
2480 * The same is true for the USE-ORDER component. Hence start_at. */
2481 for (aaa
= start_at
; aaa
< start_at
+ num_attributes
; ++aaa
) {
2482 if (sdef
->elements
[aaa
].xerAttribute
) { /* "proper" ATTRIBUTE */
2483 src
= mputprintf(src
,
2484 " if (%s_xer_.dfeValue) field_%s = "
2485 "*static_cast<const %s*>(%s_xer_.dfeValue);\n"
2486 , sdef
->elements
[aaa
].typegen
, sdef
->elements
[aaa
].name
2487 , sdef
->elements
[aaa
].type
, sdef
->elements
[aaa
].typegen
);
2488 if (sdef
->elements
[aaa
].isOptional
) src
= mputprintf(src
,
2489 " else field_%s = OMIT_VALUE;\n", sdef
->elements
[aaa
].name
);
2491 else { /* must be the ANY-ATTRIBUTES */
2492 src
= mputprintf(src
,
2494 , sdef
->elements
[aaa
].name
2495 , sdef
->elements
[aaa
].isOptional
? " = OMIT_VALUE" : ".set_size(0)");
2499 src
= mputstr(src
, " if (!omit_tag || parent_tag) {\n");
2501 if (num_attributes
==0 /* therefore sdef->xerUseNilPossible is true */ ) {
2502 /* Only the "nil" attribute may be present. If there is no USE-NIL,
2503 * then there can be no attributes at all. */
2505 " if (e_xer && (p_td.xer_bits & (USE_NIL|USE_TYPE_ATTR))) {\n");
2508 if (aa_index
> -1) src
= mputstr(src
, " size_t num_aa = 0;\n");
2509 if (sdef
->xerUseNilPossible
) {
2511 " static const namespace_t *control_ns = p_td.my_module->get_controlns();\n");
2515 " if(parent_tag && p_reader.NodeType() == XML_READER_TYPE_ATTRIBUTE) {\n"
2516 " rd_ok = p_reader.Ok();\n"
2518 " rd_ok = p_reader.MoveToFirstAttribute();\n"
2520 " for (; rd_ok==1 && "
2521 "p_reader.NodeType()==XML_READER_TYPE_ATTRIBUTE; "
2522 "rd_ok = p_reader.AdvanceAttribute()) {\n"
2523 " if (p_reader.IsNamespaceDecl()) continue;\n");
2524 /* if the only attribute is ANY-ATTRIBUTE, it doesn't need attr_name */
2525 if (num_attributes
==1 && aa_index
!=-1 /*&& !sdef->xerUseNilPossible*/) {}
2528 " const char *attr_name = (const char*)p_reader.LocalName();\n"
2529 " const char *ns_uri = (const char*)p_reader.NamespaceUri();\n");
2532 if (sdef
->xerUseNilPossible
) {
2533 src
= mputprintf(src
,
2534 " const char *prefix = (const char*)p_reader.Prefix();\n"
2535 /* prefix may be NULL, control_ns->px is never NULL or empty */
2536 " if (prefix && !strcmp(prefix, control_ns->px)\n"
2537 " && !strcmp((const char*)p_reader.LocalName(), \"nil\")){\n"
2538 " const char *value = (const char*)p_reader.Value();\n"
2539 " if (!strcmp(value, \"1\") || !strcmp(value, \"true\")) {\n"
2540 " field_%s = OMIT_VALUE;\n"
2541 " nil_attribute = TRUE;\n"
2542 /* found the "nil" attribute */
2545 , sdef
->elements
[sdef
->nElements
-1].name
);
2548 for (i
= start_at
; i
< start_at
+ num_attributes
; ++i
) {
2549 if (i
== aa_index
) continue; /* ANY_ATTR. is handled below */
2550 src
= mputprintf(src
,
2551 " if (check_name(attr_name, %s_xer_, 1) && check_namespace(ns_uri, %s_xer_)) {\n"
2552 " ec_1.set_msg(\"%s': \");\n"
2553 " field_%s.XER_decode(%s_xer_, p_reader, p_flavor | (p_td.xer_bits & USE_NIL), p_flavor2, 0);\n"
2555 , sdef
->elements
[i
].typegen
, sdef
->elements
[i
].typegen
2556 , sdef
->elements
[i
].dispname
/* set_msg */
2557 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typegen
2561 if(sdef
->xerUseNilPossible
) {
2562 src
= mputprintf(src
,
2563 " if(p_td.xer_bits & USE_NIL) {\n"
2564 " field_%s.XER_decode(%s_xer_, p_reader, p_flavor | USE_NIL, p_flavor2 | USE_NIL_PARENT_TAG, 0);\n"
2565 " already_processed = TRUE;\n"
2568 , sdef
->elements
[sdef
->nElements
-1].name
2569 , sdef
->elements
[sdef
->nElements
-1].typegen
2573 if (sdef
->control_ns_prefix
&& !(num_attributes
==1 && aa_index
!=-1)) {
2574 src
= mputprintf(src
,
2575 " if (parent_tag && !strcmp(attr_name, \"type\") "
2576 "&& !strcmp((const char*)p_reader.Prefix(), \"%s\")) {} else\n"
2577 , sdef
->control_ns_prefix
);
2578 /* xsi:type; already processed by parent with USE-UNION or USE-TYPE */
2582 if (aa_index
>= 0) {
2583 /* we are at a dangling else */
2584 src
= mputprintf(src
,
2586 " TTCN_EncDec_ErrorContext ec_0(\"Attribute %%d: \", (int)num_aa);\n"
2587 " UNIVERSAL_CHARSTRING& new_elem = field_%s%s[num_aa++];\n"
2588 /* Construct the AnyAttributeFormat (X.693amd1, 18.2.6) */
2589 " TTCN_Buffer aabuf;\n"
2590 " const xmlChar *x_name = p_reader.LocalName();\n"
2591 " const xmlChar *x_val = p_reader.Value();\n"
2592 " const xmlChar *x_uri = p_reader.NamespaceUri();\n"
2593 " if (%s_xer_.xer_bits & (ANY_FROM | ANY_EXCEPT)) {\n"
2594 " check_namespace_restrictions(%s_xer_, (const char*)x_uri);\n"
2596 /* We don't care about p_reader.Prefix() */
2597 /* Using strlen to count bytes */
2598 " aabuf.put_s(x_uri ? strlen((const char*)x_uri) : 0, x_uri);\n"
2599 " if (x_uri && *x_uri) aabuf.put_c(' ');\n"
2600 " aabuf.put_s(x_name ? strlen((const char*)x_name) : 0, x_name);\n"
2601 " aabuf.put_c('=');\n"
2602 " aabuf.put_c('\"');\n"
2603 " aabuf.put_s(x_val ? strlen((const char*)x_val) : 0, x_val);\n"
2604 " aabuf.put_c('\"');\n"
2605 " new_elem.decode_utf8(aabuf.get_len(), aabuf.get_data());\n"
2607 , sdef
->elements
[aa_index
].name
2608 , sdef
->elements
[aa_index
].isOptional
? "()" : ""
2609 , sdef
->elements
[aa_index
].typegen
, sdef
->elements
[aa_index
].typegen
2613 /* we are at a dangling else */
2614 src
= mputstr(src
, " {\n");
2615 if (sdef
->control_ns_prefix
) {
2616 src
= mputprintf(src
,
2617 // Lastly check for the xsi:schemaLocation attribute, this does not
2618 // affect TTCN-3, but it shouldn't cause a DTE
2619 " if (!p_reader.LocalName() || strcmp((const char*)p_reader.LocalName(), \"schemaLocation\") ||\n"
2620 " !p_reader.Prefix() || strcmp((const char*)p_reader.Prefix(), \"%s\"))\n"
2621 , sdef
->control_ns_prefix
);
2625 " ec_0.set_msg(\" \"); ec_1.set_msg(\" \");\n" /* we have no component */
2626 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, "
2627 "\"Unexpected attribute '%s', ns '%s'\", attr_name, ns_uri ? ns_uri : \"\");\n"
2631 src
= mputstr(src
, " }\n"); /* for */
2633 for (i
= start_at
; i
< start_at
+ num_attributes
; ++i
) {
2634 if (sdef
->elements
[i
].isOptional
) continue; /* allowed to be missing */
2635 src
= mputprintf(src
, " if (!field_%s.is_bound()) "
2636 "TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, "
2637 "\"Missing attribute '%s'\");\n"
2638 , sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
);
2641 if (num_attributes
==0) src
= mputstr(src
, " }\n"); /* if USE_NIL or USE_TYPE_ATTR */
2642 src
= mputstr(src
, " }\n"); /* process (attributes) in (own or parent) tag */
2643 } /* * * * * * * * * end if(attributes...) * * * * * * * * * * * * */
2645 src
= mputprintf(src
,
2646 " if ((!omit_tag || parent_tag) && !p_reader.IsEmptyElement()%s) "
2647 "rd_ok = p_reader.Read();\n"
2648 , sdef
->xerUseNilPossible
? " && !already_processed" : "");
2650 if (sdef
->xerEmbedValuesPossible
&& num_attributes
==0) {
2651 /* EMBED-VALUES possible, but isn't: the first component is a non-special
2652 * record of strings. This means there are no attributes, unless
2653 * the first component is an ATTRIBUTE or ANY-ATTRIBUTES. */
2654 src
= mputprintf(src
,
2655 " if (!(p_td.xer_bits & EMBED_VALUES)) {\n"
2656 " ec_1.set_msg(\"%s': \");\n"
2657 " field_%s.XER_decode(%s_xer_, p_reader, "
2658 "p_flavor | (p_td.xer_bits & USE_NIL)| (tag_closed ? PARENT_CLOSED : XER_NONE), p_flavor2, 0);\n"
2660 , sdef
->elements
[0].dispname
2661 , sdef
->elements
[0].name
, sdef
->elements
[0].typegen
2665 if (num_attributes
|| sdef
->xerEmbedValuesPossible
|| sdef
->xerUseOrderPossible
) {
2667 "} else {\n" /* now the non-EXER processing of (would-be) attributes */
2668 " if (!p_reader.IsEmptyElement()) p_reader.Read();\n"
2672 if (sdef
->xerUseOrderPossible
) {
2674 " if (e_xer && p_td.xer_bits & USE_ORDER) ; else {");
2677 if (start_at
+ num_attributes
> 0)
2679 /* No attributes nor USE-NIL:
2680 * Just decode the specials and would-be attributes. */
2682 // FIXME: WTF is this?
2683 //if (sdef->xerEmbedValuesPossible) {
2684 // /* Only decode the first member if it really is EMBED-VALUES */
2685 // src = mputprintf(src, "if (p_td.xer_bits & EMBED_VALUES) ");
2687 for (i
= 0; i
< start_at
+ num_attributes
; ++i
) {
2688 /* Decode the field */
2689 src
= mputprintf(src
,
2691 " ec_1.set_msg(\"%s': \");\n"
2692 " field_%s.XER_decode(%s_xer_, p_reader, p_flavor | (p_td.xer_bits & USE_NIL), p_flavor2, 0);\n"
2694 , sdef
->elements
[i
].dispname
2695 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typegen
2699 if (sdef
->xerUseOrderPossible
) {
2700 src
= mputstr(src
, " }\n");
2704 if (num_attributes
|| sdef
->xerEmbedValuesPossible
|| sdef
->xerUseOrderPossible
) {
2705 src
= mputstr(src
, "}\n");
2708 if (sdef
->xerEmbedValuesPossible
) {
2709 src
= mputprintf(src
,
2710 " embed_values_dec_struct_t* emb_val = 0;\n"
2711 " if (e_xer && (p_td.xer_bits & EMBED_VALUES)) {\n"
2712 " emb_val = new embed_values_dec_struct_t;\n"
2713 /* If the first field is a record of ANY-ELEMENTs, then it won't be a pre-generated
2714 * record of universal charstring, so it needs a cast to avoid a compilation error */
2715 " emb_val->embval_array%s = (PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING%s*)&field_%s%s;\n"
2716 " emb_val->embval_array%s = NULL;\n"
2717 " emb_val->embval_index = 0;\n"
2718 " field_%s%s.set_size(0);\n"
2720 , sdef
->elements
[0].optimizedMemAlloc
? "_opt" : "_reg"
2721 , sdef
->elements
[0].optimizedMemAlloc
? "__OPTIMIZED" : ""
2722 , sdef
->elements
[0].name
2723 , sdef
->elements
[0].isOptional
? "()" : ""
2724 , sdef
->elements
[0].optimizedMemAlloc
? "_reg" : "_opt"
2725 , sdef
->elements
[0].name
2726 , sdef
->elements
[0].isOptional
? "()" : "");
2729 if (sdef
->xerUseOrderPossible
) {
2730 size_t begin
= start_at
+ num_attributes
; /* first non-attribute */
2731 size_t end
= sdef
->nElements
;
2732 size_t n_optionals
= 0, n_embed
;
2733 int max_ordered
= sdef
->nElements
- start_at
- num_attributes
;
2734 int min_ordered
= max_ordered
- n_opt_elements
;
2735 if (sdef
->xerUseNilPossible
) { /* USE-NIL on top of USE-ORDER */
2736 begin
= sdef
->nElements
;
2737 end
= sdef
->totalElements
;
2739 n_embed
= end
- begin
;
2742 " if (e_xer && (p_td.xer_bits & USE_ORDER)) {\n"
2744 for (i
= begin
; i
< end
; ++i
) {
2745 if (sdef
->elements
[i
].isOptional
) {
2746 src
= mputprintf(src
, " field_%s = OMIT_VALUE;\n",
2747 sdef
->elements
[i
].name
);
2752 if (sdef
->xerUseNilPossible
) { /* USE-NIL and USE-ORDER */
2753 src
= mputprintf(src
,
2754 " if (nil_attribute) field_%s.set_size(0);\n else"
2755 , sdef
->elements
[uo
].name
);
2758 src
= mputprintf(src
,
2760 " field_%s.set_size(0);\n"
2761 " if (!tag_closed) {\n" /* Nothing to order if there are no child elements */
2762 " int e_val, num_seen = 0, *seen_f = new int[%lu];\n"
2763 , sdef
->elements
[uo
].name
2764 , (unsigned long)(n_embed
)
2766 if (sdef
->xerEmbedValuesPossible
) {
2767 // The index of the latest embedded value can change outside of this function
2768 // (if the field is a untagged record of), in this case the next value should
2769 // be ignored, as it's already been handled by the record of
2770 src
= mputstr(src
, " int last_embval_index = 0;\n");
2772 src
= mputprintf(src
,
2773 " bool early_exit = false;\n"
2774 " for (int i=0; i < %lu; ++i) {\n"
2775 " for (rd_ok=p_reader.Ok(); rd_ok==1; rd_ok=p_reader.Read()) {\n"
2776 , (unsigned long)(n_embed
));
2778 if (sdef
->xerEmbedValuesPossible
) {
2779 /* read and store embedValues text if present */
2780 src
= mputprintf(src
,
2781 " if (0 != emb_val && p_reader.NodeType()==XML_READER_TYPE_TEXT) {\n"
2782 " UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
2783 " field_%s%s[emb_val->embval_index] = emb_ustr;\n"
2785 , sdef
->elements
[0].name
2786 , sdef
->elements
[0].isOptional
? "()" : "");
2790 " type = p_reader.NodeType();\n"
2791 " if (type==XML_READER_TYPE_ELEMENT) break;\n"
2792 " if (type == XML_READER_TYPE_END_ELEMENT) {\n"
2793 " early_exit = true;\n"
2797 " if (rd_ok != 1 || early_exit) break;\n"
2798 " const char * x_name = (const char*)p_reader.LocalName();\n" /* Name or LocalName ? */);
2800 if (sdef
->xerEmbedValuesPossible
) {
2802 " if (0 != emb_val) {\n"
2803 " if (last_embval_index == emb_val->embval_index) {\n"
2804 " ++emb_val->embval_index;\n"
2806 " last_embval_index = emb_val->embval_index;\n"
2810 /* * * * * code for USE-ORDER * * * * */
2812 for (i
= begin
; i
< end
; ++i
) {
2813 // Check non-anyElement fields first
2814 if (!(sdef
->elements
[i
].xerAnyKind
& ANY_ELEM_BIT
)) {
2815 src
= mputprintf(src
,
2816 " if (check_name(x_name, %s_xer_, 1)) {\n"
2817 " ec_1.set_msg(\"%s': \");\n"
2818 " field_%s%s%s%s.XER_decode(%s_xer_, p_reader, p_flavor, p_flavor2, %s);\n"
2819 , sdef
->elements
[i
].typegen
2820 , sdef
->elements
[i
].dispname
2821 , (sdef
->xerUseNilPossible
? sdef
->elements
[sdef
->nElements
-1].name
: sdef
->elements
[i
].name
)
2822 , (sdef
->xerUseNilPossible
? "()." : "")
2823 , (sdef
->xerUseNilPossible
? sdef
->elements
[i
].name
: "")
2824 , (sdef
->xerUseNilPossible
? "()" : "")
2825 , sdef
->elements
[i
].typegen
2826 , sdef
->xerEmbedValuesPossible
? "emb_val" : "0"
2828 src
= mputprintf(src
,
2829 " field_%s[i] = e_val = %s::of_type::%s;\n"
2830 , sdef
->elements
[uo
].name
2831 , sdef
->elements
[uo
].typegen
, sdef
->elements
[i
].name
);
2832 src
= mputstr(src
, " }\n else");
2837 " boolean any_found = false;\n"
2838 " if (!any_found)");
2839 for (i
= begin
; i
< end
; ++i
) {
2840 // Check anyElement fields after all other fields
2841 if (sdef
->elements
[i
].xerAnyKind
& ANY_ELEM_BIT
) {
2842 src
= mputstr(src
, " {\n");
2843 src
= mputprintf(src
,
2844 " e_val = %s::of_type::%s;\n"
2845 , sdef
->elements
[uo
].typegen
, sdef
->elements
[i
].name
);
2846 src
= mputprintf(src
,
2847 " boolean next_any = false;\n"
2848 " for (int d_f = 0; d_f < num_seen; ++d_f) {\n"
2849 " if (e_val == seen_f[d_f]) {\n"
2850 " next_any = true;\n"
2853 " if (!next_any) {\n"
2854 " ec_1.set_msg(\"%s': \");\n"
2855 " field_%s%s%s%s.XER_decode(%s_xer_, p_reader, p_flavor, p_flavor2, 0);\n"
2856 " field_%s[i] = e_val;\n"
2857 " any_found = true;\n"
2861 , sdef
->elements
[i
].dispname
2862 , (sdef
->xerUseNilPossible
? sdef
->elements
[sdef
->nElements
-1].name
: sdef
->elements
[i
].name
)
2863 , (sdef
->xerUseNilPossible
? "()." : "")
2864 , (sdef
->xerUseNilPossible
? sdef
->elements
[i
].name
: "")
2865 , (sdef
->xerUseNilPossible
? "()" : "")
2866 , sdef
->elements
[i
].typegen
, sdef
->elements
[uo
].name
2872 " {\n" /* take care of the dangling else */
2873 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n"
2874 " \"Bad XML tag '%s' instead of a valid field\", x_name);\n"
2878 " for (int d_f = 0; d_f < num_seen; ++d_f)\n"
2879 " if (e_val == seen_f[d_f])\n"
2880 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT, \"Duplicate field\");\n"
2881 " seen_f[num_seen++] = e_val;\n"
2884 if (sdef
->xerEmbedValuesPossible
) {
2885 /* read and store embedValues text if present */
2886 src
= mputprintf(src
,
2887 " if (0 != emb_val) {\n"
2888 " if (p_reader.NodeType()==XML_READER_TYPE_TEXT) {\n"
2889 " UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
2890 " field_%s%s[emb_val->embval_index] = emb_ustr;\n"
2892 " if (last_embval_index == emb_val->embval_index) {\n"
2893 " ++emb_val->embval_index;\n"
2896 , sdef
->elements
[0].name
2897 , sdef
->elements
[0].isOptional
? "()" : "");
2900 src
= mputprintf(src
,
2901 " delete [] seen_f;\n"
2903 " int n_collected = field_%s.size_of();\n"
2904 " if (p_td.xer_bits & USE_NIL) {\n"
2907 " if (n_collected < %d || n_collected > %d) {\n"
2908 " ec_0.set_msg(\" \");\n"
2909 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT, \"Wrong number of elements\");\n"
2912 " } // !tag_closed\n"
2913 " } else { // !uo\n"
2914 , sdef
->elements
[uo
].dispname
2915 , min_ordered
, max_ordered
2917 } /* end if(UseOrder possible) */
2919 /* * * * * non-UseOrder code always written, executed when * * * *
2920 * * * * * UseOrder not possible or in the "else" clause * * * * */
2922 if (sdef
->xerUseNilPossible
) {
2923 /* value absent, nothing more to do */
2925 " if (nil_attribute) {\n"
2926 " p_reader.MoveToElement();\n"
2929 if (sdef
->xerEmbedValuesPossible
) {
2930 // The index of the latest embedded value can change outside of this function
2931 // (if the field is a untagged record of), in this case the next value should
2932 // be ignored, as it's already been handled by the record of
2933 // Omitted fields can also reset this value
2934 src
= mputstr(src
, " int last_embval_index = 0;\n");
2936 /* for all the non-attribute fields... */
2937 for (i
= start_at
+ num_attributes
; i
< sdef
->nElements
; ++i
) {
2938 if (sdef
->xerEmbedValuesPossible
) {
2939 /* read and store embedValues text if present */
2940 src
= mputprintf(src
,
2941 " if (0 != emb_val) {\n"
2942 " if (p_reader.NodeType()==XML_READER_TYPE_TEXT) {\n"
2943 " UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
2944 " field_%s%s[emb_val->embval_index] = emb_ustr;\n"
2946 " if (last_embval_index == emb_val->embval_index) {\n"
2947 " ++emb_val->embval_index;\n"
2949 " last_embval_index = emb_val->embval_index;\n"
2951 , sdef
->elements
[0].name
2952 , sdef
->elements
[0].isOptional
? "()" : "");
2954 /* The DEFAULT-FOR-EMPTY member can not be involved with EMBED-VALUES,
2955 * so we can use the same pattern: optional "if(...) else" before {}
2956 * XXX check with single-element record where nElements-1 == 0 !! */
2957 if (sdef
->kind
== RECORD
&& i
== sdef
->nElements
-1) {
2958 src
= mputprintf(src
,
2959 " if (e_xer && p_td.dfeValue && p_reader.IsEmptyElement()) {\n"
2960 " field_%s = *static_cast<const %s*>(p_td.dfeValue);\n"
2963 , sdef
->elements
[i
].name
, sdef
->elements
[i
].type
2964 , sdef
->xerUseNilPossible
? " if (!already_processed)" : "");
2966 /* Decode the field */
2967 src
= mputprintf(src
,
2969 " ec_1.set_msg(\"%s': \");\n"
2970 , sdef
->elements
[i
].dispname
);
2972 if ( (sdef
->elements
[i
].xerAnyKind
& ANY_ELEM_BIT
)
2973 && !strcmp(sdef
->elements
[i
].type
,"UNIVERSAL_CHARSTRING") ) {
2974 // In case the field is an optional anyElement -> check if it should be omitted
2975 if (sdef
->elements
[i
].isOptional
) {
2976 src
= mputprintf(src
,
2977 " if (field_%s.XER_check_any_elem(p_reader, \"%s\", tag_closed))\n "
2978 , sdef
->elements
[i
].name
2979 , (i
== sdef
->nElements
- 1) ? "NULL" : sdef
->elements
[i
+ 1].name
);
2981 // If the record is emptyElement, there's no way it will have an anyElement field
2982 src
= mputstr(src
, " if (tag_closed) p_reader.Read(); \n");
2986 src
= mputprintf(src
,
2987 " field_%s.XER_decode(%s_xer_, p_reader, p_flavor"
2988 " | (p_td.xer_bits & USE_NIL)| (tag_closed ? PARENT_CLOSED : XER_NONE), p_flavor2, %s);\n"
2990 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typegen
2991 , sdef
->xerEmbedValuesPossible
? "emb_val" : "0");
2992 if (sdef
->xerEmbedValuesPossible
) {
2993 src
= mputprintf(src
,
2994 " if (!field_%s.is_present()) {\n"
2995 // there was no new element, the last embedded value is for the next field
2996 // (or the end of the record if this is the last field)
2997 " last_embval_index = -1;\n"
2999 , sdef
->elements
[i
].name
);
3003 if (sdef
->xerEmbedValuesPossible
) {
3004 /* read and store embedValues text if present */
3005 src
= mputprintf(src
,
3006 " if (0 != emb_val) {\n"
3007 " if (p_reader.NodeType()==XML_READER_TYPE_TEXT) {\n"
3008 " UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
3009 " field_%s%s[emb_val->embval_index] = emb_ustr;\n"
3011 " if (last_embval_index == emb_val->embval_index) {\n"
3012 " ++emb_val->embval_index;\n"
3015 , sdef
->elements
[0].name
3016 , sdef
->elements
[0].isOptional
? "()" : "");
3019 if (sdef
->xerUseNilPossible
) {
3020 src
= mputstr(src
, " } // use_nil\n");
3023 if (sdef
->xerUseOrderPossible
) {
3024 src
= mputstr(src
, " } // uo\n");
3027 if (sdef
->xerEmbedValuesPossible
) {
3028 src
= mputprintf(src
,
3030 " if (0 != emb_val) {\n"
3031 " %s::of_type empty_string(\"\");\n"
3032 " for (int j_j = 0; j_j < emb_val->embval_index; ++j_j) {\n"
3033 " if (!field_%s%s[j_j].is_bound()) {\n"
3034 " field_%s%s[j_j] = empty_string;\n"
3037 " delete emb_val;\n"
3039 , sdef
->elements
[0].isOptional
? " bool all_unbound = true;\n" : ""
3040 , sdef
->elements
[0].type
3041 , sdef
->elements
[0].name
3042 , sdef
->elements
[0].isOptional
? "()" : ""
3043 , sdef
->elements
[0].name
3044 , sdef
->elements
[0].isOptional
? "()" : ""
3045 , sdef
->elements
[0].isOptional
? " else if(field_" : "\n"
3046 , sdef
->elements
[0].isOptional
? sdef
->elements
[0].name
: ""
3047 , sdef
->elements
[0].isOptional
? "()" : ""
3048 , sdef
->elements
[0].isOptional
? "[j_j] != empty_string) {\n all_unbound = false;\n }\n" : ""
3051 if(sdef
->elements
[0].isOptional
) {
3052 src
= mputprintf(src
,
3053 " if (e_xer && (p_td.xer_bits & EMBED_VALUES) && all_unbound) {\n"
3054 " field_%s = OMIT_VALUE;\n"
3056 , sdef
->elements
[0].name
3061 if (sdef
->xerUseQName
) {
3062 src
= mputstr(src
, " } // qn\n");
3066 " } // errorcontext\n"); /* End scope for error context objects */
3068 /* Check if every non-optional field has been set */
3069 for (i
= 0; i
< sdef
->nElements
; ++i
) {
3070 if (!sdef
->elements
[i
].isOptional
) {
3071 src
= mputprintf(src
,
3072 " if (!field_%s.is_bound()) {\n"
3073 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG,\n"
3074 " \"No data found for non-optional field '%s'\");\n"
3076 , sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
);
3080 " if (!omit_tag) {\n"
3081 " int current_depth;\n"
3082 " for (rd_ok = p_reader.Ok(); rd_ok == 1; rd_ok = p_reader.Read()) {\n"
3083 " type = p_reader.NodeType();\n"
3084 " if ((current_depth = p_reader.Depth()) > xml_depth) {\n"
3085 " if (XML_READER_TYPE_ELEMENT == type) {\n"
3086 /* An element deeper than our start tag has not been processed */
3087 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG,\n"
3088 " \"Unprocessed XML tag `%s'\", (const char *)p_reader.Name());\n"
3092 " else if (current_depth == xml_depth) {\n"
3093 " if (XML_READER_TYPE_ELEMENT == type) {\n"
3094 " verify_name(p_reader, p_td, e_xer);\n"
3095 " if (p_reader.IsEmptyElement()) {\n"
3096 " p_reader.Read();\n" /* advance one more time */
3100 " else if (XML_READER_TYPE_END_ELEMENT == type) {\n"
3101 " verify_end(p_reader, p_td, xml_depth, e_xer);\n"
3102 " rd_ok = p_reader.Read();\n"
3106 " else break;" /* depth is less, we are in trouble... */
3109 " return 1;\n}\n\n");
3115 void defRecordClass1(const struct_def
*sdef
, output_struct
*output
)
3118 size_t mandatory_fields_count
;
3119 const char *name
= sdef
->name
, *dispname
= sdef
->dispname
;
3120 const char* kind_str
= sdef
->kind
== SET
? "set" : "record";
3121 char *def
= NULL
, *src
= NULL
;
3122 boolean ber_needed
= sdef
->isASN1
&& enable_ber();
3123 boolean raw_needed
= sdef
->hasRaw
&& enable_raw();
3124 boolean text_needed
= sdef
->hasText
&& enable_text();
3125 boolean xer_needed
= sdef
->hasXer
&& enable_xer();
3126 boolean json_needed
= sdef
->hasJson
&& enable_json();
3128 /* class declaration code */
3129 output
->header
.class_decls
= mputprintf(output
->header
.class_decls
,
3130 "class %s;\n", name
);
3132 if (sdef
->nElements
<= 0) {
3133 defEmptyRecordClass(sdef
, output
);
3137 /* class definition and source code */
3138 if(ber_needed
|| raw_needed
|| text_needed
|| xer_needed
|| json_needed
) {
3142 "// written by %s in " __FILE__
" at line %d\n"
3144 "class %s : public Base_Type {\n"
3146 , __FUNCTION__
, __LINE__
3150 def
=mputprintf(def
, "class %s {\n", name
);
3153 for (i
= 0; i
< sdef
->nElements
; i
++) {
3154 if(sdef
->elements
[i
].isOptional
)
3155 def
= mputprintf(def
, " OPTIONAL<%s> field_%s;\n",
3156 sdef
->elements
[i
].type
,
3157 sdef
->elements
[i
].name
);
3159 def
= mputprintf(def
, " %s field_%s;\n",
3160 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
3163 /* default constructor */
3164 def
= mputprintf(def
, "public:\n"
3166 src
= mputprintf(src
, "%s::%s()\n"
3168 "}\n\n", name
, name
);
3170 /* constructor by fields */
3171 def
= mputprintf(def
, " %s(", name
);
3172 src
= mputprintf(src
, "%s::%s(", name
, name
);
3174 for (i
= 0; i
< sdef
->nElements
; i
++) {
3176 if (i
> 0) tmp
= mputstr(tmp
, ",\n ");
3177 if (sdef
->elements
[i
].isOptional
)
3180 "const OPTIONAL<%s>& par_%s",
3181 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
3186 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
3187 def
= mputstr(def
, tmp
);
3188 src
= mputstr(src
, tmp
);
3191 def
= mputstr(def
, ");\n");
3192 src
= mputstr(src
, ")\n"
3194 for (i
= 0; i
< sdef
->nElements
; i
++) {
3195 if (i
> 0) src
= mputstr(src
, ",\n");
3196 src
= mputprintf(src
, " field_%s(par_%s)", sdef
->elements
[i
].name
,
3197 sdef
->elements
[i
].name
);
3199 src
= mputstr(src
, "\n"
3203 /* copy constructor */
3204 def
= mputprintf(def
, " %s(const %s& other_value);\n", name
, name
);
3205 src
= mputprintf(src
, "%s::%s(const %s& other_value)\n"
3207 "if(!other_value.is_bound()) "
3208 "TTCN_error(\"Copying an unbound value of type %s.\");\n",
3209 name
, name
, name
, dispname
);
3210 for (i
= 0; i
< sdef
->nElements
; i
++) {
3211 src
= mputprintf(src
,
3212 "if (other_value.%s().is_bound()) field_%s = other_value.%s();\n"
3213 "else field_%s.clean_up();\n",
3214 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
3215 sdef
->elements
[i
].name
);
3217 src
= mputstr(src
, "}\n\n");
3219 /* not a component */
3220 def
= mputstr(def
, " inline boolean is_component() { return FALSE; }\n");
3223 def
= mputstr(def
, " void clean_up();\n");
3224 src
= mputprintf(src
, "void %s::clean_up()\n"
3226 for (i
= 0; i
< sdef
->nElements
; i
++) {
3227 src
= mputprintf(src
,
3228 "field_%s.clean_up();\n", sdef
->elements
[i
].name
);
3234 def
= mputprintf(def
, " %s& operator=(const %s& other_value);\n", name
, name
);
3235 src
= mputprintf(src
, "%s& %s::operator=(const %s& other_value)\n"
3237 "if (this != &other_value) {\n"
3238 " if(!other_value.is_bound()) "
3239 "TTCN_error(\"Assignment of an unbound value of type %s.\");\n",
3240 name
, name
, name
, dispname
);
3241 for (i
= 0; i
< sdef
->nElements
; i
++) {
3242 src
= mputprintf(src
,
3243 " if (other_value.%s().is_bound()) field_%s = other_value.%s();\n"
3244 " else field_%s.clean_up();\n",
3245 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
3246 sdef
->elements
[i
].name
);
3254 def
= mputprintf(def
, " boolean operator==(const %s& other_value) "
3256 src
= mputprintf(src
,
3257 "boolean %s::operator==(const %s& other_value) const\n"
3259 "return ", name
, name
);
3260 for (i
= 0; i
< sdef
->nElements
; i
++) {
3261 if (i
> 0) src
= mputstr(src
, "\n && ");
3262 src
= mputprintf(src
, "field_%s==other_value.field_%s",
3263 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
3265 src
= mputstr(src
, ";\n}\n\n");
3267 /* != and () operator */
3268 def
= mputprintf(def
,
3269 " inline boolean operator!=(const %s& other_value) const\n"
3270 " { return !(*this == other_value); }\n\n", name
);
3273 def
= mputprintf(def
,
3274 " boolean is_bound() const;\n\n");
3275 src
= mputprintf(src
,
3276 "boolean %s::is_bound() const\n"
3278 for(i
=0; i
< sdef
->nElements
; i
++) {
3279 if(sdef
->elements
[i
].isOptional
) {
3280 src
= mputprintf(src
,
3281 "if(OPTIONAL_OMIT == field_%s.get_selection() || field_%s.is_bound()) return TRUE;\n",
3282 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
3284 src
= mputprintf(src
,
3285 "if(field_%s.is_bound()) return TRUE;\n",
3286 sdef
->elements
[i
].name
);
3289 src
= mputprintf(src
,
3295 "inline boolean is_present() const { return is_bound(); }\n");
3298 def
= mputprintf(def
,
3299 " boolean is_value() const;\n\n");
3300 src
= mputprintf(src
,
3301 "boolean %s::is_value() const\n"
3303 for(i
=0; i
< sdef
->nElements
; i
++) {
3304 if(sdef
->elements
[i
].isOptional
) {
3305 src
= mputprintf(src
,
3306 "if(OPTIONAL_OMIT != field_%s.get_selection() && !field_%s.is_value()) return FALSE;\n",
3307 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
3309 src
= mputprintf(src
,
3310 "if(!field_%s.is_value()) return FALSE;\n",
3311 sdef
->elements
[i
].name
);
3314 src
= mputprintf(src
,
3315 "return TRUE;\n}\n");
3317 /* field accessor methods */
3318 for (i
= 0; i
< sdef
->nElements
; i
++) {
3319 if(sdef
->elements
[i
].isOptional
)
3322 " inline OPTIONAL<%s>& %s()\n"
3323 " {return field_%s;}\n"
3324 " inline const OPTIONAL<%s>& %s() const\n"
3325 " {return field_%s;}\n",
3326 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
,
3327 sdef
->elements
[i
].name
,
3328 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
,
3329 sdef
->elements
[i
].name
);
3330 else def
= mputprintf
3332 " inline %s& %s()\n"
3333 " {return field_%s;}\n"
3334 " inline const %s& %s() const\n"
3335 " {return field_%s;}\n",
3336 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
,
3337 sdef
->elements
[i
].name
, sdef
->elements
[i
].type
,
3338 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
3342 /* sizeof operation */
3343 mandatory_fields_count
= 0;
3344 for (i
= 0; i
< sdef
->nElements
; i
++)
3345 if (!sdef
->elements
[i
].isOptional
) mandatory_fields_count
++;
3347 if(sdef
->nElements
== mandatory_fields_count
){
3348 def
= mputprintf(def
,
3349 " inline int size_of() const\n"
3350 " {return %lu;}\n", (unsigned long) mandatory_fields_count
);
3352 def
= mputstr(def
, " int size_of() const;\n");
3353 src
= mputprintf(src
,
3354 "int %s::size_of() const\n"
3357 src
= mputprintf(src
, " int ret_val = %lu;\n",
3358 (unsigned long) mandatory_fields_count
);
3359 for (i
= 0; i
< sdef
->nElements
; i
++)
3360 if (sdef
->elements
[i
].isOptional
)
3361 src
= mputprintf(src
,
3362 " if (field_%s.ispresent()) ret_val++;\n",
3363 sdef
->elements
[i
].name
);
3365 " return ret_val;\n"
3370 def
= mputstr(def
, " void log() const;\n");
3371 src
= mputprintf(src
,
3372 "void %s::log() const\n{\n"
3373 "if (!is_bound()) {\n"
3374 "TTCN_Logger::log_event_unbound();\n"
3377 for (i
= 0; i
< sdef
->nElements
; i
++) {
3378 src
= mputstr(src
, "TTCN_Logger::log_event_str(\"");
3379 if (i
== 0) src
= mputc(src
, '{');
3380 else src
= mputc(src
, ',');
3381 src
= mputprintf(src
, " %s := \");\n"
3382 "field_%s.log();\n",
3383 sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
);
3385 src
= mputstr(src
, "TTCN_Logger::log_event_str(\" }\");\n}\n\n");
3387 /* set param function */
3388 def
= mputstr(def
, " void set_param(Module_Param& param);\n");
3391 "void %s::set_param(Module_Param& param)\n{\n"
3392 " if (dynamic_cast<Module_Param_Name*>(param.get_id()) != NULL &&\n"
3393 " param.get_id()->next_name()) {\n"
3394 // Haven't reached the end of the module parameter name
3395 // => the name refers to one of the fields, not to the whole record
3396 " char* param_field = param.get_id()->get_current_name();\n"
3397 " if (param_field[0] >= '0' && param_field[0] <= '9') {\n"
3398 " param.error(\"Unexpected array index in module parameter, expected a valid field\"\n"
3399 " \" name for %s type `%s'\");\n"
3401 " ", name
, kind_str
, dispname
);
3402 for (i
= 0; i
< sdef
->nElements
; i
++) {
3403 src
= mputprintf(src
,
3404 "if (strcmp(\"%s\", param_field) == 0) {\n"
3405 " %s().set_param(param);\n"
3408 sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
);
3410 src
= mputprintf(src
,
3411 "param.error(\"Field `%%s' not found in %s type `%s'\", param_field);\n"
3413 " param.basic_check(Module_Param::BC_VALUE, \"%s value\");\n"
3414 " Module_Param_Ptr m_p = ¶m;\n"
3415 " if (param.get_type() == Module_Param::MP_Reference) {\n"
3416 " m_p = param.get_referenced_param();\n"
3418 " switch (m_p->get_type()) {\n"
3419 " case Module_Param::MP_Value_List:\n"
3420 " if (%lu<m_p->get_size()) {\n"
3421 " param.error(\"%s value of type %s has %lu fields but list value has %%d fields\", (int)m_p->get_size());\n"
3423 kind_str
, dispname
, kind_str
, (unsigned long)sdef
->nElements
, kind_str
, dispname
, (unsigned long)sdef
->nElements
);
3425 for (i
= 0; i
< sdef
->nElements
; ++i
) {
3426 src
= mputprintf(src
,
3427 " if (m_p->get_size()>%lu && m_p->get_elem(%lu)->get_type()!=Module_Param::MP_NotUsed) %s().set_param(*m_p->get_elem(%lu));\n",
3428 (unsigned long)i
, (unsigned long)i
, sdef
->elements
[i
].name
, (unsigned long)i
);
3432 " case Module_Param::MP_Assignment_List: {\n"
3433 " Vector<bool> value_used(m_p->get_size());\n"
3434 " value_used.resize(m_p->get_size(), false);\n");
3435 for (i
= 0; i
< sdef
->nElements
; ++i
) {
3436 src
= mputprintf(src
,
3437 " for (size_t val_idx=0; val_idx<m_p->get_size(); val_idx++) {\n"
3438 " Module_Param* const curr_param = m_p->get_elem(val_idx);\n"
3439 " if (!strcmp(curr_param->get_id()->get_name(), \"%s\")) {\n"
3440 " if (curr_param->get_type()!=Module_Param::MP_NotUsed) {\n"
3441 " %s().set_param(*curr_param);\n"
3443 " value_used[val_idx]=true;\n"
3446 , sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
);
3448 src
= mputprintf(src
,
3449 " for (size_t val_idx=0; val_idx<m_p->get_size(); val_idx++) if (!value_used[val_idx]) {\n"
3450 " m_p->get_elem(val_idx)->error(\"Non existent field name in type %s: %%s\", m_p->get_elem(val_idx)->get_id()->get_name());\n"
3455 " param.type_error(\"%s value\", \"%s\");\n"
3457 "}\n\n", dispname
, kind_str
, dispname
);
3459 /* get param function */
3460 def
= mputstr(def
, "Module_Param* get_param(Module_Param_Name& param_name) const;\n");
3461 src
= mputprintf(src
,
3462 "Module_Param* %s::get_param(Module_Param_Name& param_name) const\n"
3464 " if (!is_bound()) {\n"
3465 " return new Module_Param_Unbound();\n"
3467 " if (param_name.next_name()) {\n"
3468 // Haven't reached the end of the module parameter name
3469 // => the name refers to one of the fields, not to the whole record
3470 " char* param_field = param_name.get_current_name();\n"
3471 " if (param_field[0] >= '0' && param_field[0] <= '9') {\n"
3472 " TTCN_error(\"Unexpected array index in module parameter reference, \"\n"
3473 " \"expected a valid field name for %s type `%s'\");\n"
3475 " ", name
, kind_str
, dispname
);
3476 for (i
= 0; i
< sdef
->nElements
; i
++) {
3477 src
= mputprintf(src
,
3478 "if (strcmp(\"%s\", param_field) == 0) {\n"
3479 " return %s().get_param(param_name);\n"
3481 sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
);
3483 src
= mputprintf(src
,
3484 "TTCN_error(\"Field `%%s' not found in %s type `%s'\", param_field);\n"
3486 " Module_Param_Assignment_List* m_p = new Module_Param_Assignment_List();\n"
3487 , kind_str
, dispname
);
3488 for (i
= 0; i
< sdef
->nElements
; i
++) {
3489 src
= mputprintf(src
,
3490 " Module_Param* mp_field_%s = field_%s.get_param(param_name);\n"
3491 " mp_field_%s->set_id(new Module_Param_FieldName(mcopystr(\"%s\")));\n"
3492 " m_p->add_elem(mp_field_%s);\n"
3493 , sdef
->elements
[i
].name
, sdef
->elements
[i
].name
3494 , sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
3495 , sdef
->elements
[i
].name
);
3501 /* set implicit omit function, recursive */
3502 def
= mputstr(def
, " void set_implicit_omit();\n");
3503 src
= mputprintf(src
, "void %s::set_implicit_omit()\n{\n", name
);
3504 for (i
= 0; i
< sdef
->nElements
; i
++) {
3505 if (sdef
->elements
[i
].isOptional
) {
3506 src
= mputprintf(src
,
3507 "if (!%s().is_bound()) %s() = OMIT_VALUE;\n"
3508 "else %s().set_implicit_omit();\n",
3509 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
3511 src
= mputprintf(src
,
3512 "if (%s().is_bound()) %s().set_implicit_omit();\n",
3513 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
3516 src
= mputstr(src
, "}\n\n");
3518 /* text encoder function */
3519 def
= mputstr(def
, " void encode_text(Text_Buf& text_buf) const;\n");
3520 src
= mputprintf(src
,"void %s::encode_text(Text_Buf& text_buf) const\n{\n",
3522 for (i
= 0; i
< sdef
->nElements
; i
++) {
3523 src
= mputprintf(src
, "field_%s.encode_text(text_buf);\n",
3524 sdef
->elements
[i
].name
);
3526 src
= mputstr(src
, "}\n\n");
3528 /* text decoder function */
3529 def
= mputstr(def
, " void decode_text(Text_Buf& text_buf);\n");
3530 src
= mputprintf(src
, "void %s::decode_text(Text_Buf& text_buf)\n{\n",
3532 for (i
= 0; i
< sdef
->nElements
; i
++) {
3533 src
= mputprintf(src
, "field_%s.decode_text(text_buf);\n",
3534 sdef
->elements
[i
].name
);
3536 src
= mputstr(src
, "}\n\n");
3538 /* The common "classname::encode()" and "classname::decode()" functions */
3539 if(ber_needed
|| raw_needed
|| text_needed
|| xer_needed
|| json_needed
)
3540 def_encdec(name
, &def
, &src
, ber_needed
, raw_needed
,
3541 text_needed
, xer_needed
, json_needed
, FALSE
);
3545 /* BER_encode_TLV() */
3548 "ASN_BER_TLV_t* %s::BER_encode_TLV(const TTCN_Typedescriptor_t& p_td,"
3549 " unsigned p_coding) const\n"
3551 " if (!is_bound()) TTCN_EncDec_ErrorContext::error"
3552 "(TTCN_EncDec::ET_UNBOUND, \"Encoding an unbound value.\");\n"
3553 " BER_chk_descr(p_td);\n"
3554 " ASN_BER_TLV_t *new_tlv=ASN_BER_TLV_t::construct(NULL);\n"
3555 " TTCN_EncDec_ErrorContext ec_0(\"Component '\");\n"
3556 " TTCN_EncDec_ErrorContext ec_1;\n"
3559 for(i
=0; i
<sdef
->nElements
; i
++) {
3560 if(!default_as_optional
&& sdef
->elements
[i
].isDefault
) { /* is DEFAULT */
3563 " if(field_%s!=%s) {\n"
3564 " ec_1.set_msg(\"%s': \");\n"
3565 " new_tlv->add_TLV(field_%s.BER_encode_TLV(%s_descr_,"
3568 , sdef
->elements
[i
].name
, sdef
->elements
[i
].defvalname
3569 , sdef
->elements
[i
].dispname
3570 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
3573 else { /* is not DEFAULT */
3576 " ec_1.set_msg(\"%s': \");\n"
3577 " new_tlv->add_TLV(field_%s.BER_encode_TLV(%s_descr_,"
3579 , sdef
->elements
[i
].dispname
3580 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
3584 if(sdef
->kind
==SET
) {
3587 " if(p_coding==BER_ENCODE_DER)\n"
3588 " new_tlv->sort_tlvs_tag();\n"
3593 " new_tlv=ASN_BER_V2TLV(new_tlv, p_td, p_coding);\n"
3594 " return new_tlv;\n"
3599 /* BER_decode_TLV() */
3602 "boolean %s::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,"
3603 " const ASN_BER_TLV_t& p_tlv, unsigned L_form)\n"
3605 " BER_chk_descr(p_td);\n"
3606 " ASN_BER_TLV_t stripped_tlv;\n"
3607 " BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv);\n"
3608 " TTCN_EncDec_ErrorContext ec_0(\"While decoding '%s' type: \");\n"
3609 " stripped_tlv.chk_constructed_flag(TRUE);\n"
3610 " size_t V_pos=0;\n"
3611 " ASN_BER_TLV_t tmp_tlv;\n"
3612 , name
, sdef
->dispname
3615 if(sdef
->kind
==RECORD
)
3616 { /* SEQUENCE decoding */
3619 " boolean tlv_present=FALSE;\n"
3621 " TTCN_EncDec_ErrorContext ec_1(\"Component '\");\n"
3622 " TTCN_EncDec_ErrorContext ec_2;\n"
3624 for(i
=0; i
<sdef
->nElements
; i
++) {
3627 " ec_2.set_msg(\"%s': \");\n"
3628 " if(!tlv_present) tlv_present=BER_decode_constdTLV_next"
3629 "(stripped_tlv, V_pos, L_form, tmp_tlv);\n"
3630 , sdef
->elements
[i
].dispname
3632 if(sdef
->elements
[i
].isDefault
) { /* is DEFAULT */
3635 " if(!tlv_present || !field_%s.BER_decode_isMyMsg(%s_descr_,"
3639 " field_%s.BER_decode_TLV(%s_descr_, tmp_tlv,"
3641 " tlv_present=FALSE;\n"
3643 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
3644 , sdef
->elements
[i
].name
, sdef
->elements
[i
].defvalname
3645 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
3648 else if(sdef
->elements
[i
].isOptional
) { /* is OPTIONAL */
3651 " if(!tlv_present) field_%s=OMIT_VALUE;\n"
3653 " field_%s.BER_decode_TLV(%s_descr_, tmp_tlv, L_form);\n"
3654 " if(field_%s.ispresent()) tlv_present=FALSE;\n"
3656 , sdef
->elements
[i
].name
3657 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
3658 , sdef
->elements
[i
].name
3661 else { /* is not DEFAULT OPTIONAL */
3664 " if(!tlv_present){\n"
3665 " ec_2.error(TTCN_EncDec::ET_INCOMPL_MSG,\"Invalid or incomplete message was received.\");\n"
3668 " field_%s.BER_decode_TLV(%s_descr_, tmp_tlv, L_form);\n"
3669 " tlv_present=FALSE;\n"
3670 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
3677 " BER_decode_constdTLV_end(stripped_tlv, V_pos, L_form, tmp_tlv,"
3680 } /* SEQUENCE decoding */
3681 else { /* SET decoding */
3684 " const char *fld_name[%lu]={"
3685 , (unsigned long) sdef
->nElements
3687 for(i
=0; i
<sdef
->nElements
; i
++)
3692 , sdef
->elements
[i
].dispname
3695 * 0x01: value arrived
3696 * 0x02: is optional / not used :)
3697 * 0x04: has default / not used :)
3702 " unsigned char fld_indctr[%lu]={"
3703 , (unsigned long) sdef
->nElements
3705 for(i
=0; i
<sdef
->nElements
; i
++)
3714 " size_t fld_curr;\n"
3715 " while(BER_decode_constdTLV_next(stripped_tlv, V_pos,"
3716 " L_form, tmp_tlv)) {\n"
3718 for(i
=0; i
<sdef
->nElements
; i
++)
3721 " %sif(field_%s.BER_decode_isMyMsg(%s_descr_, tmp_tlv)) {\n"
3723 " TTCN_EncDec_ErrorContext ec_1(\"Component '%%s': \","
3724 " fld_name[%lu]);\n"
3725 " field_%s.BER_decode_TLV(%s_descr_, tmp_tlv, L_form);\n"
3728 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
3729 , (unsigned long) i
, (unsigned long) i
3730 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
3735 " /* ellipsis or error... */\n"
3736 " fld_curr=static_cast<size_t>(-1);\n"
3738 " if(fld_curr!=static_cast<size_t>(-1)) {\n"
3739 " if(fld_indctr[fld_curr])\n"
3740 " ec_0.error(TTCN_EncDec::ET_DEC_DUPFLD, \"Duplicated"
3741 " value for component '%%s'.\", fld_name[fld_curr]);\n"
3742 " fld_indctr[fld_curr]=1;\n"
3743 " }\n" /* if != -1 */
3745 " for(fld_curr=0; fld_curr<%lu; fld_curr++) {\n"
3746 " if(fld_indctr[fld_curr]) continue;\n"
3747 " switch(fld_curr) {\n"
3748 , (unsigned long) sdef
->nElements
3750 for(i
=0; i
<sdef
->nElements
; i
++) {
3751 if(sdef
->elements
[i
].isDefault
)
3758 , sdef
->elements
[i
].name
, sdef
->elements
[i
].defvalname
3760 else if(sdef
->elements
[i
].isOptional
)
3764 " field_%s=OMIT_VALUE;\n"
3767 , sdef
->elements
[i
].name
3773 " ec_0.error(TTCN_EncDec::ET_DEC_MISSFLD, \"Missing"
3774 " value for component '%s'.\", fld_name[fld_curr]);\n"
3776 " }\n" /* for fld_curr */
3778 } /* SET decoding */
3780 if(sdef
->opentype_outermost
) {
3783 " TTCN_EncDec_ErrorContext ec_1(\"While decoding opentypes: \");\n"
3784 " TTCN_Type_list p_typelist;\n"
3785 " BER_decode_opentypes(p_typelist, L_form);\n"
3787 } /* if sdef->opentype_outermost */
3795 if(sdef
->has_opentypes
) {
3796 /* BER_decode_opentypes() */
3799 "void BER_decode_opentypes(TTCN_Type_list& p_typelist,"
3800 " unsigned L_form);\n");
3803 "void %s::BER_decode_opentypes(TTCN_Type_list& p_typelist,"
3804 " unsigned L_form)\n"
3806 " p_typelist.push(this);\n"
3807 " TTCN_EncDec_ErrorContext ec_0(\"Component '\");\n"
3808 " TTCN_EncDec_ErrorContext ec_1;\n"
3811 for(i
=0; i
<sdef
->nElements
; i
++) {
3814 " ec_1.set_msg(\"%s': \");\n"
3815 " field_%s.BER_decode_opentypes(p_typelist, L_form);\n"
3816 , sdef
->elements
[i
].dispname
3817 , sdef
->elements
[i
].name
3822 " p_typelist.pop();\n"
3826 } /* if sdef->has_opentypes */
3828 } /* if ber_needed */
3834 size_t last_man_index
=0;
3835 for(i
=0;i
<sdef
->nElements
;i
++){
3836 if(sdef
->elements
[i
].isOptional
) opt_number
++;
3837 else {man_num
++;last_man_index
=i
+1;}
3838 if(sdef
->elements
[i
].of_type
) seof
++;
3842 "int %s::TEXT_encode(const TTCN_Typedescriptor_t& p_td,"
3843 " TTCN_Buffer& p_buf) const{\n"
3844 " if (!is_bound()) TTCN_EncDec_ErrorContext::error"
3845 "(TTCN_EncDec::ET_UNBOUND, \"Encoding an unbound value.\");\n"
3846 " bool need_separator=false;\n"
3847 " int encoded_length=0;\n"
3848 " if(p_td.text->begin_encode){\n"
3849 " p_buf.put_cs(*p_td.text->begin_encode);\n"
3850 " encoded_length+=p_td.text->begin_encode->lengthof();\n"
3855 for(i
=0;i
<sdef
->nElements
;i
++){
3856 if(sdef
->elements
[i
].isOptional
){
3858 " if(field_%s.ispresent()){\n"
3859 ,sdef
->elements
[i
].name
3863 " if(need_separator && p_td.text->separator_encode){\n"
3864 " p_buf.put_cs(*p_td.text->separator_encode);\n"
3865 " encoded_length+=p_td.text->separator_encode->lengthof();\n"
3867 " encoded_length+=field_%s%s.TEXT_encode(%s_descr_,p_buf);\n"
3868 " need_separator=true;\n"
3869 ,sdef
->elements
[i
].name
3870 ,sdef
->elements
[i
].isOptional
?"()":"",sdef
->elements
[i
].typedescrname
3872 if(sdef
->elements
[i
].isOptional
){
3880 " if(p_td.text->end_encode){\n"
3881 " p_buf.put_cs(*p_td.text->end_encode);\n"
3882 " encoded_length+=p_td.text->end_encode->lengthof();\n"
3884 " return encoded_length;\n"
3888 if(sdef
->kind
==SET
){ /* set decoder start*/
3889 src
= mputprintf(src
,
3890 "int %s::TEXT_decode(const TTCN_Typedescriptor_t& p_td,"
3891 " TTCN_Buffer& p_buf, Limit_Token_List& limit, boolean no_err, boolean){\n"
3892 " int decoded_length=0;\n"
3893 " int decoded_field_length=0;\n"
3894 " size_t pos=p_buf.get_pos();\n"
3895 " boolean sep_found=FALSE;\n"
3897 " int sep_length=0;\n"
3898 " int mand_field_num=%d;\n"
3899 " int opt_field_num=%d;\n"
3900 " int loop_detector=1;\n"
3901 " int last_field_num=-1;\n"
3902 " int field_map[%lu];\n"
3903 " memset(field_map, 0, sizeof(field_map));\n"
3904 " if(p_td.text->begin_decode){\n"
3906 " if((tl=p_td.text->begin_decode->match_begin(p_buf))<0){\n"
3907 " if(no_err)return -1;\n"
3908 " TTCN_EncDec_ErrorContext::error\n"
3909 " (TTCN_EncDec::ET_TOKEN_ERR, \"The specified token '%%s'"
3910 " not found for '%%s': \",(const char*)*(p_td.text->begin_decode)"
3914 " decoded_length+=tl;\n"
3915 " p_buf.increase_pos(tl);\n"
3917 " if(p_td.text->end_decode){\n"
3918 " limit.add_token(p_td.text->end_decode);\n"
3921 " if(p_td.text->separator_decode){\n"
3922 " limit.add_token(p_td.text->separator_decode);\n"
3925 ,name
,man_num
,opt_number
,(unsigned long) sdef
->nElements
3931 " int has_repeatable=0;\n"
3934 for(i
=0;i
<sdef
->nElements
;i
++){
3935 if(sdef
->elements
[i
].of_type
){
3937 "%s%s_descr_.text->val.parameters->decoding_params.repeatable"
3939 ,sdef
->elements
[i
].typedescrname
3945 ") has_repeatable=1;\n"
3949 for(i
=0;i
<sdef
->nElements
;i
++){
3950 if(sdef
->elements
[i
].isOptional
){
3952 " field_%s=OMIT_VALUE;\n"
3953 ,sdef
->elements
[i
].name
3957 src
= mputprintf(src
,
3958 " while(mand_field_num+opt_field_num%s){\n"
3959 " loop_detector=1;\n"
3961 ,seof
?"+has_repeatable":""
3964 for(i
=0;i
<sdef
->nElements
;i
++){
3965 if(sdef
->elements
[i
].of_type
){
3967 " if( (%s_descr_.text->val.parameters->decoding_params.repeatable"
3968 " && field_map[%lu]<3) || !field_map[%lu]){\n"
3969 " pos=p_buf.get_pos();\n"
3970 " decoded_field_length=field_%s%s.TEXT_decode(%s_descr_,p_buf,"
3971 "limit,true,!field_map[%lu]);\n"
3972 " if(decoded_field_length<0){\n"
3973 " p_buf.set_pos(pos);\n"
3974 ,sdef
->elements
[i
].typedescrname
,(unsigned long) i
,(unsigned long) i
3975 ,sdef
->elements
[i
].name
,sdef
->elements
[i
].isOptional
?"()":""
3976 ,sdef
->elements
[i
].typedescrname
3980 if(sdef
->elements
[i
].isOptional
){
3982 " if(!field_map[%lu]) field_%s=OMIT_VALUE;\n"
3984 ,sdef
->elements
[i
].name
3989 " loop_detector=0;\n"
3990 " if(!field_map[%lu]) {%s--;field_map[%lu]=1;}\n"
3991 " else field_map[%lu]=2;\n"
3992 " last_field_num=%lu;\n"
3997 ,sdef
->elements
[i
].isOptional
?"opt_field_num":"mand_field_num"
3998 ,(unsigned long) i
,(unsigned long) i
,(unsigned long) i
4002 " if(!field_map[%lu]){\n"
4003 " pos=p_buf.get_pos();\n"
4004 " decoded_field_length=field_%s%s.TEXT_decode(%s_descr_,p_buf,"
4006 " if(decoded_field_length<0){\n"
4007 " p_buf.set_pos(pos);\n"
4010 " loop_detector=0;\n"
4011 " field_map[%lu]=1;\n"
4013 " last_field_num=%lu;\n"
4018 ,sdef
->elements
[i
].name
,sdef
->elements
[i
].isOptional
?"()":""
4019 ,sdef
->elements
[i
].typedescrname
4020 ,sdef
->elements
[i
].isOptional
?" field_":""
4021 ,sdef
->elements
[i
].isOptional
?sdef
->elements
[i
].name
:""
4022 ,sdef
->elements
[i
].isOptional
?"=OMIT_VALUE;\n":"",(unsigned long) i
4023 ,sdef
->elements
[i
].isOptional
?"opt_field_num":"mand_field_num"
4032 " if(loop_detector) break;\n"
4033 " if(p_td.text->separator_decode){\n"
4035 " if((tl=p_td.text->separator_decode->match_begin(p_buf))<0){\n"
4036 " if(p_td.text->end_decode){\n"
4038 " if((tl=p_td.text->end_decode->match_begin(p_buf))!=-1){\n"
4039 " sep_found=FALSE;\n"
4042 " } else if(limit.has_token(ml)){\n"
4044 " if((tl=limit.match(p_buf,ml))==0){\n"
4045 " sep_found=FALSE;\n"
4049 " p_buf.set_pos(pos);\n"
4050 " decoded_length-=decoded_field_length;\n"
4051 " field_map[last_field_num]+=2;\n"
4056 "switch(last_field_num){\n"
4058 for(i
=0;i
<sdef
->nElements
;i
++){
4059 if(sdef
->elements
[i
].of_type
){
4060 if(sdef
->elements
[i
].isOptional
){
4063 " if(field_map[%lu]==3){\n"
4064 " field_%s=OMIT_VALUE;\n"
4065 " opt_field_num++;\n"
4068 ,(unsigned long) i
,(unsigned long) i
,sdef
->elements
[i
].name
4073 " if(field_map[%lu]==3){\n"
4074 " mand_field_num++;\n"
4077 ,(unsigned long) i
,(unsigned long) i
4080 } else if(sdef
->elements
[i
].isOptional
){
4083 " field_%s=OMIT_VALUE;\n"
4084 " opt_field_num++;\n"
4086 ,(unsigned long) i
,sdef
->elements
[i
].name
4092 " mand_field_num++;\n"
4098 src
= mputprintf(src
,
4101 " decoded_length+=tl;\n"
4102 " p_buf.increase_pos(tl);\n"
4103 " for(int a=0;a<%lu;a++) if(field_map[a]>2) field_map[a]-=3;\n"
4104 " sep_found=TRUE;}\n"
4105 " } else if(p_td.text->end_decode){\n"
4107 " if((tl=p_td.text->end_decode->match_begin(p_buf))!=-1){\n"
4108 " decoded_length+=tl;\n"
4109 " p_buf.increase_pos(tl);\n"
4110 " limit.remove_tokens(ml);\n"
4111 " if(mand_field_num) return -1;\n"
4112 " return decoded_length;\n"
4114 " } else if(limit.has_token(ml)){\n"
4116 " if((tl=limit.match(p_buf,ml))==0){\n"
4117 " sep_found=FALSE;\n"
4122 " limit.remove_tokens(ml);\n"
4124 " if(mand_field_num){\n"
4125 " if(no_err)return -1;\n"
4126 " TTCN_EncDec_ErrorContext::error"
4127 "(TTCN_EncDec::ET_TOKEN_ERR, \"Error during decoding '%%s': \","
4129 " return decoded_length;\n"
4131 " decoded_length-=sep_length;\n"
4132 " p_buf.set_pos(p_buf.get_pos()-sep_length);\n"
4135 " if(p_td.text->end_decode){\n"
4137 " if((tl=p_td.text->end_decode->match_begin(p_buf))<0){\n"
4138 " if(no_err)return -1;\n"
4139 " TTCN_EncDec_ErrorContext::error"
4140 "(TTCN_EncDec::ET_TOKEN_ERR, \"The specified token '%%s'"
4141 " not found for '%%s': \",(const char*)*(p_td.text->end_decode)"
4143 " return decoded_length;\n"
4145 " decoded_length+=tl;\n"
4146 " p_buf.increase_pos(tl);\n"
4148 " if(mand_field_num) return -1;\n"
4149 " return decoded_length;\n"
4151 ,(unsigned long) sdef
->nElements
4153 } else { /* record decoder start */
4154 src
= mputprintf(src
,
4155 "int %s::TEXT_decode(const TTCN_Typedescriptor_t& p_td,"
4156 " TTCN_Buffer& p_buf, Limit_Token_List& limit, boolean no_err, boolean){\n"
4157 " int decoded_length=0;\n"
4158 " int decoded_field_length=0;\n"
4160 " boolean sep_found=FALSE;\n"
4161 " int sep_length=0;\n"
4163 " if(p_td.text->begin_decode){\n"
4165 " if((tl=p_td.text->begin_decode->match_begin(p_buf))<0){\n"
4166 " if(no_err)return -1;\n"
4167 " TTCN_EncDec_ErrorContext::error\n"
4168 " (TTCN_EncDec::ET_TOKEN_ERR, \"The specified token '%%s'"
4169 " not found for '%%s': \",(const char*)*(p_td.text->begin_decode)"
4173 " decoded_length+=tl;\n"
4174 " p_buf.increase_pos(tl);\n"
4176 " if(p_td.text->end_decode){\n"
4177 " limit.add_token(p_td.text->end_decode);\n"
4180 " if(p_td.text->separator_decode){\n"
4181 " limit.add_token(p_td.text->separator_decode);\n"
4184 ,name
,opt_number
?" size_t pos=p_buf.get_pos();\n":""
4186 for(i
=0;i
<sdef
->nElements
;i
++){
4187 if(sdef
->elements
[i
].isOptional
){
4189 " field_%s=OMIT_VALUE;\n"
4190 ,sdef
->elements
[i
].name
4196 for(i
=0;i
<sdef
->nElements
;i
++){
4197 if(sdef
->elements
[i
].isOptional
){
4199 " pos=p_buf.get_pos();\n"
4203 " decoded_field_length=field_%s%s.TEXT_decode(%s_descr_,p_buf"
4205 " if(decoded_field_length<0){\n"
4206 ,sdef
->elements
[i
].name
,sdef
->elements
[i
].isOptional
?"()":""
4207 ,sdef
->elements
[i
].typedescrname
4209 if(sdef
->elements
[i
].isOptional
){
4211 " field_%s=OMIT_VALUE;\n"
4212 " p_buf.set_pos(pos);\n"
4214 ,sdef
->elements
[i
].name
4218 " limit.remove_tokens(ml);\n"
4219 " if(no_err)return -1;\n"
4220 " TTCN_EncDec_ErrorContext::error"
4221 "(TTCN_EncDec::ET_TOKEN_ERR, \"Error during decoding "
4222 "field '%s' for '%%s': \", p_td.name);\n"
4223 " return decoded_length;\n"
4225 ,sdef
->elements
[i
].name
4229 " decoded_length+=decoded_field_length;\n"
4231 if(last_man_index
>(i
+1)){
4233 " if(p_td.text->separator_decode){\n"
4235 " if((tl=p_td.text->separator_decode->match_begin(p_buf))<0){\n"
4238 if(sdef
->elements
[i
].isOptional
){
4240 " field_%s=OMIT_VALUE;\n"
4241 " p_buf.set_pos(pos);\n"
4242 " decoded_length-=decoded_field_length;\n"
4243 ,sdef
->elements
[i
].name
4247 " limit.remove_tokens(ml);\n"
4248 " if(no_err)return -1;\n"
4249 " TTCN_EncDec_ErrorContext::error"
4250 "(TTCN_EncDec::ET_TOKEN_ERR, \"The specified token '%s'"
4251 " not found for '%s': \",(const char*)*(p_td.text->"
4252 "separator_decode),p_td.name);\n"
4253 " return decoded_length;\n"
4259 " decoded_length+=tl;\n"
4260 " p_buf.increase_pos(tl);\n"
4262 " sep_found=TRUE;}\n"
4263 " } else sep_found=FALSE;\n"
4265 } else if(i
==(sdef
->nElements
-1)){
4267 " sep_found=FALSE;\n"
4271 " if(p_td.text->separator_decode){\n"
4273 " if((tl=p_td.text->separator_decode->match_begin(p_buf))<0){\n"
4275 if(sdef
->elements
[i
].isOptional
){
4277 " if(p_td.text->end_decode){\n"
4279 " if((tl=p_td.text->end_decode->match_begin(p_buf))!=-1){\n"
4280 " decoded_length+=tl;\n"
4281 " p_buf.increase_pos(tl);\n"
4282 " limit.remove_tokens(ml);\n"
4283 " return decoded_length;\n"
4285 " } else if(limit.has_token(ml)){\n"
4286 " if((tl=limit.match(p_buf,ml))==0){\n"
4287 " sep_found=FALSE;\n"
4291 " field_%s=OMIT_VALUE;\n"
4292 " p_buf.set_pos(pos);\n"
4293 " decoded_length-=decoded_field_length;\n"
4294 ,sdef
->elements
[i
].name
4298 " sep_found=FALSE;\n"
4304 " decoded_length+=tl;\n"
4305 " p_buf.increase_pos(tl);\n"
4307 " sep_found=TRUE;}\n"
4309 " sep_found=FALSE;\n"
4310 " if(p_td.text->end_decode){\n"
4312 " if((tl=p_td.text->end_decode->match_begin(p_buf))!=-1){\n"
4313 " decoded_length+=tl;\n"
4314 " p_buf.increase_pos(tl);\n"
4315 " limit.remove_tokens(ml);\n"
4316 " return decoded_length;\n"
4318 " } else if(limit.has_token(ml)){\n"
4320 " if((tl=limit.match(p_buf,ml))==0){\n"
4321 " sep_found=FALSE;\n"
4336 " limit.remove_tokens(ml);\n"
4338 " p_buf.set_pos(p_buf.get_pos()-sep_length);\n"
4339 " decoded_length-=sep_length;\n"
4341 " if(p_td.text->end_decode){\n"
4343 " if((tl=p_td.text->end_decode->match_begin(p_buf))<0){\n"
4344 " if(no_err)return -1;\n"
4345 " TTCN_EncDec_ErrorContext::error"
4346 "(TTCN_EncDec::ET_TOKEN_ERR, \"The specified token '%s'"
4347 " not found for '%s': \",(const char*)*(p_td.text->end_decode)"
4349 " return decoded_length;\n"
4351 " decoded_length+=tl;\n"
4352 " p_buf.increase_pos(tl);\n"
4354 " return decoded_length;\n"
4362 struct raw_option_struct
*raw_options
;
4363 boolean haslengthto
, haspointer
, hascrosstag
, has_ext_bit
;
4364 raw_options
= (struct raw_option_struct
*)
4365 Malloc(sdef
->nElements
* sizeof(*raw_options
));
4367 set_raw_options(sdef
, raw_options
, &haslengthto
,
4368 &haspointer
, &hascrosstag
, &has_ext_bit
);
4370 src
= generate_raw_coding(src
, sdef
, raw_options
, haspointer
, hascrosstag
,
4373 for (i
= 0; i
< sdef
->nElements
; i
++) {
4374 Free(raw_options
[i
].lengthoffield
);
4375 Free(raw_options
[i
].dependent_fields
);
4378 } /* if raw_needed */
4380 if (xer_needed
) gen_xer(sdef
, &def
, &src
);
4384 src
= mputprintf(src
,
4385 "int %s::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const\n"
4387 " if (!is_bound()) {\n"
4388 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,\n"
4389 " \"Encoding an unbound value of type %s.\");\n"
4392 " int enc_len = p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL);\n\n"
4394 for (i
= 0; i
< sdef
->nElements
; ++i
) {
4395 if (sdef
->elements
[i
].isOptional
&& !sdef
->elements
[i
].jsonOmitAsNull
&&
4396 !sdef
->elements
[i
].jsonMetainfoUnbound
) {
4397 src
= mputprintf(src
,
4398 " if (field_%s.is_present())\n"
4399 , sdef
->elements
[i
].name
);
4401 src
= mputprintf(src
,
4403 " enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, \"%s\");\n "
4404 , sdef
->elements
[i
].jsonAlias
? sdef
->elements
[i
].jsonAlias
: sdef
->elements
[i
].dispname
);
4405 if (sdef
->elements
[i
].jsonMetainfoUnbound
) {
4406 src
= mputprintf(src
,
4407 "if (!field_%s.is_bound()) {\n"
4408 " enc_len += p_tok.put_next_token(JSON_TOKEN_LITERAL_NULL);\n"
4409 " enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, \"metainfo %s\");\n"
4410 " enc_len += p_tok.put_next_token(JSON_TOKEN_STRING, \"\\\"unbound\\\"\");\n"
4413 , sdef
->elements
[i
].name
4414 , sdef
->elements
[i
].jsonAlias
? sdef
->elements
[i
].jsonAlias
: sdef
->elements
[i
].dispname
);
4416 src
= mputprintf(src
,
4417 "enc_len += field_%s.JSON_encode(%s_descr_, p_tok);\n"
4419 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
);
4422 " enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);\n"
4423 " return enc_len;\n"
4427 src
= mputprintf(src
,
4428 "int %s::JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok, boolean p_silent)\n"
4430 " json_token_t j_token = JSON_TOKEN_NONE;\n"
4431 " int dec_len = p_tok.get_next_token(&j_token, NULL, NULL);\n"
4432 " if (JSON_TOKEN_ERROR == j_token) {\n"
4433 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, \"\");\n"
4434 " return JSON_ERROR_FATAL;\n"
4436 " else if (JSON_TOKEN_OBJECT_START != j_token) {\n"
4437 " return JSON_ERROR_INVALID_TOKEN;\n"
4440 boolean has_metainfo_enabled
= FALSE
;
4441 for (i
= 0; i
< sdef
->nElements
; ++i
) {
4442 src
= mputprintf(src
, " boolean %s_found = FALSE;\n", sdef
->elements
[i
].name
);
4443 if (sdef
->elements
[i
].jsonMetainfoUnbound
) {
4444 // initialize meta info states
4445 src
= mputprintf(src
,
4446 " int metainfo_%s = JSON_METAINFO_NONE;\n"
4447 , sdef
->elements
[i
].name
);
4448 has_metainfo_enabled
= TRUE
;
4452 // Read name - value token pairs until we reach some other token
4453 "\n while (true) {\n"
4454 " char* fld_name = 0;\n"
4455 " size_t name_len = 0;\n"
4456 " size_t buf_pos = p_tok.get_buf_pos();\n"
4457 " dec_len += p_tok.get_next_token(&j_token, &fld_name, &name_len);\n"
4458 " if (JSON_TOKEN_ERROR == j_token) {\n"
4459 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_NAME_TOKEN_ERROR);\n"
4460 " return JSON_ERROR_FATAL;\n"
4462 // undo the last action on the buffer
4463 " else if (JSON_TOKEN_NAME != j_token) {\n"
4464 " p_tok.set_buf_pos(buf_pos);\n"
4468 if (has_metainfo_enabled
) {
4469 // check for meta info
4471 "boolean is_metainfo = FALSE;\n"
4472 " if (name_len > 9 && 0 == strncmp(fld_name, \"metainfo \", 9)) {\n"
4475 " is_metainfo = TRUE;\n"
4478 for (i
= 0; i
< sdef
->nElements
; ++i
) {
4479 src
= mputprintf(src
,
4481 "if (%d == name_len && 0 == strncmp(fld_name, \"%s\", name_len)) {\n"
4482 " %s_found = TRUE;\n"
4483 , (int)strlen(sdef
->elements
[i
].jsonAlias
? sdef
->elements
[i
].jsonAlias
: sdef
->elements
[i
].dispname
)
4484 , sdef
->elements
[i
].jsonAlias
? sdef
->elements
[i
].jsonAlias
: sdef
->elements
[i
].dispname
4485 , sdef
->elements
[i
].name
);
4486 if (has_metainfo_enabled
) {
4487 src
= mputstr(src
, " if (is_metainfo) {\n");
4488 if (sdef
->elements
[i
].jsonMetainfoUnbound
) {
4489 src
= mputprintf(src
,
4491 " char* info_value = 0;\n"
4492 " size_t info_len = 0;\n"
4493 " dec_len += p_tok.get_next_token(&j_token, &info_value, &info_len);\n"
4494 " if (JSON_TOKEN_STRING == j_token && 9 == info_len &&\n"
4495 " 0 == strncmp(info_value, \"\\\"unbound\\\"\", 9)) {\n"
4496 " metainfo_%s = JSON_METAINFO_UNBOUND;\n"
4499 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_METAINFO_VALUE_ERROR, \"%s\");\n"
4500 " return JSON_ERROR_FATAL;\n"
4502 , sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
);
4505 src
= mputprintf(src
,
4506 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_METAINFO_NOT_APPLICABLE, \"%s\");\n"
4507 " return JSON_ERROR_FATAL;\n"
4508 , sdef
->elements
[i
].dispname
);
4513 if (sdef
->elements
[i
].jsonMetainfoUnbound
) {
4514 src
= mputstr(src
, " buf_pos = p_tok.get_buf_pos();\n");
4517 src
= mputprintf(src
,
4518 " int ret_val = field_%s.JSON_decode(%s_descr_, p_tok, p_silent);\n"
4519 " if (0 > ret_val) {\n"
4520 " if (JSON_ERROR_INVALID_TOKEN == ret_val) {\n"
4521 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
);
4522 if (sdef
->elements
[i
].jsonMetainfoUnbound
) {
4523 src
= mputprintf(src
,
4524 // undo the last action on the buffer, check if the invalid token was a null token
4525 " p_tok.set_buf_pos(buf_pos);\n"
4526 " p_tok.get_next_token(&j_token, NULL, NULL);\n"
4527 " if (JSON_TOKEN_LITERAL_NULL == j_token) {\n"
4528 " if (JSON_METAINFO_NONE == metainfo_%s) {\n"
4529 // delay reporting an error for now, there might be meta info later
4530 " metainfo_%s = JSON_METAINFO_NEEDED;\n"
4533 " else if (JSON_METAINFO_UNBOUND == metainfo_%s) {\n"
4534 // meta info already found
4538 , sdef
->elements
[i
].name
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
4540 src
= mputprintf(src
,
4541 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, \"%s\");\n"
4543 " return JSON_ERROR_FATAL;\n"
4545 " dec_len += ret_val;\n"
4546 , sdef
->elements
[i
].dispname
);
4547 if (has_metainfo_enabled
) {
4548 src
= mputstr(src
, " }\n");
4554 src
= mputprintf(src
,
4556 // invalid field name
4557 " char* fld_name2 = mcopystrn(fld_name, name_len);\n"
4558 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, %sJSON_DEC_INVALID_NAME_ERROR, fld_name2);\n"
4559 // if this is set to a warning, skip the value of the field
4560 " dec_len += p_tok.get_next_token(&j_token, NULL, NULL);\n"
4561 " if (JSON_TOKEN_NUMBER != j_token && JSON_TOKEN_STRING != j_token &&\n"
4562 " JSON_TOKEN_LITERAL_TRUE != j_token && JSON_TOKEN_LITERAL_FALSE != j_token &&\n"
4563 " JSON_TOKEN_LITERAL_NULL != j_token) {\n"
4564 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, fld_name2);\n"
4565 " Free(fld_name2);\n"
4566 " return JSON_ERROR_FATAL;\n"
4568 " Free(fld_name2);\n"
4572 " dec_len += p_tok.get_next_token(&j_token, NULL, NULL);\n"
4573 " if (JSON_TOKEN_OBJECT_END != j_token) {\n"
4574 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_OBJECT_END_TOKEN_ERROR, \"\");\n"
4575 " return JSON_ERROR_FATAL;\n"
4577 , has_metainfo_enabled
? "is_metainfo ?\n JSON_DEC_METAINFO_NAME_ERROR : " : "");
4578 // Check if every field has been set and handle meta info
4579 for (i
= 0; i
< sdef
->nElements
; ++i
) {
4580 if (sdef
->elements
[i
].jsonMetainfoUnbound
) {
4581 src
= mputprintf(src
,
4582 "if (JSON_METAINFO_UNBOUND == metainfo_%s) {\n"
4583 " field_%s.clean_up();\n"
4585 " else if (JSON_METAINFO_NEEDED == metainfo_%s) {\n"
4586 // no meta info was found for this field, report the delayed error
4587 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, \"%s\");\n"
4590 , sdef
->elements
[i
].name
, sdef
->elements
[i
].name
4591 , sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
);
4593 src
= mputprintf(src
,
4594 "if (!%s_found) {\n"
4595 , sdef
->elements
[i
].name
);
4596 if (sdef
->elements
[i
].jsonDefaultValue
) {
4597 src
= mputprintf(src
,
4598 " field_%s.JSON_decode(%s_descr_, DUMMY_BUFFER, p_silent);\n"
4599 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
);
4601 else if (sdef
->elements
[i
].isOptional
) {
4602 src
= mputprintf(src
,
4603 " field_%s = OMIT_VALUE;\n"
4604 , sdef
->elements
[i
].name
);
4606 src
= mputprintf(src
,
4607 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_MISSING_FIELD_ERROR, \"%s\");\n"
4608 " return JSON_ERROR_FATAL;\n"
4609 , sdef
->elements
[i
].dispname
);
4615 "\n return dec_len;\n"
4619 /* end of class definition */
4620 def
= mputstr(def
, "};\n\n");
4622 output
->header
.class_defs
= mputstr(output
->header
.class_defs
, def
);
4625 output
->source
.methods
= mputstr(output
->source
.methods
, src
);
4630 static char *genRawFieldDecodeLimit(char *src
, const struct_def
*sdef
,
4631 int i
, const struct raw_option_struct
*raw_options
)
4633 /* number of arguments passed to min_of_ints() */
4636 for (j
= 0; j
< raw_options
[i
].lengthof
; j
++) {
4637 int field_index
= raw_options
[i
].lengthoffield
[j
];
4638 if (i
> field_index
&& sdef
->elements
[field_index
].raw
.unit
!=-1)
4641 if (raw_options
[i
].extbitgroup
&& sdef
->raw
.ext_bit_groups
[
4642 raw_options
[i
].extbitgroup
-1].ext_bit
!= XDEFNO
) nof_args
++;
4644 src
= mputprintf(src
, "min_of_ints(%d, limit", nof_args
);
4645 for (j
= 0; j
< raw_options
[i
].lengthof
; j
++) {
4646 int field_index
= raw_options
[i
].lengthoffield
[j
];
4647 if (i
> field_index
&& sdef
->elements
[field_index
].raw
.unit
!= -1)
4648 src
= mputprintf(src
, ", value_of_length_field%d", field_index
);
4650 if (raw_options
[i
].extbitgroup
&& sdef
->raw
.ext_bit_groups
[
4651 raw_options
[i
].extbitgroup
-1].ext_bit
!= XDEFNO
)
4652 src
= mputstr(src
, ", group_limit");
4653 src
= mputc(src
, ')');
4655 src
= mputstr(src
, "limit");
4660 static char *genRawDecodeRecordField(char *src
, const struct_def
*sdef
,
4661 int i
, const struct raw_option_struct
*raw_options
, boolean delayed_decode
,
4662 int *prev_ext_group
)
4665 if(raw_options
[i
].ptrbase
)
4667 " start_pos_of_field%d=p_buf.get_pos_bit();\n"
4670 if (*prev_ext_group
!= raw_options
[i
].extbitgroup
) {
4671 *prev_ext_group
= raw_options
[i
].extbitgroup
;
4672 if(prev_ext_group
&&
4673 sdef
->raw
.ext_bit_groups
[raw_options
[i
].extbitgroup
-1].ext_bit
!=XDEFNO
){
4674 if(raw_options
[i
].pointerof
) /* pointed field */
4676 " {size_t old_pos=p_buf.get_pos_bit();\n"
4677 " if(start_of_field%d!=-1 && start_pos_of_field%d!=-1){\n"
4678 " start_of_field%d=start_pos_of_field%d"
4679 "+(int)field_%s%s*%d+%d;\n"
4680 " p_buf.set_pos_bit(start_of_field%d);\n"
4681 " limit=end_of_available_data-start_of_field%d;\n"
4683 ,sdef
->elements
[raw_options
[i
].pointerof
-1].raw
.pointerbase
4685 ,sdef
->elements
[raw_options
[i
].pointerof
-1].raw
.pointerbase
4686 ,sdef
->elements
[raw_options
[i
].pointerof
-1].name
4687 ,sdef
->elements
[raw_options
[i
].pointerof
-1].isOptional
?"()":""
4688 ,sdef
->elements
[raw_options
[i
].pointerof
-1].raw
.unit
4689 ,sdef
->elements
[raw_options
[i
].pointerof
-1].raw
.ptroffset
4694 " cbyte* data=p_buf.get_read_data();\n"
4696 " int rot=local_top_order==ORDER_LSB?0:7;\n"
4697 " while(((data[count-1]>>rot)&0x01)==%d && count*8<"
4698 "(int)limit) count++;\n"
4699 " if(limit) group_limit=count*8;\n"
4701 ,sdef
->raw
.ext_bit_groups
[raw_options
[i
].extbitgroup
-1].ext_bit
==
4704 if(raw_options
[i
].pointerof
) /* pointed field */
4706 " } else group_limit=0;\n"
4707 " p_buf.set_pos_bit(old_pos);\n"
4708 " limit=end_of_available_data-old_pos;}\n"
4712 if(sdef
->elements
[i
].hasRaw
&& /* check the crosstag */
4713 sdef
->elements
[i
].raw
.crosstaglist
.nElements
){
4714 /* field index of the otherwise rule */
4716 boolean first_value
= TRUE
;
4718 for (j
= 0; j
< sdef
->elements
[i
].raw
.crosstaglist
.nElements
; j
++) {
4719 rawAST_coding_taglist
* cur_choice
=
4720 sdef
->elements
[i
].raw
.crosstaglist
.list
+ j
;
4721 if (cur_choice
->nElements
> 0) {
4722 /* this is a normal rule */
4724 src
= mputstr(src
, " if (");
4725 first_value
= FALSE
;
4726 } else src
= mputstr(src
, " else if (");
4727 src
= genRawFieldChecker(src
, cur_choice
, TRUE
);
4728 /* set selected_field in the if's body */
4729 src
= mputprintf(src
, ") selected_field = %d;\n",
4730 cur_choice
->fieldnum
);
4732 /* this is an otherwise rule */
4733 other
= cur_choice
->fieldnum
;
4736 /* set selected_field to the field index of the otherwise rule or -1 */
4737 src
= mputprintf(src
, " else selected_field = %d;\n", other
);
4739 /* check the presence of optional field*/
4740 if(sdef
->elements
[i
].isOptional
){
4741 /* check if enough bits to decode the field*/
4742 src
= mputstr(src
, " if (limit > 0");
4743 for (a
= 0; a
< raw_options
[i
].lengthof
; a
++){
4744 int field_index
= raw_options
[i
].lengthoffield
[a
];
4745 if (i
> field_index
) src
= mputprintf(src
,
4746 " && value_of_length_field%d > 0", field_index
);
4748 if (raw_options
[i
].extbitgroup
&&
4749 sdef
->raw
.ext_bit_groups
[raw_options
[i
].extbitgroup
-1].ext_bit
!=XDEFNO
){
4750 src
= mputstr(src
, " && group_limit > 0");
4752 if(raw_options
[i
].pointerof
){ /* valid pointer?*/
4754 " && start_of_field%d!=-1 && start_pos_of_field%d!=-1"
4755 ,i
,sdef
->elements
[raw_options
[i
].pointerof
-1].raw
.pointerbase
4758 if(sdef
->elements
[i
].hasRaw
&&
4759 sdef
->elements
[i
].raw
.presence
.nElements
)
4761 src
= mputstr(src
, " && ");
4762 if (sdef
->elements
[i
].raw
.presence
.nElements
> 1) src
= mputc(src
, '(');
4763 src
= genRawFieldChecker(src
, &sdef
->elements
[i
].raw
.presence
, TRUE
);
4764 if (sdef
->elements
[i
].raw
.presence
.nElements
> 1) src
= mputc(src
, ')');
4766 if(sdef
->elements
[i
].hasRaw
&&
4767 sdef
->elements
[i
].raw
.crosstaglist
.nElements
)
4770 "&& selected_field!=-1"
4777 if(raw_options
[i
].pointerof
){ /* pointed field */
4779 " start_of_field%d=start_pos_of_field%d"
4780 "+(int)field_%s%s*%d+%d;\n"
4782 ,sdef
->elements
[raw_options
[i
].pointerof
-1].raw
.pointerbase
4783 ,sdef
->elements
[raw_options
[i
].pointerof
-1].name
4784 ,sdef
->elements
[raw_options
[i
].pointerof
-1].isOptional
?"()":""
4785 ,sdef
->elements
[raw_options
[i
].pointerof
-1].raw
.unit
4786 ,sdef
->elements
[raw_options
[i
].pointerof
-1].raw
.ptroffset
4789 " p_buf.set_pos_bit(start_of_field%d);\n"
4790 " limit=end_of_available_data-start_of_field%d;\n"
4794 /* decoding of normal field */
4795 if (sdef
->elements
[i
].isOptional
) src
= mputstr(src
,
4796 " size_t fl_start_pos = p_buf.get_pos_bit();\n");
4797 src
= mputprintf(src
,
4798 " decoded_field_length = field_%s%s.RAW_decode(%s_descr_, p_buf, ",
4799 sdef
->elements
[i
].name
, sdef
->elements
[i
].isOptional
? "()" : "",
4800 sdef
->elements
[i
].typedescrname
);
4801 if (delayed_decode
) {
4802 /* the fixed field length is used as limit in case of delayed decoding */
4803 src
= mputprintf(src
, "%d", sdef
->elements
[i
].raw
.length
);
4805 src
= genRawFieldDecodeLimit(src
, sdef
, i
, raw_options
);
4807 src
= mputprintf(src
, ", local_top_order, %s",
4808 sdef
->elements
[i
].isOptional
? "TRUE" : "no_err");
4809 if (sdef
->elements
[i
].hasRaw
&&
4810 sdef
->elements
[i
].raw
.crosstaglist
.nElements
> 0)
4811 src
= mputstr(src
, ", selected_field");
4812 for (a
= 0; a
< raw_options
[i
].lengthof
; a
++) {
4813 int field_index
= raw_options
[i
].lengthoffield
[a
];
4814 /* number of elements in 'record of' or 'set of' */
4815 if (sdef
->elements
[field_index
].raw
.unit
== -1) {
4816 src
= mputprintf(src
, ", value_of_length_field%d", field_index
);
4820 src
= mputstr(src
, ");\n");
4821 if (delayed_decode
) {
4822 src
= mputprintf(src
, " if (decoded_field_length != %d) return -1;\n",
4823 sdef
->elements
[i
].raw
.length
);
4824 } else if (sdef
->elements
[i
].isOptional
) {
4825 src
= mputprintf(src
, " if (decoded_field_length < 1) {\n"
4826 " field_%s = OMIT_VALUE;\n" /* transform errors into omit */
4827 " p_buf.set_pos_bit(fl_start_pos);\n"
4828 " } else {\n", sdef
->elements
[i
].name
);
4830 src
= mputstr(src
, " if (decoded_field_length < 0) return decoded_field_length;\n");
4832 if(raw_options
[i
].tag_type
&& sdef
->raw
.taglist
.list
[raw_options
[i
].tag_type
-1].nElements
){
4833 rawAST_coding_taglist
* cur_choice
=
4834 sdef
->raw
.taglist
.list
+raw_options
[i
].tag_type
-1;
4837 src
=genRawFieldChecker(src
,cur_choice
,FALSE
);
4840 if(sdef
->elements
[i
].isOptional
){
4842 "{\n field_%s=OMIT_VALUE;\n"
4843 " p_buf.set_pos_bit(fl_start_pos);\n }\n"
4845 ,sdef
->elements
[i
].name
4847 }else src
=mputstr(src
, " return -1;\n");
4849 if (!delayed_decode
) {
4851 " decoded_length+=decoded_field_length;\n"
4852 " limit-=decoded_field_length;\n"
4853 " last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());\n"
4856 if(raw_options
[i
].extbitgroup
&&
4857 sdef
->raw
.ext_bit_groups
[raw_options
[i
].extbitgroup
-1].ext_bit
!=XDEFNO
){
4859 "group_limit-=decoded_field_length;\n"
4862 if(raw_options
[i
].lengthto
){ /* if the field is lengthto store the value*/
4863 if(sdef
->elements
[i
].raw
.lengthindex
){
4864 if(sdef
->elements
[i
].raw
.lengthindex
->fieldtype
== OPTIONAL_FIELD
){
4866 " if(field_%s%s.%s().ispresent()){\n"
4867 ,sdef
->elements
[i
].name
,sdef
->elements
[i
].isOptional
?"()":""
4868 ,sdef
->elements
[i
].raw
.lengthindex
->nthfieldname
4872 " value_of_length_field%d+=(int)field_%s%s.%s%s()*%d;\n"
4873 ,i
,sdef
->elements
[i
].name
,sdef
->elements
[i
].isOptional
?"()":""
4874 ,sdef
->elements
[i
].raw
.lengthindex
->nthfieldname
4875 ,sdef
->elements
[i
].raw
.lengthindex
->fieldtype
== OPTIONAL_FIELD
?"()":""
4876 ,sdef
->elements
[i
].raw
.unit
==-1?1:sdef
->elements
[i
].raw
.unit
4878 if(sdef
->elements
[i
].raw
.lengthindex
->fieldtype
== OPTIONAL_FIELD
){
4884 else if(sdef
->elements
[i
].raw
.union_member_num
){
4886 src
= mputprintf(src
, " switch (field_%s%s.get_selection()) {\n",
4887 sdef
->elements
[i
].name
, sdef
->elements
[i
].isOptional
? "()" : "");
4888 for (m
= 1; m
< sdef
->elements
[i
].raw
.union_member_num
+ 1; m
++) {
4889 src
= mputprintf(src
, " case %s%s%s:\n"
4890 " value_of_length_field%d += (int)field_%s%s.%s() * %d;\n"
4891 " break;\n", sdef
->elements
[i
].raw
.member_name
[0],
4893 sdef
->elements
[i
].raw
.member_name
[m
], i
, sdef
->elements
[i
].name
,
4894 sdef
->elements
[i
].isOptional
? "()" : "",
4895 sdef
->elements
[i
].raw
.member_name
[m
],
4896 sdef
->elements
[i
].raw
.unit
== -1 ? 1 : sdef
->elements
[i
].raw
.unit
);
4898 src
= mputprintf(src
, " default:\n"
4899 " value_of_length_field%d = 0;\n"
4904 " value_of_length_field%d+=(int)field_%s%s*%d;\n"
4905 ,i
,sdef
->elements
[i
].name
,sdef
->elements
[i
].isOptional
?"()":""
4906 ,sdef
->elements
[i
].raw
.unit
==-1?1:sdef
->elements
[i
].raw
.unit
4910 if(raw_options
[i
].pointerto
){ /* store the start of pointed field*/
4912 " start_of_field%d=(int)field_%s%s+%d?1:-1;\n"
4913 ,sdef
->elements
[i
].raw
.pointerto
4914 ,sdef
->elements
[i
].name
,sdef
->elements
[i
].isOptional
?"()":""
4915 ,sdef
->elements
[i
].raw
.ptroffset
4918 if (!delayed_decode
) {
4919 /* mark the used bits in length area*/
4920 for (a
= 0; a
< raw_options
[i
].lengthof
; a
++) {
4921 int field_index
= raw_options
[i
].lengthoffield
[a
];
4922 src
= mputprintf(src
,
4923 " value_of_length_field%d -= decoded_field_length;\n", field_index
);
4924 if (i
== field_index
) src
= mputprintf(src
,
4925 " if (value_of_length_field%d < 0) return -1;\n", field_index
);
4928 if(sdef
->elements
[i
].isOptional
){
4931 " else field_%s=OMIT_VALUE;\n"
4932 ,raw_options
[i
].tag_type
?" }\n":"",sdef
->elements
[i
].name
4939 #define SUNPRO_PUBLIC "public:\n"
4940 #define SUNPRO_PRIVATE "private:\n"
4942 #define SUNPRO_PUBLIC
4943 #define SUNPRO_PRIVATE
4946 void defRecordTemplate1(const struct_def
*sdef
, output_struct
*output
)
4949 const char *name
= sdef
->name
, *dispname
= sdef
->dispname
;
4950 const char* kind_str
= sdef
->kind
== SET
? "set" : "record";
4951 char *def
= NULL
, *src
= NULL
;
4953 size_t mandatory_fields_count
;
4955 /* class declaration */
4956 output
->header
.class_decls
= mputprintf(output
->header
.class_decls
,
4957 "class %s_template;\n", name
);
4959 if(sdef
->nElements
<= 0) {
4960 defEmptyRecordTemplate(name
, dispname
, output
);
4964 /* template class definition */
4965 def
= mputprintf(def
, "class %s_template : public Base_Template {\n", name
);
4968 def
= mputprintf(def
,
4970 "struct single_value_struct;\n"
4973 "single_value_struct *single_value;\n"
4975 "unsigned int n_values;\n"
4976 "%s_template *list_value;\n"
4979 /* the definition of single_value_struct must be put into the source file
4980 * because the types of optional fields may be incomplete in this position
4981 * of header file (e.g. due to type recursion) */
4982 src
= mputprintf(src
, "struct %s_template::single_value_struct {\n", name
);
4983 for (i
= 0; i
< sdef
->nElements
; i
++) {
4984 src
= mputprintf(src
, "%s_template field_%s;\n",
4985 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
4987 src
= mputstr(src
, "};\n\n");
4989 /* set_specific function (used in field access members) */
4990 def
= mputstr(def
, "void set_specific();\n");
4991 src
= mputprintf(src
, "void %s_template::set_specific()\n"
4993 "if (template_selection != SPECIFIC_VALUE) {\n"
4994 "template_sel old_selection = template_selection;\n"
4996 "single_value = new single_value_struct;\n"
4997 "set_selection(SPECIFIC_VALUE);\n"
4998 "if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) {\n",
5000 for (i
= 0; i
< sdef
->nElements
; i
++) {
5001 src
= mputprintf(src
, "single_value->field_%s = %s;\n",
5002 sdef
->elements
[i
].name
,
5003 sdef
->elements
[i
].isOptional
? "ANY_OR_OMIT" : "ANY_VALUE");
5005 src
= mputstr(src
, "}\n"
5009 /* copy_value function */
5010 def
= mputprintf(def
, "void copy_value(const %s& other_value);\n", name
);
5011 src
= mputprintf(src
,
5012 "void %s_template::copy_value(const %s& other_value)\n"
5014 "single_value = new single_value_struct;\n", name
, name
);
5015 for (i
= 0; i
< sdef
->nElements
; i
++) {
5016 src
= mputprintf(src
,
5017 "if (other_value.%s().is_bound()) {\n", sdef
->elements
[i
].name
);
5018 if (sdef
->elements
[i
].isOptional
) {
5019 /* If the value is present, "reach into" the OPTIONAL with operator()
5020 * and pass the contained object to the template's constructor.
5021 * Else set the template to omit. */
5022 src
= mputprintf(src
,
5023 " if (other_value.%s().ispresent()) single_value->field_%s = "
5024 "other_value.%s()();\n"
5025 " else single_value->field_%s = OMIT_VALUE;\n",
5026 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
5027 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
5029 src
= mputprintf(src
,
5030 " single_value->field_%s = other_value.%s();\n",
5031 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
5033 src
= mputprintf(src
, "} else {\n"
5034 " single_value->field_%s.clean_up();\n"
5035 "}\n", sdef
->elements
[i
].name
);
5037 src
= mputstr(src
, "set_selection(SPECIFIC_VALUE);\n"
5040 /* copy_template function */
5041 def
= mputprintf(def
, "void copy_template(const %s_template& "
5042 "other_value);\n\n", name
);
5043 src
= mputprintf(src
,
5044 "void %s_template::copy_template(const %s_template& other_value)\n"
5046 "switch (other_value.template_selection) {\n"
5047 "case SPECIFIC_VALUE:\n", name
, name
);
5049 "single_value = new single_value_struct;\n");
5050 for (i
= 0; i
< sdef
->nElements
; i
++) {
5051 src
= mputprintf(src
,
5052 "if (UNINITIALIZED_TEMPLATE != other_value.%s().get_selection()) {\n",
5053 sdef
->elements
[i
].name
);
5054 src
= mputprintf(src
,
5055 "single_value->field_%s = other_value.%s();\n",
5056 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
5057 src
= mputprintf(src
, "} else {\n"
5058 "single_value->field_%s.clean_up();\n"
5059 "}\n", sdef
->elements
[i
].name
);
5061 src
= mputprintf(src
,
5062 "case OMIT_VALUE:\n"
5064 "case ANY_OR_OMIT:\n"
5066 "case VALUE_LIST:\n"
5067 "case COMPLEMENTED_LIST:\n"
5068 "value_list.n_values = other_value.value_list.n_values;\n"
5069 "value_list.list_value = new %s_template[value_list.n_values];\n"
5070 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
5072 "value_list.list_value[list_count].copy_template("
5073 "other_value.value_list.list_value[list_count]);\n"
5076 "TTCN_error(\"Copying an uninitialized/unsupported template of type "
5080 "set_selection(other_value);\n"
5081 "}\n\n", name
, dispname
);
5083 /* default constructor */
5084 def
= mputprintf(def
, "public:\n"
5085 "%s_template();\n", name
);
5086 src
= mputprintf(src
, "%s_template::%s_template()\n"
5088 "}\n\n", name
, name
);
5090 /* constructor t1_template(template_sel other_value) */
5091 def
= mputprintf(def
, "%s_template(template_sel other_value);\n", name
);
5092 src
= mputprintf(src
, "%s_template::%s_template(template_sel other_value)\n"
5093 " : Base_Template(other_value)\n"
5095 "check_single_selection(other_value);\n"
5096 "}\n\n", name
, name
);
5098 /* constructor t1_template(const t1& other_value) */
5099 def
= mputprintf(def
, "%s_template(const %s& other_value);\n", name
, name
);
5100 src
= mputprintf(src
, "%s_template::%s_template(const %s& other_value)\n"
5102 "copy_value(other_value);\n"
5103 "}\n\n", name
, name
, name
);
5105 /* constructor t1_template(const OPTIONAL<t1>& other_value) */
5106 def
= mputprintf(def
, "%s_template(const OPTIONAL<%s>& other_value);\n",
5108 src
= mputprintf(src
,
5109 "%s_template::%s_template(const OPTIONAL<%s>& other_value)\n"
5111 "switch (other_value.get_selection()) {\n"
5112 "case OPTIONAL_PRESENT:\n"
5113 "copy_value((const %s&)other_value);\n"
5115 "case OPTIONAL_OMIT:\n"
5116 "set_selection(OMIT_VALUE);\n"
5119 "TTCN_error(\"Creating a template of type %s from an unbound optional "
5122 "}\n\n", name
, name
, name
, name
, dispname
);
5124 /* copy constructor */
5125 def
= mputprintf(def
, "%s_template(const %s_template& other_value);\n",
5127 src
= mputprintf(src
, "%s_template::%s_template(const %s_template& "
5129 ": Base_Template()\n" /* yes, the base class _default_ constructor */
5131 "copy_template(other_value);\n"
5132 "}\n\n", name
, name
, name
);
5135 def
= mputprintf(def
, "~%s_template();\n", name
);
5136 src
= mputprintf(src
, "%s_template::~%s_template()\n"
5139 "}\n\n", name
, name
);
5141 /* assignment operator <- template_sel */
5142 def
= mputprintf(def
, "%s_template& operator=(template_sel other_value);\n",
5144 src
= mputprintf(src
,
5145 "%s_template& %s_template::operator=(template_sel other_value)\n"
5147 "check_single_selection(other_value);\n"
5149 "set_selection(other_value);\n"
5151 "}\n\n", name
, name
);
5153 /* assignment operator <- value */
5154 def
= mputprintf(def
, "%s_template& operator=(const %s& other_value);\n",
5157 src
= mputprintf(src
,
5158 "%s_template& %s_template::operator=(const %s& other_value)\n"
5161 "copy_value(other_value);\n"
5163 "}\n\n", name
, name
, name
);
5165 /* assignment operator <- optional value */
5166 def
= mputprintf(def
, "%s_template& operator=(const OPTIONAL<%s>& "
5167 "other_value);\n", name
, name
);
5169 src
= mputprintf(src
,
5170 "%s_template& %s_template::operator=(const OPTIONAL<%s>& other_value)\n"
5173 "switch (other_value.get_selection()) {\n"
5174 "case OPTIONAL_PRESENT:\n"
5175 "copy_value((const %s&)other_value);\n"
5177 "case OPTIONAL_OMIT:\n"
5178 "set_selection(OMIT_VALUE);\n"
5181 "TTCN_error(\"Assignment of an unbound optional field to a template "
5185 "}\n\n", name
, name
, name
, name
, dispname
);
5187 /* assignment operator <- template*/
5188 def
= mputprintf(def
,
5189 "%s_template& operator=(const %s_template& other_value);\n",
5192 src
= mputprintf(src
,
5193 "%s_template& %s_template::operator=(const %s_template& other_value)\n"
5195 "if (&other_value != this) {\n"
5197 "copy_template(other_value);\n"
5200 "}\n\n", name
, name
, name
);
5202 /* match operation (template matching) */
5203 def
= mputprintf(def
, "boolean match(const %s& other_value, boolean legacy "
5204 "= FALSE) const;\n", name
);
5206 src
= mputprintf(src
,
5207 "boolean %s_template::match(const %s& other_value, boolean legacy) const\n"
5209 "if (!other_value.is_bound()) return FALSE;\n"
5210 "switch (template_selection) {\n"
5212 "case ANY_OR_OMIT:\n"
5214 "case OMIT_VALUE:\n"
5216 "case SPECIFIC_VALUE:\n", name
, name
);
5217 for (i
= 0; i
< sdef
->nElements
; i
++) {
5218 src
= mputprintf(src
,"if(!other_value.%s().is_bound()) return FALSE;\n", sdef
->elements
[i
].name
);
5219 if (sdef
->elements
[i
].isOptional
) src
= mputprintf(src
,
5220 "if((other_value.%s().ispresent() ? "
5221 "!single_value->field_%s.match((const %s&)other_value.%s(), legacy) : "
5222 "!single_value->field_%s.match_omit(legacy)))",
5223 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
5224 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
,
5225 sdef
->elements
[i
].name
);
5226 else src
= mputprintf(src
,
5227 "if(!single_value->field_%s.match(other_value.%s(), legacy))",
5228 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
5229 src
= mputstr(src
, "return FALSE;\n");
5231 src
= mputprintf(src
,
5233 "case VALUE_LIST:\n"
5234 "case COMPLEMENTED_LIST:\n"
5235 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
5237 "if (value_list.list_value[list_count].match(other_value, legacy)) "
5238 "return template_selection == VALUE_LIST;\n"
5239 "return template_selection == COMPLEMENTED_LIST;\n"
5241 "TTCN_error(\"Matching an uninitialized/unsupported template of "
5248 def
= mputstr(def
, "boolean is_bound() const;\n");
5250 src
= mputprintf(src
, "boolean %s_template::is_bound() const\n"
5252 "if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) "
5253 "return FALSE;\n", name
);
5254 src
= mputstr(src
, "if (template_selection != SPECIFIC_VALUE) return TRUE;\n");
5255 for (i
= 0; i
< sdef
->nElements
; i
++) {
5256 if (sdef
->elements
[i
].isOptional
) {
5257 src
= mputprintf(src
,
5258 "if (single_value->field_%s.is_omit() ||"
5259 " single_value->field_%s.is_bound()) return TRUE;\n",
5260 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
5262 src
= mputprintf(src
,
5263 "if (single_value->field_%s.is_bound()) return TRUE;\n",
5264 sdef
->elements
[i
].name
);
5267 src
= mputstr(src
, "return FALSE;\n"
5271 def
= mputstr(def
, "boolean is_value() const;\n");
5273 src
= mputprintf(src
, "boolean %s_template::is_value() const\n"
5275 "if (template_selection != SPECIFIC_VALUE || is_ifpresent) "
5276 "return FALSE;\n", name
);
5277 for (i
= 0; i
< sdef
->nElements
; i
++) {
5278 if (sdef
->elements
[i
].isOptional
) {
5279 src
= mputprintf(src
,
5280 "if (!single_value->field_%s.is_omit() &&"
5281 " !single_value->field_%s.is_value()) return FALSE;\n",
5282 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
5284 src
= mputprintf(src
,
5285 "if (!single_value->field_%s.is_value()) return FALSE;\n",
5286 sdef
->elements
[i
].name
);
5289 src
= mputstr(src
, "return TRUE;\n"
5292 /* clean_up function */
5293 def
= mputstr(def
, "void clean_up();\n");
5294 src
= mputprintf(src
,
5295 "void %s_template::clean_up()\n"
5297 "switch (template_selection) {\n"
5298 "case SPECIFIC_VALUE:\n"
5299 "delete single_value;\n"
5301 "case VALUE_LIST:\n"
5302 "case COMPLEMENTED_LIST:\n"
5303 "delete [] value_list.list_value;\n"
5307 "template_selection = UNINITIALIZED_TEMPLATE;\n"
5310 /* valueof operation */
5311 def
= mputprintf(def
, "%s valueof() const;\n", name
);
5313 src
= mputprintf(src
, "%s %s_template::valueof() const\n"
5315 "if (template_selection != SPECIFIC_VALUE || is_ifpresent)\n"
5316 "TTCN_error(\"Performing valueof or send operation on a non-specific "
5317 "template of type %s.\");\n"
5318 "%s ret_val;\n", name
, name
, dispname
, name
);
5319 for (i
= 0; i
< sdef
->nElements
; i
++) {
5320 if (sdef
->elements
[i
].isOptional
) {
5321 src
= mputprintf(src
,
5322 "if (single_value->field_%s.is_omit()) "
5323 "ret_val.%s() = OMIT_VALUE;\n"
5325 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
5327 src
= mputprintf(src
, "if (single_value->field_%s.is_bound()) {\n"
5328 "ret_val.%s() = single_value->field_%s.valueof();\n"
5330 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
5332 src
= mputstr(src
, "return ret_val;\n"
5335 /* void set_type(template_sel, int) function */
5337 "void set_type(template_sel template_type, "
5338 "unsigned int list_length);\n");
5340 src
= mputprintf(src
,
5341 "void %s_template::set_type(template_sel template_type, "
5342 "unsigned int list_length)\n"
5344 "if (template_type != VALUE_LIST "
5345 "&& template_type != COMPLEMENTED_LIST)\n"
5346 "TTCN_error(\"Setting an invalid list for a template of type %s.\");\n"
5348 "set_selection(template_type);\n"
5349 "value_list.n_values = list_length;\n"
5350 "value_list.list_value = new %s_template[list_length];\n"
5351 "}\n\n", name
, dispname
, name
);
5353 /* list_item(int) function */
5355 def
= mputprintf(def
,
5356 "%s_template& list_item(unsigned int list_index) const;\n", name
);
5358 src
= mputprintf(src
,
5359 "%s_template& %s_template::list_item(unsigned int list_index) const\n"
5361 "if (template_selection != VALUE_LIST "
5362 "&& template_selection != COMPLEMENTED_LIST)\n"
5363 "TTCN_error(\"Accessing a list element of a non-list template of "
5365 "if (list_index >= value_list.n_values)\n"
5366 "TTCN_error(\"Index overflow in a value list template of type "
5368 "return value_list.list_value[list_index];\n"
5369 "}\n\n", name
, name
, dispname
, dispname
);
5371 /* template field access functions (non-const & const) */
5372 for (i
= 0; i
< sdef
->nElements
; i
++) {
5373 def
= mputprintf(def
, "%s_template& %s();\n",
5374 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
5375 src
= mputprintf(src
, "%s_template& %s_template::%s()\n"
5378 "return single_value->field_%s;\n"
5380 sdef
->elements
[i
].type
, name
, sdef
->elements
[i
].name
,
5381 sdef
->elements
[i
].name
);
5382 def
= mputprintf(def
, "const %s_template& %s() const;\n",
5383 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
5384 src
= mputprintf(src
, "const %s_template& %s_template::%s() const\n"
5386 "if (template_selection != SPECIFIC_VALUE)\n"
5387 "TTCN_error(\"Accessing field %s of a non-specific "
5388 "template of type %s.\");\n"
5389 "return single_value->field_%s;\n"
5391 sdef
->elements
[i
].type
, name
, sdef
->elements
[i
].name
,
5392 sdef
->elements
[i
].dispname
, dispname
, sdef
->elements
[i
].name
);
5395 /* sizeof operation */
5396 def
= mputstr(def
, "int size_of() const;\n");
5397 src
= mputprintf(src
,
5398 "int %s_template::size_of() const\n"
5400 " if (is_ifpresent) TTCN_error(\"Performing sizeof() operation on a "
5401 "template of type %s which has an ifpresent attribute.\");\n"
5402 " switch (template_selection)\n"
5404 " case SPECIFIC_VALUE:\n",
5406 mandatory_fields_count
= 0;
5407 for (i
= 0; i
< sdef
->nElements
; i
++)
5408 if (!sdef
->elements
[i
].isOptional
) mandatory_fields_count
++;
5409 if(sdef
->nElements
== mandatory_fields_count
){
5410 src
= mputprintf(src
," return %lu;\n",
5411 (unsigned long) mandatory_fields_count
);
5413 src
= mputprintf(src
,
5415 " int ret_val = %lu;\n", (unsigned long) mandatory_fields_count
);
5416 for (i
= 0; i
< sdef
->nElements
; i
++)
5417 if (sdef
->elements
[i
].isOptional
)
5418 src
= mputprintf(src
,
5419 " if (single_value->field_%s.is_present()) ret_val++;\n",
5420 sdef
->elements
[i
].name
);
5422 " return ret_val;\n"
5425 src
= mputprintf(src
,
5427 " case VALUE_LIST:\n"
5429 " if (value_list.n_values<1)\n"
5430 " TTCN_error(\"Internal error: Performing sizeof() operation on a "
5431 "template of type %s containing an empty list.\");\n"
5432 " int item_size = value_list.list_value[0].size_of();\n"
5433 " for (unsigned int l_idx = 1; l_idx < value_list.n_values; l_idx++)\n"
5435 " if (value_list.list_value[l_idx].size_of()!=item_size)\n"
5436 " TTCN_error(\"Performing sizeof() operation on a template "
5437 "of type %s containing a value list with different sizes.\");\n"
5439 " return item_size;\n"
5441 " case OMIT_VALUE:\n"
5442 " TTCN_error(\"Performing sizeof() operation on a template of type %s "
5443 "containing omit value.\");\n"
5444 " case ANY_VALUE:\n"
5445 " case ANY_OR_OMIT:\n"
5446 " TTCN_error(\"Performing sizeof() operation on a template of type %s "
5447 "containing */? value.\");\n"
5448 " case COMPLEMENTED_LIST:\n"
5449 " TTCN_error(\"Performing sizeof() operation on a template of type %s "
5450 "containing complemented list.\");\n"
5452 " TTCN_error(\"Performing sizeof() operation on an "
5453 "uninitialized/unsupported template of type %s.\");\n"
5457 dispname
,dispname
,dispname
,dispname
,dispname
,dispname
);
5460 def
= mputstr(def
, "void log() const;\n");
5461 src
= mputprintf(src
,
5462 "void %s_template::log() const\n"
5464 "switch (template_selection) {\n"
5465 "case SPECIFIC_VALUE:\n", name
);
5466 for (i
= 0; i
< sdef
->nElements
; i
++) {
5467 src
= mputstr(src
, "TTCN_Logger::log_event_str(\"");
5468 if (i
== 0) src
= mputc(src
, '{');
5469 else src
= mputc(src
, ',');
5470 src
= mputprintf(src
, " %s := \");\n"
5471 "single_value->field_%s.log();\n",
5472 sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
);
5475 "TTCN_Logger::log_event_str(\" }\");\n"
5477 "case COMPLEMENTED_LIST:\n"
5478 "TTCN_Logger::log_event_str(\"complement \");\n"
5479 "case VALUE_LIST:\n"
5480 "TTCN_Logger::log_char('(');\n"
5481 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
5483 "if (list_count > 0) TTCN_Logger::log_event_str(\", \");\n"
5484 "value_list.list_value[list_count].log();\n"
5486 "TTCN_Logger::log_char(')');\n"
5491 "log_ifpresent();\n"
5494 /* log_match function */
5495 def
= mputprintf(def
, "void log_match(const %s& match_value, "
5496 "boolean legacy = FALSE) const;\n", name
);
5497 src
= mputprintf(src
,
5498 "void %s_template::log_match(const %s& match_value, boolean legacy) const\n"
5500 "if(TTCN_Logger::VERBOSITY_COMPACT"
5501 " == TTCN_Logger::get_matching_verbosity()){\n"
5502 "if(match(match_value, legacy)){\n"
5503 "TTCN_Logger::print_logmatch_buffer();\n"
5504 "TTCN_Logger::log_event_str(\" matched\");\n"
5506 "if (template_selection == SPECIFIC_VALUE) {\n"
5507 "size_t previous_size = TTCN_Logger::get_logmatch_buffer_len();\n"
5509 for (i
= 0; i
< sdef
->nElements
; i
++) {
5510 if (sdef
->elements
[i
].isOptional
){
5511 src
= mputprintf(src
,
5512 "if (match_value.%s().ispresent()){\n"
5513 "if(!single_value->field_%s.match(match_value.%s(), legacy)){\n"
5514 "TTCN_Logger::log_logmatch_info(\".%s\");\n"
5515 "single_value->field_%s.log_match(match_value.%s(), legacy);\n"
5516 "TTCN_Logger::set_logmatch_buffer_len(previous_size);\n"
5519 "if (!single_value->field_%s.match_omit(legacy)){\n "
5520 "TTCN_Logger::log_logmatch_info(\".%s := omit with \");\n"
5521 "TTCN_Logger::print_logmatch_buffer();\n"
5522 "single_value->field_%s.log();\n"
5523 "TTCN_Logger::log_event_str(\" unmatched\");\n"
5524 "TTCN_Logger::set_logmatch_buffer_len(previous_size);\n"
5527 , sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
5528 sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
,
5529 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
5530 sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
,
5531 sdef
->elements
[i
].name
);
5533 src
= mputprintf(src
,
5534 "if(!single_value->field_%s.match(match_value.%s(), legacy)){\n"
5535 "TTCN_Logger::log_logmatch_info(\".%s\");\n"
5536 "single_value->field_%s.log_match(match_value.%s(), legacy);\n"
5537 "TTCN_Logger::set_logmatch_buffer_len(previous_size);\n"
5538 "}\n",sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
5539 sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
,
5540 sdef
->elements
[i
].name
);
5544 src
= mputstr(src
,"}else {\n"
5545 "TTCN_Logger::print_logmatch_buffer();\n"
5546 "match_value.log();\n"
5547 "TTCN_Logger::log_event_str(\" with \");\n"
5549 "TTCN_Logger::log_event_str(\" unmatched\");\n"
5554 "if (template_selection == SPECIFIC_VALUE) {\n");
5555 for (i
= 0; i
< sdef
->nElements
; i
++) {
5556 src
= mputstr(src
, "TTCN_Logger::log_event_str(\"");
5557 if (i
== 0) src
= mputc(src
, '{');
5558 else src
= mputc(src
, ',');
5559 src
= mputprintf(src
, " %s := \");\n", sdef
->elements
[i
].dispname
);
5560 if (sdef
->elements
[i
].isOptional
) src
= mputprintf(src
,
5561 "if (match_value.%s().ispresent()) "
5562 "single_value->field_%s.log_match(match_value.%s(), legacy);\n"
5564 "TTCN_Logger::log_event_str(\"omit with \");\n"
5565 "single_value->field_%s.log();\n"
5566 "if (single_value->field_%s.match_omit(legacy)) "
5567 "TTCN_Logger::log_event_str(\" matched\");\n"
5568 "else TTCN_Logger::log_event_str(\" unmatched\");\n"
5570 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
5571 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
5572 sdef
->elements
[i
].name
);
5573 else src
= mputprintf(src
,
5574 "single_value->field_%s.log_match(match_value.%s(), legacy);\n",
5575 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
5578 "TTCN_Logger::log_event_str(\" }\");\n"
5580 "match_value.log();\n"
5581 "TTCN_Logger::log_event_str(\" with \");\n"
5583 "if (match(match_value, legacy)) TTCN_Logger::log_event_str(\" matched\");\n"
5584 "else TTCN_Logger::log_event_str(\" unmatched\");\n"
5588 /*encode_text function*/
5589 def
= mputstr(def
, "void encode_text(Text_Buf& text_buf) const;\n");
5590 src
= mputprintf(src
,
5591 "void %s_template::encode_text(Text_Buf& text_buf) const\n"
5593 "encode_text_base(text_buf);\n"
5594 "switch (template_selection) {\n"
5595 "case SPECIFIC_VALUE:\n", name
);
5596 for (i
= 0; i
< sdef
->nElements
; i
++) {
5597 src
= mputprintf(src
, "single_value->field_%s.encode_text(text_buf);\n",
5598 sdef
->elements
[i
].name
);
5600 src
= mputprintf(src
,
5601 "case OMIT_VALUE:\n"
5603 "case ANY_OR_OMIT:\n"
5605 "case VALUE_LIST:\n"
5606 "case COMPLEMENTED_LIST:\n"
5607 "text_buf.push_int(value_list.n_values);\n"
5608 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
5610 "value_list.list_value[list_count].encode_text(text_buf);\n"
5613 "TTCN_error(\"Text encoder: Encoding an uninitialized/unsupported "
5614 "template of type %s.\");\n"
5618 /*decode_text function*/
5619 def
= mputstr(def
, "void decode_text(Text_Buf& text_buf);\n");
5620 src
= mputprintf(src
,
5621 "void %s_template::decode_text(Text_Buf& text_buf)\n"
5624 "decode_text_base(text_buf);\n"
5625 "switch (template_selection) {\n"
5626 "case SPECIFIC_VALUE:\n"
5627 "single_value = new single_value_struct;\n", name
);
5628 for (i
= 0; i
< sdef
->nElements
; i
++) {
5629 src
= mputprintf(src
, "single_value->field_%s.decode_text(text_buf);\n",
5630 sdef
->elements
[i
].name
);
5632 src
= mputprintf(src
,
5633 "case OMIT_VALUE:\n"
5635 "case ANY_OR_OMIT:\n"
5637 "case VALUE_LIST:\n"
5638 "case COMPLEMENTED_LIST:\n"
5639 "value_list.n_values = text_buf.pull_int().get_val();\n"
5640 "value_list.list_value = new %s_template[value_list.n_values];\n"
5641 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
5643 "value_list.list_value[list_count].decode_text(text_buf);\n"
5646 "TTCN_error(\"Text decoder: An unknown/unsupported selection was "
5647 "received in a template of type %s.\");\n"
5649 "}\n\n", name
, dispname
);
5652 def
= mputstr(def
, "void set_param(Module_Param& param);\n");
5653 src
= mputprintf(src
,
5654 "void %s_template::set_param(Module_Param& param)\n"
5656 " if (dynamic_cast<Module_Param_Name*>(param.get_id()) != NULL &&\n"
5657 " param.get_id()->next_name()) {\n"
5658 // Haven't reached the end of the module parameter name
5659 // => the name refers to one of the fields, not to the whole record
5660 " char* param_field = param.get_id()->get_current_name();\n"
5661 " if (param_field[0] >= '0' && param_field[0] <= '9') {\n"
5662 " param.error(\"Unexpected array index in module parameter, expected a valid field\"\n"
5663 " \" name for %s template type `%s'\");\n"
5665 " ", name
, kind_str
, dispname
);
5666 for (i
= 0; i
< sdef
->nElements
; i
++) {
5667 src
= mputprintf(src
,
5668 "if (strcmp(\"%s\", param_field) == 0) {\n"
5669 " %s().set_param(param);\n"
5672 sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
);
5674 src
= mputprintf(src
,
5675 "param.error(\"Field `%%s' not found in %s template type `%s'\", param_field);\n"
5677 " param.basic_check(Module_Param::BC_TEMPLATE, \"%s template\");\n"
5678 " Module_Param_Ptr m_p = ¶m;\n"
5679 " if (param.get_type() == Module_Param::MP_Reference) {\n"
5680 " m_p = param.get_referenced_param();\n"
5682 " switch (m_p->get_type()) {\n"
5683 " case Module_Param::MP_Omit:\n"
5684 " *this = OMIT_VALUE;\n"
5686 " case Module_Param::MP_Any:\n"
5687 " *this = ANY_VALUE;\n"
5689 " case Module_Param::MP_AnyOrNone:\n"
5690 " *this = ANY_OR_OMIT;\n"
5692 " case Module_Param::MP_List_Template:\n"
5693 " case Module_Param::MP_ComplementList_Template: {\n"
5694 " %s_template new_temp;\n"
5695 " new_temp.set_type(m_p->get_type()==Module_Param::MP_List_Template ? "
5696 "VALUE_LIST : COMPLEMENTED_LIST, m_p->get_size());\n"
5697 " for (size_t p_i=0; p_i<m_p->get_size(); p_i++) {\n"
5698 " new_temp.list_item(p_i).set_param(*m_p->get_elem(p_i));\n"
5700 " *this = new_temp;\n"
5702 " case Module_Param::MP_Value_List:\n"
5703 " if (%lu<m_p->get_size()) {\n"
5704 " param.error(\"%s template of type %s has %lu fields but list value has %%d fields\", (int)m_p->get_size());\n"
5706 kind_str
, dispname
, kind_str
, name
, (unsigned long)sdef
->nElements
, kind_str
, dispname
, (unsigned long)sdef
->nElements
);
5707 for (i
= 0; i
< sdef
->nElements
; ++i
) {
5708 src
= mputprintf(src
,
5709 " if (m_p->get_size()>%lu && m_p->get_elem(%lu)->get_type()!=Module_Param::MP_NotUsed) %s().set_param(*m_p->get_elem(%lu));\n",
5710 (unsigned long)i
, (unsigned long)i
, sdef
->elements
[i
].name
, (unsigned long)i
);
5714 " case Module_Param::MP_Assignment_List: {\n"
5715 " Vector<bool> value_used(m_p->get_size());\n"
5716 " value_used.resize(m_p->get_size(), false);\n");
5717 for (i
= 0; i
< sdef
->nElements
; ++i
) {
5718 src
= mputprintf(src
,
5719 " for (size_t val_idx=0; val_idx<m_p->get_size(); val_idx++) {\n"
5720 " Module_Param* const curr_param = m_p->get_elem(val_idx);\n"
5721 " if (!strcmp(curr_param->get_id()->get_name(), \"%s\")) {\n"
5722 " if (curr_param->get_type()!=Module_Param::MP_NotUsed) {\n"
5723 " %s().set_param(*curr_param);\n"
5725 " value_used[val_idx]=true;\n"
5728 , sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
);
5730 src
= mputprintf(src
,
5731 " for (size_t val_idx=0; val_idx<m_p->get_size(); val_idx++) if (!value_used[val_idx]) {\n"
5732 " m_p->get_elem(val_idx)->error(\"Non existent field name in type %s: %%s\", m_p->get_elem(val_idx)->get_id()->get_name());\n"
5737 " param.type_error(\"%s template\", \"%s\");\n"
5739 " is_ifpresent = param.get_ifpresent() || m_p->get_ifpresent();\n"
5740 "}\n\n", dispname
, kind_str
, dispname
);
5743 def
= mputstr(def
, "Module_Param* get_param(Module_Param_Name& param_name) const;\n");
5744 src
= mputprintf(src
,
5745 "Module_Param* %s_template::get_param(Module_Param_Name& param_name) const\n"
5747 " if (param_name.next_name()) {\n"
5748 // Haven't reached the end of the module parameter name
5749 // => the name refers to one of the fields, not to the whole record
5750 " char* param_field = param_name.get_current_name();\n"
5751 " if (param_field[0] >= '0' && param_field[0] <= '9') {\n"
5752 " TTCN_error(\"Unexpected array index in module parameter reference, \"\n"
5753 " \"expected a valid field name for %s template type `%s'\");\n"
5755 " ", name
, kind_str
, dispname
);
5756 for (i
= 0; i
< sdef
->nElements
; i
++) {
5757 src
= mputprintf(src
,
5758 "if (strcmp(\"%s\", param_field) == 0) {\n"
5759 " return %s().get_param(param_name);\n"
5761 sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
);
5763 src
= mputprintf(src
,
5764 "TTCN_error(\"Field `%%s' not found in %s type `%s'\", param_field);\n"
5766 " Module_Param* m_p = NULL;\n"
5767 " switch (template_selection) {\n"
5768 " case UNINITIALIZED_TEMPLATE:\n"
5769 " m_p = new Module_Param_Unbound();\n"
5771 " case OMIT_VALUE:\n"
5772 " m_p = new Module_Param_Omit();\n"
5774 " case ANY_VALUE:\n"
5775 " m_p = new Module_Param_Any();\n"
5777 " case ANY_OR_OMIT:\n"
5778 " m_p = new Module_Param_AnyOrNone();\n"
5780 " case SPECIFIC_VALUE: {\n"
5781 " m_p = new Module_Param_Assignment_List();\n"
5782 , kind_str
, dispname
);
5783 for (i
= 0; i
< sdef
->nElements
; i
++) {
5784 src
= mputprintf(src
,
5785 " Module_Param* mp_field_%s = single_value->field_%s.get_param(param_name);\n"
5786 " mp_field_%s->set_id(new Module_Param_FieldName(mcopystr(\"%s\")));\n"
5787 " m_p->add_elem(mp_field_%s);\n"
5788 , sdef
->elements
[i
].name
, sdef
->elements
[i
].name
5789 , sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
5790 , sdef
->elements
[i
].name
);
5794 " case VALUE_LIST:\n"
5795 " case COMPLEMENTED_LIST: {\n"
5796 " if (template_selection == VALUE_LIST) {\n"
5797 " m_p = new Module_Param_List_Template();\n"
5800 " m_p = new Module_Param_ComplementList_Template();\n"
5802 " for (size_t i_i = 0; i_i < value_list.n_values; ++i_i) {\n"
5803 " m_p->add_elem(value_list.list_value[i_i].get_param(param_name));\n"
5809 " if (is_ifpresent) {\n"
5810 " m_p->set_ifpresent();\n"
5815 /* check template restriction */
5816 def
= mputstr(def
, "void check_restriction(template_res t_res, "
5817 "const char* t_name=NULL, boolean legacy = FALSE) const;\n");
5818 src
= mputprintf(src
,
5819 "void %s_template::check_restriction("
5820 "template_res t_res, const char* t_name, boolean legacy) const\n"
5822 "if (template_selection==UNINITIALIZED_TEMPLATE) return;\n"
5823 "switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {\n"
5825 "if (template_selection==OMIT_VALUE) return;\n"
5827 "if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;\n",
5829 for (i
= 0; i
< sdef
->nElements
; i
++) {
5830 src
= mputprintf(src
, "single_value->field_%s.check_restriction("
5831 "t_res, t_name ? t_name : \"%s\");\n",
5832 sdef
->elements
[i
].name
, dispname
);
5834 src
= mputprintf(src
,
5836 "case TR_PRESENT:\n"
5837 "if (!match_omit(legacy)) return;\n"
5842 "TTCN_error(\"Restriction `%%s' on template of type %%s "
5843 "violated.\", get_res_name(t_res), t_name ? t_name : \"%s\");\n"
5846 defCommonRecordTemplate(name
, &def
, &src
);
5848 def
= mputstr(def
, "};\n\n");
5850 output
->header
.class_defs
= mputstr(output
->header
.class_defs
, def
);
5853 output
->source
.methods
= mputstr(output
->source
.methods
, src
);
5857 static void defEmptyRecordClass(const struct_def
*sdef
,
5858 output_struct
*output
)
5860 const char *name
= sdef
->name
, *dispname
= sdef
->dispname
;
5861 char *def
= NULL
, *src
= NULL
;
5862 boolean ber_needed
= sdef
->isASN1
&& enable_ber();
5863 boolean raw_needed
= sdef
->hasRaw
&& enable_raw();
5864 boolean text_needed
= sdef
->hasText
&& enable_text();
5865 boolean xer_needed
= sdef
->hasXer
&& enable_xer();
5866 boolean json_needed
= sdef
->hasJson
&& enable_json();
5868 def
= mputprintf(def
,
5870 "// written by %s in " __FILE__
" at line %d\n"
5872 "class %s : public Base_Type {\n"
5873 "boolean bound_flag;\n"
5876 , __FUNCTION__
, __LINE__
5881 def
= mputprintf(def
, "%s();\n", name
);
5882 src
= mprintf("%s::%s()\n"
5884 "bound_flag = FALSE;\n"
5885 "}\n\n", name
, name
);
5887 /* ctor from NULL_VALUE (i.e. {}) */
5888 def
= mputprintf(def
, "%s(null_type other_value);\n", name
);
5889 src
= mputprintf(src
, "%s::%s(null_type)\n"
5891 "bound_flag = TRUE;\n"
5892 "}\n\n", name
, name
);
5895 def
= mputprintf(def
, "%s(const %s& other_value);\n", name
, name
);
5896 src
= mputprintf(src
, "%s::%s(const %s& other_value)\n"
5898 "other_value.must_bound(\"Copying an unbound value of "
5900 "bound_flag = TRUE;\n"
5901 "}\n\n", name
, name
, name
, dispname
);
5903 /* assignment op: from NULL_VALUE */
5904 def
= mputprintf(def
, "%s& operator=(null_type other_value);\n", name
);
5905 src
= mputprintf(src
, "%s& %s::operator=(null_type)\n"
5907 "bound_flag = TRUE;\n"
5909 "}\n\n", name
, name
);
5911 /* assignment op: from itself */
5912 def
= mputprintf(def
, "%s& operator=(const %s& other_value);\n", name
,
5914 src
= mputprintf(src
, "%s& %s::operator=(const %s& other_value)\n"
5916 "other_value.must_bound(\"Assignment of an unbound value of type "
5918 "bound_flag = TRUE;\n"
5920 "}\n\n", name
, name
, name
, dispname
);
5922 /* comparison op: with NULL_VALUE */
5923 def
= mputstr(def
, "boolean operator==(null_type other_value) const;\n");
5924 src
= mputprintf(src
,
5925 "boolean %s::operator==(null_type) const\n"
5927 "must_bound(\"Comparison of an unbound value of type %s.\");\n"
5929 "}\n\n", name
, dispname
);
5931 /* comparison op: with itself */
5932 def
= mputprintf(def
, "boolean operator==(const %s& other_value) const;\n",
5934 src
= mputprintf(src
,
5935 "boolean %s::operator==(const %s& other_value) const\n"
5937 "must_bound(\"Comparison of an unbound value of type %s.\");\n"
5938 "other_value.must_bound(\"Comparison of an unbound value of type "
5941 "}\n\n", name
, name
, dispname
, dispname
);
5943 /* non-equal operators */
5944 def
= mputprintf(def
,
5945 "inline boolean operator!=(null_type other_value) const "
5946 "{ return !(*this == other_value); }\n"
5947 "inline boolean operator!=(const %s& other_value) const "
5948 "{ return !(*this == other_value); }\n", name
);
5951 /* is_bound function */
5952 def
= mputstr(def
, "inline boolean is_bound() const "
5953 "{ return bound_flag; }\n");
5955 /* is_present function */
5957 "inline boolean is_present() const { return is_bound(); }\n");
5959 /* is_value function */
5960 def
= mputstr(def
, "inline boolean is_value() const "
5961 "{ return bound_flag; }\n");
5963 /* clean_up function */
5964 def
= mputstr(def
, "inline void clean_up() "
5965 "{ bound_flag = FALSE; }\n");
5967 /* must_bound function */
5968 def
= mputstr(def
, "inline void must_bound(const char *err_msg) const "
5969 "{ if (!bound_flag) TTCN_error(\"%s\", err_msg); }\n");
5972 def
= mputstr(def
, "void log() const;\n");
5973 src
= mputprintf(src
, "void %s::log() const\n"
5975 "if (bound_flag) TTCN_Logger::log_event_str(\"{ }\");\n"
5976 "else TTCN_Logger::log_event_unbound();\n"
5979 /* set_param function */
5980 def
= mputstr(def
, "void set_param(Module_Param& param);\n");
5981 src
= mputprintf(src
, "void %s::set_param(Module_Param& param)\n"
5983 " param.basic_check(Module_Param::BC_VALUE, \"empty record/set value (i.e. { })\");\n"
5984 " Module_Param_Ptr mp = ¶m;\n"
5985 " if (param.get_type() == Module_Param::MP_Reference) {\n"
5986 " mp = param.get_referenced_param();\n"
5988 " if (mp->get_type()!=Module_Param::MP_Value_List || mp->get_size()>0) {\n"
5989 " param.type_error(\"empty record/set value (i.e. { })\", \"%s\");\n"
5991 " bound_flag = TRUE;\n"
5992 "}\n\n", name
, dispname
);
5994 /* get param function */
5995 def
= mputstr(def
, "Module_Param* get_param(Module_Param_Name& param_name) const;\n");
5996 src
= mputprintf(src
,
5997 "Module_Param* %s::get_param(Module_Param_Name& /* param_name */) const\n"
5999 " if (!is_bound()) {\n"
6000 " return new Module_Param_Unbound();\n"
6002 " return new Module_Param_Value_List();\n"
6005 /* encode_text function */
6006 def
= mputstr(def
, "void encode_text(Text_Buf& text_buf) const;\n");
6007 src
= mputprintf(src
, "void %s::encode_text(Text_Buf& /*text_buf*/) const\n"
6009 "must_bound(\"Text encoder: Encoding an unbound value of type %s.\");\n"
6010 "}\n\n", name
, dispname
);
6012 /* decode_text function */
6013 def
= mputstr(def
, "void decode_text(Text_Buf& text_buf);\n");
6014 src
= mputprintf(src
, "void %s::decode_text(Text_Buf& /*text_buf*/)\n"
6016 "bound_flag = TRUE;\n"
6019 if(ber_needed
|| raw_needed
|| text_needed
|| xer_needed
|| json_needed
)
6020 def_encdec(name
, &def
, &src
, ber_needed
, raw_needed
,
6021 text_needed
, xer_needed
, json_needed
, FALSE
);
6025 /* BER_encode_TLV() */
6028 "ASN_BER_TLV_t* %s::BER_encode_TLV(const TTCN_Typedescriptor_t& p_td,"
6029 " unsigned p_coding) const\n"
6031 " BER_chk_descr(p_td);\n"
6032 " ASN_BER_TLV_t *new_tlv=ASN_BER_TLV_t::construct(NULL);\n"
6033 " new_tlv=ASN_BER_V2TLV(new_tlv, p_td, p_coding);\n"
6034 " return new_tlv;\n"
6040 /* BER_decode_TLV() */
6043 "boolean %s::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,"
6044 " const ASN_BER_TLV_t& p_tlv, unsigned L_form)\n"
6046 " BER_chk_descr(p_td);\n"
6047 " ASN_BER_TLV_t stripped_tlv;\n"
6048 " BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv);\n"
6049 " TTCN_EncDec_ErrorContext ec_0(\"While decoding '%s' type: \");\n"
6050 " stripped_tlv.chk_constructed_flag(TRUE);\n"
6051 " bound_flag=TRUE;\n"
6055 , name
, sdef
->dispname
6057 } /* if ber_needed */
6059 src
= mputprintf(src
,
6060 "int %s::TEXT_encode(const TTCN_Typedescriptor_t& p_td,"
6061 "TTCN_Buffer& p_buf) const{\n"
6062 " int encoded_length=0;\n"
6063 " if(p_td.text->begin_encode){\n"
6064 " p_buf.put_cs(*p_td.text->begin_encode);\n"
6065 " encoded_length+=p_td.text->begin_encode->lengthof();\n"
6067 " if(!bound_flag) {\n"
6068 " TTCN_EncDec_ErrorContext::error\n"
6069 " (TTCN_EncDec::ET_UNBOUND, \"Encoding an unbound value.\");\n"
6071 " if(p_td.text->end_encode){\n"
6072 " p_buf.put_cs(*p_td.text->end_encode);\n"
6073 " encoded_length+=p_td.text->end_encode->lengthof();\n"
6075 " return encoded_length;\n"
6079 src
= mputprintf(src
,
6080 "int %s::TEXT_decode(const TTCN_Typedescriptor_t& p_td,"
6081 " TTCN_Buffer& p_buf, Limit_Token_List& limit, boolean no_err, boolean){\n"
6082 " bound_flag = TRUE;\n"
6083 " int decoded_length=0;\n"
6084 " if(p_td.text->begin_decode){\n"
6086 " if((tl=p_td.text->begin_decode->match_begin(p_buf))<0){\n"
6087 " if(no_err)return -1;\n"
6088 " TTCN_EncDec_ErrorContext::error\n"
6089 " (TTCN_EncDec::ET_TOKEN_ERR, \"The specified token '%%s'"
6090 " not found for '%%s': \",(const char*)*(p_td.text->begin_decode)"
6094 " decoded_length+=tl;\n"
6095 " p_buf.increase_pos(tl);\n"
6097 " if(p_td.text->end_decode){\n"
6099 " if((tl=p_td.text->end_decode->match_begin(p_buf))<0){\n"
6100 " if(no_err)return -1;\n"
6101 " TTCN_EncDec_ErrorContext::error\n"
6102 " (TTCN_EncDec::ET_TOKEN_ERR, \"The specified token '%%s'"
6103 " not found for '%%s': \",(const char*)*(p_td.text->end_decode)"
6107 " decoded_length+=tl;\n"
6108 " p_buf.increase_pos(tl);\n"
6110 " return decoded_length;\n"
6118 src
= mputprintf(src
,
6119 "int %s::RAW_encode(const TTCN_Typedescriptor_t& p_td, "
6120 "RAW_enc_tree& /*myleaf*/) const\n"
6122 "if (!bound_flag) TTCN_EncDec_ErrorContext::error"
6123 "(TTCN_EncDec::ET_UNBOUND, \"Encoding an unbound value of "
6124 "type %%s.\", p_td.name);\n"
6128 src
= mputprintf(src
,
6129 "int %s::RAW_decode(const TTCN_Typedescriptor_t& p_td, "
6130 "TTCN_Buffer& p_buf, int, raw_order_t, boolean, int, boolean)\n"
6132 "bound_flag = TRUE;\n"
6133 "return p_buf.increase_pos_padd(p_td.raw->prepadding) + "
6134 "p_buf.increase_pos_padd(p_td.raw->padding);\n"
6138 if (xer_needed
) { /* XERSTUFF codegen for empty record/SEQUENCE */
6140 "boolean %s::can_start(const char *p_name, const char *p_uri, "
6141 "const XERdescriptor_t& p_td, unsigned int p_flavor) {\n"
6142 " boolean e_xer = is_exer(p_flavor);\n"
6143 " if (e_xer && (p_td.xer_bits & UNTAGGED)) return false;\n"
6144 " else return check_name(p_name, p_td, e_xer) && (!e_xer || check_namespace(p_uri, p_td));\n"
6149 src
= mputprintf(src
,
6150 "int %s::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, "
6151 "unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const{\n"
6152 " int encoded_length=(int)p_buf.get_len();\n"
6153 " int is_indented = !is_canonical(p_flavor);\n"
6154 " int e_xer = is_exer(p_flavor);\n"
6155 " if (is_indented) do_indent(p_buf, p_indent);\n"
6156 " p_buf.put_c('<');\n"
6157 " if (e_xer) write_ns_prefix(p_td, p_buf);\n"
6158 " p_buf.put_s((size_t)p_td.namelens[e_xer]-2, (cbyte*)p_td.names[e_xer]);\n"
6159 " p_buf.put_s(2 + is_indented, (cbyte*)\"/>\\n\");\n"
6160 " return (int)p_buf.get_len() - encoded_length;\n"
6163 src
= mputprintf(src
,
6165 "// written by %s in " __FILE__
" at %d\n"
6167 "int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader, "
6168 "unsigned int p_flavor, unsigned int /*p_flavor2*/, embed_values_dec_struct_t*)\n"
6170 " int e_xer = is_exer(p_flavor);\n"
6171 " bound_flag = true;\n"
6172 " int rd_ok, depth=-1;\n"
6173 " for (rd_ok=p_reader.Ok(); rd_ok==1; rd_ok=p_reader.Read()) {\n"
6174 " int type = p_reader.NodeType();\n"
6175 " if (type==XML_READER_TYPE_ELEMENT) {\n"
6176 " verify_name(p_reader, p_td, e_xer);\n"
6177 " depth=p_reader.Depth();\n"
6178 " if (p_reader.IsEmptyElement()) {\n"
6179 " rd_ok = p_reader.Read(); break;\n"
6181 " else if ((p_flavor & XER_MASK) == XER_CANONICAL) {\n"
6182 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, "
6183 "\"Expected an empty element tag\");\n"
6186 " else if (type == XML_READER_TYPE_END_ELEMENT && depth != -1) {\n"
6187 " verify_end(p_reader, p_td, depth, e_xer);\n"
6188 " rd_ok = p_reader.Read(); break;\n"
6194 , __FUNCTION__
, __LINE__
6200 src
= mputprintf(src
,
6201 "int %s::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const\n"
6203 " if (!is_bound()) {\n"
6204 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,\n"
6205 " \"Encoding an unbound value of type %s.\");\n"
6208 " return p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL) + \n"
6209 " p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);\n"
6214 src
= mputprintf(src
,
6215 "int %s::JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok, boolean p_silent)\n"
6217 " json_token_t token = JSON_TOKEN_NONE;\n"
6218 " int dec_len = p_tok.get_next_token(&token, NULL, NULL);\n"
6219 " if (JSON_TOKEN_ERROR == token) {\n"
6220 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, \"\");\n"
6221 " return JSON_ERROR_FATAL;\n"
6223 " else if (JSON_TOKEN_OBJECT_START != token) {\n"
6224 " return JSON_ERROR_INVALID_TOKEN;\n"
6226 " dec_len += p_tok.get_next_token(&token, NULL, NULL);\n"
6227 " if (JSON_TOKEN_OBJECT_END != token) {\n"
6228 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_STATIC_OBJECT_END_TOKEN_ERROR, \"\");\n"
6229 " return JSON_ERROR_FATAL;\n"
6231 " bound_flag = true;\n\n"
6232 " return dec_len;\n"
6237 /* closing class definition */
6238 def
= mputstr(def
, "};\n\n");
6240 output
->header
.class_defs
= mputstr(output
->header
.class_defs
, def
);
6243 output
->source
.methods
= mputstr(output
->source
.methods
, src
);
6246 output
->header
.function_prototypes
=
6247 mputprintf(output
->header
.function_prototypes
,
6248 "extern boolean operator==(null_type null_value, const %s& "
6249 "other_value);\n", name
);
6250 output
->source
.function_bodies
=
6251 mputprintf(output
->source
.function_bodies
,
6252 "boolean operator==(null_type, const %s& other_value)\n"
6254 "other_value.must_bound(\"Comparison of an unbound value of type "
6257 "}\n\n", name
, dispname
);
6259 output
->header
.function_prototypes
=
6260 mputprintf(output
->header
.function_prototypes
,
6261 "inline boolean operator!=(null_type null_value, const %s& "
6263 "{ return !(null_value == other_value); }\n", name
);
6266 static void defEmptyRecordTemplate(const char *name
, const char *dispname
,
6267 output_struct
*output
)
6269 char *def
= NULL
, *src
= NULL
;
6271 /* class definition */
6272 def
= mprintf("class %s_template : public Base_Template {\n"
6274 "unsigned int n_values;\n"
6275 "%s_template *list_value;\n"
6276 "} value_list;\n", name
, name
);
6278 /* copy_template function */
6279 def
= mputprintf(def
, "void copy_template(const %s_template& "
6280 "other_value);\n\n", name
);
6281 src
= mputprintf(src
,
6282 "void %s_template::copy_template(const %s_template& other_value)\n"
6284 "set_selection(other_value);\n"
6285 "switch (template_selection) {\n"
6286 "case OMIT_VALUE:\n"
6288 "case ANY_OR_OMIT:\n"
6289 "case SPECIFIC_VALUE:\n"
6291 "case VALUE_LIST:\n"
6292 "case COMPLEMENTED_LIST:\n"
6293 "value_list.n_values = other_value.value_list.n_values;\n"
6294 "value_list.list_value = new %s_template[value_list.n_values];\n"
6295 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
6297 "value_list.list_value[list_count].copy_template("
6298 "other_value.value_list.list_value[list_count]);\n"
6301 "TTCN_error(\"Copying an uninitialized/unsupported template of type "
6305 "}\n\n", name
, name
, name
, dispname
);
6308 def
= mputprintf(def
, "public:\n"
6309 "%s_template();\n", name
);
6310 src
= mputprintf(src
, "%s_template::%s_template()\n"
6312 "}\n\n", name
, name
);
6314 /* ctor for generic wildcards */
6315 def
= mputprintf(def
, "%s_template(template_sel other_value);\n", name
);
6316 src
= mputprintf(src
, "%s_template::%s_template(template_sel other_value)\n"
6317 " : Base_Template(other_value)\n"
6319 "check_single_selection(other_value);\n"
6320 "}\n\n", name
, name
);
6322 /* ctor for value {} */
6323 def
= mputprintf(def
, "%s_template(null_type other_value);\n", name
);
6324 src
= mputprintf(src
, "%s_template::%s_template(null_type)\n"
6325 " : Base_Template(SPECIFIC_VALUE)\n"
6327 "}\n\n", name
, name
);
6329 /* ctor for specific value */
6330 def
= mputprintf(def
, "%s_template(const %s& other_value);\n", name
, name
);
6331 src
= mputprintf(src
, "%s_template::%s_template(const %s& other_value)\n"
6332 " : Base_Template(SPECIFIC_VALUE)\n"
6334 "other_value.must_bound(\"Creating a template from an unbound value of "
6336 "}\n\n", name
, name
, name
, dispname
);
6338 /* ctor for optional value */
6339 def
= mputprintf(def
, "%s_template(const OPTIONAL<%s>& other_value);\n",
6341 src
= mputprintf(src
, "%s_template::%s_template(const OPTIONAL<%s>& "
6344 "switch (other_value.get_selection()) {\n"
6345 "case OPTIONAL_PRESENT:\n"
6346 "set_selection(SPECIFIC_VALUE);\n"
6348 "case OPTIONAL_OMIT:\n"
6349 "set_selection(OMIT_VALUE);\n"
6352 "TTCN_error(\"Creating a template of type %s from an unbound optional "
6355 "}\n\n", name
, name
, name
, dispname
);
6358 def
= mputprintf(def
, "%s_template(const %s_template& other_value);\n",
6360 src
= mputprintf(src
, "%s_template::%s_template(const %s_template& "
6362 ": Base_Template()" /* yes, the base class _default_ constructor */
6364 "copy_template(other_value);\n"
6365 "}\n\n", name
, name
, name
);
6368 def
= mputprintf(def
, "~%s_template();\n", name
);
6369 src
= mputprintf(src
, "%s_template::~%s_template()\n"
6372 "}\n\n", name
, name
);
6374 /* clean_up function */
6375 def
= mputstr(def
, "void clean_up();\n");
6376 src
= mputprintf(src
, "void %s_template::clean_up()\n"
6378 "if (template_selection == VALUE_LIST || "
6379 "template_selection == COMPLEMENTED_LIST)\n"
6380 "delete [] value_list.list_value;\n"
6381 "template_selection = UNINITIALIZED_TEMPLATE;\n"
6384 /* assignment op for generic wildcards */
6385 def
= mputprintf(def
, "%s_template& operator=(template_sel other_value);\n",
6387 src
= mputprintf(src
, "%s_template& %s_template::operator=(template_sel "
6390 "check_single_selection(other_value);\n"
6392 "set_selection(other_value);\n"
6394 "}\n\n", name
, name
);
6396 /* assignment op for value {} */
6397 def
= mputprintf(def
, "%s_template& operator=(null_type other_value);\n",
6399 src
= mputprintf(src
, "%s_template& %s_template::operator=(null_type)\n"
6402 "set_selection(SPECIFIC_VALUE);\n"
6404 "}\n\n", name
, name
);
6406 /* assignment op for specific value */
6407 def
= mputprintf(def
, "%s_template& operator=(const %s& other_value);\n",
6409 src
= mputprintf(src
, "%s_template& %s_template::operator=(const %s& "
6412 "other_value.must_bound(\"Assignment of an unbound value of type %s "
6413 "to a template.\");\n"
6415 "set_selection(SPECIFIC_VALUE);\n"
6417 "}\n\n", name
, name
, name
, dispname
);
6419 /* assignment op for optional value */
6420 def
= mputprintf(def
, "%s_template& operator=(const OPTIONAL<%s>& "
6421 "other_value);\n", name
, name
);
6422 src
= mputprintf(src
, "%s_template& %s_template::operator="
6423 "(const OPTIONAL<%s>& other_value)\n"
6426 "switch (other_value.get_selection()) {\n"
6427 "case OPTIONAL_PRESENT:\n"
6428 "set_selection(SPECIFIC_VALUE);\n"
6430 "case OPTIONAL_OMIT:\n"
6431 "set_selection(OMIT_VALUE);\n"
6434 "TTCN_error(\"Assignment of an unbound optional field to a template "
6438 "}\n\n", name
, name
, name
, dispname
);
6440 /* assignment op for itself */
6441 def
= mputprintf(def
, "%s_template& operator=(const %s_template& "
6442 "other_value);\n", name
, name
);
6443 src
= mputprintf(src
, "%s_template& %s_template::operator="
6444 "(const %s_template& other_value)\n"
6446 "if (&other_value != this) {\n"
6448 "set_selection(other_value);\n"
6451 "}\n\n", name
, name
, name
);
6453 /* match operation with {} */
6454 def
= mputstr(def
, "boolean match(null_type other_value, boolean legacy "
6455 "= FALSE) const;\n");
6456 src
= mputprintf(src
, "boolean %s_template::match(null_type other_value,"
6459 "switch (template_selection) {\n"
6461 "case ANY_OR_OMIT:\n"
6462 "case SPECIFIC_VALUE:\n"
6464 "case OMIT_VALUE:\n"
6466 "case VALUE_LIST:\n"
6467 "case COMPLEMENTED_LIST:\n"
6468 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
6470 "if (value_list.list_value[list_count].match(other_value)) "
6471 "return template_selection == VALUE_LIST;\n"
6472 "return template_selection == COMPLEMENTED_LIST;\n"
6474 "TTCN_error(\"Matching an uninitialized/unsupported template of "
6478 "}\n\n", name
, dispname
);
6480 /* match operation with specific value */
6481 def
= mputprintf(def
, "boolean match(const %s& other_value, boolean legacy "
6482 "= FALSE) const;\n", name
);
6483 src
= mputprintf(src
, "boolean %s_template::match(const %s& other_value, "
6486 "if (!other_value.is_bound()) return FALSE;"
6487 "return match(NULL_VALUE);\n"
6488 "}\n\n", name
, name
);
6490 /* valueof operation */
6491 def
= mputprintf(def
, "%s valueof() const;\n", name
);
6492 src
= mputprintf(src
, "%s %s_template::valueof() const\n"
6494 "if (template_selection != SPECIFIC_VALUE || is_ifpresent) "
6495 "TTCN_error(\"Performing a valueof or send operation on a "
6496 "non-specific template of type %s.\");\n"
6497 "return NULL_VALUE;\n"
6498 "}\n\n", name
, name
, dispname
);
6500 /* void set_type(template_sel, int) function */
6502 "void set_type(template_sel template_type, "
6503 "unsigned int list_length);\n");
6505 src
= mputprintf(src
,
6506 "void %s_template::set_type(template_sel template_type, "
6507 "unsigned int list_length)\n"
6509 "if (template_type != VALUE_LIST "
6510 "&& template_type != COMPLEMENTED_LIST)\n"
6511 "TTCN_error(\"Setting an invalid list for a template of type %s.\");\n"
6513 "set_selection(template_type);\n"
6514 "value_list.n_values = list_length;\n"
6515 "value_list.list_value = new %s_template[list_length];\n"
6516 "}\n\n", name
, dispname
, name
);
6518 /* list_item(int) function */
6520 def
= mputprintf(def
,
6521 "%s_template& list_item(unsigned int list_index) const;\n", name
);
6523 src
= mputprintf(src
,
6524 "%s_template& %s_template::list_item(unsigned int list_index) const\n"
6526 "if (template_selection != VALUE_LIST "
6527 "&& template_selection != COMPLEMENTED_LIST)\n"
6528 "TTCN_error(\"Accessing a list element of a non-list template of "
6530 "if (list_index >= value_list.n_values)\n"
6531 "TTCN_error(\"Index overflow in a value list template of type "
6533 "return value_list.list_value[list_index];\n"
6534 "}\n\n", name
, name
, dispname
, dispname
);
6537 def
= mputstr(def
, "void log() const;\n");
6538 src
= mputprintf(src
, "void %s_template::log() const\n"
6540 "switch (template_selection) {\n"
6541 "case SPECIFIC_VALUE:\n"
6542 "TTCN_Logger::log_event_str(\"{ }\");\n"
6544 "case COMPLEMENTED_LIST:\n"
6545 "TTCN_Logger::log_event_str(\"complement \");\n"
6546 "case VALUE_LIST:\n"
6547 "TTCN_Logger::log_char('(');\n"
6548 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
6550 "if (list_count > 0) TTCN_Logger::log_event_str(\", \");\n"
6551 "value_list.list_value[list_count].log();\n"
6553 "TTCN_Logger::log_char(')');\n"
6558 "log_ifpresent();\n"
6561 /* log_match function */
6562 def
= mputprintf(def
, "void log_match(const %s& match_value, "
6563 "boolean legacy = FALSE) const;\n", name
);
6564 src
= mputprintf(src
, "void %s_template::log_match(const %s& match_value, "
6567 "match_value.log();\n"
6568 "TTCN_Logger::log_event_str(\" with \");\n"
6570 "if (match(match_value)) TTCN_Logger::log_event_str(\" matched\");\n"
6571 "else TTCN_Logger::log_event_str(\" unmatched\");\n"
6572 "}\n\n", name
, name
);
6574 /* encode_text function */
6575 def
= mputstr(def
, "void encode_text(Text_Buf& text_buf) const;\n");
6576 src
= mputprintf(src
, "void %s_template::encode_text(Text_Buf& text_buf) "
6579 "encode_text_base(text_buf);\n"
6580 "switch (template_selection) {\n"
6581 "case OMIT_VALUE:\n"
6583 "case ANY_OR_OMIT:\n"
6584 "case SPECIFIC_VALUE:\n"
6586 "case VALUE_LIST:\n"
6587 "case COMPLEMENTED_LIST:\n"
6588 "text_buf.push_int(value_list.n_values);\n"
6589 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
6591 "value_list.list_value[list_count].encode_text(text_buf);\n"
6594 "TTCN_error(\"Text encoder: Encoding an uninitialized/unsupported "
6595 "template of type %s.\");\n"
6597 "}\n\n", name
, dispname
);
6599 /* decode_text function */
6600 def
= mputstr(def
, "void decode_text(Text_Buf& text_buf);\n");
6601 src
= mputprintf(src
, "void %s_template::decode_text(Text_Buf& text_buf)\n"
6604 "decode_text_base(text_buf);\n"
6605 "switch (template_selection) {\n"
6606 "case OMIT_VALUE:\n"
6608 "case ANY_OR_OMIT:\n"
6609 "case SPECIFIC_VALUE:\n"
6611 "case VALUE_LIST:\n"
6612 "case COMPLEMENTED_LIST:\n"
6613 "value_list.n_values = text_buf.pull_int().get_val();\n"
6614 "value_list.list_value = new %s_template[value_list.n_values];\n"
6615 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
6617 "value_list.list_value[list_count].decode_text(text_buf);\n"
6620 "TTCN_error(\"Text decoder: An unknown/unsupported selection was "
6621 "received in a template of type %s.\");\n"
6623 "}\n\n", name
, name
, dispname
);
6626 def
= mputstr(def
, "void set_param(Module_Param& param);\n");
6627 src
= mputprintf(src
,
6628 "void %s_template::set_param(Module_Param& param)\n"
6630 " param.basic_check(Module_Param::BC_TEMPLATE, \"empty record/set template\");\n"
6631 " Module_Param_Ptr mp = ¶m;\n"
6632 " if (param.get_type() == Module_Param::MP_Reference) {\n"
6633 " mp = param.get_referenced_param();\n"
6635 " switch (mp->get_type()) {\n"
6636 " case Module_Param::MP_Omit:\n"
6637 " *this = OMIT_VALUE;\n"
6639 " case Module_Param::MP_Any:\n"
6640 " *this = ANY_VALUE;\n"
6642 " case Module_Param::MP_AnyOrNone:\n"
6643 " *this = ANY_OR_OMIT;\n"
6645 " case Module_Param::MP_List_Template:\n"
6646 " case Module_Param::MP_ComplementList_Template: {\n"
6647 " %s_template temp;\n"
6648 " temp.set_type(mp->get_type()==Module_Param::MP_List_Template ? "
6649 "VALUE_LIST : COMPLEMENTED_LIST, mp->get_size());\n"
6650 " for (size_t p_i=0; p_i<mp->get_size(); p_i++) {\n"
6651 " temp.list_item(p_i).set_param(*mp->get_elem(p_i));\n"
6655 " case Module_Param::MP_Value_List:\n"
6656 " if (mp->get_size()>0) param.type_error(\"empty record/set template\", \"%s\");\n"
6657 " *this = NULL_VALUE;\n"
6660 " param.type_error(\"empty record/set template\", \"%s\");\n"
6662 " is_ifpresent = param.get_ifpresent() || mp->get_ifpresent();\n"
6663 "}\n\n", name
, name
, dispname
, dispname
);
6666 def
= mputstr(def
, "Module_Param* get_param(Module_Param_Name& param_name) const;\n");
6667 src
= mputprintf(src
,
6668 "Module_Param* %s_template::get_param(Module_Param_Name& param_name) const\n"
6670 " Module_Param* mp = NULL;\n"
6671 " switch (template_selection) {\n"
6672 " case UNINITIALIZED_TEMPLATE:\n"
6673 " mp = new Module_Param_Unbound();\n"
6675 " case OMIT_VALUE:\n"
6676 " mp = new Module_Param_Omit();\n"
6678 " case ANY_VALUE:\n"
6679 " mp = new Module_Param_Any();\n"
6681 " case ANY_OR_OMIT:\n"
6682 " mp = new Module_Param_AnyOrNone();\n"
6684 " case SPECIFIC_VALUE:\n"
6685 " mp = new Module_Param_Value_List();\n"
6687 " case VALUE_LIST:\n"
6688 " case COMPLEMENTED_LIST: {\n"
6689 " if (template_selection == VALUE_LIST) {\n"
6690 " mp = new Module_Param_List_Template();\n"
6693 " mp = new Module_Param_ComplementList_Template();\n"
6695 " for (size_t i = 0; i < value_list.n_values; ++i) {\n"
6696 " mp->add_elem(value_list.list_value[i].get_param(param_name));\n"
6702 " if (is_ifpresent) {\n"
6703 " mp->set_ifpresent();\n"
6708 /* check template restriction */
6709 def
= mputstr(def
, "void check_restriction(template_res t_res, "
6710 "const char* t_name=NULL, boolean legacy = FALSE) const;\n");
6711 src
= mputprintf(src
,
6712 "void %s_template::check_restriction("
6713 "template_res t_res, const char* t_name, boolean legacy) const\n"
6715 "if (template_selection==UNINITIALIZED_TEMPLATE) return;\n"
6716 "switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {\n"
6718 "if (template_selection==OMIT_VALUE) return;\n"
6720 "if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;\n"
6722 "case TR_PRESENT:\n"
6723 "if (!match_omit(legacy)) return;\n"
6728 "TTCN_error(\"Restriction `%%s' on template of type %%s "
6729 "violated.\", get_res_name(t_res), t_name ? t_name : \"%s\");\n"
6730 "}\n\n", name
, dispname
);
6732 defCommonRecordTemplate(name
, &def
, &src
);
6734 def
= mputstr(def
, "};\n\n");
6736 output
->header
.class_defs
= mputstr(output
->header
.class_defs
, def
);
6739 output
->source
.methods
= mputstr(output
->source
.methods
, src
);
6743 static void defCommonRecordTemplate(const char *name
,
6744 char **def
, char **src
)
6746 /* TTCN-3 ispresent() function */
6747 *def
= mputstr(*def
, "boolean is_present(boolean legacy = FALSE) const;\n");
6748 *src
= mputprintf(*src
,
6749 "boolean %s_template::is_present(boolean legacy) const\n"
6751 "if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;\n"
6752 "return !match_omit(legacy);\n"
6756 *def
= mputstr(*def
, "boolean match_omit(boolean legacy = FALSE) const;\n");
6757 *src
= mputprintf(*src
,
6758 "boolean %s_template::match_omit(boolean legacy) const\n"
6760 "if (is_ifpresent) return TRUE;\n"
6761 "switch (template_selection) {\n"
6762 "case OMIT_VALUE:\n"
6763 "case ANY_OR_OMIT:\n"
6765 "case VALUE_LIST:\n"
6766 "case COMPLEMENTED_LIST:\n"
6768 "for (unsigned int l_idx=0; l_idx<value_list.n_values; l_idx++)\n"
6769 "if (value_list.list_value[l_idx].match_omit())\n"
6770 "return template_selection==VALUE_LIST;\n"
6771 "return template_selection==COMPLEMENTED_LIST;\n"
6772 "} // else fall through\n"
6780 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
6782 void defRecordClass2(const struct_def
*sdef
, output_struct
*output
)
6785 size_t optional_num
= 0;
6786 const char *name
= sdef
->name
;
6787 char *def
= NULL
, *src
= NULL
;
6789 boolean xer_needed
= sdef
->hasXer
&& enable_xer();
6790 boolean raw_needed
= sdef
->hasRaw
&& enable_raw();
6791 boolean has_optional
= FALSE
;
6792 boolean has_default
= FALSE
;
6794 const char* base_class
= (sdef
->nElements
==0) ? "Empty_Record_Type" : "Record_Type";
6796 /* class declaration code */
6797 output
->header
.class_decls
= mputprintf(output
->header
.class_decls
,
6798 "class %s;\n", name
);
6800 /* class definition and source code */
6801 def
=mputprintf(def
, "class %s : public %s {\n", name
, base_class
);
6804 for (i
= 0; i
< sdef
->nElements
; i
++) {
6805 if(sdef
->elements
[i
].isOptional
) {
6807 def
= mputprintf(def
, " OPTIONAL<%s> field_%s;\n",
6808 sdef
->elements
[i
].type
,
6809 sdef
->elements
[i
].name
);
6811 def
= mputprintf(def
, " %s field_%s;\n",
6812 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
6815 if (sdef
->nElements
) {
6816 def
= mputprintf(def
, " Base_Type* fld_vec[%lu];\n", (unsigned long)sdef
->nElements
);
6819 /* default constructor */
6820 if (sdef
->nElements
==0) {
6821 def
= mputprintf(def
, "public:\n"
6823 src
= mputprintf(src
,
6824 "%s::%s() : Empty_Record_Type() {}\n\n",
6827 def
= mputstr(def
, " void init_vec();\n");
6828 src
= mputprintf(src
, "void %s::init_vec() { ", name
);
6829 for (i
= 0; i
< sdef
->nElements
; i
++) {
6830 src
= mputprintf(src
, "fld_vec[%lu]=&field_%s; ",
6831 (unsigned long)i
, sdef
->elements
[i
].name
);
6833 src
= mputstr(src
, " }\n\n");
6835 def
= mputprintf(def
, "public:\n"
6837 src
= mputprintf(src
,
6838 "%s::%s() : Record_Type() { init_vec(); }\n\n", name
, name
);
6841 /* copy constructor */
6842 if (sdef
->nElements
) {
6843 def
= mputprintf(def
, " %s(const %s& other_value);\n", name
, name
);
6844 src
= mputprintf(src
, "%s::%s(const %s& other_value) : Record_Type(other_value)\n", name
, name
, name
);
6845 src
= mputstr(src
, "{\n"
6846 " if(!other_value.is_bound()) "
6847 "TTCN_error(\"Copying an unbound record/set value.\");\n");
6848 for (i
= 0; i
< sdef
->nElements
; i
++) {
6849 src
= mputprintf(src
,
6850 "if (other_value.field_%s.is_bound() )\n"
6851 " field_%s = other_value.field_%s;\n",
6852 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
6853 sdef
->elements
[i
].name
);
6856 src
= mputstr(src
, "init_vec();\n"
6859 def
= mputprintf(def
, " %s(const %s& other_value): %s(other_value) {}\n", name
, name
, base_class
);
6862 if (sdef
->nElements
>0) { /* constructor by fields */
6863 def
= mputprintf(def
, " %s(", name
);
6864 src
= mputprintf(src
, "%s::%s(", name
, name
);
6865 for (i
= 0; i
< sdef
->nElements
; i
++) {
6867 if (i
> 0) tmp
= mputstr(tmp
, ",\n ");
6868 if (sdef
->elements
[i
].isOptional
)
6871 "const OPTIONAL<%s>& par_%s",
6872 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
6877 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
6878 def
= mputstr(def
, tmp
);
6879 src
= mputstr(src
, tmp
);
6882 def
= mputstr(def
, ");\n");
6883 src
= mputprintf(src
, ") : ");
6884 for (i
= 0; i
< sdef
->nElements
; i
++) {
6885 if (i
> 0) src
= mputstr(src
, ",\n ");
6886 src
= mputprintf(src
, "field_%s(par_%s)", sdef
->elements
[i
].name
,
6887 sdef
->elements
[i
].name
);
6889 src
= mputstr(src
, "\n"
6893 } else { /* constructor from null */
6894 def
= mputprintf(def
, " %s(null_type) {bound_flag = TRUE;}\n", name
);
6897 /* assignment operators */
6898 def
= mputprintf(def
, "inline %s& operator=(const %s& other_value) "
6899 "{ set_value(&other_value); return *this; }\n\n", name
, name
);
6900 if (sdef
->nElements
== 0) {
6901 def
= mputprintf(def
, "inline %s& operator=(null_type) "
6902 "{ bound_flag = TRUE; return *this; }\n", name
);
6906 def
= mputprintf(def
, "inline boolean operator==(const %s& other_value) "
6907 "const { return is_equal(&other_value); }\n", name
);
6909 def
= mputprintf(def
,
6910 " inline boolean operator!=(const %s& other_value) const\n"
6911 " { return !is_equal(&other_value); }\n\n", name
);
6913 for (i
= 0; i
< sdef
->nElements
; i
++) {
6914 if(sdef
->elements
[i
].isOptional
)
6917 " inline OPTIONAL<%s>& %s()\n"
6918 " {return field_%s;}\n"
6919 " inline const OPTIONAL<%s>& %s() const\n"
6920 " {return field_%s;}\n",
6921 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
,
6922 sdef
->elements
[i
].name
,
6923 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
,
6924 sdef
->elements
[i
].name
);
6925 else def
= mputprintf
6927 " inline %s& %s()\n"
6928 " {return field_%s;}\n"
6929 " inline const %s& %s() const\n"
6930 " {return field_%s;}\n",
6931 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
,
6932 sdef
->elements
[i
].name
, sdef
->elements
[i
].type
,
6933 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
6937 /* override virtual functions where needed */
6938 def
= mputprintf(def
,
6939 "Base_Type* clone() const { return new %s(*this); }\n"
6940 "const TTCN_Typedescriptor_t* get_descriptor() const;\n"
6941 "boolean is_set() const { return %s; }\n",
6943 (sdef
->kind
==SET
) ? "TRUE" : "FALSE");
6944 src
= mputprintf(src
,
6945 "const TTCN_Typedescriptor_t* %s::get_descriptor() const { return &%s_descr_; }\n",
6948 if (sdef
->nElements
> 0) {
6950 /* field access functions */
6951 def
= mputprintf(def
,
6952 "Base_Type* get_at(int index_value) { return fld_vec[index_value]; }\n"
6953 "const Base_Type* get_at(int index_value) const { return fld_vec[index_value]; }\n\n"
6954 "int get_count() const { return %lu; }\n", (unsigned long)sdef
->nElements
);
6956 /* override if there are optional fields */
6958 def
= mputprintf(def
,
6959 "int optional_count() const { return %lu; }\n", (unsigned long)optional_num
);
6962 if (sdef
->opentype_outermost
)
6963 def
= mputstr(def
, "boolean is_opentype_outermost() const { return TRUE; }\n");
6965 /* FIXME: use static member in Record_Type and initialize somewhere */
6966 if (default_as_optional
)
6967 def
= mputstr(def
, "boolean default_as_optional() const { return TRUE; }\n");
6969 for (i
= 0; i
< sdef
->nElements
; i
++) {
6970 if (sdef
->elements
[i
].isOptional
) {
6971 has_optional
= TRUE
;
6976 for (i
= 0; i
< sdef
->nElements
; i
++) {
6977 if (sdef
->elements
[i
].isDefault
) {
6983 "static const TTCN_Typedescriptor_t* fld_descriptors[];\n"
6984 "const TTCN_Typedescriptor_t* fld_descr(int p_index) const;\n\n"
6985 "static const char* fld_names[];\n"
6986 "const char* fld_name(int p_index) const;\n\n");
6988 src
= mputprintf(src
, "const TTCN_Typedescriptor_t* %s::fld_descriptors[] = ", name
);
6989 for (i
= 0; i
< sdef
->nElements
; i
++) {
6990 src
= mputprintf(src
, "%c &%s_descr_",
6991 (i
? ',' : '{'), sdef
->elements
[i
].typedescrname
);
6993 src
= mputstr(src
, " };\n");
6994 src
= mputprintf(src
,
6995 "const TTCN_Typedescriptor_t* %s::fld_descr(int p_index) const "
6996 "{ return fld_descriptors[p_index]; }\n\n", name
);
6998 src
= mputprintf(src
, "const char* %s::fld_names[] = ", name
);
6999 for (i
= 0; i
< sdef
->nElements
; i
++) {
7000 src
= mputprintf(src
, "%c \"%s\"",
7001 (i
? ',' : '{'), sdef
->elements
[i
].dispname
);
7003 src
= mputstr(src
, " };\n");
7005 src
= mputprintf(src
,
7006 "const char* %s::fld_name(int p_index) const "
7007 "{ return fld_names[p_index]; }\n\n", name
);
7011 "static const int optional_indexes[];\n"
7012 "const int* get_optional_indexes() const;\n\n");
7013 src
= mputprintf(src
, "const int %s::optional_indexes[] = { ", name
);
7014 for (i
= 0; i
< sdef
->nElements
; i
++) {
7015 if (sdef
->elements
[i
].isOptional
) {
7016 src
= mputprintf(src
, "%lu, ", (unsigned long)i
);
7019 src
= mputstr(src
, "-1 };\n");
7020 src
= mputprintf(src
,
7021 "const int* %s::get_optional_indexes() const "
7022 "{ return optional_indexes; }\n\n", name
);
7027 "static const default_struct default_indexes[];\n"
7028 "const default_struct* get_default_indexes() const;\n");
7029 src
= mputprintf(src
, "const Record_Type::default_struct %s::default_indexes[] = { ", name
);
7030 for (i
= 0; i
< sdef
->nElements
; i
++) {
7031 if (sdef
->elements
[i
].isDefault
) {
7032 src
= mputprintf(src
, "{%lu,&%s}, ",
7033 (unsigned long)i
, sdef
->elements
[i
].defvalname
);
7036 src
= mputstr(src
, "{-1,NULL} };\n");
7037 src
= mputprintf(src
,
7038 "const Record_Type::default_struct* %s::get_default_indexes() const "
7039 "{ return default_indexes; }\n", name
);
7043 struct raw_option_struct
*raw_options
;
7044 boolean haslengthto
, haspointer
, hascrosstag
, has_ext_bit
;
7045 boolean generate_raw_function
= FALSE
;
7047 raw_options
= (struct raw_option_struct
*)
7048 Malloc(sdef
->nElements
* sizeof(*raw_options
));
7050 set_raw_options(sdef
, raw_options
, &haslengthto
,
7051 &haspointer
, &hascrosstag
, &has_ext_bit
);
7053 /* set the value of generate_raw_function: if the coding/decoding is too
7054 complex for this type then generate the functions, otherwise generate
7055 helper functions only which are called by the default RAW enc/dec
7057 if (haslengthto
|| haspointer
|| hascrosstag
) {
7058 generate_raw_function
= TRUE
;
7059 goto check_generate_end
;
7061 for (i
= 0; i
< sdef
->nElements
; i
++) {
7062 if (raw_options
[i
].lengthto
|| raw_options
[i
].lengthof
||
7063 raw_options
[i
].lengthoffield
|| raw_options
[i
].pointerto
||
7064 raw_options
[i
].pointerof
|| raw_options
[i
].ptrbase
||
7065 raw_options
[i
].extbitgroup
|| raw_options
[i
].tag_type
||
7066 raw_options
[i
].delayed_decode
|| raw_options
[i
].nof_dependent_fields
7067 || raw_options
[i
].dependent_fields
) {
7068 generate_raw_function
= TRUE
;
7069 goto check_generate_end
;
7072 for (i
= 0; i
< sdef
->nElements
; i
++) {
7073 if (raw_options
[i
].lengthof
|| raw_options
[i
].lengthoffield
||
7074 raw_options
[i
].nof_dependent_fields
||
7075 raw_options
[i
].dependent_fields
) {
7076 generate_raw_function
= TRUE
;
7077 goto check_generate_end
;
7080 if (sdef
->raw
.ext_bit_goup_num
|| sdef
->raw
.ext_bit_groups
||
7081 sdef
->raw
.lengthto
|| sdef
->raw
.lengthindex
||
7082 sdef
->raw
.taglist
.nElements
|| sdef
->raw
.crosstaglist
.nElements
||
7083 sdef
->raw
.presence
.fieldnum
|| sdef
->raw
.presence
.fields
||
7084 sdef
->raw
.member_name
) {
7085 generate_raw_function
= TRUE
;
7086 goto check_generate_end
;
7088 for (i
= 0; i
< sdef
->nElements
; i
++) {
7089 if (sdef
->elements
[i
].hasRaw
) {
7090 generate_raw_function
= TRUE
;
7091 goto check_generate_end
;
7096 if (generate_raw_function
) {
7097 def
= mputprintf(def
,
7098 "int RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree&) const;\n"
7099 "virtual int RAW_encode_negtest(const Erroneous_descriptor_t *, const TTCN_Typedescriptor_t&, RAW_enc_tree&) const;\n"
7100 "int RAW_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, "
7101 "int, raw_order_t, boolean no_err = FALSE, "
7102 "int sel_field = -1, boolean first_call = TRUE);\n");
7103 src
= generate_raw_coding(src
, sdef
, raw_options
, haspointer
,
7104 hascrosstag
, has_ext_bit
);
7105 } else { /* generate helper functions for the default RAW enc/dec */
7107 def
= mputstr(def
,"boolean raw_has_ext_bit() const { return TRUE; }\n");
7109 for (i
= 0; i
< sdef
->nElements
; i
++) {
7110 Free(raw_options
[i
].lengthoffield
);
7111 Free(raw_options
[i
].dependent_fields
);
7114 } /* if (raw_needed) */
7116 if (xer_needed
) { /* XERSTUFF codegen for record/SEQUENCE in RT2 */
7117 size_t num_attributes
= 0;
7119 /* XER descriptors needed because of the xer antipattern */
7121 "static const XERdescriptor_t* xer_descriptors[];\n"
7122 "const XERdescriptor_t* xer_descr(int p_index) const;\n"
7123 "virtual boolean can_start_v(const char *name, const char *prefix, "
7124 "XERdescriptor_t const& xd, unsigned int flavor);\n"
7125 "static boolean can_start (const char *name, const char *prefix, "
7126 "XERdescriptor_t const& xd, unsigned int flavor);\n");
7127 src
= mputprintf(src
, "const XERdescriptor_t* %s::xer_descriptors[] = ", name
);
7128 for (i
= 0; i
< sdef
->nElements
; i
++) {
7129 src
= mputprintf(src
, "%c &%s_xer_",
7130 (i
? ',' : '{'), sdef
->elements
[i
].typegen
);
7132 src
= mputstr(src
, " };\n");
7133 src
= mputprintf(src
,
7134 "const XERdescriptor_t* %s::xer_descr(int p_index) const "
7135 "{ return xer_descriptors[p_index]; }\n"
7136 /* The virtual can_start_v hands off to the static can_start.
7137 * We must make a virtual call in Record_Type::XER_decode because
7138 * we don't know the actual type (derived from Record_Type) */
7139 "boolean %s::can_start_v(const char *p_name, const char *p_uri, "
7140 "XERdescriptor_t const& p_td, unsigned int p_flavor)\n"
7141 "{ return can_start(p_name, p_uri, p_td, p_flavor); }\n"
7142 "boolean %s::can_start(const char *p_name, const char *p_uri, "
7143 "XERdescriptor_t const& p_td, unsigned int p_flavor) {\n"
7144 " boolean e_xer = is_exer(p_flavor);\n"
7145 " if (!e_xer || (!(p_td.xer_bits & UNTAGGED) && !(p_flavor & USE_NIL))) return check_name(p_name, p_td, e_xer) && (!e_xer || check_namespace(p_uri, p_td));\n"
7146 , name
, name
, name
);
7147 for (i
= 0; i
< sdef
->nElements
; i
++) {
7148 src
= mputprintf(src
,
7149 " else if (%s::can_start(p_name, p_uri, %s_xer_, p_flavor)) return true;\n"
7150 , sdef
->elements
[i
].type
, sdef
->elements
[i
].typegen
);
7155 /* end of antipattern */
7157 /* calculate num_attributes in compile time */
7158 for ( i
=0; i
< sdef
->nElements
; ++i
) {
7159 if (sdef
->elements
[i
].xerAttribute
7160 ||(sdef
->elements
[i
].xerAnyKind
& ANY_ATTRIB_BIT
)) ++num_attributes
;
7161 else if (num_attributes
) break;
7164 /* generate helper virtual functions for XER encdec */
7165 if (num_attributes
) {
7166 def
= mputprintf(def
,
7167 "int get_xer_num_attr() const { return %lu; }\n",
7168 (unsigned long)num_attributes
);
7171 else { /* XER not needed */
7173 "boolean can_start_v(const char *, const char *, XERdescriptor_t const&, unsigned int)\n"
7174 "{ return FALSE; }\n"
7176 } /* if (xer_needed) */
7177 } /* if (sdef->nElements > 0) */
7179 /* end of class definition */
7180 def
= mputstr(def
, "};\n\n");
7182 output
->header
.class_defs
= mputstr(output
->header
.class_defs
, def
);
7185 output
->source
.methods
= mputstr(output
->source
.methods
, src
);
7189 void defRecordTemplate2(const struct_def
*sdef
, output_struct
*output
)
7192 const char *name
= sdef
->name
;
7193 char *def
= NULL
, *src
= NULL
;
7195 const char* base_class
= (sdef
->nElements
==0) ? "Empty_Record_Template" : "Record_Template";
7197 /* class declaration */
7198 output
->header
.class_decls
= mputprintf(output
->header
.class_decls
,
7199 "class %s_template;\n", name
);
7201 /* template class definition */
7202 def
= mputprintf(def
, "class %s_template : public %s {\n", name
, base_class
);
7204 if (sdef
->nElements
>0) {
7205 /* set_specific function (used in field access members) */
7206 def
= mputstr(def
, "void set_specific();\n");
7207 src
= mputprintf(src
, "void %s_template::set_specific()\n"
7209 "if (template_selection != SPECIFIC_VALUE) {\n"
7212 "single_value.n_elements = %lu;\n"
7213 "single_value.value_elements = (Base_Template**)allocate_pointers(single_value.n_elements);\n"
7214 "set_selection(SPECIFIC_VALUE);\n",
7215 name
, sdef
->nElements
? "boolean was_any = (template_selection == ANY_VALUE || template_selection == ANY_OR_OMIT);\n" : "",
7216 (unsigned long)sdef
->nElements
);
7217 for (i
= 0; i
< sdef
->nElements
; i
++) {
7218 src
= mputprintf(src
,
7219 "single_value.value_elements[%d] = was_any ? new %s_template(%s) : new %s_template;\n",
7220 i
, sdef
->elements
[i
].type
,
7221 sdef
->elements
[i
].isOptional
? "ANY_OR_OMIT" : "ANY_VALUE",
7222 sdef
->elements
[i
].type
);
7229 /* default constructor */
7230 def
= mputprintf(def
, "public:\n"
7231 "%s_template(): %s() {}\n", name
, base_class
);
7233 if (sdef
->nElements
==0) {
7234 /* ctor for value {} */
7235 def
= mputprintf(def
, "%s_template(null_type) : "
7236 "Empty_Record_Template() { set_selection(SPECIFIC_VALUE); }\n",
7240 /* constructor t1_template(template_sel other_value) */
7241 def
= mputprintf(def
, "%s_template(template_sel other_value): "
7242 "%s(other_value) {}\n", name
, base_class
);
7244 /* constructor t1_template(const t1& other_value) */
7245 def
= mputprintf(def
, "%s_template(const %s& other_value): "
7246 "%s() { copy_value(&other_value); }\n",
7247 name
, name
, base_class
);
7249 /* constructor t1_template(const OPTIONAL<t1>& other_value) */
7250 def
= mputprintf(def
, "%s_template(const OPTIONAL<%s>& other_value): "
7251 "%s() { copy_optional(&other_value); }\n",
7252 name
, name
, base_class
);
7254 /* copy constructor */
7255 def
= mputprintf(def
, "%s_template(const %s_template& other_value): %s() "
7256 "{ copy_template(other_value); }\n", name
, name
, base_class
);
7258 /* assignment operator <- template_sel */
7259 def
= mputprintf(def
, "%s_template& operator=(template_sel other_value);\n",
7261 src
= mputprintf(src
,
7262 "%s_template& %s_template::operator=(template_sel other_value)\n"
7264 "check_single_selection(other_value);\n"
7266 "set_selection(other_value);\n"
7268 "}\n\n", name
, name
);
7270 /* assignment operator <- value */
7271 def
= mputprintf(def
, "%s_template& operator=(const %s& other_value);\n",
7273 src
= mputprintf(src
,
7274 "%s_template& %s_template::operator=(const %s& other_value)\n"
7277 "copy_value(&other_value);\n"
7279 "}\n\n", name
, name
, name
);
7281 /* assignment operator <- optional value */
7282 def
= mputprintf(def
, "%s_template& operator=(const OPTIONAL<%s>& "
7283 "other_value);\n", name
, name
);
7284 src
= mputprintf(src
,
7285 "%s_template& %s_template::operator=(const OPTIONAL<%s>& other_value)\n"
7288 "copy_optional(&other_value);\n"
7290 "}\n\n", name
, name
, name
);
7292 /* assignment operator <- template*/
7293 def
= mputprintf(def
,
7294 "%s_template& operator=(const %s_template& other_value);\n",
7296 src
= mputprintf(src
,
7297 "%s_template& %s_template::operator=(const %s_template& other_value)\n"
7299 "if (&other_value != this) {\n"
7301 "copy_template(other_value);\n"
7304 "}\n\n", name
, name
, name
);
7306 if (sdef
->nElements
==0) {
7307 /* assignment op for value {} */
7308 def
= mputprintf(def
, "%s_template& operator=(null_type other_value);\n",
7310 src
= mputprintf(src
, "%s_template& %s_template::operator=(null_type)\n"
7313 "set_selection(SPECIFIC_VALUE);\n"
7315 "}\n\n", name
, name
);
7318 /* match operation (template matching) */
7319 def
= mputprintf(def
, "inline boolean match(const %s& other_value, "
7320 "boolean legacy = FALSE) const "
7321 "{ return matchv(&other_value, legacy); }\n", name
);
7324 def
= mputprintf(def
, "inline void log_match(const %s& match_value, "
7325 "boolean legacy = FALSE) const "
7326 "{ log_matchv(&match_value, legacy); }\n", name
);
7328 /* valueof operation */
7329 def
= mputprintf(def
, "%s valueof() const;\n", name
);
7331 src
= mputprintf(src
, "%s %s_template::valueof() const\n"
7334 "valueofv(&ret_val);\n"
7336 "}\n\n", name
, name
, name
);
7338 /* list_item(int) function */
7340 def
= mputprintf(def
,
7341 "inline %s_template& list_item(unsigned int list_index) const "
7342 "{ return *(static_cast<%s_template*>(get_list_item(list_index))); }\n", name
, name
);
7344 if (sdef
->nElements
>0) {
7345 /* template field access functions (non-const & const) */
7346 for (i
= 0; i
< sdef
->nElements
; i
++) {
7347 def
= mputprintf(def
,
7348 "%s_template& %s();\n"
7349 "const %s_template& %s() const;\n",
7350 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
,
7351 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
7352 src
= mputprintf(src
,
7353 "%s_template& %s_template::%s() { return *(static_cast<%s_template*>(get_at(%d))); }\n"
7354 "const %s_template& %s_template::%s() const { return *(static_cast<const %s_template*>(get_at(%d))); }\n",
7355 sdef
->elements
[i
].type
, name
, sdef
->elements
[i
].name
, sdef
->elements
[i
].type
, i
,
7356 sdef
->elements
[i
].type
, name
, sdef
->elements
[i
].name
, sdef
->elements
[i
].type
, i
);
7360 /* virtual functions */
7361 def
= mputprintf(def
,
7362 "%s* create() const { return new %s_template; }\n"
7363 "const TTCN_Typedescriptor_t* get_descriptor() const;\n",
7365 src
= mputprintf(src
,
7366 "const TTCN_Typedescriptor_t* %s_template::get_descriptor() const { return &%s_descr_; }\n",
7369 if (sdef
->nElements
>0) {
7370 def
= mputprintf(def
, "const char* fld_name(int p_index) const;\n");
7371 src
= mputprintf(src
,
7372 "const char* %s_template::fld_name(int p_index) const { return %s::fld_names[p_index]; }\n",
7376 def
= mputstr(def
, "};\n\n");
7378 output
->header
.class_defs
= mputstr(output
->header
.class_defs
, def
);
7381 output
->source
.methods
= mputstr(output
->source
.methods
, src
);