1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 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
7 ///////////////////////////////////////////////////////////////////////////////
10 #include "../common/memory.h"
16 #include "ttcn3/compiler.h"
18 static void defEmptyRecordClass(const struct_def
*sdef
,
19 output_struct
*output
);
21 static void defEmptyRecordTemplate(const char *name
, const char *dispname
,
22 output_struct
*output
);
24 /** this is common code for both empty and non-empty cases, called from
25 * both functions for template generation */
26 static void defCommonRecordTemplate(const char *name
,
27 char **def
, char **src
);
29 /** code generation for original runtime */
30 static void defRecordClass1(const struct_def
*sdef
, output_struct
*output
);
31 static void defRecordTemplate1(const struct_def
*sdef
, output_struct
*output
);
32 /** code generation for alternative runtime (TITAN_RUNTIME_2) */
33 static void defRecordClass2(const struct_def
*sdef
, output_struct
*output
);
34 static void defRecordTemplate2(const struct_def
*sdef
, output_struct
*output
);
36 void defRecordClass(const struct_def
*sdef
, output_struct
*output
)
38 if (use_runtime_2
) defRecordClass2(sdef
, output
);
39 else defRecordClass1(sdef
, output
);
42 void defRecordTemplate(const struct_def
*sdef
, output_struct
*output
)
44 if (use_runtime_2
) defRecordTemplate2(sdef
, output
);
45 else defRecordTemplate1(sdef
, output
);
48 struct raw_option_struct
{
49 boolean lengthto
; /* indicates whether this field contains a length */
50 int lengthof
; /* how many length indicators this field counted in */
51 int *lengthoffield
; /* the list of length indicator field indices */
57 boolean delayed_decode
; /* indicates whether the field has to be decoded
58 out of order (later) */
59 int nof_dependent_fields
; /* list of fields that are to be decoded */
60 int *dependent_fields
; /* after this field */
63 static char *genRawFieldDecodeLimit(char *src
, const struct_def
*sdef
,
64 int i
, const struct raw_option_struct
*raw_options
);
66 static char *genRawDecodeRecordField(char *src
, const struct_def
*sdef
,
67 int i
, const struct raw_option_struct
*raw_options
, boolean delayed_decode
,
70 static void set_raw_options(const struct_def
*sdef
,
71 struct raw_option_struct
*raw_options
, boolean
* haslengthto
,
72 boolean
* haspointer
, boolean
* hascrosstag
, boolean
* has_ext_bit
);
74 static char *generate_raw_coding(char *src
,
75 const struct_def
*sdef
, struct raw_option_struct
*raw_options
,
76 boolean haspointer
, boolean hascrosstag
, boolean has_ext_bit
);
77 static char *generate_raw_coding_negtest(char *src
,
78 const struct_def
*sdef
, struct raw_option_struct
*raw_options
);
80 void set_raw_options(const struct_def
*sdef
,
81 struct raw_option_struct
*raw_options
, boolean
*haslengthto
,
82 boolean
*haspointer
, boolean
*hascrosstag
, boolean
*has_ext_bit
)
85 for (i
= 0; i
< sdef
->nElements
; i
++) {
86 raw_options
[i
].lengthto
= FALSE
;
87 raw_options
[i
].lengthof
= 0;
88 raw_options
[i
].lengthoffield
= NULL
;
89 raw_options
[i
].pointerto
= FALSE
;
90 raw_options
[i
].pointerof
= 0;
91 raw_options
[i
].ptrbase
= FALSE
;
92 raw_options
[i
].extbitgroup
= 0;
93 raw_options
[i
].tag_type
= 0;
94 raw_options
[i
].delayed_decode
= FALSE
;
95 raw_options
[i
].nof_dependent_fields
= 0;
96 raw_options
[i
].dependent_fields
= NULL
;
100 *hascrosstag
= FALSE
;
101 *has_ext_bit
= sdef
->hasRaw
&& sdef
->raw
.extension_bit
!=XDEFNO
&&
102 sdef
->raw
.extension_bit
!=XDEFDEFAULT
;
103 for(i
=0;i
<sdef
->nElements
;i
++){
104 if(sdef
->elements
[i
].hasRaw
&&
105 sdef
->elements
[i
].raw
.crosstaglist
.nElements
){
110 if(sdef
->hasRaw
){ /* fill tag_type. 0-No tag, >0 index of the tag + 1 */
111 for(i
=0;i
<sdef
->raw
.taglist
.nElements
;i
++){
112 raw_options
[sdef
->raw
.taglist
.list
[i
].fieldnum
].tag_type
= i
+1;
114 for(i
=0;i
<sdef
->raw
.ext_bit_goup_num
;i
++){
116 for(k
=sdef
->raw
.ext_bit_groups
[i
].from
;
117 k
<=sdef
->raw
.ext_bit_groups
[i
].to
;k
++)
118 raw_options
[k
].extbitgroup
=i
+1;
121 for(i
=0;i
<sdef
->nElements
;i
++){
122 if (sdef
->elements
[i
].hasRaw
&& sdef
->elements
[i
].raw
.lengthto_num
> 0) {
125 raw_options
[i
].lengthto
= TRUE
;
126 for(j
= 0; j
< sdef
->elements
[i
].raw
.lengthto_num
; j
++) {
127 int field_index
= sdef
->elements
[i
].raw
.lengthto
[j
];
128 raw_options
[field_index
].lengthoffield
= (int*)
129 Realloc(raw_options
[field_index
].lengthoffield
,
130 (raw_options
[field_index
].lengthof
+ 1) * sizeof(int));
131 raw_options
[field_index
].lengthoffield
[
132 raw_options
[field_index
].lengthof
] = i
;
133 raw_options
[field_index
].lengthof
++;
136 if(sdef
->elements
[i
].hasRaw
&& sdef
->elements
[i
].raw
.pointerto
!=-1){
137 raw_options
[i
].pointerto
= TRUE
;
138 raw_options
[sdef
->elements
[i
].raw
.pointerto
].pointerof
=i
+1;
140 raw_options
[sdef
->elements
[i
].raw
.pointerbase
].ptrbase
= TRUE
;
143 if (sdef
->kind
== RECORD
&& *hascrosstag
) {
144 /* looking for fields that require delayed decoding because of
145 forward references in CROSSTAG */
146 for (i
= 0; i
< sdef
->nElements
; i
++) {
148 /* we are looking for a field index that is greater than i */
149 size_t max_index
= i
;
150 if (!sdef
->elements
[i
].hasRaw
) continue;
151 for (j
= 0; j
< sdef
->elements
[i
].raw
.crosstaglist
.nElements
; j
++) {
153 rawAST_coding_taglist
*crosstag
=
154 sdef
->elements
[i
].raw
.crosstaglist
.list
+ j
;
155 for (k
= 0; k
< crosstag
->nElements
; k
++) {
156 rawAST_coding_field_list
*keyid
= crosstag
->fields
+ k
;
157 if (keyid
->nElements
>= 1) {
158 int field_index
= keyid
->fields
[0].nthfield
;
159 if (field_index
> max_index
) max_index
= field_index
;
164 raw_options
[i
].delayed_decode
= TRUE
;
165 raw_options
[max_index
].nof_dependent_fields
++;
166 raw_options
[max_index
].dependent_fields
= (int*)
167 Realloc(raw_options
[max_index
].dependent_fields
,
168 raw_options
[max_index
].nof_dependent_fields
*
169 sizeof(*raw_options
[max_index
].dependent_fields
));
170 raw_options
[max_index
].dependent_fields
[
171 raw_options
[max_index
].nof_dependent_fields
- 1] = i
;
177 char* generate_raw_coding(char* src
,
178 const struct_def
*sdef
, struct raw_option_struct
*raw_options
,
179 boolean haspointer
, boolean hascrosstag
, boolean has_ext_bit
)
182 const char *name
= sdef
->name
;
184 if (sdef
->kind
== SET
) { /* set decoder start */
186 for (i
= 0; i
< sdef
->nElements
; i
++) {
187 if (!sdef
->elements
[i
].isOptional
) mand_num
++;
189 src
= mputprintf(src
, "int %s::RAW_decode(const TTCN_Typedescriptor_t& "
190 "p_td, TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, "
191 "boolean, int, boolean)\n"
193 "bound_flag = TRUE;\n"
194 "int prepaddlength = p_buf.increase_pos_padd(p_td.raw->prepadding);\n"
195 "limit -= prepaddlength;\n"
196 "int decoded_length = 0;\n"
197 "int field_map[%lu];\n"
198 "memset(field_map, 0, sizeof(field_map));\n",
199 name
, (unsigned long) sdef
->nElements
);
201 src
= mputstr(src
, "size_t nof_mand_fields = 0;\n");
202 for (i
= 0; i
< sdef
->nElements
; i
++) {
203 if (sdef
->elements
[i
].isOptional
)
204 src
= mputprintf(src
, "field_%s = OMIT_VALUE;\n",
205 sdef
->elements
[i
].name
);
208 "raw_order_t local_top_order;\n"
209 "if (p_td.raw->top_bit_order == TOP_BIT_INHERITED) "
210 "local_top_order = top_bit_ord;\n"
211 "else if (p_td.raw->top_bit_order == TOP_BIT_RIGHT) "
212 "local_top_order = ORDER_MSB;\n"
213 "else local_top_order = ORDER_LSB;\n"
214 "while (limit > 0) {\n"
215 "size_t fl_start_pos = p_buf.get_pos_bit();\n"
217 for (i
= 0; i
< sdef
->nElements
; i
++) { /* decoding fields with tag */
218 if (raw_options
[i
].tag_type
&&
219 sdef
->raw
.taglist
.list
[raw_options
[i
].tag_type
- 1].nElements
> 0) {
220 rawAST_coding_taglist
* cur_choice
=
221 sdef
->raw
.taglist
.list
+ raw_options
[i
].tag_type
- 1;
223 boolean has_fixed
= FALSE
, has_variable
= FALSE
, flag_needed
= FALSE
;
224 for (j
= 0; j
< cur_choice
->nElements
; j
++) {
225 if (cur_choice
->fields
[j
].start_pos
>= 0) {
226 if (has_fixed
|| has_variable
) flag_needed
= TRUE
;
229 if (has_fixed
) flag_needed
= TRUE
;
232 if (has_fixed
&& has_variable
) break;
234 src
= mputprintf(src
, "if (field_map[%lu] == 0) {\n",
237 src
= mputstr(src
, "boolean already_failed = FALSE;\n");
239 /* first check the fields we can precode
240 * try to decode those key variables whose position we know
241 * this way we might be able to step over bad values faster
243 boolean first_fixed
= TRUE
;
244 src
= mputstr(src
, "raw_order_t temporal_top_order;\n"
245 "int temporal_decoded_length;\n");
246 for (j
= 0; j
< cur_choice
->nElements
; j
++) {
248 rawAST_coding_field_list
*cur_field_list
= cur_choice
->fields
+ j
;
249 if (cur_field_list
->start_pos
< 0) continue;
250 if (!first_fixed
) src
= mputstr(src
, "if (!already_failed) {\n");
251 for (k
= cur_field_list
->nElements
- 1; k
> 0; k
--) {
252 src
= mputprintf(src
, "if (%s_descr_.raw->top_bit_order == "
253 "TOP_BIT_RIGHT) temporal_top_order = ORDER_MSB;\n"
254 "else if (%s_descr_.raw->top_bit_order == TOP_BIT_LEFT) "
255 "temporal_top_order = ORDER_LSB;\n"
256 "else ", cur_field_list
->fields
[k
- 1].typedescr
,
257 cur_field_list
->fields
[k
- 1].typedescr
);
259 src
= mputprintf(src
, "temporal_top_order = top_bit_ord;\n"
261 "p_buf.set_pos_bit(fl_start_pos + %d);\n"
262 "temporal_decoded_length = temporal_%lu.RAW_decode(%s_descr_, "
263 "p_buf, limit, temporal_top_order, TRUE);\n"
264 "p_buf.set_pos_bit(fl_start_pos);\n"
265 "if (temporal_decoded_length > 0 && temporal_%lu == %s) {\n"
266 "int decoded_field_length = field_%s%s.RAW_decode(%s_descr_, "
267 "p_buf, limit, local_top_order, TRUE);\n"
268 "if (decoded_field_length %s 0 && (",
269 cur_field_list
->fields
[cur_field_list
->nElements
- 1].type
,
270 (unsigned long) j
, cur_field_list
->start_pos
, (unsigned long) j
,
271 cur_field_list
->fields
[cur_field_list
->nElements
- 1].typedescr
,
272 (unsigned long) j
, cur_field_list
->value
,
273 sdef
->elements
[i
].name
,
274 sdef
->elements
[i
].isOptional
? "()" : "",
275 sdef
->elements
[i
].typedescrname
,
276 sdef
->elements
[i
].isOptional
? ">" : ">=");
277 src
= genRawFieldChecker(src
, cur_choice
, TRUE
);
278 src
= mputstr(src
, ")) {\n"
279 "decoded_length += decoded_field_length;\n"
280 "limit -= decoded_field_length;\n");
281 if (!sdef
->elements
[i
].isOptional
)
282 src
= mputstr(src
, "nof_mand_fields++;\n");
283 src
= mputprintf(src
, "field_map[%lu] = 1;\n"
286 "p_buf.set_pos_bit(fl_start_pos);\n", (unsigned long) i
);
287 if (sdef
->elements
[i
].isOptional
)
288 src
= mputprintf(src
, "field_%s = OMIT_VALUE;\n",
289 sdef
->elements
[i
].name
);
290 if (flag_needed
) src
= mputstr(src
, "already_failed = TRUE;\n");
291 src
= mputstr(src
, "}\n"
293 if (first_fixed
) first_fixed
= FALSE
;
294 else src
= mputstr(src
, "}\n");
298 /* if there is one tag key whose position we don't know
299 * and we couldn't decide yet if element can be decoded or not
300 * than we have to decode it.
302 if (flag_needed
) src
= mputstr(src
, "if (!already_failed) {\n");
303 src
= mputprintf(src
, "int decoded_field_length = "
304 "field_%s%s.RAW_decode(%s_descr_, p_buf, limit, "
305 "local_top_order, TRUE);\n"
306 "if (decoded_field_length %s 0 && (",
307 sdef
->elements
[i
].name
, sdef
->elements
[i
].isOptional
? "()" : "",
308 sdef
->elements
[i
].typedescrname
,
309 sdef
->elements
[i
].isOptional
? ">" : ">=");
310 src
= genRawFieldChecker(src
, cur_choice
, TRUE
);
311 src
= mputstr(src
, ")) {\n"
312 "decoded_length += decoded_field_length;\n"
313 "limit -= decoded_field_length;\n");
314 if (!sdef
->elements
[i
].isOptional
)
315 src
= mputstr(src
, "nof_mand_fields++;\n");
316 src
= mputprintf(src
, "field_map[%lu] = 1;\n"
319 "p_buf.set_pos_bit(fl_start_pos);\n", (unsigned long) i
);
320 if (sdef
->elements
[i
].isOptional
)
321 src
= mputprintf(src
, "field_%s = OMIT_VALUE;\n",
322 sdef
->elements
[i
].name
);
323 src
= mputstr(src
, "}\n");
324 if (flag_needed
) src
= mputstr(src
, "}\n");
326 src
= mputstr(src
, "}\n");
329 for (i
= 0; i
< sdef
->nElements
; i
++) {
330 /* decoding fields without TAG */
331 if (!raw_options
[i
].tag_type
) {
333 if (sdef
->elements
[i
].of_type
&& sdef
->elements
[i
].hasRaw
&&
334 sdef
->elements
[i
].raw
.repeatable
== XDEFYES
) repeatable
= TRUE
;
337 src
= mputprintf(src
, "if (field_map[%lu] == 0) ",
340 src
= mputprintf(src
, "{\n"
341 "int decoded_field_length = field_%s%s.RAW_decode(%s_descr_, "
342 "p_buf, limit, local_top_order, TRUE",
343 sdef
->elements
[i
].name
, sdef
->elements
[i
].isOptional
? "()" : "",
344 sdef
->elements
[i
].typedescrname
);
346 src
= mputprintf(src
, ", -1, field_map[%lu] == 0",
348 src
= mputprintf(src
, ");\n"
349 "if (decoded_field_length %s 0) {\n"
350 "decoded_length += decoded_field_length;\n"
351 "limit -= decoded_field_length;\n",
352 sdef
->elements
[i
].isOptional
? ">" : ">=");
354 if (!sdef
->elements
[i
].isOptional
) src
= mputprintf(src
,
355 "if (field_map[%lu] == 0) nof_mand_fields++;\n",
357 src
= mputprintf(src
, "field_map[%lu]++;\n", (unsigned long) i
);
359 if (!sdef
->elements
[i
].isOptional
)
360 src
= mputstr(src
, "nof_mand_fields++;\n");
361 src
= mputprintf(src
, "field_map[%lu] = 1;\n", (unsigned long) i
);
363 src
= mputstr(src
, "continue;\n"
365 "p_buf.set_pos_bit(fl_start_pos);\n");
366 if (sdef
->elements
[i
].isOptional
) {
368 src
= mputprintf(src
, "if (field_map[%lu] == 0) ",
370 src
= mputprintf(src
, "field_%s = OMIT_VALUE;\n",
371 sdef
->elements
[i
].name
);
373 src
= mputstr(src
, "}\n"
377 for (i
= 0; i
< sdef
->nElements
; i
++){
378 /* decoding fields with tag OTHERWISE */
379 if (raw_options
[i
].tag_type
&&
380 sdef
->raw
.taglist
.list
[raw_options
[i
].tag_type
-1].nElements
== 0) {
381 src
= mputprintf(src
, "if (field_map[%lu] == 0) {\n"
382 "int decoded_field_length = field_%s%s.RAW_decode(%s_descr_, "
383 "p_buf, limit, local_top_order, TRUE);\n"
384 "if (decoded_field_length %s 0) {\n"
385 "decoded_length += decoded_field_length;\n"
386 "limit -= decoded_field_length;\n", (unsigned long) i
,
387 sdef
->elements
[i
].name
, sdef
->elements
[i
].isOptional
? "()" : "",
388 sdef
->elements
[i
].typedescrname
,
389 sdef
->elements
[i
].isOptional
? ">" : ">=");
390 if (!sdef
->elements
[i
].isOptional
)
391 src
= mputstr(src
, "nof_mand_fields++;\n");
392 src
= mputprintf(src
, "field_map[%lu] = 1;\n"
395 "p_buf.set_pos_bit(fl_start_pos);\n", (unsigned long) i
);
396 if (sdef
->elements
[i
].isOptional
)
397 src
= mputprintf(src
, "field_%s = OMIT_VALUE;\n",
398 sdef
->elements
[i
].name
);
399 src
= mputstr(src
, "}\n"
403 src
= mputstr(src
, "break;\n" /* no field decoded successfully, quit */
405 if (mand_num
> 0) src
= mputprintf(src
,
406 "if (nof_mand_fields != %lu) return limit ? -1 : -TTCN_EncDec::ET_INCOMPL_MSG;\n",
407 (unsigned long) mand_num
);
408 /* If not all required fields were decoded and there are no bits left,
409 * that means that the last field was decoded successfully but used up
410 * the buffer. Signal "incomplete". If there were bits left, that means that
411 * no field could be decoded from them; signal an error.
413 src
= mputstr(src
, "return decoded_length + prepaddlength + "
414 "p_buf.increase_pos_padd(p_td.raw->padding);\n"
417 /* set decoder end, record decoder start */
418 int prev_ext_group
= 0;
419 src
= mputprintf(src
,
420 "int %s::RAW_decode(const TTCN_Typedescriptor_t& p_td, "
421 "TTCN_Buffer& p_buf, int limit, raw_order_t top_bit_ord, boolean no_err, "
424 " bound_flag = TRUE;\n"
425 " int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);\n"
426 " limit-=prepaddlength;\n"
427 " size_t last_decoded_pos = p_buf.get_pos_bit();\n"
428 " int decoded_length = 0;\n"
429 " int decoded_field_length = 0;\n"
430 " raw_order_t local_top_order;\n"
433 src
= mputstr(src
, " int selected_field = -1;\n");
435 if (sdef
->raw
.ext_bit_goup_num
) {
436 src
=mputstr(src
, " int group_limit = 0;\n");
439 " if(p_td.raw->top_bit_order==TOP_BIT_INHERITED)"
440 "local_top_order=top_bit_ord;\n"
441 " else if(p_td.raw->top_bit_order==TOP_BIT_RIGHT)local_top_order"
443 " else local_top_order=ORDER_LSB;\n"
448 " cbyte* data=p_buf.get_read_data();\n"
450 " unsigned mask = 1 << (local_top_order==ORDER_LSB ? 0 : 7);\n"
451 " if(p_td.raw->extension_bit==EXT_BIT_YES){\n"
452 " while((data[count-1] & mask)==0 && count*8<(int)limit) count++;\n"
455 " while((data[count-1] & mask)!=0 && count*8<(int)limit) count++;\n"
457 " if(limit) limit=count*8;\n"
463 " int end_of_available_data=last_decoded_pos+limit;\n");
464 for(i
=0;i
<sdef
->nElements
;i
++){
465 if(raw_options
[i
].pointerof
)
467 " int start_of_field%lu=-1;\n"
470 if(raw_options
[i
].ptrbase
)
472 " int start_pos_of_field%lu=-1;\n"
475 if(raw_options
[i
].lengthto
)
477 " int value_of_length_field%lu = 0;\n"
481 for(i
=0;i
<sdef
->nElements
;i
++){ /* decoding fields */
482 if (raw_options
[i
].delayed_decode
) {
484 /* checking whether there are enough bits in the buffer to decode
486 src
= mputstr(src
, " if (");
487 src
= genRawFieldDecodeLimit(src
, sdef
, i
, raw_options
);
488 src
= mputprintf(src
, " < %d) return -TTCN_EncDec::ET_LEN_ERR;\n",
489 sdef
->elements
[i
].raw
.length
);
490 /* skipping over the field that has to be decoded later because of
491 forward referencing in CROSSTAG */
492 src
= mputprintf(src
,
493 " size_t start_of_field%lu = p_buf.get_pos_bit();\n"
494 " p_buf.set_pos_bit(start_of_field%lu + %d);\n"
495 " decoded_length += %d;\n"
496 " last_decoded_pos += %d;\n"
498 (unsigned long) i
, (unsigned long) i
, sdef
->elements
[i
].raw
.length
,
499 sdef
->elements
[i
].raw
.length
,
500 sdef
->elements
[i
].raw
.length
, sdef
->elements
[i
].raw
.length
);
501 for (j
= 0; j
< raw_options
[i
].lengthof
; j
++) {
502 src
= mputprintf(src
,
503 " value_of_length_field%d -= %d;\n",
504 raw_options
[i
].lengthoffield
[j
], sdef
->elements
[i
].raw
.length
);
507 src
= genRawDecodeRecordField(src
, sdef
, i
, raw_options
, FALSE
,
509 if (raw_options
[i
].nof_dependent_fields
> 0) {
511 for (j
= 0; j
< raw_options
[i
].nof_dependent_fields
; j
++) {
512 int dependent_field_index
= raw_options
[i
].dependent_fields
[j
];
513 /* seek to the beginning of the dependent field */
514 src
= mputprintf(src
,
515 " p_buf.set_pos_bit(start_of_field%d);\n",
516 dependent_field_index
);
517 /* decode the dependent field */
518 src
= genRawDecodeRecordField(src
, sdef
, dependent_field_index
,
519 raw_options
, TRUE
, &prev_ext_group
);
521 if (i
< sdef
->nElements
- 1) {
522 /* seek back if there are more regular fields to decode */
524 " p_buf.set_pos_bit(last_decoded_pos);\n");
528 } /* decoding fields*/
530 if(sdef
->hasRaw
&& sdef
->raw
.presence
.nElements
> 0)
532 src
= mputstr(src
, " if (");
533 src
= genRawFieldChecker(src
, &sdef
->raw
.presence
, FALSE
);
534 src
= mputstr(src
, ") return -1;\n");
538 " p_buf.set_pos_bit(last_decoded_pos);\n"
539 " return decoded_length+prepaddlength+"
540 "p_buf.increase_pos_padd(p_td.raw->padding);\n}\n\n");
541 } /* record decoder end */
543 src
= mputprintf(src
, /* encoder */
544 "int %s::RAW_encode(const TTCN_Typedescriptor_t&%s, "
545 "RAW_enc_tree& myleaf) const {\n", name
,
546 use_runtime_2
? " p_td" : "");
548 src
= mputstr(src
, " if (err_descr) return RAW_encode_negtest(err_descr, p_td, myleaf);\n");
550 src
= mputprintf(src
,
551 " if (!is_bound()) TTCN_EncDec_ErrorContext::error"
552 "(TTCN_EncDec::ET_UNBOUND, \"Encoding an unbound value.\");\n"
553 " int encoded_length = 0;\n"
554 " myleaf.isleaf = false;\n"
555 " myleaf.body.node.num_of_nodes = %lu;\n"
556 " myleaf.body.node.nodes = init_nodes_of_enc_tree(%lu);\n",
557 (unsigned long)sdef
->nElements
, (unsigned long)sdef
->nElements
);
559 for (i
= 0; i
< sdef
->nElements
; i
++) {
560 if (sdef
->elements
[i
].isOptional
) {
561 src
= mputprintf(src
,
562 " if (field_%s.ispresent()) {\n", sdef
->elements
[i
].name
);
564 src
= mputprintf(src
,
565 " myleaf.body.node.nodes[%lu] = new RAW_enc_tree(true, &myleaf, "
566 "&(myleaf.curr_pos), %lu, %s_descr_.raw);\n",
567 (unsigned long)i
, (unsigned long)i
, sdef
->elements
[i
].typedescrname
);
568 if (sdef
->elements
[i
].isOptional
) {
569 src
= mputprintf(src
,
571 " else myleaf.body.node.nodes[%lu] = NULL;\n", (unsigned long)i
);
574 for (i
= 0; i
< sdef
->raw
.ext_bit_goup_num
; i
++) {
575 if (sdef
->raw
.ext_bit_groups
[i
].ext_bit
!= XDEFNO
) {
576 src
= mputprintf(src
,
578 " int node_idx = %d;\n"
579 " while (node_idx <= %d && myleaf.body.node.nodes[node_idx] == NULL) node_idx++;\n"
580 " if (myleaf.body.node.nodes[node_idx]) {\n"
581 " myleaf.body.node.nodes[node_idx]->ext_bit_handling = 1;\n"
582 " myleaf.body.node.nodes[node_idx]->ext_bit = %s;\n }\n"
584 " while (node_idx >= %d && myleaf.body.node.nodes[node_idx] == NULL) node_idx--;\n"
585 " if (myleaf.body.node.nodes[node_idx]) myleaf.body.node.nodes[node_idx]"
586 "->ext_bit_handling += 2;\n"
588 sdef
->raw
.ext_bit_groups
[i
].from
,
589 sdef
->raw
.ext_bit_groups
[i
].to
,
590 sdef
->raw
.ext_bit_groups
[i
].ext_bit
== XDEFYES
? "EXT_BIT_YES" : "EXT_BIT_REVERSE",
591 sdef
->raw
.ext_bit_groups
[i
].to
,
592 sdef
->raw
.ext_bit_groups
[i
].from
);
595 for (i
= 0; i
< sdef
->nElements
; i
++) {
596 /* encoding fields */
597 if (sdef
->elements
[i
].isOptional
) {
598 src
= mputprintf(src
,
599 " if (field_%s.ispresent()) {\n", sdef
->elements
[i
].name
);
601 if (raw_options
[i
].lengthto
&& sdef
->elements
[i
].raw
.lengthindex
== NULL
602 && sdef
->elements
[i
].raw
.union_member_num
== 0) {
603 /* encoding of lenghto fields */
605 src
= mputprintf(src
,
606 " encoded_length += %d;\n"
607 " myleaf.body.node.nodes[%lu]->calc = CALC_LENGTH;\n"
608 " myleaf.body.node.nodes[%lu]->coding_descr = &%s_descr_;\n"
609 " myleaf.body.node.nodes[%lu]->calcof.lengthto.num_of_fields = %d;\n"
610 " myleaf.body.node.nodes[%lu]->calcof.lengthto.unit = %d;\n"
611 " myleaf.body.node.nodes[%lu]->calcof.lengthto.fields = "
612 "init_lengthto_fields_list(%d);\n"
613 " myleaf.body.node.nodes[%lu]->length = %d;\n",
614 sdef
->elements
[i
].raw
.fieldlength
, (unsigned long)i
,
615 (unsigned long)i
, sdef
->elements
[i
].typedescrname
,
616 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthto_num
,
617 (unsigned long)i
, sdef
->elements
[i
].raw
.unit
,
618 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthto_num
,
619 (unsigned long)i
, sdef
->elements
[i
].raw
.fieldlength
);
620 for (a
= 0; a
< sdef
->elements
[i
].raw
.lengthto_num
; a
++) {
621 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
622 src
= mputprintf(src
,
623 " if (field_%s.ispresent()) {\n",
624 sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].name
);
626 src
= mputprintf(src
,
627 " myleaf.body.node.nodes[%lu]->calcof.lengthto.fields[%d].level = "
628 "myleaf.body.node.nodes[%d]->curr_pos.level;\n"
629 " myleaf.body.node.nodes[%lu]->calcof.lengthto.fields[%d].pos = "
630 "myleaf.body.node.nodes[%d]->curr_pos.pos;\n",
631 (unsigned long)i
, a
, sdef
->elements
[i
].raw
.lengthto
[a
],
632 (unsigned long)i
, a
, sdef
->elements
[i
].raw
.lengthto
[a
]);
633 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
634 src
= mputprintf(src
,
636 " myleaf.body.node.nodes[%lu]->calcof.lengthto.fields[%d].level = 0;\n"
637 " myleaf.body.node.nodes[%lu]->calcof.lengthto.fields[%d].pos = 0;\n"
638 " }\n", (unsigned long)i
, a
, (unsigned long)i
, a
);
641 } else if (raw_options
[i
].pointerto
) {
642 /* encoding of pointerto fields */
643 if (sdef
->elements
[sdef
->elements
[i
].raw
.pointerto
].isOptional
) {
644 src
= mputprintf(src
,
645 " if (field_%s.ispresent()) {\n",
646 sdef
->elements
[sdef
->elements
[i
].raw
.pointerto
].name
);
648 src
= mputprintf(src
,
649 " encoded_length += %d;\n"
650 " myleaf.body.node.nodes[%lu]->calc = CALC_POINTER;\n"
651 " myleaf.body.node.nodes[%lu]->coding_descr = &%s_descr_;\n"
652 " myleaf.body.node.nodes[%lu]->calcof.pointerto.unit = %d;\n"
653 " myleaf.body.node.nodes[%lu]->calcof.pointerto.ptr_offset = %d;\n"
654 " myleaf.body.node.nodes[%lu]->calcof.pointerto.ptr_base = %d;\n"
655 " myleaf.body.node.nodes[%lu]->calcof.pointerto.target.level = "
656 "myleaf.body.node.nodes[%d]->curr_pos.level;\n"
657 " myleaf.body.node.nodes[%lu]->calcof.pointerto.target.pos = "
658 "myleaf.body.node.nodes[%d]->curr_pos.pos;\n"
659 " myleaf.body.node.nodes[%lu]->length = %d;\n",
660 sdef
->elements
[i
].raw
.fieldlength
,(unsigned long)i
,
661 (unsigned long)i
, sdef
->elements
[i
].typedescrname
,
662 (unsigned long)i
, sdef
->elements
[i
].raw
.unit
,
663 (unsigned long)i
, sdef
->elements
[i
].raw
.ptroffset
,
664 (unsigned long)i
, sdef
->elements
[i
].raw
.pointerbase
,
665 (unsigned long)i
, sdef
->elements
[i
].raw
.pointerto
,
666 (unsigned long)i
, sdef
->elements
[i
].raw
.pointerto
,
667 (unsigned long)i
, sdef
->elements
[i
].raw
.fieldlength
);
668 if (sdef
->elements
[sdef
->elements
[i
].raw
.pointerto
].isOptional
) {
669 src
= mputprintf(src
,
673 " encoded_length += atm.RAW_encode(%s_descr_"
674 ", *myleaf.body.node.nodes[%lu]);\n"
676 sdef
->elements
[i
].typedescrname
, (unsigned long)i
);
679 /* encoding of normal fields */
680 src
= mputprintf(src
,
681 " encoded_length += field_%s%s.RAW_encode(%s_descr_"
682 ", *myleaf.body.node.nodes[%lu]);\n",
683 sdef
->elements
[i
].name
, sdef
->elements
[i
].isOptional
? "()" : "",
684 sdef
->elements
[i
].typedescrname
, (unsigned long)i
);
686 if (sdef
->elements
[i
].isOptional
) {
687 src
= mputstr(src
, " }\n");
690 for (i
= 0; i
< sdef
->nElements
; i
++) {
691 /* fill presence, tag and crosstag */
692 if (raw_options
[i
].lengthto
&& sdef
->elements
[i
].raw
.lengthindex
) {
693 /* encoding of lenghto fields */
695 if (sdef
->elements
[i
].isOptional
) {
696 src
= mputprintf(src
,
697 " if (field_%s.ispresent()) {\n",
698 sdef
->elements
[i
].name
);
700 src
= mputprintf(src
,
701 " if (myleaf.body.node.nodes[%lu]->body.node.nodes[%d]) {\n"
702 " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]->"
703 "calc = CALC_LENGTH;\n"
704 " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]->"
705 "coding_descr = &%s_descr_;\n"
706 " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]->"
707 "calcof.lengthto.num_of_fields = %d;\n"
708 " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]->"
709 "calcof.lengthto.unit = %d;\n"
710 " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]->"
711 "calcof.lengthto.fields = "
712 "init_lengthto_fields_list(%d);\n",
713 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
714 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
715 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
716 sdef
->elements
[i
].raw
.lengthindex
->typedescr
,
717 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
718 sdef
->elements
[i
].raw
.lengthto_num
,
719 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
720 sdef
->elements
[i
].raw
.unit
,
721 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
722 sdef
->elements
[i
].raw
.lengthto_num
);
723 for (a
= 0; a
< sdef
->elements
[i
].raw
.lengthto_num
; a
++) {
724 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
725 src
= mputprintf(src
,
726 " if (field_%s.ispresent()) {\n",
727 sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].name
);
729 src
= mputprintf(src
,
730 " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]"
731 "->calcof.lengthto.fields[%d].level = "
732 "myleaf.body.node.nodes[%d]->curr_pos.level;\n"
733 " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]"
734 "->calcof.lengthto.fields[%d].pos = "
735 "myleaf.body.node.nodes[%d]->curr_pos.pos;\n",
736 (unsigned long)i
,sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
737 a
, sdef
->elements
[i
].raw
.lengthto
[a
],
738 (unsigned long)i
,sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
739 a
, sdef
->elements
[i
].raw
.lengthto
[a
]);
740 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
741 src
= mputprintf(src
,
743 " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]->"
744 "calcof.lengthto.fields[%d].level = 0;\n"
745 " myleaf.body.node.nodes[%lu]->body.node.nodes[%d]->"
746 "calcof.lengthto.fields[%d].pos = 0;\n"
748 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
, a
,
749 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
, a
);
752 src
= mputstr(src
, " }\n");
753 if (sdef
->elements
[i
].isOptional
) {
754 src
= mputstr(src
, " }\n");
757 if (raw_options
[i
].lengthto
&& sdef
->elements
[i
].raw
.union_member_num
) {
758 /* encoding of lenghto fields */
760 if (sdef
->elements
[i
].isOptional
) {
761 src
= mputprintf(src
,
762 " if (field_%s.ispresent()) ", sdef
->elements
[i
].name
);
765 src
= mputprintf(src
,
767 " int sel_field = 0;\n"
768 " while (myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field] == NULL) "
770 " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]->"
771 "calc = CALC_LENGTH;\n"
772 " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]->"
773 "calcof.lengthto.num_of_fields = %d;\n"
774 " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]->"
775 "calcof.lengthto.unit = %d;\n"
776 " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]->"
777 "calcof.lengthto.fields = init_lengthto_fields_list(%d);\n",
778 (unsigned long)i
,(unsigned long)i
,
779 (unsigned long)i
,sdef
->elements
[i
].raw
.lengthto_num
,
780 (unsigned long)i
,sdef
->elements
[i
].raw
.unit
,
781 (unsigned long)i
,sdef
->elements
[i
].raw
.lengthto_num
);
782 for (a
= 0; a
< sdef
->elements
[i
].raw
.lengthto_num
; a
++) {
783 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
784 src
= mputprintf(src
,
785 " if (field_%s.ispresent()) {\n",
786 sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].name
);
788 src
= mputprintf(src
,
789 " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]"
790 "->calcof.lengthto.fields[%d].level = "
791 "myleaf.body.node.nodes[%d]->curr_pos.level;\n"
792 " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]"
793 "->calcof.lengthto.fields[%d].pos = "
794 "myleaf.body.node.nodes[%d]->curr_pos.pos;\n",
795 (unsigned long)i
, a
, sdef
->elements
[i
].raw
.lengthto
[a
],
796 (unsigned long)i
, a
, sdef
->elements
[i
].raw
.lengthto
[a
]);
797 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
798 src
= mputprintf(src
,
800 " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]"
801 "->calcof.lengthto.fields[%d].level = 0;\n"
802 " myleaf.body.node.nodes[%lu]->body.node.nodes[sel_field]"
803 "->calcof.lengthto.fields[%d].pos = 0;\n"
806 (unsigned long)i
, a
);
812 if (raw_options
[i
].tag_type
&& sdef
->raw
.taglist
.list
[raw_options
[i
].tag_type
- 1].nElements
) {
814 rawAST_coding_taglist
*cur_choice
=
815 sdef
->raw
.taglist
.list
+ raw_options
[i
].tag_type
- 1;
816 src
= mputstr(src
, " if (");
817 if (sdef
->elements
[i
].isOptional
) {
818 src
= mputprintf(src
, "field_%s.ispresent() && (", sdef
->elements
[i
].name
);
820 src
= genRawFieldChecker(src
, cur_choice
, FALSE
);
821 if (sdef
->elements
[i
].isOptional
) src
= mputstr(src
, ")");
822 src
= mputstr(src
,") {\n");
823 src
= genRawTagChecker(src
, cur_choice
);
824 src
=mputstr(src
," }\n");
826 if (sdef
->elements
[i
].hasRaw
&& sdef
->elements
[i
].raw
.presence
.nElements
) {
828 src
= mputstr(src
, " if (");
829 if (sdef
->elements
[i
].isOptional
) {
830 src
= mputprintf(src
, "field_%s.ispresent() && (", sdef
->elements
[i
].name
);
832 src
= genRawFieldChecker(src
, &sdef
->elements
[i
].raw
.presence
, FALSE
);
833 if (sdef
->elements
[i
].isOptional
) src
= mputstr(src
, ")");
834 src
= mputstr(src
, ") {\n");
835 src
= genRawTagChecker(src
, &sdef
->elements
[i
].raw
.presence
);
836 src
= mputstr(src
," }\n");
838 if (sdef
->elements
[i
].hasRaw
&&
839 sdef
->elements
[i
].raw
.crosstaglist
.nElements
) {
842 if (sdef
->elements
[i
].isOptional
) {
843 src
= mputprintf(src
,
844 " if (field_%s.ispresent()) {\n",
845 sdef
->elements
[i
].name
);
847 src
= mputprintf(src
,
848 " switch (field_%s%s.get_selection()) {\n",
849 sdef
->elements
[i
].name
,sdef
->elements
[i
].isOptional
? "()" : "");
850 for (a
= 0; a
< sdef
->elements
[i
].raw
.crosstaglist
.nElements
; a
++) {
851 rawAST_coding_taglist
*cur_choice
=
852 sdef
->elements
[i
].raw
.crosstaglist
.list
+ a
;
853 if (cur_choice
->nElements
> 0) {
854 src
= mputprintf(src
, " case %s%s%s:\n"
855 " if (", sdef
->elements
[i
].type
,
856 "::ALT_", cur_choice
->fieldName
);
857 src
= genRawFieldChecker(src
, cur_choice
, FALSE
);
858 src
= mputstr(src
, ") {\n");
859 if (!strcmp(cur_choice
->fields
[0].value
, "OMIT_VALUE")) {
860 if (cur_choice
->fields
[0].nElements
!= 1)
861 NOTSUPP("omit value with multiple fields in CROSSTAG");
862 /* eliminating the corresponding encoded leaf, which will have
863 the same effect as if the referred field had been omit */
864 src
= mputprintf(src
,
865 " encoded_length -= myleaf.body.node.nodes[%d]->length;\n"
866 " delete myleaf.body.node.nodes[%d];\n"
867 " myleaf.body.node.nodes[%d] = NULL;\n",
868 cur_choice
->fields
[0].fields
[0].nthfield
,
869 cur_choice
->fields
[0].fields
[0].nthfield
,
870 cur_choice
->fields
[0].fields
[0].nthfield
);
873 src
= mputprintf(src
,
874 " RAW_enc_tr_pos pr_pos;\n"
875 " pr_pos.level = myleaf.curr_pos.level + %d;\n"
876 " int new_pos[] = { ",
877 cur_choice
->fields
[0].nElements
);
878 for (ll
= 0; ll
< cur_choice
->fields
[0].nElements
; ll
++) {
879 if (ll
> 0) src
= mputstr(src
, ", ");
880 src
= mputprintf(src
, "%d",
881 cur_choice
->fields
[0].fields
[ll
].nthfield
);
883 src
= mputprintf(src
, " };\n"
884 " pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, %d, "
886 cur_choice
->fields
[0].nElements
);
887 if (cur_choice
->fields
[0].value
[0] == ' ') {
888 /* the value is a string literal (the encoder can be called
889 on that object directly */
890 src
= mputprintf(src
,
891 " RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);\n"
892 " if (temp_leaf != NULL)\n"
893 " %s.RAW_encode(%s_descr_,*temp_leaf);\n"
895 " TTCN_EncDec_ErrorContext::error\n"
896 " (TTCN_EncDec::ET_OMITTED_TAG, \"Encoding a tagged,"
897 " but omitted value.\");\n",
898 cur_choice
->fields
[0].value
,
899 cur_choice
->fields
[0].fields
[
900 cur_choice
->fields
[0].nElements
- 1].typedescr
);
902 /* a temporary object needs to be created for encoding */
903 src
= mputprintf(src
,
905 " RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);\n"
906 " if (temp_leaf != NULL)\n"
907 " new_val.RAW_encode(%s_descr_,*temp_leaf);\n"
909 " TTCN_EncDec_ErrorContext::error\n"
910 " (TTCN_EncDec::ET_OMITTED_TAG, \"Encoding a tagged,"
911 " but omitted value.\");\n",
912 cur_choice
->fields
[0].fields
[
913 cur_choice
->fields
[0].nElements
- 1].type
,
914 cur_choice
->fields
[0].value
,
915 cur_choice
->fields
[0].fields
[
916 cur_choice
->fields
[0].nElements
- 1].typedescr
);
918 src
= mputstr(src
, " free_tree_pos(pr_pos.pos);\n");
920 src
= mputstr(src
, " }\n"
924 src
= mputstr(src
, " default:;\n"
926 if (sdef
->elements
[i
].isOptional
) src
= mputstr(src
, " }\n");
930 if (sdef
->hasRaw
&& sdef
->raw
.presence
.nElements
> 0) {
931 src
= mputstr(src
, " if (");
932 src
= genRawFieldChecker(src
, &sdef
->raw
.presence
, FALSE
);
933 src
= mputstr(src
,") {\n");
934 src
= genRawTagChecker(src
, &sdef
->raw
.presence
);
935 src
= mputstr(src
," }\n");
937 src
= mputstr(src
, " return myleaf.length = encoded_length;\n}\n\n");
940 src
= generate_raw_coding_negtest(src
, sdef
, raw_options
);
944 char *generate_raw_coding_negtest(char *src
, const struct_def
*sdef
,
945 struct raw_option_struct
*raw_options
)
948 const char *name
= sdef
->name
;
949 src
= mputprintf(src
,
950 /* Count the nodes and discover the new node order only. No node creation
952 "int %s::RAW_encode_negtest(const Erroneous_descriptor_t *p_err_descr, "
953 "const TTCN_Typedescriptor_t& /*p_td*/, RAW_enc_tree& myleaf) const\n"
955 " if (!is_bound()) TTCN_EncDec_ErrorContext::error"
956 "(TTCN_EncDec::ET_UNBOUND, \"Encoding an unbound value.\");\n"
957 " int idx_map[%lu];\n"
958 " for (int idx_map_idx = 0; idx_map_idx < %lu; ++idx_map_idx)\n"
959 " idx_map[idx_map_idx] = -1;\n"
961 " int encoded_length = 0;\n"
962 " int num_fields = get_count();\n"
963 " myleaf.isleaf = false;\n"
964 " myleaf.body.node.num_of_nodes = 0;\n"
965 " for (int field_idx = 0; field_idx < num_fields; ++field_idx) {\n"
966 " if ((p_err_descr->omit_before != -1) &&\n"
967 " (field_idx < p_err_descr->omit_before))\n"
969 " const Erroneous_values_t *err_vals = p_err_descr->get_field_err_values(field_idx);\n"
970 " const Erroneous_descriptor_t *emb_descr = p_err_descr->get_field_emb_descr(field_idx);\n"
971 " if (err_vals && err_vals->before)\n"
972 " ++myleaf.body.node.num_of_nodes;\n"
973 " if (err_vals && err_vals->value) {\n"
974 " if (err_vals->value->errval) {\n"
975 " // Field is modified, but it's still there. Otherwise, it's\n"
976 " // initialized to `-1'.\n"
977 " idx_map[field_idx] = -2;\n"
978 " ++myleaf.body.node.num_of_nodes;\n"
981 " if (emb_descr) idx_map[field_idx] = -2;\n"
982 " else idx_map[field_idx] = myleaf.body.node.num_of_nodes;\n"
983 " ++myleaf.body.node.num_of_nodes;\n"
985 " if (err_vals && err_vals->after)\n"
986 " ++myleaf.body.node.num_of_nodes;\n"
987 " if ((p_err_descr->omit_after != -1) &&\n"
988 " (field_idx >= p_err_descr->omit_after))\n"
991 name
, (unsigned long)sdef
->nElements
, (unsigned long)sdef
->nElements
);
993 src
= mputprintf(src
,
994 " myleaf.body.node.nodes =\n"
995 " init_nodes_of_enc_tree(myleaf.body.node.num_of_nodes);\n"
996 " TTCN_EncDec_ErrorContext e_c;\n"
997 " int node_pos = 0;\n"
998 " int next_optional_idx = 0;\n"
999 " const int *my_optional_indexes = get_optional_indexes();\n"
1000 " for (int field_idx = 0; field_idx < num_fields; ++field_idx) {\n"
1001 " boolean is_optional_field = my_optional_indexes &&\n"
1002 " (my_optional_indexes[next_optional_idx] == field_idx);\n"
1003 " if ((p_err_descr->omit_before != -1) &&\n"
1004 " (field_idx < p_err_descr->omit_before)) {\n"
1005 " if (is_optional_field) ++next_optional_idx;\n"
1008 " const Erroneous_values_t *err_vals =\n"
1009 " p_err_descr->get_field_err_values(field_idx);\n"
1010 " if (err_vals && err_vals->before) {\n"
1011 " if (err_vals->before->errval == NULL)\n"
1012 " TTCN_error(\"internal error: erroneous before value missing\");\n"
1013 " if (err_vals->before->raw) {\n"
1014 " myleaf.body.node.nodes[node_pos] =\n"
1015 " new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos),\n"
1016 " node_pos, err_vals->before->errval"
1017 "->get_descriptor()->raw);\n"
1019 " if (err_vals->before->type_descr == NULL)\n"
1020 " TTCN_error(\"internal error: erroneous before typedescriptor "
1022 " myleaf.body.node.nodes[node_pos] =\n"
1023 " new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos),\n"
1024 " node_pos, err_vals->before->type_descr->raw);\n"
1028 " if (err_vals && err_vals->value) {\n"
1029 " if (err_vals->value->errval) {\n"
1030 " e_c.set_msg(\"'%%s'(erroneous value): \", fld_name(field_idx));\n"
1031 " if (err_vals->value->raw) {\n"
1032 " myleaf.body.node.nodes[node_pos] =\n"
1033 " new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos),\n"
1034 " node_pos, err_vals->value->errval"
1035 "->get_descriptor()->raw);\n"
1037 " if (err_vals->value->type_descr == NULL)\n"
1038 " TTCN_error(\"internal error: erroneous value typedescriptor "
1040 " myleaf.body.node.nodes[node_pos] =\n"
1041 " new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos),\n"
1042 " node_pos, err_vals->value->type_descr->raw);\n"
1047 " e_c.set_msg(\"'%%s': \", fld_name(field_idx));\n"
1048 " if (!is_optional_field || get_at(field_idx)->ispresent()) {\n"
1049 " myleaf.body.node.nodes[node_pos] =\n"
1050 " new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos),\n"
1051 " node_pos, fld_descr(field_idx)->raw);\n"
1053 " // `omitted' field.\n"
1054 " myleaf.body.node.nodes[node_pos] = NULL;\n"
1058 " if (err_vals && err_vals->after) {\n"
1059 " if (err_vals->after->errval == NULL)\n"
1060 " TTCN_error(\"internal error: erroneous before value missing\");\n"
1061 " if (err_vals->after->raw) {\n"
1062 " myleaf.body.node.nodes[node_pos] =\n"
1063 " new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos),\n"
1064 " node_pos, err_vals->after->errval"
1065 "->get_descriptor()->raw);\n"
1067 " if (err_vals->after->type_descr == NULL)\n"
1068 " TTCN_error(\"internal error: erroneous after typedescriptor "
1070 " myleaf.body.node.nodes[node_pos] =\n"
1071 " new RAW_enc_tree(true, &myleaf, &(myleaf.curr_pos),\n"
1072 " node_pos, err_vals->after->type_descr->raw);\n"
1076 " if (is_optional_field) ++next_optional_idx;\n"
1077 " if ((p_err_descr->omit_after != -1) &&\n"
1078 " (field_idx >= p_err_descr->omit_after))\n"
1081 /* Handling of the tricky attributes. A simple integer array will be used
1082 to track changes (field positions) in the record.
1083 int idx_map[n_fields] = {
1084 -1 (= field 0. was omitted),
1085 1 (= field 1. can be found at index 1.),
1086 -2 (= field 2. is still at index 2., but its value has changed) }; */
1087 for (i
= 0; i
< sdef
->raw
.ext_bit_goup_num
; i
++) {
1088 if (sdef
->raw
.ext_bit_groups
[i
].ext_bit
!= XDEFNO
) {
1089 src
= mputprintf(src
,
1091 " bool in_between_modified = false;\n"
1092 " for (int idx_map_idx = %d; idx_map_idx <= %d; ++idx_map_idx)\n"
1093 " if (idx_map[idx_map_idx] < 0) {\n"
1094 " in_between_modified = true;\n"
1097 " if (idx_map[%d] < 0 || idx_map[%d] < 0 ||\n"
1098 " %d != idx_map[%d] - idx_map[%d] || in_between_modified) {\n"
1099 " e_c.set_msg(\"Field #%d and/or #%d: \");\n"
1100 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1101 " \"Conflicting negative testing attributes, extension bit "
1102 "group #%d will be ignored\");\n"
1104 " int node_idx = idx_map[%d];\n"
1105 " while (node_idx <= idx_map[%d] &&\n"
1106 " myleaf.body.node.nodes[node_idx] == NULL)\n"
1108 " if (myleaf.body.node.nodes[node_idx]) {\n"
1109 " myleaf.body.node.nodes[node_idx]->ext_bit_handling = 1;\n"
1110 " myleaf.body.node.nodes[node_idx]->ext_bit = %s;\n"
1112 " node_idx = idx_map[%d];\n"
1113 " while (node_idx >= idx_map[%d] &&\n"
1114 " myleaf.body.node.nodes[node_idx] == NULL)\n"
1116 " if (myleaf.body.node.nodes[node_idx])\n"
1117 " myleaf.body.node.nodes[node_idx]->ext_bit_handling += 2;\n"
1120 sdef
->raw
.ext_bit_groups
[i
].from
,
1121 sdef
->raw
.ext_bit_groups
[i
].to
,
1122 sdef
->raw
.ext_bit_groups
[i
].from
,
1123 sdef
->raw
.ext_bit_groups
[i
].to
,
1124 sdef
->raw
.ext_bit_groups
[i
].to
- sdef
->raw
.ext_bit_groups
[i
].from
,
1125 sdef
->raw
.ext_bit_groups
[i
].to
,
1126 sdef
->raw
.ext_bit_groups
[i
].from
,
1127 sdef
->raw
.ext_bit_groups
[i
].from
,
1128 sdef
->raw
.ext_bit_groups
[i
].to
, i
,
1129 sdef
->raw
.ext_bit_groups
[i
].from
,
1130 sdef
->raw
.ext_bit_groups
[i
].to
,
1131 sdef
->raw
.ext_bit_groups
[i
].ext_bit
== XDEFYES
? "EXT_BIT_YES" : "EXT_BIT_REVERSE",
1132 sdef
->raw
.ext_bit_groups
[i
].to
,
1133 sdef
->raw
.ext_bit_groups
[i
].from
);
1136 for (i
= 0; i
< sdef
->nElements
; i
++) {
1137 if (sdef
->elements
[i
].isOptional
) {
1138 src
= mputprintf(src
,
1139 " if (field_%s.ispresent()) {\n",
1140 sdef
->elements
[i
].name
);
1142 if (raw_options
[i
].lengthto
&& sdef
->elements
[i
].raw
.lengthindex
== NULL
1143 && sdef
->elements
[i
].raw
.union_member_num
== 0) {
1144 /* Encoding of lenghto fields. */
1146 src
= mputprintf(src
,
1147 " if (idx_map[%lu] < 0) {\n"
1148 " e_c.set_msg(\"Field '%s': \");\n"
1149 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1150 " \"Conflicting negative testing attributes, LENGTHTO "
1151 "attribute will be ignored\");\n"
1153 " bool negtest_confl_lengthto = false;\n",
1154 (unsigned long)i
, sdef
->elements
[i
].name
);
1155 for (a
= 0; a
< sdef
->elements
[i
].raw
.lengthto_num
; a
++) {
1156 src
= mputprintf(src
,
1157 " if (idx_map[%lu] < 0) {\n"
1158 " negtest_confl_lengthto = true;\n"
1159 " e_c.set_msg(\"Field '%s': \");\n"
1160 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1161 " \"Conflicting negative testing attributes, LENGTHTO "
1162 "attribute will be ignored\");\n"
1164 (unsigned long)sdef
->elements
[i
].raw
.lengthto
[a
],
1165 sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].name
);
1167 src
= mputprintf(src
,
1168 " if (!negtest_confl_lengthto) {\n"
1169 " encoded_length += %d;\n"
1170 " myleaf.body.node.nodes[idx_map[%lu]]->calc = CALC_LENGTH;\n"
1171 " myleaf.body.node.nodes[idx_map[%lu]]->coding_descr = &%s_descr_;\n"
1172 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.lengthto.num_of_fields = %d;\n"
1173 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.lengthto.unit = %d;\n"
1174 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.lengthto.fields = "
1175 "init_lengthto_fields_list(%d);\n"
1176 " myleaf.body.node.nodes[idx_map[%lu]]->length = %d;\n",
1177 sdef
->elements
[i
].raw
.fieldlength
, (unsigned long)i
,
1178 (unsigned long)i
, sdef
->elements
[i
].typedescrname
,
1179 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthto_num
,
1180 (unsigned long)i
, sdef
->elements
[i
].raw
.unit
,
1181 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthto_num
,
1182 (unsigned long)i
, sdef
->elements
[i
].raw
.fieldlength
);
1183 for (a
= 0; a
< sdef
->elements
[i
].raw
.lengthto_num
; a
++) {
1184 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
1185 src
= mputprintf(src
,
1186 " if (field_%s.ispresent()) {\n",
1187 sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].name
);
1189 src
= mputprintf(src
,
1190 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.lengthto.fields[%lu].level = "
1191 "myleaf.body.node.nodes[idx_map[%lu]]->curr_pos.level;\n"
1192 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.lengthto.fields[%lu].pos = "
1193 "myleaf.body.node.nodes[idx_map[%lu]]->curr_pos.pos;\n",
1194 (unsigned long)i
, (unsigned long)a
,
1195 (unsigned long)sdef
->elements
[i
].raw
.lengthto
[a
],
1196 (unsigned long)i
, (unsigned long)a
,
1197 (unsigned long)sdef
->elements
[i
].raw
.lengthto
[a
]);
1198 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
1199 src
= mputprintf(src
,
1201 " myleaf.body.node.nodes[idx_map[%lu]]->"
1202 "calcof.lengthto.fields[%lu].level = 0;\n"
1203 " myleaf.body.node.nodes[idx_map[%lu]]->"
1204 "calcof.lengthto.fields[%lu].pos = 0;\n"
1206 (unsigned long)i
, (unsigned long)a
,
1207 (unsigned long)i
, (unsigned long)a
);
1210 /* Closing inner index check. */
1213 /* Closing outer index check. */
1216 } else if (raw_options
[i
].pointerto
) {
1217 /* Encoding of pointerto fields. */
1218 if (sdef
->elements
[sdef
->elements
[i
].raw
.pointerto
].isOptional
) {
1219 src
= mputprintf(src
,
1220 " if (field_%s.ispresent()) {\n",
1221 sdef
->elements
[sdef
->elements
[i
].raw
.pointerto
].name
);
1223 src
= mputprintf(src
,
1224 " bool in_between_modified_pointerto_%s = false;\n"
1225 " for (int idx_map_idx = %d; idx_map_idx <= %d; ++idx_map_idx) {\n"
1226 " if (idx_map[idx_map_idx] < 0) {\n"
1227 " in_between_modified_pointerto_%s = true;\n"
1231 " if (idx_map[%lu] < 0 || idx_map[%lu] < 0 ||\n"
1232 " %lu != idx_map[%lu] - idx_map[%lu] || in_between_modified_pointerto_%s) {\n"
1233 " e_c.set_msg(\"Field '%s' and/or '%s': \");\n"
1234 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1235 " \"Conflicting negative testing attributes, POINTERTO "
1236 "attribute will be ignored\");\n"
1238 " encoded_length += %d;\n"
1239 " myleaf.body.node.nodes[idx_map[%lu]]->calc = CALC_POINTER;\n"
1240 " myleaf.body.node.nodes[idx_map[%lu]]->coding_descr = &%s_descr_;\n"
1241 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.pointerto.unit = %d;\n"
1242 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.pointerto.ptr_offset = %d;\n"
1243 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.pointerto.ptr_base = %d;\n"
1244 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.pointerto.target.level = "
1245 "myleaf.body.node.nodes[%d]->curr_pos.level;\n"
1246 " myleaf.body.node.nodes[idx_map[%lu]]->calcof.pointerto.target.pos = "
1247 "myleaf.body.node.nodes[%d]->curr_pos.pos;\n"
1248 " myleaf.body.node.nodes[idx_map[%lu]]->length = %d;\n"
1250 sdef
->elements
[i
].name
,
1251 i
, sdef
->elements
[i
].raw
.pointerto
,
1252 sdef
->elements
[i
].name
, (unsigned long)i
,
1253 (unsigned long)sdef
->elements
[i
].raw
.pointerto
,
1254 (unsigned long)sdef
->elements
[i
].raw
.pointerto
- (unsigned long)i
,
1255 (unsigned long)sdef
->elements
[i
].raw
.pointerto
, (unsigned long)i
,
1256 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
1257 sdef
->elements
[sdef
->elements
[i
].raw
.pointerto
].name
,
1258 sdef
->elements
[i
].raw
.fieldlength
, (unsigned long)i
,
1259 (unsigned long)i
, sdef
->elements
[i
].typedescrname
,
1260 (unsigned long)i
, sdef
->elements
[i
].raw
.unit
,
1261 (unsigned long)i
, sdef
->elements
[i
].raw
.ptroffset
,
1262 (unsigned long)i
, sdef
->elements
[i
].raw
.pointerbase
,
1263 (unsigned long)i
, sdef
->elements
[i
].raw
.pointerto
,
1264 (unsigned long)i
, sdef
->elements
[i
].raw
.pointerto
,
1265 (unsigned long)i
, sdef
->elements
[i
].raw
.fieldlength
);
1266 if (sdef
->elements
[sdef
->elements
[i
].raw
.pointerto
].isOptional
) {
1267 src
= mputprintf(src
,
1271 " encoded_length += atm.RAW_encode(%s_descr_, "
1272 "*myleaf.body.node.nodes[idx_map[%lu]]);\n"
1274 sdef
->elements
[i
].typedescrname
, (unsigned long)i
);
1277 /* Encoding of normal fields with no negative testing. Needed for the
1279 src
= mputprintf(src
,
1280 " if (idx_map[%lu] >= 0) "
1281 "encoded_length += field_%s%s.RAW_encode(%s_descr_, "
1282 "*myleaf.body.node.nodes[idx_map[%lu]]);\n",
1283 (unsigned long)i
, sdef
->elements
[i
].name
,
1284 sdef
->elements
[i
].isOptional
? "()" : "",
1285 sdef
->elements
[i
].typedescrname
, (unsigned long)i
);
1287 if (sdef
->elements
[i
].isOptional
) {
1292 for (i
= 0; i
< sdef
->nElements
; i
++) {
1293 /* Fill presence, tag and crosstag. */
1294 if (raw_options
[i
].lengthto
&& sdef
->elements
[i
].raw
.lengthindex
) {
1295 /* Encoding of lenghto fields with lengthindex. */
1297 if (sdef
->elements
[i
].isOptional
) {
1298 src
= mputprintf(src
,
1299 " if (field_%s.ispresent()) {\n",
1300 sdef
->elements
[i
].name
);
1302 src
= mputprintf(src
,
1303 " if (idx_map[%lu] < 0) {\n"
1304 " e_c.set_msg(\"Field '%s': \");\n"
1305 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1306 " \"Conflicting negative testing attributes, LENGTHTO/LENGTHINDEX "
1307 "attribute will be ignored\");\n"
1309 " if (myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]) {\n"
1310 " bool negtest_confl_lengthto = false;\n",
1311 (unsigned long)i
, sdef
->elements
[i
].name
, (unsigned long)i
,
1312 sdef
->elements
[i
].raw
.lengthindex
->nthfield
);
1313 for (a
= 0; a
< sdef
->elements
[i
].raw
.lengthto_num
; a
++) {
1314 src
= mputprintf(src
,
1315 " if (idx_map[%lu] < 0) {\n"
1316 " negtest_confl_lengthto = true;\n"
1317 " e_c.set_msg(\"Field '%s': \");\n"
1318 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1319 " \"Conflicting negative testing attributes, LENGTHTO/LENGTHINDEX "
1320 "attribute will be ignored\");\n"
1322 (unsigned long)sdef
->elements
[i
].raw
.lengthto
[a
],
1323 sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].name
);
1325 src
= mputprintf(src
,
1326 " if (!negtest_confl_lengthto) {\n"
1327 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]->"
1328 "calc = CALC_LENGTH;\n"
1329 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]->"
1330 "coding_descr = &%s_descr_;\n"
1331 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]->"
1332 "calcof.lengthto.num_of_fields = %d;\n"
1333 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]->"
1334 "calcof.lengthto.unit = %d;\n"
1335 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]->"
1336 "calcof.lengthto.fields = init_lengthto_fields_list(%d);\n",
1337 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
1338 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
1339 sdef
->elements
[i
].raw
.lengthindex
->typedescr
,
1340 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
1341 sdef
->elements
[i
].raw
.lengthto_num
,
1342 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
1343 sdef
->elements
[i
].raw
.unit
,
1344 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
,
1345 sdef
->elements
[i
].raw
.lengthto_num
);
1346 for (a
= 0; a
< sdef
->elements
[i
].raw
.lengthto_num
; a
++) {
1347 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
1348 src
= mputprintf(src
,
1349 " if (field_%s.ispresent()) {\n",
1350 sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].name
);
1352 src
= mputprintf(src
,
1353 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]"
1354 "->calcof.lengthto.fields[%d].level = "
1355 "myleaf.body.node.nodes[idx_map[%d]]->curr_pos.level;\n"
1356 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]"
1357 "->calcof.lengthto.fields[%d].pos = "
1358 "myleaf.body.node.nodes[idx_map[%d]]->curr_pos.pos;\n",
1359 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
, a
,
1360 sdef
->elements
[i
].raw
.lengthto
[a
], (unsigned long)i
,
1361 sdef
->elements
[i
].raw
.lengthindex
->nthfield
, a
,
1362 sdef
->elements
[i
].raw
.lengthto
[a
]);
1363 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
1364 src
= mputprintf(src
,
1366 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]->"
1367 "calcof.lengthto.fields[%d].level = 0;\n"
1368 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[%d]->"
1369 "calcof.lengthto.fields[%d].pos = 0;\n"
1371 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
, a
,
1372 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthindex
->nthfield
, a
);
1375 /* Closing index check. */
1378 src
= mputstr(src
, " }\n }\n");
1379 if (sdef
->elements
[i
].isOptional
) {
1380 src
= mputstr(src
, " }\n");
1383 if (raw_options
[i
].lengthto
&& sdef
->elements
[i
].raw
.union_member_num
) {
1384 /* Encoding of lenghto fields. */
1386 if (sdef
->elements
[i
].isOptional
) {
1387 src
= mputprintf(src
,
1388 " if (field_%s.ispresent()) ", sdef
->elements
[i
].name
);
1390 src
= mputprintf(src
,
1392 " if (idx_map[%lu] < 0) {\n"
1393 " e_c.set_msg(\"Field '%s': \");\n"
1394 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1395 " \"Conflicting negative testing attributes, LENGTHTO/LENGTHINDEX "
1396 "attribute will be ignored\");\n"
1398 " bool negtest_confl_lengthto = false;\n",
1399 (unsigned long)i
, sdef
->elements
[i
].name
);
1400 for (a
= 0; a
< sdef
->elements
[i
].raw
.lengthto_num
; a
++) {
1401 src
= mputprintf(src
,
1402 " if (idx_map[%lu] < 0) {\n"
1403 " negtest_confl_lengthto = true;\n"
1404 " e_c.set_msg(\"Field '%s': \");\n"
1405 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1406 " \"Conflicting negative testing attributes, LENGTHTO/LENGTHINDEX "
1407 "attribute will be ignored\");\n"
1409 (unsigned long)sdef
->elements
[i
].raw
.lengthto
[a
],
1410 sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].name
);
1412 src
= mputprintf(src
,
1413 " if (!negtest_confl_lengthto) {\n"
1414 " int sel_field = 0;\n"
1415 " while (myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[sel_field] == NULL) "
1416 "{ sel_field++; }\n"
1417 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[sel_field]->"
1418 "calc = CALC_LENGTH;\n"
1419 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[sel_field]->"
1420 "calcof.lengthto.num_of_fields = %d;\n"
1421 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[sel_field]->"
1422 "calcof.lengthto.unit = %d;\n"
1423 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[sel_field]->"
1424 "calcof.lengthto.fields = init_lengthto_fields_list(%d);\n",
1425 (unsigned long)i
, (unsigned long)i
,
1426 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthto_num
,
1427 (unsigned long)i
, sdef
->elements
[i
].raw
.unit
,
1428 (unsigned long)i
, sdef
->elements
[i
].raw
.lengthto_num
);
1429 for (a
= 0; a
< sdef
->elements
[i
].raw
.lengthto_num
; a
++) {
1430 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
1431 src
= mputprintf(src
,
1432 " if (field_%s.ispresent()) {\n",
1433 sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].name
);
1435 src
= mputprintf(src
,
1436 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[sel_field]"
1437 "->calcof.lengthto.fields[%d].level = "
1438 "myleaf.body.node.nodes[%d]->curr_pos.level;\n"
1439 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[sel_field]"
1440 "->calcof.lengthto.fields[%d].pos = "
1441 "myleaf.body.node.nodes[%d]->curr_pos.pos;\n",
1442 (unsigned long)i
, a
, sdef
->elements
[i
].raw
.lengthto
[a
],
1443 (unsigned long)i
, a
, sdef
->elements
[i
].raw
.lengthto
[a
]);
1444 if (sdef
->elements
[sdef
->elements
[i
].raw
.lengthto
[a
]].isOptional
) {
1445 src
= mputprintf(src
,
1447 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[sel_field]"
1448 "->calcof.lengthto.fields[%d].level = 0;\n"
1449 " myleaf.body.node.nodes[idx_map[%lu]]->body.node.nodes[sel_field]"
1450 "->calcof.lengthto.fields[%d].pos = 0;\n"
1452 (unsigned long)i
, a
,
1453 (unsigned long)i
, a
);
1456 /* Closing inner index check. */
1459 /* Closing outer index check. */
1462 /* Closing ispresent or local block. */
1466 if (raw_options
[i
].tag_type
&&
1467 sdef
->raw
.taglist
.list
[raw_options
[i
].tag_type
- 1].nElements
) {
1468 /* Plain, old tag. */
1469 rawAST_coding_taglist
*cur_choice
=
1470 sdef
->raw
.taglist
.list
+ raw_options
[i
].tag_type
- 1;
1471 src
= mputprintf(src
,
1472 " bool negtest_confl_tag_%s = false;\n"
1473 " if (idx_map[%lu] < 0) {\n"
1474 " negtest_confl_tag_%s = true;\n"
1475 " e_c.set_msg(\"Field '%s': \");\n"
1476 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1477 " \"Conflicting negative testing attributes, TAG attribute will "
1480 sdef
->elements
[i
].name
, (unsigned long)i
, sdef
->elements
[i
].name
,
1481 sdef
->elements
[i
].name
);
1482 src
= mputprintf(src
, " if (!negtest_confl_tag_%s && (",
1483 sdef
->elements
[i
].name
);
1484 if (sdef
->elements
[i
].isOptional
) {
1485 src
= mputprintf(src
, "field_%s.ispresent() && (", sdef
->elements
[i
].name
);
1487 src
= genRawFieldChecker(src
, cur_choice
, FALSE
);
1488 if (sdef
->elements
[i
].isOptional
) src
= mputstr(src
, ")");
1489 src
= mputstr(src
,")) {\n");
1490 src
= genRawTagChecker(src
, cur_choice
);
1491 src
= mputstr(src
," }\n");
1493 if (sdef
->elements
[i
].hasRaw
&& sdef
->elements
[i
].raw
.presence
.nElements
) {
1494 /* Presence attribute for fields. */
1495 int taglist_idx
, field_idx
;
1496 /* The optional field itself. */
1497 src
= mputprintf(src
,
1498 " bool negtest_confl_presence_%s = false;\n"
1499 " if (idx_map[%lu] < 0) {\n"
1500 " negtest_confl_presence_%s = true;\n"
1501 " e_c.set_msg(\"Field '%s': \");\n"
1502 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1503 " \"Conflicting negative testing attributes, PRESENCE attribute "
1504 "will be ignored\");\n"
1506 sdef
->elements
[i
].name
, (unsigned long)i
, sdef
->elements
[i
].name
,
1507 sdef
->elements
[i
].name
);
1508 /* Check the referenced fields. */
1509 for (taglist_idx
= 0;
1510 taglist_idx
< sdef
->elements
[i
].raw
.presence
.nElements
; ++taglist_idx
) {
1511 rawAST_coding_field_list
*fields
=
1512 sdef
->elements
[i
].raw
.presence
.fields
+ taglist_idx
;
1513 for (field_idx
= 0; field_idx
< fields
->nElements
; ++field_idx
) {
1514 /* The top level field is enough. >0 index is for subrefs. */
1515 if (field_idx
== 0) {
1516 rawAST_coding_fields
*field
= fields
->fields
+ field_idx
;
1517 src
= mputprintf(src
,
1518 " if (idx_map[%d] < 0) {\n"
1519 " negtest_confl_presence_%s = true;\n"
1520 " e_c.set_msg(\"Field '%s': \");\n"
1521 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1522 " \"Conflicting negative testing attributes, PRESENCE attribute "
1523 "will be ignored\");\n"
1525 field
->nthfield
, sdef
->elements
[i
].name
, field
->nthfieldname
);
1532 src
= mputprintf(src
, " if (!negtest_confl_presence_%s && (",
1533 sdef
->elements
[i
].name
);
1534 if (sdef
->elements
[i
].isOptional
) {
1535 src
= mputprintf(src
, "field_%s.ispresent() && (", sdef
->elements
[i
].name
);
1537 src
= genRawFieldChecker(src
, &sdef
->elements
[i
].raw
.presence
, FALSE
);
1538 if (sdef
->elements
[i
].isOptional
) src
= mputstr(src
, ")");
1539 src
= mputstr(src
, ")) {\n");
1540 src
= genRawTagChecker(src
, &sdef
->elements
[i
].raw
.presence
);
1541 src
= mputstr(src
, " }\n");
1543 if (sdef
->elements
[i
].hasRaw
&&
1544 sdef
->elements
[i
].raw
.crosstaglist
.nElements
) {
1547 /* The union field itself. */
1548 src
= mputprintf(src
,
1549 " if (idx_map[%lu] < 0) {\n"
1550 " e_c.set_msg(\"Field '%s': \");\n"
1551 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1552 " \"Conflicting negative testing attributes, CROSSTAG attribute "
1553 "will be ignored\");\n"
1555 (unsigned long)i
, sdef
->elements
[i
].name
);
1556 if (sdef
->elements
[i
].isOptional
) {
1557 src
= mputprintf(src
,
1558 " if (field_%s.ispresent()) {\n",
1559 sdef
->elements
[i
].name
);
1561 src
= mputprintf(src
,
1562 " switch (field_%s%s.get_selection()) {\n",
1563 sdef
->elements
[i
].name
,sdef
->elements
[i
].isOptional
? "()" : "");
1564 for (a
= 0; a
< sdef
->elements
[i
].raw
.crosstaglist
.nElements
; a
++) {
1565 rawAST_coding_taglist
*cur_choice
=
1566 sdef
->elements
[i
].raw
.crosstaglist
.list
+ a
;
1567 if (cur_choice
->nElements
> 0) {
1568 int taglist_idx
, field_idx
;
1569 src
= mputprintf(src
,
1571 " bool negtest_confl_crosstag = false;\n",
1572 sdef
->elements
[i
].type
, "::ALT_",
1573 cur_choice
->fieldName
);
1574 for (taglist_idx
= 0;
1575 taglist_idx
< cur_choice
->nElements
; ++taglist_idx
) {
1576 rawAST_coding_field_list
*fields
= cur_choice
->fields
+ taglist_idx
;
1577 for (field_idx
= 0; field_idx
< fields
->nElements
; ++field_idx
) {
1578 rawAST_coding_fields
*field
= fields
->fields
+ field_idx
;
1579 if (field_idx
== 0) {
1580 src
= mputprintf(src
,
1581 " if (idx_map[%d] < 0) {\n"
1582 " negtest_confl_crosstag = true;\n"
1583 " e_c.set_msg(\"Field '%s': \");\n"
1584 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1585 " \"Conflicting negative testing attributes, CROSSTAG attribute "
1586 "will be ignored\");\n"
1588 field
->nthfield
, field
->nthfieldname
);
1594 src
= mputstr(src
, " if (!negtest_confl_crosstag && (");
1595 src
= genRawFieldChecker(src
, cur_choice
, FALSE
);
1596 src
= mputstr(src
, ")) {\n");
1597 if (!strcmp(cur_choice
->fields
[0].value
, "OMIT_VALUE")) {
1598 if (cur_choice
->fields
[0].nElements
!= 1)
1599 NOTSUPP("omit value with multiple fields in CROSSTAG");
1600 /* eliminating the corresponding encoded leaf, which will have
1601 the same effect as if the referred field had been omit */
1602 src
= mputprintf(src
,
1603 " encoded_length -= myleaf.body.node.nodes[%d]->length;\n"
1604 " delete myleaf.body.node.nodes[%d];\n"
1605 " myleaf.body.node.nodes[%d] = NULL;\n",
1606 cur_choice
->fields
[0].fields
[0].nthfield
,
1607 cur_choice
->fields
[0].fields
[0].nthfield
,
1608 cur_choice
->fields
[0].fields
[0].nthfield
);
1611 src
= mputprintf(src
,
1612 " RAW_enc_tr_pos pr_pos;\n"
1613 " pr_pos.level = myleaf.curr_pos.level + %d;\n"
1614 " int new_pos[] = { ",
1615 cur_choice
->fields
[0].nElements
);
1616 for (ll
= 0; ll
< cur_choice
->fields
[0].nElements
; ll
++) {
1617 if (ll
> 0) src
= mputstr(src
, ", ");
1618 src
= mputprintf(src
, "%d",
1619 cur_choice
->fields
[0].fields
[ll
].nthfield
);
1621 src
= mputprintf(src
, " };\n"
1622 " pr_pos.pos = init_new_tree_pos(myleaf.curr_pos, %d, "
1624 cur_choice
->fields
[0].nElements
);
1625 if (cur_choice
->fields
[0].value
[0] == ' ') {
1626 /* the value is a string literal (the encoder can be called
1627 on that object directly */
1628 src
= mputprintf(src
,
1629 " RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);\n"
1630 " if (temp_leaf != NULL)\n"
1631 " %s.RAW_encode(%s_descr_, *temp_leaf);\n"
1633 " TTCN_EncDec_ErrorContext::error\n"
1634 " (TTCN_EncDec::ET_OMITTED_TAG, \"Encoding a tagged, "
1635 "but omitted value.\");\n",
1636 cur_choice
->fields
[0].value
,
1637 cur_choice
->fields
[0].fields
[
1638 cur_choice
->fields
[0].nElements
- 1].typedescr
);
1640 /* a temporary object needs to be created for encoding */
1641 src
= mputprintf(src
,
1642 " %s new_val(%s);\n"
1643 " RAW_enc_tree* temp_leaf = myleaf.get_node(pr_pos);\n"
1644 " if (temp_leaf != NULL)\n"
1645 " new_val.RAW_encode(%s_descr_, *temp_leaf);\n"
1647 " TTCN_EncDec_ErrorContext::error\n"
1648 " (TTCN_EncDec::ET_OMITTED_TAG, \"Encoding a tagged, "
1649 "but omitted value.\");\n",
1650 cur_choice
->fields
[0].fields
[
1651 cur_choice
->fields
[0].nElements
- 1].type
,
1652 cur_choice
->fields
[0].value
,
1653 cur_choice
->fields
[0].fields
[
1654 cur_choice
->fields
[0].nElements
- 1].typedescr
);
1656 src
= mputstr(src
, " free_tree_pos(pr_pos.pos);\n");
1658 src
= mputstr(src
, " }\n"
1662 src
= mputstr(src
, " default:;\n"
1664 if (sdef
->elements
[i
].isOptional
) src
= mputstr(src
, " }\n");
1665 src
= mputstr(src
, " }\n");
1668 src
= mputprintf(src
,
1670 " next_optional_idx = 0;\n"
1671 " for (int field_idx = 0; field_idx < num_fields; ++field_idx) {\n"
1672 " boolean is_optional_field = my_optional_indexes &&\n"
1673 " (my_optional_indexes[next_optional_idx] == field_idx);\n"
1674 " if ((p_err_descr->omit_before != -1) &&\n"
1675 " (field_idx < p_err_descr->omit_before)) {\n"
1676 " if (is_optional_field) ++next_optional_idx;\n"
1679 " const Erroneous_values_t *err_vals = p_err_descr->get_field_err_values(field_idx);\n"
1680 " const Erroneous_descriptor_t *emb_descr = p_err_descr->get_field_emb_descr(field_idx);\n"
1681 " if (err_vals && err_vals->before) {\n"
1682 " if (err_vals->before->errval == NULL)\n"
1683 " TTCN_error(\"internal error: erroneous before value missing\");\n"
1684 " if (err_vals->before->raw) {\n"
1685 " encoded_length += err_vals->before->errval->"
1686 "RAW_encode_negtest_raw(*myleaf.body.node.nodes[node_pos++]);\n"
1688 " if (err_vals->before->type_descr == NULL)\n"
1689 " TTCN_error(\"internal error: erroneous before typedescriptor missing\");\n"
1690 " encoded_length += err_vals->before->errval->RAW_encode(*(err_vals->before->type_descr),\n"
1691 " *myleaf.body.node.nodes[node_pos++]);\n"
1694 " if (err_vals && err_vals->value) {\n"
1695 " if (err_vals->value->errval) {\n"
1696 " e_c.set_msg(\"'%%s'(erroneous value): \", fld_name(field_idx));\n"
1697 " if (err_vals->value->raw) {\n"
1698 " encoded_length += err_vals->value->errval->"
1699 "RAW_encode_negtest_raw(*myleaf.body.node.nodes[node_pos++]);\n"
1701 " if (err_vals->value->type_descr == NULL)\n"
1702 " TTCN_error(\"internal error: erroneous value typedescriptor missing\");\n"
1703 " encoded_length += err_vals->value->errval->"
1704 "RAW_encode(*(err_vals->value->type_descr), *myleaf.body.node.nodes[node_pos++]);\n"
1708 " e_c.set_msg(\"'%%s': \", fld_name(field_idx));\n"
1709 " if (!is_optional_field || get_at(field_idx)->ispresent()) {\n"
1710 " const Base_Type *curr_field = is_optional_field "
1711 "? get_at(field_idx)->get_opt_value() : get_at(field_idx);\n"
1712 " if (emb_descr) {\n"
1713 " encoded_length += curr_field\n"
1714 " ->RAW_encode_negtest(emb_descr, *fld_descr(field_idx),\n"
1715 " *myleaf.body.node.nodes[node_pos]);\n"
1718 " // `omitted' field.\n"
1719 " myleaf.body.node.nodes[node_pos] = NULL;\n"
1723 " if (err_vals && err_vals->after) {\n"
1724 " if (err_vals->after->errval == NULL)\n"
1725 " TTCN_error(\"internal error: erroneous before value missing\");\n"
1726 " if (err_vals->after->raw) {\n"
1727 " encoded_length += err_vals->after->errval->"
1728 "RAW_encode_negtest_raw(*myleaf.body.node.nodes[node_pos++]);\n"
1730 " if (err_vals->after->type_descr == NULL)\n"
1731 " TTCN_error(\"internal error: erroneous after typedescriptor missing\");\n"
1732 " encoded_length += err_vals->after->errval->"
1733 "RAW_encode(*(err_vals->after->type_descr), *myleaf.body.node.nodes[node_pos++]);\n"
1736 " if (is_optional_field) ++next_optional_idx;\n"
1737 " if ((p_err_descr->omit_after != -1) &&\n"
1738 " (field_idx >= p_err_descr->omit_after))\n"
1741 /* Presence for the whole record. */
1742 if (sdef
->hasRaw
&& sdef
->raw
.presence
.nElements
> 0) {
1743 /* Check the referenced fields. */
1744 int taglist_idx
, field_idx
;
1745 src
= mputstr(src
, " bool negtest_confl_presence = false;\n");
1746 for (taglist_idx
= 0; taglist_idx
< sdef
->raw
.presence
.nElements
; ++taglist_idx
) {
1747 rawAST_coding_field_list
*fields
=
1748 sdef
->raw
.presence
.fields
+ taglist_idx
;
1749 for (field_idx
= 0; field_idx
< fields
->nElements
; ++field_idx
) {
1750 if (field_idx
== 0) {
1751 rawAST_coding_fields
*field
= fields
->fields
+ field_idx
;
1752 src
= mputprintf(src
,
1753 " if (idx_map[%d] < 0) {\n"
1754 " negtest_confl_presence = true;\n"
1755 " e_c.set_msg(\"Field '%s': \");\n"
1756 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1757 " \"Conflicting negative testing attributes, PRESENCE attribute "
1758 "will be ignored\");\n"
1760 field
->nthfield
, field
->nthfieldname
);
1766 src
= mputstr(src
, " if (!negtest_confl_presence && (");
1767 src
= genRawFieldChecker(src
, &sdef
->raw
.presence
, FALSE
);
1768 src
= mputstr(src
,")) {\n");
1769 src
= genRawTagChecker(src
, &sdef
->raw
.presence
);
1770 src
= mputstr(src
," }\n");
1773 " return myleaf.length = encoded_length;\n"
1778 void gen_xer(const struct_def
*sdef
, char **pdef
, char **psrc
)
1779 { /* XERSTUFF codegen for record/SEQUENCE */
1781 char *def
= *pdef
, *src
= *psrc
;
1782 const char * const name
= sdef
->name
;
1785 * NOTE! Decisions based on the coding instructions of the components
1786 * (e.g. number of attributes) can be made at compile time.
1787 * Decisions on coding instructions of the record itself (e.g. D-F-E,
1788 * EMBED-VALUES, USE-NIL, USE-ORDER) __must__ be postponed to run-time,
1789 * because these can be applied to type references,
1790 * which will not be visible when the code is generated.
1793 /* Number of fields with ATTRIBUTE, includes ANY-ATTRIBUTES */
1794 size_t num_attributes
= 0;
1796 /* index of USE-ORDER member, which may be bumped into second place by EMBED-VALUES */
1797 size_t uo
= (sdef
->xerEmbedValuesPossible
!=0);
1799 /* start_at is the index of the first "real" member of the record */
1800 size_t start_at
= uo
+ (sdef
->xerUseOrderPossible
!= 0);
1802 /* Number of optional non-attributes */
1803 size_t n_opt_elements
= 0;
1805 const boolean want_namespaces
= !sdef
->isASN1
/* TODO remove this when ASN.1 gets EXER */;
1808 /* Find the number of attributes (compile time) */
1809 for (i
= 0; i
< sdef
->nElements
; ++i
) {
1810 if (sdef
->elements
[i
].xerAttribute
) {
1813 else if (sdef
->elements
[i
].xerAnyKind
& ANY_ATTRIB_BIT
) {
1814 ++num_attributes
; /* ANY-ATTRIBUTES also included with attributes */
1816 /* If the first member is ANY-ATTRIBUTES, then xerEmbedValuesPossible
1817 * is merely an illusion and USE-ORDER is not possible. */
1822 else /* not attribute */ if (sdef
->elements
[i
].isOptional
) {
1827 /* Write some helper functions */
1829 "char **collect_ns(const XERdescriptor_t& p_td, size_t& num_ns, bool& def_ns) const;\n");
1831 src
= mputprintf(src
,
1832 "char ** %s::collect_ns(const XERdescriptor_t& p_td, size_t& num_ns, bool& def_ns) const {\n"
1833 " size_t num_collected;\n"
1834 " char **collected_ns = Base_Type::collect_ns(p_td, num_collected, def_ns);\n"
1835 /* The above might throw but then nothing was allocated. */
1838 /* Collect namespaces from the "non-special" members (incl. attributes) */
1839 if (start_at
< sdef
->nElements
) src
= mputstr(src
,
1842 " size_t num_new;\n"
1843 " bool def_ns_1 = false;\n");
1844 for (i
= start_at
; i
< sdef
->nElements
; ++i
) {
1845 src
= mputprintf(src
,
1846 " new_ns = field_%s.collect_ns(%s_xer_, num_new, def_ns);\n"
1847 " merge_ns(collected_ns, num_collected, new_ns, num_new);\n"
1848 " def_ns = def_ns || def_ns_1;\n" /* alas, no ||= */
1849 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typegen
1852 if (sdef
->xerUseNilPossible
) {
1853 src
= mputprintf(src
,
1854 " if((p_td.xer_bits & USE_NIL) && !field_%s.ispresent()) {\n" /* "nil" attribute to be written*/
1855 " collected_ns = (char**)Realloc(collected_ns, sizeof(char*) * ++num_collected);\n"
1856 " const namespace_t *c_ns = p_td.my_module->get_controlns();\n"
1857 " collected_ns[num_collected-1] = mprintf(\" xmlns:%%s='%%s'\", c_ns->px, c_ns->ns);\n"
1859 , sdef
->elements
[sdef
->nElements
-1].name
1862 if (start_at
< sdef
->nElements
) src
= mputstr(src
,
1865 /* Probably a TC_Error thrown from field_%s->collect_ns() if e.g.
1866 * encoding an unbound value. */
1867 " while (num_collected > 0) Free(collected_ns[--num_collected]);\n"
1868 " Free(collected_ns);\n"
1874 " num_ns = num_collected;\n"
1875 " return collected_ns;\n"
1879 src
= mputprintf(src
,
1880 "boolean %s::can_start(const char *name, const char *uri, const XERdescriptor_t& xd, unsigned int flavor) {\n"
1881 " boolean e_xer = is_exer(flavor &= ~XER_RECOF);\n"
1882 " 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"
1885 for (i
= start_at
; i
< sdef
->nElements
; ++i
) {
1886 src
= mputprintf(src
,
1887 " else if (%s::can_start(name, uri, %s_xer_, flavor)) return true;\n"
1888 /* Here we know for sure it's exer */
1889 , sdef
->elements
[i
].type
1890 , sdef
->elements
[i
].typegen
1892 if (!sdef
->elements
[i
].isOptional
) break;
1893 /* The last component with which it can begin is the first non-optional.
1894 * Does that sentence makes sense to you ? */
1896 src
= mputstr(src
, " return false;\n}\n\n");
1898 /* * * * * * * * * * XER_encode * * * * * * * * * * * * * * */
1899 src
= mputprintf(src
,
1900 "int %s::XER_encode(const XERdescriptor_t& p_td, "
1901 "TTCN_Buffer& p_buf, unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const\n"
1903 " if (!is_bound()) TTCN_EncDec_ErrorContext::error"
1904 "(TTCN_EncDec::ET_UNBOUND, \"Encoding an unbound value.\");\n"
1905 " TTCN_EncDec_ErrorContext ec_0(\"Component '\");\n"
1906 " TTCN_EncDec_ErrorContext ec_1;\n"
1907 " int encoded_length=(int)p_buf.get_len();\n"
1908 " int e_xer = is_exer(p_flavor);\n"
1909 " const boolean omit_tag = e_xer && p_indent "
1910 "&& ((p_td.xer_bits & (UNTAGGED|XER_ATTRIBUTE)) || (p_flavor & (USE_NIL|USE_TYPE_ATTR)));\n"
1911 " if (e_xer && (p_td.xer_bits & EMBED_VALUES)) p_flavor |= XER_CANONICAL;\n"
1912 " int is_indented = !is_canonical(p_flavor);\n"
1915 if (want_namespaces
&& !(num_attributes
|sdef
->xerUseQName
)) src
= mputstr(src
,
1916 " const boolean need_control_ns = (p_td.xer_bits & (USE_NIL));\n");
1918 if (start_at
< sdef
->nElements
) { /* there _are_ non-special members */
1920 " size_t num_collected = 0;\n"
1921 " char **collected_ns = NULL;\n"
1922 " bool def_ns = false;\n"
1924 " if (p_indent == 0) {\n" /* top-level */
1925 " collected_ns = collect_ns(p_td, num_collected, def_ns);\n" /* our own ns */
1927 " else if ((p_flavor & DEF_NS_SQUASHED) && p_td.my_module && p_td.ns_index != -1){\n"
1928 " const namespace_t * ns = p_td.my_module->get_ns(p_td.ns_index);\n"
1929 " if (*ns->px == '\\0') {\n"
1930 " collected_ns = Base_Type::collect_ns(p_td, num_collected, def_ns);\n"
1937 if (want_namespaces
) {
1939 " const boolean empty_ns_hack = e_xer && !omit_tag && (p_indent > 0)\n"
1940 " && (p_td.xer_bits & FORM_UNQUALIFIED)\n"
1941 " && p_td.my_module && p_td.ns_index != -1\n"
1942 " && *p_td.my_module->get_ns(p_td.ns_index)->px == '\\0';\n"
1945 src
= mputstr(src
, " const boolean delay_close = e_xer");
1946 if (!(num_attributes
| sdef
->xerUseQName
)) {
1947 src
= mputprintf(src
, " && (need_control_ns%s || empty_ns_hack)",
1948 (start_at
< sdef
->nElements
) ? " || num_collected" : "");
1950 src
= mputstr(src
, ";\n");
1954 { /* write start tag */
1956 * lose the \n if : not indenting or (single untagged(*) or attributes (*)) AND e_xer
1957 * lose the > if attributes are present (*) AND e_xer
1959 src
= mputprintf(src
,
1960 " size_t chopped_chars = 0;\n"
1961 " if (!omit_tag) {\n"
1962 " if (is_indented) do_indent(p_buf, p_indent);\n"
1963 " p_buf.put_c('<');\n"
1964 " if (e_xer) write_ns_prefix(p_td, p_buf);\n"
1965 " p_buf.put_s((size_t)p_td.namelens[e_xer]%s-(!is_indented%s), "
1966 "(cbyte*)p_td.names[e_xer]);\n"
1968 " else if (p_flavor & USE_TYPE_ATTR) {\n"
1969 " size_t buf_len = p_buf.get_len();\n"
1970 " const unsigned char * const buf_data = p_buf.get_data();\n"
1971 " if (buf_data[buf_len-1-chopped_chars] == '\\n') ++chopped_chars;\n"
1972 " if (buf_data[buf_len-1-chopped_chars] == '>' ) ++chopped_chars;\n"
1973 " if (chopped_chars) {\n"
1974 " p_buf.increase_length(-chopped_chars);\n"
1977 , (want_namespaces
? "-(delay_close || (e_xer && (p_td.xer_bits & HAS_1UNTAGGED)))" : "")
1978 , (want_namespaces
? " || delay_close" : ""));
1981 src
= mputprintf(src
,
1982 " int sub_len=0%s;\n"
1983 " p_flavor &= XER_MASK;\n",
1984 num_attributes
? ", tmp_len; (void)tmp_len" : "");
1986 if (sdef
->xerUseQName
) {
1987 src
= mputprintf(src
,
1988 " if (e_xer && (p_td.xer_bits & USE_QNAME)) {\n"
1989 " if (field_%s.is_value()) {\n"
1990 " p_buf.put_s(11, (cbyte*)\" xmlns:b0='\");\n"
1991 " field_%s.XER_encode(%s_xer_, p_buf, p_flavor | XER_LIST, p_indent+1, 0);\n"
1992 " p_buf.put_c('\\'');\n"
1994 " if (p_td.xer_bits & XER_ATTRIBUTE) begin_attribute(p_td, p_buf);\n"
1995 " else p_buf.put_c('>');\n"
1996 " if (field_%s.is_value()) {\n"
1997 " p_buf.put_s(3, (cbyte*)\"b0:\");\n"
2000 " sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor | XER_LIST, p_indent+1, 0);\n"
2001 " if (p_td.xer_bits & XER_ATTRIBUTE) p_buf.put_c('\\'');\n"
2002 " } else" /* no newline */
2003 , sdef
->elements
[0].name
2004 , sdef
->elements
[0].name
, sdef
->elements
[0].typegen
2005 , sdef
->elements
[0].name
2006 , sdef
->elements
[1].name
, sdef
->elements
[1].typegen
2009 src
= mputstr(src
, " { // !QN\n");
2011 /* First, the EMBED-VALUES member as an ordinary member if not doing EXER */
2012 if (sdef
->xerEmbedValuesPossible
) {
2013 src
= mputprintf(src
,
2014 " if (!e_xer && (p_td.xer_bits & EMBED_VALUES)) {\n"
2015 " ec_1.set_msg(\"%s': \");\n"
2016 " sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1, 0);\n"
2018 , sdef
->elements
[0].dispname
2019 , sdef
->elements
[0].name
, sdef
->elements
[0].typegen
2022 /* Then, the USE-ORDER member as an ordinary member when !EXER */
2023 if (sdef
->xerUseOrderPossible
) {
2024 src
= mputprintf(src
,
2025 " if (!e_xer && (p_td.xer_bits & USE_ORDER)) {\n"
2026 " sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1, 0);\n"
2028 , sdef
->elements
[uo
].name
, sdef
->elements
[uo
].typegen
2032 if (start_at
+num_attributes
> sdef
->nElements
) FATAL_ERROR("defRecordClass1");
2034 if (want_namespaces
&& (start_at
< sdef
->nElements
)) {
2036 " if (e_xer && num_collected) {\n"
2038 " for (num_ns = 0; num_ns < num_collected; ++num_ns) {\n"
2039 " p_buf.put_s(strlen(collected_ns[num_ns]), (cbyte*)collected_ns[num_ns]);\n"
2040 " Free(collected_ns[num_ns]);\n"
2042 " Free(collected_ns);\n"
2045 " p_flavor &= ~DEF_NS_SQUASHED;\n"
2046 " p_flavor |= DEF_NS_PRESENT;\n"
2048 " else if (empty_ns_hack) {\n"
2049 " p_buf.put_s(9, (cbyte*)\" xmlns=''\");\n"
2050 " p_flavor &= ~DEF_NS_PRESENT;\n"
2051 " p_flavor |= DEF_NS_SQUASHED;\n"
2055 /* Then, all the attributes (not added to sub_len) */
2056 for ( i
= start_at
; i
< start_at
+ num_attributes
; ++i
) {
2057 /* If the first component is a record-of with ANY-ATTRIBUTES,
2058 * it has been taken care of because it looked like an EMBED-VALUES */
2059 if (i
==0 && sdef
->xerEmbedValuesPossible
&& (sdef
->elements
[i
].xerAnyKind
& ANY_ATTRIB_BIT
)) continue ;
2060 src
= mputprintf(src
,
2061 " ec_1.set_msg(\"%s': \");\n"
2062 " tmp_len = field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1, 0);\n"
2063 " %ssub_len += tmp_len;\n" /* do not add if attribute and EXER */
2064 , sdef
->elements
[i
].dispname
2065 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typegen
2066 , sdef
->elements
[i
].xerAttribute
? "if (!e_xer) " : ""
2070 if (sdef
->xerUseNilPossible
) {
2071 src
= mputprintf(src
,
2072 " bool nil_attribute = e_xer && (p_td.xer_bits & USE_NIL) && !field_%s.ispresent();\n"
2073 " if (nil_attribute) {\n"
2074 " const namespace_t *control_ns = p_td.my_module->get_controlns();\n"
2075 " p_buf.put_c(' ');\n"
2076 " p_buf.put_s(strlen(control_ns->px), (cbyte*)control_ns->px);\n"
2077 " p_buf.put_c(':');\n"
2078 " p_buf.put_s(10, (cbyte*)\"nil='true'\");\n"
2080 , sdef
->elements
[sdef
->nElements
-1].name
2084 if (want_namespaces
) {
2085 /* there were some attributes. close the start tag left open */
2086 src
= mputprintf(src
,
2087 " if (delay_close && (!omit_tag || chopped_chars)) p_buf.put_s(1%s, (cbyte*)\">\\n\");\n", /* close the start tag */
2088 (sdef
->xerUntaggedOne
/*|| sdef->xerUseNil*/) ? "" : "+is_indented"
2092 if (sdef
->xerEmbedValuesPossible
) {
2093 src
= mputprintf(src
,
2094 " ec_1.set_msg(\"%s': \");\n"
2095 " if (e_xer && (p_td.xer_bits & EMBED_VALUES)) {\n"
2096 /* write the first string (must come AFTER the attributes) */
2097 " if (field_%s.size_of() > 0) {\n"
2098 " sub_len += field_%s[0].XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n"
2101 , sdef
->elements
[0].dispname
, sdef
->elements
[0].name
, sdef
->elements
[0].name
);
2102 if (want_namespaces
) { /* here's another chance */
2103 src
= mputprintf(src
,
2104 " else if ( !(p_td.xer_bits & EMBED_VALUES)) {\n"
2105 " %sfield_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1, 0);\n"
2107 , ((sdef
->elements
[0].xerAnyKind
& ANY_ATTRIB_BIT
) ? "" : "sub_len += " )
2108 , sdef
->elements
[0].name
, sdef
->elements
[0].typegen
2113 /* Then, all the non-attributes. Structuring the code like this depends on
2114 * all attributes appearing before all non-attributes (excluding
2115 * special members for EMBED-VALUES, USE-ORDER, etc.) */
2116 if (sdef
->xerEmbedValuesPossible
) {
2117 src
= mputprintf(src
,
2118 " embed_values_enc_struct_t* emb_val = 0;\n"
2119 " if (e_xer && (p_td.xer_bits & EMBED_VALUES) && field_%s.size_of() > 1) {\n"
2120 " emb_val = new embed_values_enc_struct_t;\n"
2121 /* If the first field is a record of ANY-ELEMENTs, then it won't be a pre-generated
2122 * record of universal charstring, so it needs a cast to avoid a compilation error */
2123 " emb_val->embval_array%s = (const PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING%s*)&field_%s;\n"
2124 " emb_val->embval_array%s = NULL;\n"
2125 " emb_val->embval_index = 1;\n"
2127 , sdef
->elements
[0].name
2128 , sdef
->elements
[0].optimizedMemAlloc
? "_opt" : "_reg"
2129 , sdef
->elements
[0].optimizedMemAlloc
? "__OPTIMIZED" : ""
2130 , sdef
->elements
[0].name
2131 , sdef
->elements
[0].optimizedMemAlloc
? "_reg" : "_opt");
2134 if (sdef
->xerUseOrderPossible
) {
2135 int max_ordered
= sdef
->nElements
- start_at
- num_attributes
;
2136 int min_ordered
= max_ordered
- n_opt_elements
;
2139 size_t limit
= sdef
->nElements
;
2140 /* base and limit are indexes into sdef->elements[] */
2141 src
= mputprintf(src
,
2142 " int dis_order = e_xer && (p_td.xer_bits & USE_ORDER);\n"
2143 " int to_send = field_%s.lengthof();\n"
2144 " int uo_limit = dis_order ? to_send : %lu;\n"
2145 , sdef
->elements
[start_at
-1].name
2146 , (unsigned long)(limit
- base
)
2148 if (sdef
->xerUseNilPossible
) { /* USE-NIL on top of USE-ORDER */
2149 base
= sdef
->nElements
;
2150 limit
= sdef
->totalElements
;
2151 min_ordered
= max_ordered
= limit
- base
;
2152 src
= mputprintf(src
,
2153 " if (!nil_attribute) {\n"
2155 " if (!e_xer) sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+!omit_tag, 0);\n"
2156 " else" /* no newline */
2157 , (sdef
->xerUseNilPossible
? " if (!(p_td.xer_bits & USE_ORDER)) p_flavor |= (p_td.xer_bits & USE_NIL);\n" : "")
2158 /* If USE-ORDER is on, the tag-removing effect of USE-NIL has been
2159 * performed by calling the sub-fields directly. */
2160 , sdef
->elements
[sdef
->nElements
-1].name
2161 , sdef
->elements
[sdef
->nElements
-1].typegen
2165 /* check incorrect data */
2166 src
= mputprintf(src
,
2168 " if (to_send < %d || to_send > %d) {\n"
2169 " ec_1.set_msg(\"%s': \");\n"
2170 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT, "
2171 "\"Wrong number of USE-ORDER, %%d instead of %d..%d\", to_send);\n"
2172 " uo_limit = -1;\n" /* squash the loop */
2174 " else {\n" /* check duplicates */
2175 " int *seen = new int [to_send];\n"
2176 " int num_seen = 0;\n"
2177 " for (int ei = 0; ei < to_send; ++ei) {\n"
2178 " int val = field_%s[ei];\n"
2179 " for (int x = 0; x < num_seen; ++x) {\n"
2180 " if (val == seen[x]) { // complain\n"
2181 " ec_1.set_msg(\"%s': \");\n"
2182 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,\n"
2183 " \"Duplicate value for USE-ORDER\");\n"
2184 " uo_limit = -1; // don't bother sending anything\n"
2188 " seen[num_seen++] = val;\n"
2194 , min_ordered
, max_ordered
2195 , sdef
->elements
[start_at
-1].dispname
2196 , min_ordered
, max_ordered
2197 , sdef
->elements
[start_at
-1].name
2198 , sdef
->elements
[start_at
-1].dispname
2201 src
= mputprintf(src
,
2202 " for (int i = 0; i < uo_limit; ++i) {\n"
2203 " switch (dis_order ? (int)field_%s[i] : i) {\n"
2204 , sdef
->elements
[start_at
-1].name
2206 for ( i
= base
; i
< limit
; ++i
) {
2207 src
= mputprintf(src
,
2209 " ec_1.set_msg(\"%s': \");\n"
2210 " sub_len += field_%s%s%s%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+!omit_tag, %s);\n"
2212 , (unsigned long)offset
++
2213 , sdef
->elements
[i
].dispname
2214 , (sdef
->xerUseNilPossible
? sdef
->elements
[sdef
->nElements
-1].name
: sdef
->elements
[i
].name
)
2215 , (sdef
->xerUseNilPossible
? "()." : "")
2216 , (sdef
->xerUseNilPossible
? sdef
->elements
[i
].name
: "")
2217 , (sdef
->xerUseNilPossible
? "()" : "")
2218 , sdef
->elements
[i
].typegen
2219 , sdef
->xerEmbedValuesPossible
? "emb_val" : "0"
2222 src
= mputstr(src
, " break;\n");
2223 } /* next element */
2226 " TTCN_error(\"Runaway value while encoding USE-ORDER\");\n"
2227 " break;\n" /* cannot happen, complain */
2230 if (sdef
->xerEmbedValuesPossible
) {
2231 src
= mputprintf(src
,
2232 " if (e_xer && (p_td.xer_bits & EMBED_VALUES) && 0 != emb_val &&\n"
2233 " emb_val->embval_index < field_%s.size_of()) { // embed-val\n"
2234 " field_%s[emb_val->embval_index].XER_encode(\n"
2235 " UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n"
2236 " ++emb_val->embval_index;\n"
2238 , sdef
->elements
[0].name
, sdef
->elements
[0].name
);
2243 " }\n" /* end of loop */
2245 if (sdef
->xerUseNilPossible
) {
2246 src
= mputstr(src
, " } // nil_attr\n");
2249 else /* not USE-ORDER */
2250 for ( /* continue with i */; i
< sdef
->nElements
; ++i
) {
2251 src
= mputprintf(src
,
2252 " ec_1.set_msg(\"%s': \");\n"
2253 , sdef
->elements
[i
].dispname
2255 src
= mputprintf(src
,
2256 " sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor%s, p_indent+!omit_tag, %s);\n"
2257 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typegen
2258 , sdef
->xerUseNilPossible
? "| (p_td.xer_bits & USE_NIL)" : ""
2259 , sdef
->xerEmbedValuesPossible
? "emb_val" : "0"
2262 if (sdef
->xerEmbedValuesPossible
) {
2263 src
= mputprintf(src
,
2264 " if (e_xer && (p_td.xer_bits & EMBED_VALUES) && 0 != emb_val &&\n"
2265 " emb_val->embval_index < field_%s.size_of()) {\n"
2266 " field_%s[emb_val->embval_index].XER_encode(\n"
2267 " UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n"
2268 " ++emb_val->embval_index;\n"
2270 , sdef
->elements
[0].name
, sdef
->elements
[0].name
);
2272 } /* next field when not USE-ORDER */
2274 if (sdef
->xerEmbedValuesPossible
) {
2275 src
= mputprintf(src
,
2276 " if (0 != emb_val) {\n"
2277 " if (emb_val->embval_index < field_%s.size_of()) {\n"
2278 " ec_1.set_msg(\"%s': \");\n"
2279 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,\n"
2280 " \"Too many EMBED-VALUEs specified: %%d (expected %%d or less)\",\n"
2281 " field_%s.size_of(), emb_val->embval_index);\n"
2283 " delete emb_val;\n"
2285 , sdef
->elements
[0].name
, sdef
->elements
[0].name
, sdef
->elements
[0].name
);
2288 src
= mputstr(src
, " } // QN?\n");
2291 src
= mputprintf(src
,
2292 " if (!omit_tag) {\n"
2293 " if (sub_len) {\n" /* something was written, now an end tag */
2294 " if (is_indented && !(e_xer && (p_td.xer_bits & (HAS_1UNTAGGED | USE_QNAME)))) {\n"
2295 " switch ((int)(e_xer && (p_td.xer_bits & USE_NIL))) {\n"
2297 " const unsigned char *buf_end = p_buf.get_data() + (p_buf.get_len()-1);\n"
2298 " if (buf_end[-1] != '>' || *buf_end != '\\n') break;\n"
2299 /* else fall through */
2302 " do_indent(p_buf, p_indent);\n"
2306 " p_buf.put_c('<');\n"
2307 " p_buf.put_c('/');\n"
2308 " if (e_xer) write_ns_prefix(p_td, p_buf);\n"
2309 " p_buf.put_s((size_t)p_td.namelens[e_xer]-!is_indented, (cbyte*)p_td.names[e_xer]);\n"
2310 " } else {\n" /* need to generate an empty element tag */
2311 " p_buf.increase_length(%s-1);\n" /* decrease length */
2312 " p_buf.put_s((size_t)2+is_indented, (cbyte*)\"/>\\n\");\n"
2314 , (sdef
->xerUntaggedOne
/*|| sdef->xerUseNil*/) ? "" : "-is_indented"
2318 " return (int)p_buf.get_len() - encoded_length;\n"
2322 src
= mputprintf(src
, "// %s has%s%s%s%s%s%s%s%s%s\n"
2323 "// written by %s in " __FILE__
" at %d\n"
2325 , (sdef
->xerUntagged
? " UNTAGGED" : "")
2326 , (sdef
->xerUntaggedOne
? "1" : "")
2327 , (sdef
->xerUseNilPossible
? " USE_NIL?" : "")
2328 , (sdef
->xerUseOrderPossible
? " USE_ORDER?" : "")
2329 , (sdef
->xerUseQName
? " USE_QNAME" : "")
2330 , (sdef
->xerUseTypeAttr
? " USE_TYPE_ATTR" : "")
2331 , (sdef
->xerUseUnion
? " USE-UNION" : "")
2332 , (sdef
->xerHasNamespaces
? " namespace" : "")
2333 , (sdef
->xerEmbedValuesPossible
? " EMBED?" : "")
2334 , __FUNCTION__
, __LINE__
2338 src
= mputprintf(src
, /* XERSTUFF decodegen for record/SEQUENCE*/
2339 "int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader,"
2340 " unsigned int p_flavor, embed_values_dec_struct_t*)\n"
2342 " bound_flag = TRUE;\n"
2343 /* Remove XER_LIST, XER_RECOF from p_flavor. This is not required
2344 * for is_exer (which tests another bit), but for subsequent code. */
2345 " int e_xer = is_exer(p_flavor);\n"
2346 " int xerbits = p_td.xer_bits;\n"
2347 " if (p_flavor & XER_TOPLEVEL) xerbits &= ~UNTAGGED;\n"
2348 " const boolean omit_tag = e_xer && ((xerbits & (UNTAGGED|XER_ATTRIBUTE)) "
2349 "|| (p_flavor & (USE_NIL|USE_TYPE_ATTR)));\n"
2351 " const boolean parent_tag = e_xer && (p_flavor & (USE_TYPE_ATTR));\n"
2352 " (void)parent_tag;\n"
2353 " p_flavor &= XER_MASK;\n" /* also removes "toplevel" bit */
2354 " int rd_ok, xml_depth=-1, type;\n"
2355 " {\n" /* scope for the error contexts */
2357 , (start_at
+ num_attributes
< sdef
->nElements
|| (sdef
->xerEmbedValuesPossible
&& num_attributes
==0)
2358 ? " boolean tag_closed = (p_flavor & PARENT_CLOSED) != 0;\n" : "")
2359 /* tag_closed needed for non-attribute normal members only,
2360 * or if EMBED-VALUES is possible, but isn't. */
2363 if (sdef
->xerUseNilPossible
) src
= mputstr(src
,
2364 " boolean nil_attribute = FALSE;\n");
2366 src
= mputprintf(src
,
2367 " TTCN_EncDec_ErrorContext ec_0(\"Component '\");\n"
2368 " TTCN_EncDec_ErrorContext ec_1;\n"
2369 " if (!omit_tag) for (rd_ok=p_reader.Ok(); rd_ok==1; rd_ok=p_reader.Read()) {\n"
2370 " type = p_reader.NodeType();\n"
2371 " if (type==XML_READER_TYPE_ELEMENT) {\n"
2372 " verify_name(p_reader, p_td, e_xer);\n"
2373 " xml_depth = p_reader.Depth();\n"
2378 , (start_at
+ num_attributes
< sdef
->nElements
|| (sdef
->xerEmbedValuesPossible
&& num_attributes
==0)
2379 ? " tag_closed = p_reader.IsEmptyElement();\n": "")
2383 if (sdef
->xerUseQName
) {
2384 src
= mputprintf(src
,
2385 " if (e_xer && (p_td.xer_bits & USE_QNAME)) {\n"
2386 " if (p_td.xer_bits & XER_ATTRIBUTE) rd_ok = 1;\n"
2387 " else for (rd_ok = p_reader.Read(); rd_ok == 1; rd_ok = p_reader.Read()) {\n"
2388 " type = p_reader.NodeType();\n"
2389 " if (type == XML_READER_TYPE_TEXT) break;\n"
2391 " if (rd_ok==1) {\n"
2392 " xmlChar *new_val = p_reader.NewValue();\n"
2393 " xmlChar *v_npfx = (xmlChar*)strchr((char*)new_val, ':');\n"
2394 " xmlChar *v_pfx;\n"
2395 " if (v_npfx != NULL) {\n"
2396 " *v_npfx++ = '\\0';\n"
2397 " v_pfx = new_val;\n"
2400 " v_npfx = new_val;\n"
2403 " xmlChar *q_ns = p_reader.LookupNamespace(v_pfx);\n"
2404 " if (q_ns) field_%s = (const char*)q_ns;\n"
2405 " else field_%s = OMIT_VALUE;\n"
2406 " field_%s = (const char*)v_npfx;\n"
2408 " xmlFree(new_val);\n"
2411 , sdef
->elements
[0].name
2412 , sdef
->elements
[0].name
2413 , sdef
->elements
[1].name
2417 if (num_attributes
|| sdef
->xerEmbedValuesPossible
|| sdef
->xerUseOrderPossible
) {
2418 src
= mputstr(src
, "if (e_xer) {\n");
2421 /* ********************************************************************
2423 ***************************/
2424 if (num_attributes
|| sdef
->xerUseNilPossible
/* maybe QNAME too ? */) {
2426 src
= mputstr(src
, " if (!omit_tag || parent_tag) {\n");
2428 /* Prepare for attributes not present in the XML.
2429 * Set all attributes with defaultForEmpty to the D-F-E value.
2430 * Set all optional components with ATTRIBUTE to omit.
2432 * If EMBED-VALUES is possible, the first component can't be optional.
2433 * The same is true for the USE-ORDER component. Hence start_at. */
2434 for (aaa
= start_at
; aaa
< start_at
+ num_attributes
; ++aaa
) {
2435 if (sdef
->elements
[aaa
].xerAttribute
) { /* "proper" ATTRIBUTE */
2436 src
= mputprintf(src
,
2437 " if (%s_xer_.dfeValue) field_%s = "
2438 "*static_cast<const %s*>(%s_xer_.dfeValue);\n"
2439 , sdef
->elements
[aaa
].typegen
, sdef
->elements
[aaa
].name
2440 , sdef
->elements
[aaa
].type
, sdef
->elements
[aaa
].typegen
);
2441 if (sdef
->elements
[aaa
].isOptional
) src
= mputprintf(src
,
2442 " else field_%s = OMIT_VALUE;\n", sdef
->elements
[aaa
].name
);
2444 else { /* must be the ANY-ATTRIBUTES */
2445 src
= mputprintf(src
,
2447 , sdef
->elements
[aaa
].name
2448 , sdef
->elements
[aaa
].isOptional
? " = OMIT_VALUE" : ".set_size(0)");
2452 if (num_attributes
==0 /* therefore sdef->xerUseNilPossible is true */ ) {
2453 /* Only the "nil" attribute may be present. If there is no USE-NIL,
2454 * then there can be no attributes at all. */
2456 " if (e_xer && (p_td.xer_bits & (USE_NIL|USE_TYPE_ATTR))) {\n");
2459 if (aa_index
> -1) src
= mputstr(src
, " size_t num_aa = 0;\n");
2460 if (sdef
->xerUseNilPossible
) {
2462 " static const namespace_t *control_ns = p_td.my_module->get_controlns();\n");
2466 " for (rd_ok = p_reader.MoveToFirstAttribute(); rd_ok==1 && "
2467 "p_reader.NodeType()==XML_READER_TYPE_ATTRIBUTE; "
2468 "rd_ok = p_reader.AdvanceAttribute()) {\n"
2469 " if (p_reader.IsNamespaceDecl()) continue;\n");
2470 /* if the only attribute is ANY-ATTRIBUTE, it doesn't need attr_name */
2471 if (num_attributes
==1 && aa_index
!=-1 /*&& !sdef->xerUseNilPossible*/) {}
2474 " const char *attr_name = (const char*)p_reader.LocalName();\n"
2475 " const char *ns_uri = (const char*)p_reader.NamespaceUri();\n");
2478 if (sdef
->xerUseNilPossible
) {
2479 src
= mputprintf(src
,
2480 " const char *prefix = (const char*)p_reader.Prefix();\n"
2481 /* prefix may be NULL, control_ns->px is never NULL or empty */
2482 " if (prefix && !strcmp(prefix, control_ns->px)\n"
2483 " && !strcmp((const char*)p_reader.LocalName(), \"nil\")){\n"
2484 " const char *value = (const char*)p_reader.Value();\n"
2485 " if (!strcmp(value, \"1\") || !strcmp(value, \"true\")) {\n"
2486 " field_%s = OMIT_VALUE;\n"
2487 " nil_attribute = TRUE;\n"
2488 /* found the "nil" attribute */
2491 , sdef
->elements
[sdef
->nElements
-1].name
);
2494 for (i
= start_at
; i
< start_at
+ num_attributes
; ++i
) {
2495 if (i
== aa_index
) continue; /* ANY_ATTR. is handled below */
2496 src
= mputprintf(src
,
2497 " if (check_name(attr_name, %s_xer_, 1) && check_namespace(ns_uri, %s_xer_)) {\n"
2498 " ec_1.set_msg(\"%s': \");\n"
2499 " field_%s.XER_decode(%s_xer_, p_reader, p_flavor | (p_td.xer_bits & USE_NIL), 0);\n"
2501 , sdef
->elements
[i
].typegen
, sdef
->elements
[i
].typegen
2502 , sdef
->elements
[i
].dispname
/* set_msg */
2503 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typegen
2507 if (sdef
->control_ns_prefix
&& !(num_attributes
==1 && aa_index
!=-1)) {
2508 src
= mputprintf(src
,
2509 " if (parent_tag && !strcmp(attr_name, \"type\") "
2510 "&& !strcmp((const char*)p_reader.Prefix(), \"%s\")) {} else\n"
2511 , sdef
->control_ns_prefix
);
2512 /* xsi:type; already processed by parent with USE-UNION or USE-TYPE */
2516 if (aa_index
>= 0) {
2517 /* we are at a dangling else */
2518 src
= mputprintf(src
,
2520 " TTCN_EncDec_ErrorContext ec_0(\"Attribute %%d: \", (int)num_aa);\n"
2521 " UNIVERSAL_CHARSTRING& new_elem = field_%s%s[num_aa++];\n"
2522 /* Construct the AnyAttributeFormat (X.693amd1, 18.2.6) */
2523 " TTCN_Buffer aabuf;\n"
2524 " const xmlChar *x_name = p_reader.LocalName();\n"
2525 " const xmlChar *x_val = p_reader.Value();\n"
2526 " const xmlChar *x_uri = p_reader.NamespaceUri();\n"
2527 " if (%s_xer_.xer_bits & (ANY_FROM | ANY_EXCEPT)) {\n"
2528 " check_namespace_restrictions(%s_xer_, (const char*)x_uri);\n"
2530 /* We don't care about p_reader.Prefix() */
2531 /* Using strlen to count bytes */
2532 " aabuf.put_s(x_uri ? strlen((const char*)x_uri) : 0, x_uri);\n"
2533 " if (x_uri && *x_uri) aabuf.put_c(' ');\n"
2534 " aabuf.put_s(x_name ? strlen((const char*)x_name) : 0, x_name);\n"
2535 " aabuf.put_c('=');\n"
2536 " aabuf.put_c('\"');\n"
2537 " aabuf.put_s(x_val ? strlen((const char*)x_val) : 0, x_val);\n"
2538 " aabuf.put_c('\"');\n"
2539 " new_elem.decode_utf8(aabuf.get_len(), aabuf.get_data());\n"
2541 , sdef
->elements
[aa_index
].name
2542 , sdef
->elements
[aa_index
].isOptional
? "()" : ""
2543 , sdef
->elements
[aa_index
].typegen
, sdef
->elements
[aa_index
].typegen
2547 /* we are at a dangling else */
2548 src
= mputstr(src
, " {\n");
2549 if (sdef
->control_ns_prefix
) {
2550 src
= mputprintf(src
,
2551 // Lastly check for the xsi:schemaLocation attribute, this does not
2552 // affect TTCN-3, but it shouldn't cause a DTE
2553 " if (!p_reader.LocalName() || strcmp((const char*)p_reader.LocalName(), \"schemaLocation\") ||\n"
2554 " !p_reader.Prefix() || strcmp((const char*)p_reader.Prefix(), \"%s\"))\n"
2555 , sdef
->control_ns_prefix
);
2559 " ec_0.set_msg(\" \"); ec_1.set_msg(\" \");\n" /* we have no component */
2560 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, "
2561 "\"Unexpected attribute '%s', ns '%s'\", attr_name, ns_uri ? ns_uri : \"\");\n"
2565 src
= mputstr(src
, " }\n"); /* for */
2567 for (i
= start_at
; i
< start_at
+ num_attributes
; ++i
) {
2568 if (sdef
->elements
[i
].isOptional
) continue; /* allowed to be missing */
2569 src
= mputprintf(src
, " if (!field_%s.is_bound()) "
2570 "TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, "
2571 "\"Missing attribute '%s'\");\n"
2572 , sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
);
2575 if (num_attributes
==0) src
= mputstr(src
, " }\n"); /* if USE_NIL or USE_TYPE_ATTR */
2576 src
= mputstr(src
, " }\n"); /* process (attributes) in (own or parent) tag */
2577 } /* * * * * * * * * end if(attributes...) * * * * * * * * * * * * */
2580 " if ((!omit_tag || parent_tag) && !p_reader.IsEmptyElement()) "
2581 "rd_ok = p_reader.Read();\n");
2583 if (sdef
->xerEmbedValuesPossible
&& num_attributes
==0) {
2584 /* EMBED-VALUES possible, but isn't: the first component is a non-special
2585 * record of strings. This means there are no attributes, unless
2586 * the first component is an ATTRIBUTE or ANY-ATTRIBUTES. */
2587 src
= mputprintf(src
,
2588 " if (!(p_td.xer_bits & EMBED_VALUES)) {\n"
2589 " ec_1.set_msg(\"%s': \");\n"
2590 " field_%s.XER_decode(%s_xer_, p_reader, "
2591 "p_flavor | (p_td.xer_bits & USE_NIL)| (tag_closed ? PARENT_CLOSED : 0), 0);\n"
2593 , sdef
->elements
[0].dispname
2594 , sdef
->elements
[0].name
, sdef
->elements
[0].typegen
2598 if (num_attributes
|| sdef
->xerEmbedValuesPossible
|| sdef
->xerUseOrderPossible
) {
2600 "} else {\n" /* now the non-EXER processing of (would-be) attributes */
2601 " if (!p_reader.IsEmptyElement()) p_reader.Read();\n"
2605 if (sdef
->xerUseOrderPossible
) {
2607 " if (e_xer && p_td.xer_bits & USE_ORDER) ; else {");
2610 if (start_at
+ num_attributes
> 0)
2612 /* No attributes nor USE-NIL:
2613 * Just decode the specials and would-be attributes. */
2615 // FIXME: WTF is this?
2616 //if (sdef->xerEmbedValuesPossible) {
2617 // /* Only decode the first member if it really is EMBED-VALUES */
2618 // src = mputprintf(src, "if (p_td.xer_bits & EMBED_VALUES) ");
2620 for (i
= 0; i
< start_at
+ num_attributes
; ++i
) {
2621 /* Decode the field */
2622 src
= mputprintf(src
,
2624 " ec_1.set_msg(\"%s': \");\n"
2625 " field_%s.XER_decode(%s_xer_, p_reader, p_flavor | (p_td.xer_bits & USE_NIL), 0);\n"
2627 , sdef
->elements
[i
].dispname
2628 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typegen
2632 if (sdef
->xerUseOrderPossible
) {
2633 src
= mputstr(src
, " }\n");
2637 if (num_attributes
|| sdef
->xerEmbedValuesPossible
|| sdef
->xerUseOrderPossible
) {
2638 src
= mputstr(src
, "}\n");
2641 if (sdef
->xerEmbedValuesPossible
) {
2642 src
= mputprintf(src
,
2643 " embed_values_dec_struct_t* emb_val = 0;\n"
2644 " if (e_xer && (p_td.xer_bits & EMBED_VALUES)) {\n"
2645 " emb_val = new embed_values_dec_struct_t;\n"
2646 /* If the first field is a record of ANY-ELEMENTs, then it won't be a pre-generated
2647 * record of universal charstring, so it needs a cast to avoid a compilation error */
2648 " emb_val->embval_array%s = (PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING%s*)&field_%s;\n"
2649 " emb_val->embval_array%s = NULL;\n"
2650 " emb_val->embval_index = 0;\n"
2651 " field_%s.set_size(0);\n"
2653 , sdef
->elements
[0].optimizedMemAlloc
? "_opt" : "_reg"
2654 , sdef
->elements
[0].optimizedMemAlloc
? "__OPTIMIZED" : ""
2655 , sdef
->elements
[0].name
2656 , sdef
->elements
[0].optimizedMemAlloc
? "_reg" : "_opt"
2657 , sdef
->elements
[0].name
);
2660 if (sdef
->xerUseOrderPossible
) {
2661 size_t begin
= start_at
+ num_attributes
; /* first non-attribute */
2662 size_t end
= sdef
->nElements
;
2663 size_t n_optionals
= 0, n_embed
;
2664 int max_ordered
= sdef
->nElements
- start_at
- num_attributes
;
2665 int min_ordered
= max_ordered
- n_opt_elements
;
2666 if (sdef
->xerUseNilPossible
) { /* USE-NIL on top of USE-ORDER */
2667 begin
= sdef
->nElements
;
2668 end
= sdef
->totalElements
;
2670 n_embed
= end
- begin
;
2673 " if (e_xer && (p_td.xer_bits & USE_ORDER)) {\n"
2675 for (i
= begin
; i
< end
; ++i
) {
2676 if (sdef
->elements
[i
].isOptional
) {
2677 src
= mputprintf(src
, " field_%s = OMIT_VALUE;\n",
2678 sdef
->elements
[i
].name
);
2683 if (sdef
->xerUseNilPossible
) { /* USE-NIL and USE-ORDER */
2684 src
= mputprintf(src
,
2685 " if (nil_attribute) field_%s.set_size(0);\n else"
2686 , sdef
->elements
[uo
].name
);
2689 src
= mputprintf(src
,
2691 " field_%s.set_size(0);\n"
2692 " if (!tag_closed) {\n" /* Nothing to order if there are no child elements */
2693 " int e_val, num_seen = 0, *seen_f = new int[%lu];\n"
2694 , sdef
->elements
[uo
].name
2695 , (unsigned long)(n_embed
)
2697 if (sdef
->xerEmbedValuesPossible
) {
2698 // The index of the latest embedded value can change outside of this function
2699 // (if the field is a untagged record of), in this case the next value should
2700 // be ignored, as it's already been handled by the record of
2701 src
= mputstr(src
, " int last_embval_index = 0;\n");
2703 src
= mputprintf(src
,
2704 " bool early_exit = false;\n"
2705 " for (int i=0; i < %lu; ++i) {\n"
2706 " for (rd_ok=p_reader.Ok(); rd_ok==1; rd_ok=p_reader.Read()) {\n"
2707 , (unsigned long)(n_embed
));
2709 if (sdef
->xerEmbedValuesPossible
) {
2710 /* read and store embedValues text if present */
2711 src
= mputprintf(src
,
2712 " if (0 != emb_val && p_reader.NodeType()==XML_READER_TYPE_TEXT) {\n"
2713 " UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
2714 " field_%s[emb_val->embval_index] = emb_ustr;\n"
2716 , sdef
->elements
[0].name
);
2720 " type = p_reader.NodeType();\n"
2721 " if (type==XML_READER_TYPE_ELEMENT) break;\n"
2722 " if (type == XML_READER_TYPE_END_ELEMENT) {\n"
2723 " early_exit = true;\n"
2727 " if (rd_ok != 1 || early_exit) break;\n"
2728 " const char * x_name = (const char*)p_reader.LocalName();\n" /* Name or LocalName ? */);
2730 if (sdef
->xerEmbedValuesPossible
) {
2732 " if (0 != emb_val) {\n"
2733 " if (last_embval_index == emb_val->embval_index) {\n"
2734 " ++emb_val->embval_index;\n"
2736 " last_embval_index = emb_val->embval_index;\n"
2740 /* * * * * code for USE-ORDER * * * * */
2742 for (i
= begin
; i
< end
; ++i
) {
2743 // Check non-anyElement fields first
2744 if (!(sdef
->elements
[i
].xerAnyKind
& ANY_ELEM_BIT
)) {
2745 src
= mputprintf(src
,
2746 " if (check_name(x_name, %s_xer_, 1)) {\n"
2747 " ec_1.set_msg(\"%s': \");\n"
2748 " field_%s%s%s%s.XER_decode(%s_xer_, p_reader, p_flavor, %s);\n"
2749 , sdef
->elements
[i
].typegen
2750 , sdef
->elements
[i
].dispname
2751 , (sdef
->xerUseNilPossible
? sdef
->elements
[sdef
->nElements
-1].name
: sdef
->elements
[i
].name
)
2752 , (sdef
->xerUseNilPossible
? "()." : "")
2753 , (sdef
->xerUseNilPossible
? sdef
->elements
[i
].name
: "")
2754 , (sdef
->xerUseNilPossible
? "()" : "")
2755 , sdef
->elements
[i
].typegen
2756 , sdef
->xerEmbedValuesPossible
? "emb_val" : "0"
2758 src
= mputprintf(src
,
2759 " field_%s[i] = e_val = %s::of_type::%s;\n"
2760 , sdef
->elements
[uo
].name
2761 , sdef
->elements
[uo
].typegen
, sdef
->elements
[i
].name
);
2762 src
= mputstr(src
, " }\n else");
2767 " boolean any_found = false;\n"
2768 " if (!any_found)");
2769 for (i
= begin
; i
< end
; ++i
) {
2770 // Check anyElement fields after all other fields
2771 if (sdef
->elements
[i
].xerAnyKind
& ANY_ELEM_BIT
) {
2772 src
= mputstr(src
, " {\n");
2773 src
= mputprintf(src
,
2774 " e_val = %s::of_type::%s;\n"
2775 , sdef
->elements
[uo
].typegen
, sdef
->elements
[i
].name
);
2776 src
= mputprintf(src
,
2777 " boolean next_any = false;\n"
2778 " for (int d_f = 0; d_f < num_seen; ++d_f) {\n"
2779 " if (e_val == seen_f[d_f]) {\n"
2780 " next_any = true;\n"
2783 " if (!next_any) {\n"
2784 " ec_1.set_msg(\"%s': \");\n"
2785 " field_%s%s%s%s.XER_decode(%s_xer_, p_reader, p_flavor, 0);\n"
2786 " field_%s[i] = e_val;\n"
2787 " any_found = true;\n"
2791 , sdef
->elements
[i
].dispname
2792 , (sdef
->xerUseNilPossible
? sdef
->elements
[sdef
->nElements
-1].name
: sdef
->elements
[i
].name
)
2793 , (sdef
->xerUseNilPossible
? "()." : "")
2794 , (sdef
->xerUseNilPossible
? sdef
->elements
[i
].name
: "")
2795 , (sdef
->xerUseNilPossible
? "()" : "")
2796 , sdef
->elements
[i
].typegen
, sdef
->elements
[uo
].name
2802 " {\n" /* take care of the dangling else */
2803 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n"
2804 " \"Bad XML tag '%s' instead of a valid field\", x_name);\n"
2808 " for (int d_f = 0; d_f < num_seen; ++d_f)\n"
2809 " if (e_val == seen_f[d_f])\n"
2810 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT, \"Duplicate field\");\n"
2811 " seen_f[num_seen++] = e_val;\n"
2814 if (sdef
->xerEmbedValuesPossible
) {
2815 /* read and store embedValues text if present */
2816 src
= mputprintf(src
,
2817 " if (0 != emb_val) {\n"
2818 " if (p_reader.NodeType()==XML_READER_TYPE_TEXT) {\n"
2819 " UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
2820 " field_%s[emb_val->embval_index] = emb_ustr;\n"
2822 " if (last_embval_index == emb_val->embval_index) {\n"
2823 " ++emb_val->embval_index;\n"
2826 , sdef
->elements
[0].name
);
2829 src
= mputprintf(src
,
2830 " delete [] seen_f;\n"
2832 " int n_collected = field_%s.size_of();\n"
2833 " if (p_td.xer_bits & USE_NIL) {\n"
2836 " if (n_collected < %d || n_collected > %d) {\n"
2837 " ec_0.set_msg(\" \");\n"
2838 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT, \"Wrong number of elements\");\n"
2841 " } // !tag_closed\n"
2842 " } else { // !uo\n"
2843 , sdef
->elements
[uo
].dispname
2844 , min_ordered
, max_ordered
2846 } /* end if(UseOrder possible) */
2848 /* * * * * non-UseOrder code always written, executed when * * * *
2849 * * * * * UseOrder not possible or in the "else" clause * * * * */
2851 if (sdef
->xerUseNilPossible
) {
2852 /* value absent, nothing more to do */
2854 " if (nil_attribute) {\n"
2855 " p_reader.MoveToElement();\n"
2858 if (sdef
->xerEmbedValuesPossible
) {
2859 // The index of the latest embedded value can change outside of this function
2860 // (if the field is a untagged record of), in this case the next value should
2861 // be ignored, as it's already been handled by the record of
2862 // Omitted fields can also reset this value
2863 src
= mputstr(src
, " int last_embval_index = 0;\n");
2865 /* for all the non-attribute fields... */
2866 for (i
= start_at
+ num_attributes
; i
< sdef
->nElements
; ++i
) {
2867 if (sdef
->xerEmbedValuesPossible
) {
2868 /* read and store embedValues text if present */
2869 src
= mputprintf(src
,
2870 " if (0 != emb_val) {\n"
2871 " if (p_reader.NodeType()==XML_READER_TYPE_TEXT) {\n"
2872 " UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
2873 " field_%s[emb_val->embval_index] = emb_ustr;\n"
2875 " if (last_embval_index == emb_val->embval_index) {\n"
2876 " ++emb_val->embval_index;\n"
2878 " last_embval_index = emb_val->embval_index;\n"
2880 , sdef
->elements
[0].name
);
2882 /* The DEFAULT-FOR-EMPTY member can not be involved with EMBED-VALUES,
2883 * so we can use the same pattern: optional "if(...) else" before {}
2884 * XXX check with single-element record where nElements-1 == 0 !! */
2885 if (sdef
->kind
== RECORD
&& i
== sdef
->nElements
-1) {
2886 src
= mputprintf(src
,
2887 " if (e_xer && p_td.dfeValue && p_reader.IsEmptyElement()) {\n"
2888 " field_%s = *static_cast<const %s*>(p_td.dfeValue);\n"
2891 , sdef
->elements
[i
].name
, sdef
->elements
[i
].type
);
2893 /* Decode the field */
2894 src
= mputprintf(src
,
2896 " ec_1.set_msg(\"%s': \");\n"
2897 , sdef
->elements
[i
].dispname
);
2899 if ( (sdef
->elements
[i
].xerAnyKind
& ANY_ELEM_BIT
)
2900 && !strcmp(sdef
->elements
[i
].type
,"UNIVERSAL_CHARSTRING") ) {
2901 // In case the field is an optional anyElement -> check if it should be omitted
2902 if (sdef
->elements
[i
].isOptional
) {
2903 src
= mputprintf(src
,
2904 " if (field_%s.XER_check_any_elem(p_reader, \"%s\", tag_closed))\n "
2905 , sdef
->elements
[i
].name
2906 , (i
== sdef
->nElements
- 1) ? "NULL" : sdef
->elements
[i
+ 1].name
);
2908 // If the record is emptyElement, there's no way it will have an anyElement field
2909 src
= mputstr(src
, " if (tag_closed) p_reader.Read(); \n");
2913 src
= mputprintf(src
,
2914 " field_%s.XER_decode(%s_xer_, p_reader, p_flavor"
2915 " | (p_td.xer_bits & USE_NIL)| (tag_closed ? PARENT_CLOSED : 0), %s);\n"
2917 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typegen
2918 , sdef
->xerEmbedValuesPossible
? "emb_val" : "0");
2919 if (sdef
->xerEmbedValuesPossible
) {
2920 src
= mputprintf(src
,
2921 " if (!field_%s.is_present()) {\n"
2922 // there was no new element, the last embedded value is for the next field
2923 // (or the end of the record if this is the last field)
2924 " last_embval_index = -1;\n"
2926 , sdef
->elements
[i
].name
);
2930 if (sdef
->xerEmbedValuesPossible
) {
2931 /* read and store embedValues text if present */
2932 src
= mputprintf(src
,
2933 " if (0 != emb_val) {\n"
2934 " if (p_reader.NodeType()==XML_READER_TYPE_TEXT) {\n"
2935 " UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
2936 " field_%s[emb_val->embval_index] = emb_ustr;\n"
2938 " if (last_embval_index == emb_val->embval_index) {\n"
2939 " ++emb_val->embval_index;\n"
2942 , sdef
->elements
[0].name
);
2945 if (sdef
->xerUseNilPossible
) {
2946 src
= mputstr(src
, " } // use_nil\n");
2949 if (sdef
->xerUseOrderPossible
) {
2950 src
= mputstr(src
, " } // uo\n");
2953 if (sdef
->xerEmbedValuesPossible
) {
2954 src
= mputprintf(src
,
2955 " if (0 != emb_val) {\n"
2956 " %s::of_type empty_string(\"\");\n"
2957 " for (int j_j = 0; j_j < emb_val->embval_index; ++j_j) {\n"
2958 " if (!field_%s[j_j].is_bound()) field_%s[j_j] = empty_string;\n"
2960 " delete emb_val;\n"
2962 , sdef
->elements
[0].type
2963 , sdef
->elements
[0].name
2964 , sdef
->elements
[0].name
2968 if (sdef
->xerUseQName
) {
2969 src
= mputstr(src
, " } // qn\n");
2973 " } // errorcontext\n"); /* End scope for error context objects */
2975 /* Check if every non-optional field has been set */
2976 for (i
= 0; i
< sdef
->nElements
; ++i
) {
2977 if (!sdef
->elements
[i
].isOptional
) {
2978 src
= mputprintf(src
,
2979 " if (!field_%s.is_bound()) {\n"
2980 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INCOMPL_MSG,\n"
2981 " \"No data found for non-optional field '%s'\");\n"
2983 , sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
);
2987 " if (!omit_tag) {\n"
2988 " int current_depth;\n"
2989 " for (rd_ok = p_reader.Ok(); rd_ok == 1; rd_ok = p_reader.Read()) {\n"
2990 " type = p_reader.NodeType();\n"
2991 " if ((current_depth = p_reader.Depth()) > xml_depth) {\n"
2992 " if (XML_READER_TYPE_ELEMENT == type) {\n"
2993 /* An element deeper than our start tag has not been processed */
2994 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG,\n"
2995 " \"Unprocessed XML tag `%s'\", (const char *)p_reader.Name());\n"
2999 " else if (current_depth == xml_depth) {\n"
3000 " if (XML_READER_TYPE_ELEMENT == type) {\n"
3001 " verify_name(p_reader, p_td, e_xer);\n"
3002 " if (p_reader.IsEmptyElement()) {\n"
3003 " p_reader.Read();\n" /* advance one more time */
3007 " else if (XML_READER_TYPE_END_ELEMENT == type) {\n"
3008 " verify_end(p_reader, p_td, xml_depth, e_xer);\n"
3009 " rd_ok = p_reader.Read();\n"
3013 " else break;" /* depth is less, we are in trouble... */
3016 " return 1;\n}\n\n");
3022 void defRecordClass1(const struct_def
*sdef
, output_struct
*output
)
3025 size_t mandatory_fields_count
;
3026 const char *name
= sdef
->name
, *dispname
= sdef
->dispname
;
3027 const char* kind_str
= sdef
->kind
== SET
? "set" : "record";
3028 char *def
= NULL
, *src
= NULL
;
3029 boolean ber_needed
= sdef
->isASN1
&& enable_ber();
3030 boolean raw_needed
= sdef
->hasRaw
&& enable_raw();
3031 boolean text_needed
= sdef
->hasText
&& enable_text();
3032 boolean xer_needed
= sdef
->hasXer
&& enable_xer();
3033 boolean json_needed
= sdef
->hasJson
&& enable_json();
3035 /* class declaration code */
3036 output
->header
.class_decls
= mputprintf(output
->header
.class_decls
,
3037 "class %s;\n", name
);
3039 if (sdef
->nElements
<= 0) {
3040 defEmptyRecordClass(sdef
, output
);
3044 /* class definition and source code */
3045 if(ber_needed
|| raw_needed
|| text_needed
|| xer_needed
|| json_needed
) {
3049 "// written by %s in " __FILE__
" at line %d\n"
3051 "class %s : public Base_Type {\n"
3053 , __FUNCTION__
, __LINE__
3057 def
=mputprintf(def
, "class %s {\n", name
);
3061 for (i
= 0; i
< sdef
->nElements
; i
++) {
3062 if(sdef
->elements
[i
].isOptional
)
3063 def
= mputprintf(def
, " OPTIONAL<%s> field_%s;\n",
3064 sdef
->elements
[i
].type
,
3065 sdef
->elements
[i
].name
);
3067 def
= mputprintf(def
, " %s field_%s;\n",
3068 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
3072 def
= mputstr(def
, " boolean bound_flag;\n");
3074 /* default constructor */
3075 def
= mputprintf(def
, "public:\n"
3077 src
= mputprintf(src
, "%s::%s()\n"
3079 " bound_flag = FALSE;\n"
3080 "}\n\n", name
, name
);
3082 /* constructor by fields */
3083 def
= mputprintf(def
, " %s(", name
);
3084 src
= mputprintf(src
, "%s::%s(", name
, name
);
3086 for (i
= 0; i
< sdef
->nElements
; i
++) {
3088 if (i
> 0) tmp
= mputstr(tmp
, ",\n ");
3089 if (sdef
->elements
[i
].isOptional
)
3092 "const OPTIONAL<%s>& par_%s",
3093 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
3098 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
3099 def
= mputstr(def
, tmp
);
3100 src
= mputstr(src
, tmp
);
3103 def
= mputstr(def
, ");\n");
3104 src
= mputstr(src
, ")\n"
3106 for (i
= 0; i
< sdef
->nElements
; i
++) {
3107 if (i
> 0) src
= mputstr(src
, ",\n");
3108 src
= mputprintf(src
, " field_%s(par_%s)", sdef
->elements
[i
].name
,
3109 sdef
->elements
[i
].name
);
3111 src
= mputstr(src
, "\n"
3113 " bound_flag = TRUE;\n"
3116 /* copy constructor */
3117 def
= mputprintf(def
, " %s(const %s& other_value);\n", name
, name
);
3118 src
= mputprintf(src
, "%s::%s(const %s& other_value)\n"
3120 "if(!other_value.is_bound()) "
3121 "TTCN_error(\"Copying an unbound value of type %s.\");\n"
3122 "bound_flag = TRUE;\n",
3123 name
, name
, name
, dispname
);
3124 for (i
= 0; i
< sdef
->nElements
; i
++) {
3125 src
= mputprintf(src
,
3126 "if (other_value.%s().is_bound()) field_%s = other_value.%s();\n"
3127 "else field_%s.clean_up();\n",
3128 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
3129 sdef
->elements
[i
].name
);
3131 src
= mputstr(src
, "}\n\n");
3133 /* not a component */
3134 def
= mputstr(def
, " inline boolean is_component() { return FALSE; }\n");
3137 def
= mputstr(def
, " void clean_up();\n");
3138 src
= mputprintf(src
, "void %s::clean_up()\n"
3140 for (i
= 0; i
< sdef
->nElements
; i
++) {
3141 src
= mputprintf(src
,
3142 "field_%s.clean_up();\n", sdef
->elements
[i
].name
);
3145 "bound_flag = FALSE;\n"
3149 def
= mputprintf(def
, " %s& operator=(const %s& other_value);\n", name
, name
);
3150 src
= mputprintf(src
, "%s& %s::operator=(const %s& other_value)\n"
3152 "if (this != &other_value) {\n"
3153 " if(!other_value.is_bound()) "
3154 "TTCN_error(\"Assignment of an unbound value of type %s.\");\n"
3155 " bound_flag = TRUE;\n",
3156 name
, name
, name
, dispname
);
3157 for (i
= 0; i
< sdef
->nElements
; i
++) {
3158 src
= mputprintf(src
,
3159 " if (other_value.%s().is_bound()) field_%s = other_value.%s();\n"
3160 " else field_%s.clean_up();\n",
3161 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
3162 sdef
->elements
[i
].name
);
3170 def
= mputprintf(def
, " boolean operator==(const %s& other_value) "
3172 src
= mputprintf(src
,
3173 "boolean %s::operator==(const %s& other_value) const\n"
3175 "if (!is_bound() && !other_value.is_bound()) return TRUE;\n"
3176 "return ", name
, name
);
3177 for (i
= 0; i
< sdef
->nElements
; i
++) {
3178 if (i
> 0) src
= mputstr(src
, "\n && ");
3179 src
= mputprintf(src
, "field_%s==other_value.field_%s",
3180 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
3182 src
= mputstr(src
, ";\n}\n\n");
3184 /* != and () operator */
3185 def
= mputprintf(def
,
3186 " inline boolean operator!=(const %s& other_value) const\n"
3187 " { return !(*this == other_value); }\n\n", name
);
3190 def
= mputprintf(def
,
3191 " boolean is_bound() const;\n\n");
3192 src
= mputprintf(src
,
3193 "boolean %s::is_bound() const\n"
3195 "if (bound_flag) return TRUE;\n", name
);
3196 for(i
=0; i
< sdef
->nElements
; i
++) {
3197 if(sdef
->elements
[i
].isOptional
) {
3198 src
= mputprintf(src
,
3199 "if(OPTIONAL_OMIT == field_%s.get_selection() || field_%s.is_bound()) return TRUE;\n",
3200 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
3202 src
= mputprintf(src
,
3203 "if(field_%s.is_bound()) return TRUE;\n",
3204 sdef
->elements
[i
].name
);
3207 src
= mputprintf(src
,
3213 "inline boolean is_present() const { return is_bound(); }\n");
3216 def
= mputprintf(def
,
3217 " boolean is_value() const;\n\n");
3218 src
= mputprintf(src
,
3219 "boolean %s::is_value() const\n"
3221 "if (!is_bound()) return FALSE;\n", name
);
3222 for(i
=0; i
< sdef
->nElements
; i
++) {
3223 if(sdef
->elements
[i
].isOptional
) {
3224 src
= mputprintf(src
,
3225 "if(OPTIONAL_OMIT != field_%s.get_selection() && !field_%s.is_value()) return FALSE;\n",
3226 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
3228 src
= mputprintf(src
,
3229 "if(!field_%s.is_value()) return FALSE;\n",
3230 sdef
->elements
[i
].name
);
3233 src
= mputprintf(src
,
3234 "return TRUE;\n}\n");
3236 /* field accessor methods */
3237 for (i
= 0; i
< sdef
->nElements
; i
++) {
3238 if(sdef
->elements
[i
].isOptional
)
3241 " inline OPTIONAL<%s>& %s()\n"
3242 " {return field_%s;}\n"
3243 " inline const OPTIONAL<%s>& %s() const\n"
3244 " {return field_%s;}\n",
3245 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
,
3246 sdef
->elements
[i
].name
,
3247 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
,
3248 sdef
->elements
[i
].name
);
3249 else def
= mputprintf
3251 " inline %s& %s()\n"
3252 " {return field_%s;}\n"
3253 " inline const %s& %s() const\n"
3254 " {return field_%s;}\n",
3255 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
,
3256 sdef
->elements
[i
].name
, sdef
->elements
[i
].type
,
3257 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
3261 /* sizeof operation */
3262 mandatory_fields_count
= 0;
3263 for (i
= 0; i
< sdef
->nElements
; i
++)
3264 if (!sdef
->elements
[i
].isOptional
) mandatory_fields_count
++;
3266 def
= mputstr(def
, " int size_of() const;\n");
3267 src
= mputprintf(src
,
3268 "int %s::size_of() const\n"
3270 " if (!is_bound()) "
3271 "TTCN_error(\"Calculating the size of an unbound record/set value of type %s\");\n"
3273 if (sdef
->nElements
== mandatory_fields_count
) {
3274 src
= mputprintf(src
, " return %lu;\n", (unsigned long) mandatory_fields_count
);
3277 src
= mputprintf(src
, " int ret_val = %lu;\n",
3278 (unsigned long) mandatory_fields_count
);
3279 for (i
= 0; i
< sdef
->nElements
; i
++)
3280 if (sdef
->elements
[i
].isOptional
)
3281 src
= mputprintf(src
,
3282 " if (field_%s.ispresent()) ret_val++;\n",
3283 sdef
->elements
[i
].name
);
3284 src
= mputstr(src
, " return ret_val;\n");
3286 src
= mputstr(src
, "}\n\n");
3289 def
= mputstr(def
, " void log() const;\n");
3290 src
= mputprintf(src
,
3291 "void %s::log() const\n{\n"
3292 "if (!is_bound()) {\n"
3293 "TTCN_Logger::log_event_unbound();\n"
3296 for (i
= 0; i
< sdef
->nElements
; i
++) {
3297 src
= mputstr(src
, "TTCN_Logger::log_event_str(\"");
3298 if (i
== 0) src
= mputc(src
, '{');
3299 else src
= mputc(src
, ',');
3300 src
= mputprintf(src
, " %s := \");\n"
3301 "field_%s.log();\n",
3302 sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
);
3304 src
= mputstr(src
, "TTCN_Logger::log_event_str(\" }\");\n}\n\n");
3306 /* set param function */
3307 def
= mputstr(def
, " void set_param(Module_Param& param);\n");
3310 "void %s::set_param(Module_Param& param)\n{\n"
3311 " bound_flag = TRUE;\n"
3312 " if (dynamic_cast<Module_Param_Name*>(param.get_id()) != NULL &&\n"
3313 " param.get_id()->next_name()) {\n"
3314 // Haven't reached the end of the module parameter name
3315 // => the name refers to one of the fields, not to the whole record
3316 " char* param_field = param.get_id()->get_current_name();\n"
3317 " if (param_field[0] >= '0' && param_field[0] <= '9') {\n"
3318 " param.error(\"Unexpected array index in module parameter, expected a valid field\"\n"
3319 " \" name for %s type `%s'\");\n"
3321 " ", name
, kind_str
, dispname
);
3322 for (i
= 0; i
< sdef
->nElements
; i
++) {
3323 src
= mputprintf(src
,
3324 "if (strcmp(\"%s\", param_field) == 0) {\n"
3325 " %s().set_param(param);\n"
3328 sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
);
3330 src
= mputprintf(src
,
3331 "param.error(\"Field `%%s' not found in %s type `%s'\", param_field);\n"
3333 " param.basic_check(Module_Param::BC_VALUE, \"%s value\");\n"
3334 " Module_Param_Ptr mp = ¶m;\n"
3335 " if (param.get_type() == Module_Param::MP_Reference) {\n"
3336 " mp = param.get_referenced_param();\n"
3338 " switch (mp->get_type()) {\n"
3339 " case Module_Param::MP_Value_List:\n"
3340 " if (%lu<mp->get_size()) {\n"
3341 " param.error(\"%s value of type %s has %lu fields but list value has %%d fields\", (int)mp->get_size());\n"
3343 kind_str
, dispname
, kind_str
, (unsigned long)sdef
->nElements
, kind_str
, dispname
, (unsigned long)sdef
->nElements
);
3345 for (i
= 0; i
< sdef
->nElements
; ++i
) {
3346 src
= mputprintf(src
,
3347 " if (mp->get_size()>%lu && mp->get_elem(%lu)->get_type()!=Module_Param::MP_NotUsed) %s().set_param(*mp->get_elem(%lu));\n",
3348 (unsigned long)i
, (unsigned long)i
, sdef
->elements
[i
].name
, (unsigned long)i
);
3352 " case Module_Param::MP_Assignment_List: {\n"
3353 " Vector<bool> value_used(mp->get_size());\n"
3354 " value_used.resize(mp->get_size(), false);\n");
3355 for (i
= 0; i
< sdef
->nElements
; ++i
) {
3356 src
= mputprintf(src
,
3357 " for (size_t val_idx=0; val_idx<mp->get_size(); val_idx++) {\n"
3358 " Module_Param* const curr_param = mp->get_elem(val_idx);\n"
3359 " if (!strcmp(curr_param->get_id()->get_name(), \"%s\")) {\n"
3360 " if (curr_param->get_type()!=Module_Param::MP_NotUsed) {\n"
3361 " %s().set_param(*curr_param);\n"
3363 " value_used[val_idx]=true;\n"
3366 , sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
);
3368 src
= mputprintf(src
,
3369 " for (size_t val_idx=0; val_idx<mp->get_size(); val_idx++) if (!value_used[val_idx]) {\n"
3370 " mp->get_elem(val_idx)->error(\"Non existent field name in type %s: %%s\", mp->get_elem(val_idx)->get_id()->get_name());\n"
3375 " param.type_error(\"%s value\", \"%s\");\n"
3377 "}\n\n", dispname
, kind_str
, dispname
);
3379 /* get param function */
3380 def
= mputstr(def
, "Module_Param* get_param(Module_Param_Name& param_name) const;\n");
3381 src
= mputprintf(src
,
3382 "Module_Param* %s::get_param(Module_Param_Name& param_name) const\n"
3384 " if (!is_bound()) {\n"
3385 " return new Module_Param_Unbound();\n"
3387 " if (param_name.next_name()) {\n"
3388 // Haven't reached the end of the module parameter name
3389 // => the name refers to one of the fields, not to the whole record
3390 " char* param_field = param_name.get_current_name();\n"
3391 " if (param_field[0] >= '0' && param_field[0] <= '9') {\n"
3392 " TTCN_error(\"Unexpected array index in module parameter reference, \"\n"
3393 " \"expected a valid field name for %s type `%s'\");\n"
3395 " ", name
, kind_str
, dispname
);
3396 for (i
= 0; i
< sdef
->nElements
; i
++) {
3397 src
= mputprintf(src
,
3398 "if (strcmp(\"%s\", param_field) == 0) {\n"
3399 " return %s().get_param(param_name);\n"
3401 sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
);
3403 src
= mputprintf(src
,
3404 "TTCN_error(\"Field `%%s' not found in %s type `%s'\", param_field);\n"
3406 " Module_Param_Assignment_List* mp = new Module_Param_Assignment_List();\n"
3407 , kind_str
, dispname
);
3408 for (i
= 0; i
< sdef
->nElements
; i
++) {
3409 src
= mputprintf(src
,
3410 " Module_Param* mp_field_%s = field_%s.get_param(param_name);\n"
3411 " mp_field_%s->set_id(new Module_Param_FieldName(mcopystr(\"%s\")));\n"
3412 " mp->add_elem(mp_field_%s);\n"
3413 , sdef
->elements
[i
].name
, sdef
->elements
[i
].name
3414 , sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
3415 , sdef
->elements
[i
].name
);
3421 /* set implicit omit function, recursive */
3422 def
= mputstr(def
, " void set_implicit_omit();\n");
3423 src
= mputprintf(src
, "void %s::set_implicit_omit()\n{\n", name
);
3424 for (i
= 0; i
< sdef
->nElements
; i
++) {
3425 if (sdef
->elements
[i
].isOptional
) {
3426 src
= mputprintf(src
,
3427 "if (!%s().is_bound()) %s() = OMIT_VALUE;\n"
3428 "else %s().set_implicit_omit();\n",
3429 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
3431 src
= mputprintf(src
,
3432 "if (%s().is_bound()) %s().set_implicit_omit();\n",
3433 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
3436 src
= mputstr(src
, "}\n\n");
3438 /* text encoder function */
3439 def
= mputstr(def
, " void encode_text(Text_Buf& text_buf) const;\n");
3440 src
= mputprintf(src
,
3441 "void %s::encode_text(Text_Buf& text_buf) const\n{\n"
3443 "TTCN_error(\"Text encoder: Encoding an unbound record/set value of type %s.\");\n"
3445 for (i
= 0; i
< sdef
->nElements
; i
++) {
3446 src
= mputprintf(src
, "field_%s.encode_text(text_buf);\n",
3447 sdef
->elements
[i
].name
);
3449 src
= mputstr(src
, "}\n\n");
3451 /* text decoder function */
3452 def
= mputstr(def
, " void decode_text(Text_Buf& text_buf);\n");
3453 src
= mputprintf(src
,
3454 "void %s::decode_text(Text_Buf& text_buf)\n{\n"
3455 "bound_flag = TRUE;\n", name
);
3456 for (i
= 0; i
< sdef
->nElements
; i
++) {
3457 src
= mputprintf(src
, "field_%s.decode_text(text_buf);\n",
3458 sdef
->elements
[i
].name
);
3460 src
= mputstr(src
, "}\n\n");
3462 /* The common "classname::encode()" and "classname::decode()" functions */
3463 if(ber_needed
|| raw_needed
|| text_needed
|| xer_needed
|| json_needed
)
3464 def_encdec(name
, &def
, &src
, ber_needed
, raw_needed
,
3465 text_needed
, xer_needed
, json_needed
, FALSE
);
3469 /* BER_encode_TLV() */
3472 "ASN_BER_TLV_t* %s::BER_encode_TLV(const TTCN_Typedescriptor_t& p_td,"
3473 " unsigned p_coding) const\n"
3475 " if (!is_bound()) TTCN_EncDec_ErrorContext::error"
3476 "(TTCN_EncDec::ET_UNBOUND, \"Encoding an unbound value.\");\n"
3477 " BER_chk_descr(p_td);\n"
3478 " ASN_BER_TLV_t *new_tlv=ASN_BER_TLV_t::construct(NULL);\n"
3479 " TTCN_EncDec_ErrorContext ec_0(\"Component '\");\n"
3480 " TTCN_EncDec_ErrorContext ec_1;\n"
3483 for(i
=0; i
<sdef
->nElements
; i
++) {
3484 if(!default_as_optional
&& sdef
->elements
[i
].isDefault
) { /* is DEFAULT */
3487 " if(field_%s!=%s) {\n"
3488 " ec_1.set_msg(\"%s': \");\n"
3489 " new_tlv->add_TLV(field_%s.BER_encode_TLV(%s_descr_,"
3492 , sdef
->elements
[i
].name
, sdef
->elements
[i
].defvalname
3493 , sdef
->elements
[i
].dispname
3494 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
3497 else { /* is not DEFAULT */
3500 " ec_1.set_msg(\"%s': \");\n"
3501 " new_tlv->add_TLV(field_%s.BER_encode_TLV(%s_descr_,"
3503 , sdef
->elements
[i
].dispname
3504 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
3508 if(sdef
->kind
==SET
) {
3511 " if(p_coding==BER_ENCODE_DER)\n"
3512 " new_tlv->sort_tlvs_tag();\n"
3517 " new_tlv=ASN_BER_V2TLV(new_tlv, p_td, p_coding);\n"
3518 " return new_tlv;\n"
3523 /* BER_decode_TLV() */
3526 "boolean %s::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,"
3527 " const ASN_BER_TLV_t& p_tlv, unsigned L_form)\n"
3529 " bound_flag = TRUE;\n"
3530 " BER_chk_descr(p_td);\n"
3531 " ASN_BER_TLV_t stripped_tlv;\n"
3532 " BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv);\n"
3533 " TTCN_EncDec_ErrorContext ec_0(\"While decoding '%s' type: \");\n"
3534 " stripped_tlv.chk_constructed_flag(TRUE);\n"
3535 " size_t V_pos=0;\n"
3536 " ASN_BER_TLV_t tmp_tlv;\n"
3537 , name
, sdef
->dispname
3540 if(sdef
->kind
==RECORD
)
3541 { /* SEQUENCE decoding */
3544 " boolean tlv_present=FALSE;\n"
3546 " TTCN_EncDec_ErrorContext ec_1(\"Component '\");\n"
3547 " TTCN_EncDec_ErrorContext ec_2;\n"
3549 for(i
=0; i
<sdef
->nElements
; i
++) {
3552 " ec_2.set_msg(\"%s': \");\n"
3553 " if(!tlv_present) tlv_present=BER_decode_constdTLV_next"
3554 "(stripped_tlv, V_pos, L_form, tmp_tlv);\n"
3555 , sdef
->elements
[i
].dispname
3557 if(sdef
->elements
[i
].isDefault
) { /* is DEFAULT */
3560 " if(!tlv_present || !field_%s.BER_decode_isMyMsg(%s_descr_,"
3564 " field_%s.BER_decode_TLV(%s_descr_, tmp_tlv,"
3566 " tlv_present=FALSE;\n"
3568 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
3569 , sdef
->elements
[i
].name
, sdef
->elements
[i
].defvalname
3570 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
3573 else if(sdef
->elements
[i
].isOptional
) { /* is OPTIONAL */
3576 " if(!tlv_present) field_%s=OMIT_VALUE;\n"
3578 " field_%s.BER_decode_TLV(%s_descr_, tmp_tlv, L_form);\n"
3579 " if(field_%s.ispresent()) tlv_present=FALSE;\n"
3581 , sdef
->elements
[i
].name
3582 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
3583 , sdef
->elements
[i
].name
3586 else { /* is not DEFAULT OPTIONAL */
3589 " if(!tlv_present){\n"
3590 " ec_2.error(TTCN_EncDec::ET_INCOMPL_MSG,\"Invalid or incomplete message was received.\");\n"
3593 " field_%s.BER_decode_TLV(%s_descr_, tmp_tlv, L_form);\n"
3594 " tlv_present=FALSE;\n"
3595 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
3602 " BER_decode_constdTLV_end(stripped_tlv, V_pos, L_form, tmp_tlv,"
3605 } /* SEQUENCE decoding */
3606 else { /* SET decoding */
3609 " const char *fld_name[%lu]={"
3610 , (unsigned long) sdef
->nElements
3612 for(i
=0; i
<sdef
->nElements
; i
++)
3617 , sdef
->elements
[i
].dispname
3620 * 0x01: value arrived
3621 * 0x02: is optional / not used :)
3622 * 0x04: has default / not used :)
3627 " unsigned char fld_indctr[%lu]={"
3628 , (unsigned long) sdef
->nElements
3630 for(i
=0; i
<sdef
->nElements
; i
++)
3639 " size_t fld_curr;\n"
3640 " while(BER_decode_constdTLV_next(stripped_tlv, V_pos,"
3641 " L_form, tmp_tlv)) {\n"
3643 for(i
=0; i
<sdef
->nElements
; i
++)
3646 " %sif(field_%s.BER_decode_isMyMsg(%s_descr_, tmp_tlv)) {\n"
3648 " TTCN_EncDec_ErrorContext ec_1(\"Component '%%s': \","
3649 " fld_name[%lu]);\n"
3650 " field_%s.BER_decode_TLV(%s_descr_, tmp_tlv, L_form);\n"
3653 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
3654 , (unsigned long) i
, (unsigned long) i
3655 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
3660 " /* ellipsis or error... */\n"
3661 " fld_curr=static_cast<size_t>(-1);\n"
3663 " if(fld_curr!=static_cast<size_t>(-1)) {\n"
3664 " if(fld_indctr[fld_curr])\n"
3665 " ec_0.error(TTCN_EncDec::ET_DEC_DUPFLD, \"Duplicated"
3666 " value for component '%%s'.\", fld_name[fld_curr]);\n"
3667 " fld_indctr[fld_curr]=1;\n"
3668 " }\n" /* if != -1 */
3670 " for(fld_curr=0; fld_curr<%lu; fld_curr++) {\n"
3671 " if(fld_indctr[fld_curr]) continue;\n"
3672 " switch(fld_curr) {\n"
3673 , (unsigned long) sdef
->nElements
3675 for(i
=0; i
<sdef
->nElements
; i
++) {
3676 if(sdef
->elements
[i
].isDefault
)
3683 , sdef
->elements
[i
].name
, sdef
->elements
[i
].defvalname
3685 else if(sdef
->elements
[i
].isOptional
)
3689 " field_%s=OMIT_VALUE;\n"
3692 , sdef
->elements
[i
].name
3698 " ec_0.error(TTCN_EncDec::ET_DEC_MISSFLD, \"Missing"
3699 " value for component '%s'.\", fld_name[fld_curr]);\n"
3701 " }\n" /* for fld_curr */
3703 } /* SET decoding */
3705 if(sdef
->opentype_outermost
) {
3708 " TTCN_EncDec_ErrorContext ec_1(\"While decoding opentypes: \");\n"
3709 " TTCN_Type_list p_typelist;\n"
3710 " BER_decode_opentypes(p_typelist, L_form);\n"
3712 } /* if sdef->opentype_outermost */
3720 if(sdef
->has_opentypes
) {
3721 /* BER_decode_opentypes() */
3724 "void BER_decode_opentypes(TTCN_Type_list& p_typelist,"
3725 " unsigned L_form);\n");
3728 "void %s::BER_decode_opentypes(TTCN_Type_list& p_typelist,"
3729 " unsigned L_form)\n"
3731 " bound_flag = TRUE;\n"
3732 " p_typelist.push(this);\n"
3733 " TTCN_EncDec_ErrorContext ec_0(\"Component '\");\n"
3734 " TTCN_EncDec_ErrorContext ec_1;\n"
3737 for(i
=0; i
<sdef
->nElements
; i
++) {
3740 " ec_1.set_msg(\"%s': \");\n"
3741 " field_%s.BER_decode_opentypes(p_typelist, L_form);\n"
3742 , sdef
->elements
[i
].dispname
3743 , sdef
->elements
[i
].name
3748 " p_typelist.pop();\n"
3752 } /* if sdef->has_opentypes */
3754 } /* if ber_needed */
3760 size_t last_man_index
=0;
3761 for(i
=0;i
<sdef
->nElements
;i
++){
3762 if(sdef
->elements
[i
].isOptional
) opt_number
++;
3763 else {man_num
++;last_man_index
=i
+1;}
3764 if(sdef
->elements
[i
].of_type
) seof
++;
3768 "int %s::TEXT_encode(const TTCN_Typedescriptor_t& p_td,"
3769 " TTCN_Buffer& p_buf) const{\n"
3770 " if (!is_bound()) TTCN_EncDec_ErrorContext::error"
3771 "(TTCN_EncDec::ET_UNBOUND, \"Encoding an unbound value.\");\n"
3772 " bool need_separator=false;\n"
3773 " int encoded_length=0;\n"
3774 " if(p_td.text->begin_encode){\n"
3775 " p_buf.put_cs(*p_td.text->begin_encode);\n"
3776 " encoded_length+=p_td.text->begin_encode->lengthof();\n"
3781 for(i
=0;i
<sdef
->nElements
;i
++){
3782 if(sdef
->elements
[i
].isOptional
){
3784 " if(field_%s.ispresent()){\n"
3785 ,sdef
->elements
[i
].name
3789 " if(need_separator && p_td.text->separator_encode){\n"
3790 " p_buf.put_cs(*p_td.text->separator_encode);\n"
3791 " encoded_length+=p_td.text->separator_encode->lengthof();\n"
3793 " encoded_length+=field_%s%s.TEXT_encode(%s_descr_,p_buf);\n"
3794 " need_separator=true;\n"
3795 ,sdef
->elements
[i
].name
3796 ,sdef
->elements
[i
].isOptional
?"()":"",sdef
->elements
[i
].typedescrname
3798 if(sdef
->elements
[i
].isOptional
){
3806 " if(p_td.text->end_encode){\n"
3807 " p_buf.put_cs(*p_td.text->end_encode);\n"
3808 " encoded_length+=p_td.text->end_encode->lengthof();\n"
3810 " return encoded_length;\n"
3814 if(sdef
->kind
==SET
){ /* set decoder start*/
3815 src
= mputprintf(src
,
3816 "int %s::TEXT_decode(const TTCN_Typedescriptor_t& p_td,"
3817 " TTCN_Buffer& p_buf, Limit_Token_List& limit, boolean no_err, boolean){\n"
3818 " bound_flag = TRUE;\n"
3819 " int decoded_length=0;\n"
3820 " int decoded_field_length=0;\n"
3821 " size_t pos=p_buf.get_pos();\n"
3822 " boolean sep_found=FALSE;\n"
3824 " int sep_length=0;\n"
3825 " int mand_field_num=%d;\n"
3826 " int opt_field_num=%d;\n"
3827 " int loop_detector=1;\n"
3828 " int last_field_num=-1;\n"
3829 " int field_map[%lu];\n"
3830 " memset(field_map, 0, sizeof(field_map));\n"
3831 " if(p_td.text->begin_decode){\n"
3833 " if((tl=p_td.text->begin_decode->match_begin(p_buf))<0){\n"
3834 " if(no_err)return -1;\n"
3835 " TTCN_EncDec_ErrorContext::error\n"
3836 " (TTCN_EncDec::ET_TOKEN_ERR, \"The specified token '%%s'"
3837 " not found for '%%s': \",(const char*)*(p_td.text->begin_decode)"
3841 " decoded_length+=tl;\n"
3842 " p_buf.increase_pos(tl);\n"
3844 " if(p_td.text->end_decode){\n"
3845 " limit.add_token(p_td.text->end_decode);\n"
3848 " if(p_td.text->separator_decode){\n"
3849 " limit.add_token(p_td.text->separator_decode);\n"
3852 ,name
,man_num
,opt_number
,(unsigned long) sdef
->nElements
3858 " int has_repeatable=0;\n"
3861 for(i
=0;i
<sdef
->nElements
;i
++){
3862 if(sdef
->elements
[i
].of_type
){
3864 "%s%s_descr_.text->val.parameters->decoding_params.repeatable"
3866 ,sdef
->elements
[i
].typedescrname
3872 ") has_repeatable=1;\n"
3876 for(i
=0;i
<sdef
->nElements
;i
++){
3877 if(sdef
->elements
[i
].isOptional
){
3879 " field_%s=OMIT_VALUE;\n"
3880 ,sdef
->elements
[i
].name
3884 src
= mputprintf(src
,
3885 " while(mand_field_num+opt_field_num%s){\n"
3886 " loop_detector=1;\n"
3888 ,seof
?"+has_repeatable":""
3891 for(i
=0;i
<sdef
->nElements
;i
++){
3892 if(sdef
->elements
[i
].of_type
){
3894 " if( (%s_descr_.text->val.parameters->decoding_params.repeatable"
3895 " && field_map[%lu]<3) || !field_map[%lu]){\n"
3896 " pos=p_buf.get_pos();\n"
3897 " decoded_field_length=field_%s%s.TEXT_decode(%s_descr_,p_buf,"
3898 "limit,true,!field_map[%lu]);\n"
3899 " if(decoded_field_length<0){\n"
3900 " p_buf.set_pos(pos);\n"
3901 ,sdef
->elements
[i
].typedescrname
,(unsigned long) i
,(unsigned long) i
3902 ,sdef
->elements
[i
].name
,sdef
->elements
[i
].isOptional
?"()":""
3903 ,sdef
->elements
[i
].typedescrname
3907 if(sdef
->elements
[i
].isOptional
){
3909 " if(!field_map[%lu]) field_%s=OMIT_VALUE;\n"
3911 ,sdef
->elements
[i
].name
3916 " loop_detector=0;\n"
3917 " if(!field_map[%lu]) {%s--;field_map[%lu]=1;}\n"
3918 " else field_map[%lu]=2;\n"
3919 " last_field_num=%lu;\n"
3924 ,sdef
->elements
[i
].isOptional
?"opt_field_num":"mand_field_num"
3925 ,(unsigned long) i
,(unsigned long) i
,(unsigned long) i
3929 " if(!field_map[%lu]){\n"
3930 " pos=p_buf.get_pos();\n"
3931 " decoded_field_length=field_%s%s.TEXT_decode(%s_descr_,p_buf,"
3933 " if(decoded_field_length<0){\n"
3934 " p_buf.set_pos(pos);\n"
3937 " loop_detector=0;\n"
3938 " field_map[%lu]=1;\n"
3940 " last_field_num=%lu;\n"
3945 ,sdef
->elements
[i
].name
,sdef
->elements
[i
].isOptional
?"()":""
3946 ,sdef
->elements
[i
].typedescrname
3947 ,sdef
->elements
[i
].isOptional
?" field_":""
3948 ,sdef
->elements
[i
].isOptional
?sdef
->elements
[i
].name
:""
3949 ,sdef
->elements
[i
].isOptional
?"=OMIT_VALUE;\n":"",(unsigned long) i
3950 ,sdef
->elements
[i
].isOptional
?"opt_field_num":"mand_field_num"
3959 " if(loop_detector) break;\n"
3960 " if(p_td.text->separator_decode){\n"
3962 " if((tl=p_td.text->separator_decode->match_begin(p_buf))<0){\n"
3963 " if(p_td.text->end_decode){\n"
3965 " if((tl=p_td.text->end_decode->match_begin(p_buf))!=-1){\n"
3966 " sep_found=FALSE;\n"
3969 " } else if(limit.has_token(ml)){\n"
3971 " if((tl=limit.match(p_buf,ml))==0){\n"
3972 " sep_found=FALSE;\n"
3976 " p_buf.set_pos(pos);\n"
3977 " decoded_length-=decoded_field_length;\n"
3978 " field_map[last_field_num]+=2;\n"
3983 "switch(last_field_num){\n"
3985 for(i
=0;i
<sdef
->nElements
;i
++){
3986 if(sdef
->elements
[i
].of_type
){
3987 if(sdef
->elements
[i
].isOptional
){
3990 " if(field_map[%lu]==3){\n"
3991 " field_%s=OMIT_VALUE;\n"
3992 " opt_field_num++;\n"
3995 ,(unsigned long) i
,(unsigned long) i
,sdef
->elements
[i
].name
4000 " if(field_map[%lu]==3){\n"
4001 " mand_field_num++;\n"
4004 ,(unsigned long) i
,(unsigned long) i
4007 } else if(sdef
->elements
[i
].isOptional
){
4010 " field_%s=OMIT_VALUE;\n"
4011 " opt_field_num++;\n"
4013 ,(unsigned long) i
,sdef
->elements
[i
].name
4019 " mand_field_num++;\n"
4025 src
= mputprintf(src
,
4028 " decoded_length+=tl;\n"
4029 " p_buf.increase_pos(tl);\n"
4030 " for(int a=0;a<%lu;a++) if(field_map[a]>2) field_map[a]-=3;\n"
4031 " sep_found=TRUE;}\n"
4032 " } else if(p_td.text->end_decode){\n"
4034 " if((tl=p_td.text->end_decode->match_begin(p_buf))!=-1){\n"
4035 " decoded_length+=tl;\n"
4036 " p_buf.increase_pos(tl);\n"
4037 " limit.remove_tokens(ml);\n"
4038 " if(mand_field_num) return -1;\n"
4039 " return decoded_length;\n"
4041 " } else if(limit.has_token(ml)){\n"
4043 " if((tl=limit.match(p_buf,ml))==0){\n"
4044 " sep_found=FALSE;\n"
4049 " limit.remove_tokens(ml);\n"
4051 " if(mand_field_num){\n"
4052 " if(no_err)return -1;\n"
4053 " TTCN_EncDec_ErrorContext::error"
4054 "(TTCN_EncDec::ET_TOKEN_ERR, \"Error during decoding '%%s': \","
4056 " return decoded_length;\n"
4058 " decoded_length-=sep_length;\n"
4059 " p_buf.set_pos(p_buf.get_pos()-sep_length);\n"
4062 " if(p_td.text->end_decode){\n"
4064 " if((tl=p_td.text->end_decode->match_begin(p_buf))<0){\n"
4065 " if(no_err)return -1;\n"
4066 " TTCN_EncDec_ErrorContext::error"
4067 "(TTCN_EncDec::ET_TOKEN_ERR, \"The specified token '%%s'"
4068 " not found for '%%s': \",(const char*)*(p_td.text->end_decode)"
4070 " return decoded_length;\n"
4072 " decoded_length+=tl;\n"
4073 " p_buf.increase_pos(tl);\n"
4075 " if(mand_field_num) return -1;\n"
4076 " return decoded_length;\n"
4078 ,(unsigned long) sdef
->nElements
4080 } else { /* record decoder start */
4081 src
= mputprintf(src
,
4082 "int %s::TEXT_decode(const TTCN_Typedescriptor_t& p_td,"
4083 " TTCN_Buffer& p_buf, Limit_Token_List& limit, boolean no_err, boolean){\n"
4084 " bound_flag = TRUE;\n"
4085 " int decoded_length=0;\n"
4086 " int decoded_field_length=0;\n"
4088 " boolean sep_found=FALSE;\n"
4089 " int sep_length=0;\n"
4091 " if(p_td.text->begin_decode){\n"
4093 " if((tl=p_td.text->begin_decode->match_begin(p_buf))<0){\n"
4094 " if(no_err)return -1;\n"
4095 " TTCN_EncDec_ErrorContext::error\n"
4096 " (TTCN_EncDec::ET_TOKEN_ERR, \"The specified token '%%s'"
4097 " not found for '%%s': \",(const char*)*(p_td.text->begin_decode)"
4101 " decoded_length+=tl;\n"
4102 " p_buf.increase_pos(tl);\n"
4104 " if(p_td.text->end_decode){\n"
4105 " limit.add_token(p_td.text->end_decode);\n"
4108 " if(p_td.text->separator_decode){\n"
4109 " limit.add_token(p_td.text->separator_decode);\n"
4112 ,name
,opt_number
?" size_t pos=p_buf.get_pos();\n":""
4114 for(i
=0;i
<sdef
->nElements
;i
++){
4115 if(sdef
->elements
[i
].isOptional
){
4117 " field_%s=OMIT_VALUE;\n"
4118 ,sdef
->elements
[i
].name
4124 for(i
=0;i
<sdef
->nElements
;i
++){
4125 if(sdef
->elements
[i
].isOptional
){
4127 " pos=p_buf.get_pos();\n"
4131 " decoded_field_length=field_%s%s.TEXT_decode(%s_descr_,p_buf"
4133 " if(decoded_field_length<0){\n"
4134 ,sdef
->elements
[i
].name
,sdef
->elements
[i
].isOptional
?"()":""
4135 ,sdef
->elements
[i
].typedescrname
4137 if(sdef
->elements
[i
].isOptional
){
4139 " field_%s=OMIT_VALUE;\n"
4140 " p_buf.set_pos(pos);\n"
4142 ,sdef
->elements
[i
].name
4146 " limit.remove_tokens(ml);\n"
4147 " if(no_err)return -1;\n"
4148 " TTCN_EncDec_ErrorContext::error"
4149 "(TTCN_EncDec::ET_TOKEN_ERR, \"Error during decoding "
4150 "field '%s' for '%%s': \", p_td.name);\n"
4151 " return decoded_length;\n"
4153 ,sdef
->elements
[i
].name
4157 " decoded_length+=decoded_field_length;\n"
4159 if(last_man_index
>(i
+1)){
4161 " if(p_td.text->separator_decode){\n"
4163 " if((tl=p_td.text->separator_decode->match_begin(p_buf))<0){\n"
4166 if(sdef
->elements
[i
].isOptional
){
4168 " field_%s=OMIT_VALUE;\n"
4169 " p_buf.set_pos(pos);\n"
4170 " decoded_length-=decoded_field_length;\n"
4171 ,sdef
->elements
[i
].name
4175 " limit.remove_tokens(ml);\n"
4176 " if(no_err)return -1;\n"
4177 " TTCN_EncDec_ErrorContext::error"
4178 "(TTCN_EncDec::ET_TOKEN_ERR, \"The specified token '%s'"
4179 " not found for '%s': \",(const char*)*(p_td.text->"
4180 "separator_decode),p_td.name);\n"
4181 " return decoded_length;\n"
4187 " decoded_length+=tl;\n"
4188 " p_buf.increase_pos(tl);\n"
4190 " sep_found=TRUE;}\n"
4191 " } else sep_found=FALSE;\n"
4193 } else if(i
==(sdef
->nElements
-1)){
4195 " sep_found=FALSE;\n"
4199 " if(p_td.text->separator_decode){\n"
4201 " if((tl=p_td.text->separator_decode->match_begin(p_buf))<0){\n"
4203 if(sdef
->elements
[i
].isOptional
){
4205 " if(p_td.text->end_decode){\n"
4207 " if((tl=p_td.text->end_decode->match_begin(p_buf))!=-1){\n"
4208 " decoded_length+=tl;\n"
4209 " p_buf.increase_pos(tl);\n"
4210 " limit.remove_tokens(ml);\n"
4211 " return decoded_length;\n"
4213 " } else if(limit.has_token(ml)){\n"
4214 " if((tl=limit.match(p_buf,ml))==0){\n"
4215 " sep_found=FALSE;\n"
4219 " field_%s=OMIT_VALUE;\n"
4220 " p_buf.set_pos(pos);\n"
4221 " decoded_length-=decoded_field_length;\n"
4222 ,sdef
->elements
[i
].name
4226 " sep_found=FALSE;\n"
4232 " decoded_length+=tl;\n"
4233 " p_buf.increase_pos(tl);\n"
4235 " sep_found=TRUE;}\n"
4237 " sep_found=FALSE;\n"
4238 " if(p_td.text->end_decode){\n"
4240 " if((tl=p_td.text->end_decode->match_begin(p_buf))!=-1){\n"
4241 " decoded_length+=tl;\n"
4242 " p_buf.increase_pos(tl);\n"
4243 " limit.remove_tokens(ml);\n"
4244 " return decoded_length;\n"
4246 " } else if(limit.has_token(ml)){\n"
4248 " if((tl=limit.match(p_buf,ml))==0){\n"
4249 " sep_found=FALSE;\n"
4264 " limit.remove_tokens(ml);\n"
4266 " p_buf.set_pos(p_buf.get_pos()-sep_length);\n"
4267 " decoded_length-=sep_length;\n"
4269 " if(p_td.text->end_decode){\n"
4271 " if((tl=p_td.text->end_decode->match_begin(p_buf))<0){\n"
4272 " if(no_err)return -1;\n"
4273 " TTCN_EncDec_ErrorContext::error"
4274 "(TTCN_EncDec::ET_TOKEN_ERR, \"The specified token '%s'"
4275 " not found for '%s': \",(const char*)*(p_td.text->end_decode)"
4277 " return decoded_length;\n"
4279 " decoded_length+=tl;\n"
4280 " p_buf.increase_pos(tl);\n"
4282 " return decoded_length;\n"
4290 struct raw_option_struct
*raw_options
;
4291 boolean haslengthto
, haspointer
, hascrosstag
, has_ext_bit
;
4292 raw_options
= (struct raw_option_struct
*)
4293 Malloc(sdef
->nElements
* sizeof(*raw_options
));
4295 set_raw_options(sdef
, raw_options
, &haslengthto
,
4296 &haspointer
, &hascrosstag
, &has_ext_bit
);
4298 src
= generate_raw_coding(src
, sdef
, raw_options
, haspointer
, hascrosstag
,
4301 for (i
= 0; i
< sdef
->nElements
; i
++) {
4302 Free(raw_options
[i
].lengthoffield
);
4303 Free(raw_options
[i
].dependent_fields
);
4306 } /* if raw_needed */
4308 if (xer_needed
) gen_xer(sdef
, &def
, &src
);
4312 src
= mputprintf(src
,
4313 "int %s::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const\n"
4315 " if (!is_bound()) {\n"
4316 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,\n"
4317 " \"Encoding an unbound value of type %s.\");\n"
4320 " int enc_len = p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL);\n\n"
4322 for (i
= 0; i
< sdef
->nElements
; ++i
) {
4323 if (sdef
->elements
[i
].isOptional
&& !sdef
->elements
[i
].jsonOmitAsNull
&&
4324 !sdef
->elements
[i
].jsonMetainfoUnbound
) {
4325 src
= mputprintf(src
,
4326 " if (field_%s.is_present())\n"
4327 , sdef
->elements
[i
].name
);
4329 src
= mputprintf(src
,
4331 " enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, \"%s\");\n "
4332 , sdef
->elements
[i
].jsonAlias
? sdef
->elements
[i
].jsonAlias
: sdef
->elements
[i
].dispname
);
4333 if (sdef
->elements
[i
].jsonMetainfoUnbound
) {
4334 src
= mputprintf(src
,
4335 "if (!field_%s.is_bound()) {\n"
4336 " enc_len += p_tok.put_next_token(JSON_TOKEN_LITERAL_NULL);\n"
4337 " enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, \"metainfo %s\");\n"
4338 " enc_len += p_tok.put_next_token(JSON_TOKEN_STRING, \"\\\"unbound\\\"\");\n"
4341 , sdef
->elements
[i
].name
4342 , sdef
->elements
[i
].jsonAlias
? sdef
->elements
[i
].jsonAlias
: sdef
->elements
[i
].dispname
);
4344 src
= mputprintf(src
,
4345 "enc_len += field_%s.JSON_encode(%s_descr_, p_tok);\n"
4347 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
);
4350 " enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);\n"
4351 " return enc_len;\n"
4355 src
= mputprintf(src
,
4356 "int %s::JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok, boolean p_silent)\n"
4358 " json_token_t j_token = JSON_TOKEN_NONE;\n"
4359 " int dec_len = p_tok.get_next_token(&j_token, NULL, NULL);\n"
4360 " if (JSON_TOKEN_ERROR == j_token) {\n"
4361 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, \"\");\n"
4362 " return JSON_ERROR_FATAL;\n"
4364 " else if (JSON_TOKEN_OBJECT_START != j_token) {\n"
4365 " return JSON_ERROR_INVALID_TOKEN;\n"
4367 " bound_flag = TRUE;\n\n"
4369 boolean has_metainfo_enabled
= FALSE
;
4370 for (i
= 0; i
< sdef
->nElements
; ++i
) {
4371 if (sdef
->elements
[i
].jsonMetainfoUnbound
) {
4372 // initialize meta info states
4373 src
= mputprintf(src
,
4374 " int metainfo_%s = JSON_METAINFO_NONE;\n"
4375 , sdef
->elements
[i
].name
);
4376 has_metainfo_enabled
= TRUE
;
4380 // Read name - value token pairs until we reach some other token
4381 "\n while (true) {\n"
4382 " char* fld_name = 0;\n"
4383 " size_t name_len = 0;\n"
4384 " size_t buf_pos = p_tok.get_buf_pos();\n"
4385 " dec_len += p_tok.get_next_token(&j_token, &fld_name, &name_len);\n"
4386 " if (JSON_TOKEN_ERROR == j_token) {\n"
4387 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_NAME_TOKEN_ERROR);\n"
4388 " return JSON_ERROR_FATAL;\n"
4390 // undo the last action on the buffer
4391 " else if (JSON_TOKEN_NAME != j_token) {\n"
4392 " p_tok.set_buf_pos(buf_pos);\n"
4396 if (has_metainfo_enabled
) {
4397 // check for meta info
4399 "boolean is_metainfo = FALSE;\n"
4400 " if (name_len > 9 && 0 == strncmp(fld_name, \"metainfo \", 9)) {\n"
4403 " is_metainfo = TRUE;\n"
4406 for (i
= 0; i
< sdef
->nElements
; ++i
) {
4407 src
= mputprintf(src
,
4409 "if (%d == name_len && 0 == strncmp(fld_name, \"%s\", name_len)) {\n"
4410 , (int)strlen(sdef
->elements
[i
].jsonAlias
? sdef
->elements
[i
].jsonAlias
: sdef
->elements
[i
].dispname
)
4411 , sdef
->elements
[i
].jsonAlias
? sdef
->elements
[i
].jsonAlias
: sdef
->elements
[i
].dispname
);
4412 if (has_metainfo_enabled
) {
4413 src
= mputstr(src
, " if (is_metainfo) {\n");
4414 if (sdef
->elements
[i
].jsonMetainfoUnbound
) {
4415 src
= mputprintf(src
,
4417 " char* info_value = 0;\n"
4418 " size_t info_len = 0;\n"
4419 " dec_len += p_tok.get_next_token(&j_token, &info_value, &info_len);\n"
4420 " if (JSON_TOKEN_STRING == j_token && 9 == info_len &&\n"
4421 " 0 == strncmp(info_value, \"\\\"unbound\\\"\", 9)) {\n"
4422 " metainfo_%s = JSON_METAINFO_UNBOUND;\n"
4425 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_METAINFO_VALUE_ERROR, \"%s\");\n"
4426 " return JSON_ERROR_FATAL;\n"
4428 , sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
);
4431 src
= mputprintf(src
,
4432 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_METAINFO_NOT_APPLICABLE, \"%s\");\n"
4433 " return JSON_ERROR_FATAL;\n"
4434 , sdef
->elements
[i
].dispname
);
4439 if (sdef
->elements
[i
].jsonMetainfoUnbound
) {
4440 src
= mputstr(src
, " buf_pos = p_tok.get_buf_pos();\n");
4443 src
= mputprintf(src
,
4444 " int ret_val = field_%s.JSON_decode(%s_descr_, p_tok, p_silent);\n"
4445 " if (0 > ret_val) {\n"
4446 " if (JSON_ERROR_INVALID_TOKEN == ret_val) {\n"
4447 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
);
4448 if (sdef
->elements
[i
].jsonMetainfoUnbound
) {
4449 src
= mputprintf(src
,
4450 // undo the last action on the buffer, check if the invalid token was a null token
4451 " p_tok.set_buf_pos(buf_pos);\n"
4452 " p_tok.get_next_token(&j_token, NULL, NULL);\n"
4453 " if (JSON_TOKEN_LITERAL_NULL == j_token) {\n"
4454 " if (JSON_METAINFO_NONE == metainfo_%s) {\n"
4455 // delay reporting an error for now, there might be meta info later
4456 " metainfo_%s = JSON_METAINFO_NEEDED;\n"
4459 " else if (JSON_METAINFO_UNBOUND == metainfo_%s) {\n"
4460 // meta info already found
4464 , sdef
->elements
[i
].name
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
4466 src
= mputprintf(src
,
4467 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, \"%s\");\n"
4469 " return JSON_ERROR_FATAL;\n"
4471 " dec_len += ret_val;\n"
4472 , sdef
->elements
[i
].dispname
);
4473 if (has_metainfo_enabled
) {
4474 src
= mputstr(src
, " }\n");
4480 src
= mputprintf(src
,
4482 // invalid field name
4483 " char* fld_name2 = mcopystrn(fld_name, name_len);\n"
4484 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, %sJSON_DEC_INVALID_NAME_ERROR, fld_name2);\n"
4485 // if this is set to a warning, skip the value of the field
4486 " dec_len += p_tok.get_next_token(&j_token, NULL, NULL);\n"
4487 " if (JSON_TOKEN_NUMBER != j_token && JSON_TOKEN_STRING != j_token &&\n"
4488 " JSON_TOKEN_LITERAL_TRUE != j_token && JSON_TOKEN_LITERAL_FALSE != j_token &&\n"
4489 " JSON_TOKEN_LITERAL_NULL != j_token) {\n"
4490 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, fld_name2);\n"
4491 " Free(fld_name2);\n"
4492 " return JSON_ERROR_FATAL;\n"
4494 " Free(fld_name2);\n"
4498 " dec_len += p_tok.get_next_token(&j_token, NULL, NULL);\n"
4499 " if (JSON_TOKEN_OBJECT_END != j_token) {\n"
4500 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_OBJECT_END_TOKEN_ERROR, \"\");\n"
4501 " return JSON_ERROR_FATAL;\n"
4503 , has_metainfo_enabled
? "is_metainfo ?\n JSON_DEC_METAINFO_NAME_ERROR : " : "");
4504 // Check if every field has been set and handle meta info
4505 for (i
= 0; i
< sdef
->nElements
; ++i
) {
4506 if (sdef
->elements
[i
].jsonMetainfoUnbound
) {
4507 src
= mputprintf(src
,
4508 "if (JSON_METAINFO_UNBOUND == metainfo_%s) {\n"
4509 " field_%s.clean_up();\n"
4511 " else if (JSON_METAINFO_NEEDED == metainfo_%s) {\n"
4512 // no meta info was found for this field, report the delayed error
4513 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, \"%s\");\n"
4516 , sdef
->elements
[i
].name
, sdef
->elements
[i
].name
4517 , sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
);
4519 src
= mputprintf(src
,
4520 "if (!field_%s.is_bound()) {\n"
4521 , sdef
->elements
[i
].name
);
4522 if (sdef
->elements
[i
].jsonDefaultValue
) {
4523 src
= mputprintf(src
,
4524 " field_%s.JSON_decode(%s_descr_, DUMMY_BUFFER, p_silent);\n"
4525 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
);
4527 else if (sdef
->elements
[i
].isOptional
) {
4528 src
= mputprintf(src
,
4529 " field_%s = OMIT_VALUE;\n"
4530 , sdef
->elements
[i
].name
);
4532 src
= mputprintf(src
,
4533 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_MISSING_FIELD_ERROR, \"%s\");\n"
4534 " return JSON_ERROR_FATAL;\n"
4535 , sdef
->elements
[i
].dispname
);
4541 "\n return dec_len;\n"
4545 /* end of class definition */
4546 def
= mputstr(def
, "};\n\n");
4548 output
->header
.class_defs
= mputstr(output
->header
.class_defs
, def
);
4551 output
->source
.methods
= mputstr(output
->source
.methods
, src
);
4556 static char *genRawFieldDecodeLimit(char *src
, const struct_def
*sdef
,
4557 int i
, const struct raw_option_struct
*raw_options
)
4559 /* number of arguments passed to min_of_ints() */
4562 for (j
= 0; j
< raw_options
[i
].lengthof
; j
++) {
4563 int field_index
= raw_options
[i
].lengthoffield
[j
];
4564 if (i
> field_index
&& sdef
->elements
[field_index
].raw
.unit
!=-1)
4567 if (raw_options
[i
].extbitgroup
&& sdef
->raw
.ext_bit_groups
[
4568 raw_options
[i
].extbitgroup
-1].ext_bit
!= XDEFNO
) nof_args
++;
4570 src
= mputprintf(src
, "min_of_ints(%d, limit", nof_args
);
4571 for (j
= 0; j
< raw_options
[i
].lengthof
; j
++) {
4572 int field_index
= raw_options
[i
].lengthoffield
[j
];
4573 if (i
> field_index
&& sdef
->elements
[field_index
].raw
.unit
!= -1)
4574 src
= mputprintf(src
, ", value_of_length_field%d", field_index
);
4576 if (raw_options
[i
].extbitgroup
&& sdef
->raw
.ext_bit_groups
[
4577 raw_options
[i
].extbitgroup
-1].ext_bit
!= XDEFNO
)
4578 src
= mputstr(src
, ", group_limit");
4579 src
= mputc(src
, ')');
4581 src
= mputstr(src
, "limit");
4586 static char *genRawDecodeRecordField(char *src
, const struct_def
*sdef
,
4587 int i
, const struct raw_option_struct
*raw_options
, boolean delayed_decode
,
4588 int *prev_ext_group
)
4591 if(raw_options
[i
].ptrbase
)
4593 " start_pos_of_field%d=p_buf.get_pos_bit();\n"
4596 if (*prev_ext_group
!= raw_options
[i
].extbitgroup
) {
4597 *prev_ext_group
= raw_options
[i
].extbitgroup
;
4598 if(prev_ext_group
&&
4599 sdef
->raw
.ext_bit_groups
[raw_options
[i
].extbitgroup
-1].ext_bit
!=XDEFNO
){
4600 if(raw_options
[i
].pointerof
) /* pointed field */
4602 " {size_t old_pos=p_buf.get_pos_bit();\n"
4603 " if(start_of_field%d!=-1 && start_pos_of_field%d!=-1){\n"
4604 " start_of_field%d=start_pos_of_field%d"
4605 "+(int)field_%s%s*%d+%d;\n"
4606 " p_buf.set_pos_bit(start_of_field%d);\n"
4607 " limit=end_of_available_data-start_of_field%d;\n"
4609 ,sdef
->elements
[raw_options
[i
].pointerof
-1].raw
.pointerbase
4611 ,sdef
->elements
[raw_options
[i
].pointerof
-1].raw
.pointerbase
4612 ,sdef
->elements
[raw_options
[i
].pointerof
-1].name
4613 ,sdef
->elements
[raw_options
[i
].pointerof
-1].isOptional
?"()":""
4614 ,sdef
->elements
[raw_options
[i
].pointerof
-1].raw
.unit
4615 ,sdef
->elements
[raw_options
[i
].pointerof
-1].raw
.ptroffset
4620 " cbyte* data=p_buf.get_read_data();\n"
4622 " int rot=local_top_order==ORDER_LSB?0:7;\n"
4623 " while(((data[count-1]>>rot)&0x01)==%d && count*8<"
4624 "(int)limit) count++;\n"
4625 " if(limit) group_limit=count*8;\n"
4627 ,sdef
->raw
.ext_bit_groups
[raw_options
[i
].extbitgroup
-1].ext_bit
==
4630 if(raw_options
[i
].pointerof
) /* pointed field */
4632 " } else group_limit=0;\n"
4633 " p_buf.set_pos_bit(old_pos);\n"
4634 " limit=end_of_available_data-old_pos;}\n"
4638 if(sdef
->elements
[i
].hasRaw
&& /* check the crosstag */
4639 sdef
->elements
[i
].raw
.crosstaglist
.nElements
){
4640 /* field index of the otherwise rule */
4642 boolean first_value
= TRUE
;
4644 for (j
= 0; j
< sdef
->elements
[i
].raw
.crosstaglist
.nElements
; j
++) {
4645 rawAST_coding_taglist
* cur_choice
=
4646 sdef
->elements
[i
].raw
.crosstaglist
.list
+ j
;
4647 if (cur_choice
->nElements
> 0) {
4648 /* this is a normal rule */
4650 src
= mputstr(src
, " if (");
4651 first_value
= FALSE
;
4652 } else src
= mputstr(src
, " else if (");
4653 src
= genRawFieldChecker(src
, cur_choice
, TRUE
);
4654 /* set selected_field in the if's body */
4655 src
= mputprintf(src
, ") selected_field = %d;\n",
4656 cur_choice
->fieldnum
);
4658 /* this is an otherwise rule */
4659 other
= cur_choice
->fieldnum
;
4662 /* set selected_field to the field index of the otherwise rule or -1 */
4663 src
= mputprintf(src
, " else selected_field = %d;\n", other
);
4665 /* check the presence of optional field*/
4666 if(sdef
->elements
[i
].isOptional
){
4667 /* check if enough bits to decode the field*/
4668 src
= mputstr(src
, " if (limit > 0");
4669 for (a
= 0; a
< raw_options
[i
].lengthof
; a
++){
4670 int field_index
= raw_options
[i
].lengthoffield
[a
];
4671 if (i
> field_index
) src
= mputprintf(src
,
4672 " && value_of_length_field%d > 0", field_index
);
4674 if (raw_options
[i
].extbitgroup
&&
4675 sdef
->raw
.ext_bit_groups
[raw_options
[i
].extbitgroup
-1].ext_bit
!=XDEFNO
){
4676 src
= mputstr(src
, " && group_limit > 0");
4678 if(raw_options
[i
].pointerof
){ /* valid pointer?*/
4680 " && start_of_field%d!=-1 && start_pos_of_field%d!=-1"
4681 ,i
,sdef
->elements
[raw_options
[i
].pointerof
-1].raw
.pointerbase
4684 if(sdef
->elements
[i
].hasRaw
&&
4685 sdef
->elements
[i
].raw
.presence
.nElements
)
4687 src
= mputstr(src
, " && ");
4688 if (sdef
->elements
[i
].raw
.presence
.nElements
> 1) src
= mputc(src
, '(');
4689 src
= genRawFieldChecker(src
, &sdef
->elements
[i
].raw
.presence
, TRUE
);
4690 if (sdef
->elements
[i
].raw
.presence
.nElements
> 1) src
= mputc(src
, ')');
4692 if(sdef
->elements
[i
].hasRaw
&&
4693 sdef
->elements
[i
].raw
.crosstaglist
.nElements
)
4696 "&& selected_field!=-1"
4703 if(raw_options
[i
].pointerof
){ /* pointed field */
4705 " start_of_field%d=start_pos_of_field%d"
4706 "+(int)field_%s%s*%d+%d;\n"
4708 ,sdef
->elements
[raw_options
[i
].pointerof
-1].raw
.pointerbase
4709 ,sdef
->elements
[raw_options
[i
].pointerof
-1].name
4710 ,sdef
->elements
[raw_options
[i
].pointerof
-1].isOptional
?"()":""
4711 ,sdef
->elements
[raw_options
[i
].pointerof
-1].raw
.unit
4712 ,sdef
->elements
[raw_options
[i
].pointerof
-1].raw
.ptroffset
4715 " p_buf.set_pos_bit(start_of_field%d);\n"
4716 " limit=end_of_available_data-start_of_field%d;\n"
4720 /* decoding of normal field */
4721 if (sdef
->elements
[i
].isOptional
) src
= mputstr(src
,
4722 " size_t fl_start_pos = p_buf.get_pos_bit();\n");
4723 src
= mputprintf(src
,
4724 " decoded_field_length = field_%s%s.RAW_decode(%s_descr_, p_buf, ",
4725 sdef
->elements
[i
].name
, sdef
->elements
[i
].isOptional
? "()" : "",
4726 sdef
->elements
[i
].typedescrname
);
4727 if (delayed_decode
) {
4728 /* the fixed field length is used as limit in case of delayed decoding */
4729 src
= mputprintf(src
, "%d", sdef
->elements
[i
].raw
.length
);
4731 src
= genRawFieldDecodeLimit(src
, sdef
, i
, raw_options
);
4733 src
= mputprintf(src
, ", local_top_order, %s",
4734 sdef
->elements
[i
].isOptional
? "TRUE" : "no_err");
4735 if (sdef
->elements
[i
].hasRaw
&&
4736 sdef
->elements
[i
].raw
.crosstaglist
.nElements
> 0)
4737 src
= mputstr(src
, ", selected_field");
4738 for (a
= 0; a
< raw_options
[i
].lengthof
; a
++) {
4739 int field_index
= raw_options
[i
].lengthoffield
[a
];
4740 /* number of elements in 'record of' or 'set of' */
4741 if (sdef
->elements
[field_index
].raw
.unit
== -1) {
4742 src
= mputprintf(src
, ", value_of_length_field%d", field_index
);
4746 src
= mputstr(src
, ");\n");
4747 if (delayed_decode
) {
4748 src
= mputprintf(src
, " if (decoded_field_length != %d) return -1;\n",
4749 sdef
->elements
[i
].raw
.length
);
4750 } else if (sdef
->elements
[i
].isOptional
) {
4751 src
= mputprintf(src
, " if (decoded_field_length < 1) {\n"
4752 " field_%s = OMIT_VALUE;\n" /* transform errors into omit */
4753 " p_buf.set_pos_bit(fl_start_pos);\n"
4754 " } else {\n", sdef
->elements
[i
].name
);
4756 src
= mputstr(src
, " if (decoded_field_length < 0) return decoded_field_length;\n");
4758 if(raw_options
[i
].tag_type
&& sdef
->raw
.taglist
.list
[raw_options
[i
].tag_type
-1].nElements
){
4759 rawAST_coding_taglist
* cur_choice
=
4760 sdef
->raw
.taglist
.list
+raw_options
[i
].tag_type
-1;
4763 src
=genRawFieldChecker(src
,cur_choice
,FALSE
);
4766 if(sdef
->elements
[i
].isOptional
){
4768 "{\n field_%s=OMIT_VALUE;\n"
4769 " p_buf.set_pos_bit(fl_start_pos);\n }\n"
4771 ,sdef
->elements
[i
].name
4773 }else src
=mputstr(src
, " return -1;\n");
4775 if (!delayed_decode
) {
4777 " decoded_length+=decoded_field_length;\n"
4778 " limit-=decoded_field_length;\n"
4779 " last_decoded_pos=bigger(last_decoded_pos, p_buf.get_pos_bit());\n"
4782 if(raw_options
[i
].extbitgroup
&&
4783 sdef
->raw
.ext_bit_groups
[raw_options
[i
].extbitgroup
-1].ext_bit
!=XDEFNO
){
4785 "group_limit-=decoded_field_length;\n"
4788 if(raw_options
[i
].lengthto
){ /* if the field is lengthto store the value*/
4789 if(sdef
->elements
[i
].raw
.lengthindex
){
4790 if(sdef
->elements
[i
].raw
.lengthindex
->fieldtype
== OPTIONAL_FIELD
){
4792 " if(field_%s%s.%s().ispresent()){\n"
4793 ,sdef
->elements
[i
].name
,sdef
->elements
[i
].isOptional
?"()":""
4794 ,sdef
->elements
[i
].raw
.lengthindex
->nthfieldname
4798 " value_of_length_field%d+=(int)field_%s%s.%s%s()*%d;\n"
4799 ,i
,sdef
->elements
[i
].name
,sdef
->elements
[i
].isOptional
?"()":""
4800 ,sdef
->elements
[i
].raw
.lengthindex
->nthfieldname
4801 ,sdef
->elements
[i
].raw
.lengthindex
->fieldtype
== OPTIONAL_FIELD
?"()":""
4802 ,sdef
->elements
[i
].raw
.unit
==-1?1:sdef
->elements
[i
].raw
.unit
4804 if(sdef
->elements
[i
].raw
.lengthindex
->fieldtype
== OPTIONAL_FIELD
){
4810 else if(sdef
->elements
[i
].raw
.union_member_num
){
4812 src
= mputprintf(src
, " switch (field_%s%s.get_selection()) {\n",
4813 sdef
->elements
[i
].name
, sdef
->elements
[i
].isOptional
? "()" : "");
4814 for (m
= 1; m
< sdef
->elements
[i
].raw
.union_member_num
+ 1; m
++) {
4815 src
= mputprintf(src
, " case %s%s%s:\n"
4816 " value_of_length_field%d += (int)field_%s%s.%s() * %d;\n"
4817 " break;\n", sdef
->elements
[i
].raw
.member_name
[0],
4819 sdef
->elements
[i
].raw
.member_name
[m
], i
, sdef
->elements
[i
].name
,
4820 sdef
->elements
[i
].isOptional
? "()" : "",
4821 sdef
->elements
[i
].raw
.member_name
[m
],
4822 sdef
->elements
[i
].raw
.unit
== -1 ? 1 : sdef
->elements
[i
].raw
.unit
);
4824 src
= mputprintf(src
, " default:\n"
4825 " value_of_length_field%d = 0;\n"
4830 " value_of_length_field%d+=(int)field_%s%s*%d;\n"
4831 ,i
,sdef
->elements
[i
].name
,sdef
->elements
[i
].isOptional
?"()":""
4832 ,sdef
->elements
[i
].raw
.unit
==-1?1:sdef
->elements
[i
].raw
.unit
4836 if(raw_options
[i
].pointerto
){ /* store the start of pointed field*/
4838 " start_of_field%d=(int)field_%s%s+%d?1:-1;\n"
4839 ,sdef
->elements
[i
].raw
.pointerto
4840 ,sdef
->elements
[i
].name
,sdef
->elements
[i
].isOptional
?"()":""
4841 ,sdef
->elements
[i
].raw
.ptroffset
4844 if (!delayed_decode
) {
4845 /* mark the used bits in length area*/
4846 for (a
= 0; a
< raw_options
[i
].lengthof
; a
++) {
4847 int field_index
= raw_options
[i
].lengthoffield
[a
];
4848 src
= mputprintf(src
,
4849 " value_of_length_field%d -= decoded_field_length;\n", field_index
);
4850 if (i
== field_index
) src
= mputprintf(src
,
4851 " if (value_of_length_field%d < 0) return -1;\n", field_index
);
4854 if(sdef
->elements
[i
].isOptional
){
4857 " else field_%s=OMIT_VALUE;\n"
4858 ,raw_options
[i
].tag_type
?" }\n":"",sdef
->elements
[i
].name
4865 #define SUNPRO_PUBLIC "public:\n"
4866 #define SUNPRO_PRIVATE "private:\n"
4868 #define SUNPRO_PUBLIC
4869 #define SUNPRO_PRIVATE
4872 void defRecordTemplate1(const struct_def
*sdef
, output_struct
*output
)
4875 const char *name
= sdef
->name
, *dispname
= sdef
->dispname
;
4876 const char* kind_str
= sdef
->kind
== SET
? "set" : "record";
4877 char *def
= NULL
, *src
= NULL
;
4879 size_t mandatory_fields_count
;
4881 /* class declaration */
4882 output
->header
.class_decls
= mputprintf(output
->header
.class_decls
,
4883 "class %s_template;\n", name
);
4885 if(sdef
->nElements
<= 0) {
4886 defEmptyRecordTemplate(name
, dispname
, output
);
4890 /* template class definition */
4891 def
= mputprintf(def
, "class %s_template : public Base_Template {\n", name
);
4894 def
= mputprintf(def
,
4896 "struct single_value_struct;\n"
4899 "single_value_struct *single_value;\n"
4901 "unsigned int n_values;\n"
4902 "%s_template *list_value;\n"
4905 /* the definition of single_value_struct must be put into the source file
4906 * because the types of optional fields may be incomplete in this position
4907 * of header file (e.g. due to type recursion) */
4908 src
= mputprintf(src
, "struct %s_template::single_value_struct {\n", name
);
4909 for (i
= 0; i
< sdef
->nElements
; i
++) {
4910 src
= mputprintf(src
, "%s_template field_%s;\n",
4911 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
4913 src
= mputstr(src
, "};\n\n");
4915 /* set_specific function (used in field access members) */
4916 def
= mputstr(def
, "void set_specific();\n");
4917 src
= mputprintf(src
, "void %s_template::set_specific()\n"
4919 "if (template_selection != SPECIFIC_VALUE) {\n"
4920 "template_sel old_selection = template_selection;\n"
4922 "single_value = new single_value_struct;\n"
4923 "set_selection(SPECIFIC_VALUE);\n"
4924 "if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) {\n",
4926 for (i
= 0; i
< sdef
->nElements
; i
++) {
4927 src
= mputprintf(src
, "single_value->field_%s = %s;\n",
4928 sdef
->elements
[i
].name
,
4929 sdef
->elements
[i
].isOptional
? "ANY_OR_OMIT" : "ANY_VALUE");
4931 src
= mputstr(src
, "}\n"
4935 /* copy_value function */
4936 def
= mputprintf(def
, "void copy_value(const %s& other_value);\n", name
);
4937 src
= mputprintf(src
,
4938 "void %s_template::copy_value(const %s& other_value)\n"
4940 "single_value = new single_value_struct;\n", name
, name
);
4941 for (i
= 0; i
< sdef
->nElements
; i
++) {
4942 src
= mputprintf(src
,
4943 "if (other_value.%s().is_bound()) {\n", sdef
->elements
[i
].name
);
4944 if (sdef
->elements
[i
].isOptional
) {
4945 /* If the value is present, "reach into" the OPTIONAL with operator()
4946 * and pass the contained object to the template's constructor.
4947 * Else set the template to omit. */
4948 src
= mputprintf(src
,
4949 " if (other_value.%s().ispresent()) single_value->field_%s = "
4950 "other_value.%s()();\n"
4951 " else single_value->field_%s = OMIT_VALUE;\n",
4952 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
4953 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
4955 src
= mputprintf(src
,
4956 " single_value->field_%s = other_value.%s();\n",
4957 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
4959 src
= mputprintf(src
, "} else {\n"
4960 " single_value->field_%s.clean_up();\n"
4961 "}\n", sdef
->elements
[i
].name
);
4963 src
= mputstr(src
, "set_selection(SPECIFIC_VALUE);\n"
4966 /* copy_template function */
4967 def
= mputprintf(def
, "void copy_template(const %s_template& "
4968 "other_value);\n\n", name
);
4969 src
= mputprintf(src
,
4970 "void %s_template::copy_template(const %s_template& other_value)\n"
4972 "switch (other_value.template_selection) {\n"
4973 "case SPECIFIC_VALUE:\n", name
, name
);
4975 "single_value = new single_value_struct;\n");
4976 for (i
= 0; i
< sdef
->nElements
; i
++) {
4977 src
= mputprintf(src
,
4978 "if (UNINITIALIZED_TEMPLATE != other_value.%s().get_selection()) {\n",
4979 sdef
->elements
[i
].name
);
4980 src
= mputprintf(src
,
4981 "single_value->field_%s = other_value.%s();\n",
4982 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
4983 src
= mputprintf(src
, "} else {\n"
4984 "single_value->field_%s.clean_up();\n"
4985 "}\n", sdef
->elements
[i
].name
);
4987 src
= mputprintf(src
,
4988 "case OMIT_VALUE:\n"
4990 "case ANY_OR_OMIT:\n"
4992 "case VALUE_LIST:\n"
4993 "case COMPLEMENTED_LIST:\n"
4994 "value_list.n_values = other_value.value_list.n_values;\n"
4995 "value_list.list_value = new %s_template[value_list.n_values];\n"
4996 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
4998 "value_list.list_value[list_count].copy_template("
4999 "other_value.value_list.list_value[list_count]);\n"
5002 "TTCN_error(\"Copying an uninitialized/unsupported template of type "
5006 "set_selection(other_value);\n"
5007 "}\n\n", name
, dispname
);
5009 /* default constructor */
5010 def
= mputprintf(def
, "public:\n"
5011 "%s_template();\n", name
);
5012 src
= mputprintf(src
, "%s_template::%s_template()\n"
5014 "}\n\n", name
, name
);
5016 /* constructor t1_template(template_sel other_value) */
5017 def
= mputprintf(def
, "%s_template(template_sel other_value);\n", name
);
5018 src
= mputprintf(src
, "%s_template::%s_template(template_sel other_value)\n"
5019 " : Base_Template(other_value)\n"
5021 "check_single_selection(other_value);\n"
5022 "}\n\n", name
, name
);
5024 /* constructor t1_template(const t1& other_value) */
5025 def
= mputprintf(def
, "%s_template(const %s& other_value);\n", name
, name
);
5026 src
= mputprintf(src
, "%s_template::%s_template(const %s& other_value)\n"
5028 "copy_value(other_value);\n"
5029 "}\n\n", name
, name
, name
);
5031 /* constructor t1_template(const OPTIONAL<t1>& other_value) */
5032 def
= mputprintf(def
, "%s_template(const OPTIONAL<%s>& other_value);\n",
5034 src
= mputprintf(src
,
5035 "%s_template::%s_template(const OPTIONAL<%s>& other_value)\n"
5037 "switch (other_value.get_selection()) {\n"
5038 "case OPTIONAL_PRESENT:\n"
5039 "copy_value((const %s&)other_value);\n"
5041 "case OPTIONAL_OMIT:\n"
5042 "set_selection(OMIT_VALUE);\n"
5045 "TTCN_error(\"Creating a template of type %s from an unbound optional "
5048 "}\n\n", name
, name
, name
, name
, dispname
);
5050 /* copy constructor */
5051 def
= mputprintf(def
, "%s_template(const %s_template& other_value);\n",
5053 src
= mputprintf(src
, "%s_template::%s_template(const %s_template& "
5055 ": Base_Template()\n" /* yes, the base class _default_ constructor */
5057 "copy_template(other_value);\n"
5058 "}\n\n", name
, name
, name
);
5061 def
= mputprintf(def
, "~%s_template();\n", name
);
5062 src
= mputprintf(src
, "%s_template::~%s_template()\n"
5065 "}\n\n", name
, name
);
5067 /* assignment operator <- template_sel */
5068 def
= mputprintf(def
, "%s_template& operator=(template_sel other_value);\n",
5070 src
= mputprintf(src
,
5071 "%s_template& %s_template::operator=(template_sel other_value)\n"
5073 "check_single_selection(other_value);\n"
5075 "set_selection(other_value);\n"
5077 "}\n\n", name
, name
);
5079 /* assignment operator <- value */
5080 def
= mputprintf(def
, "%s_template& operator=(const %s& other_value);\n",
5083 src
= mputprintf(src
,
5084 "%s_template& %s_template::operator=(const %s& other_value)\n"
5087 "copy_value(other_value);\n"
5089 "}\n\n", name
, name
, name
);
5091 /* assignment operator <- optional value */
5092 def
= mputprintf(def
, "%s_template& operator=(const OPTIONAL<%s>& "
5093 "other_value);\n", name
, name
);
5095 src
= mputprintf(src
,
5096 "%s_template& %s_template::operator=(const OPTIONAL<%s>& other_value)\n"
5099 "switch (other_value.get_selection()) {\n"
5100 "case OPTIONAL_PRESENT:\n"
5101 "copy_value((const %s&)other_value);\n"
5103 "case OPTIONAL_OMIT:\n"
5104 "set_selection(OMIT_VALUE);\n"
5107 "TTCN_error(\"Assignment of an unbound optional field to a template "
5111 "}\n\n", name
, name
, name
, name
, dispname
);
5113 /* assignment operator <- template*/
5114 def
= mputprintf(def
,
5115 "%s_template& operator=(const %s_template& other_value);\n",
5118 src
= mputprintf(src
,
5119 "%s_template& %s_template::operator=(const %s_template& other_value)\n"
5121 "if (&other_value != this) {\n"
5123 "copy_template(other_value);\n"
5126 "}\n\n", name
, name
, name
);
5128 /* match operation (template matching) */
5129 def
= mputprintf(def
, "boolean match(const %s& other_value, boolean legacy "
5130 "= FALSE) const;\n", name
);
5132 src
= mputprintf(src
,
5133 "boolean %s_template::match(const %s& other_value, boolean legacy) const\n"
5135 "if (!other_value.is_bound()) return FALSE;\n"
5136 "switch (template_selection) {\n"
5138 "case ANY_OR_OMIT:\n"
5140 "case OMIT_VALUE:\n"
5142 "case SPECIFIC_VALUE:\n", name
, name
);
5143 for (i
= 0; i
< sdef
->nElements
; i
++) {
5144 src
= mputprintf(src
,"if(!other_value.%s().is_bound()) return FALSE;\n", sdef
->elements
[i
].name
);
5145 if (sdef
->elements
[i
].isOptional
) src
= mputprintf(src
,
5146 "if((other_value.%s().ispresent() ? "
5147 "!single_value->field_%s.match((const %s&)other_value.%s(), legacy) : "
5148 "!single_value->field_%s.match_omit(legacy)))",
5149 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
5150 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
,
5151 sdef
->elements
[i
].name
);
5152 else src
= mputprintf(src
,
5153 "if(!single_value->field_%s.match(other_value.%s(), legacy))",
5154 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
5155 src
= mputstr(src
, "return FALSE;\n");
5157 src
= mputprintf(src
,
5159 "case VALUE_LIST:\n"
5160 "case COMPLEMENTED_LIST:\n"
5161 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
5163 "if (value_list.list_value[list_count].match(other_value, legacy)) "
5164 "return template_selection == VALUE_LIST;\n"
5165 "return template_selection == COMPLEMENTED_LIST;\n"
5167 "TTCN_error(\"Matching an uninitialized/unsupported template of "
5174 def
= mputstr(def
, "boolean is_bound() const;\n");
5176 src
= mputprintf(src
, "boolean %s_template::is_bound() const\n"
5178 "if (template_selection == UNINITIALIZED_TEMPLATE && !is_ifpresent) "
5179 "return FALSE;\n", name
);
5180 src
= mputstr(src
, "if (template_selection != SPECIFIC_VALUE) return TRUE;\n");
5181 for (i
= 0; i
< sdef
->nElements
; i
++) {
5182 if (sdef
->elements
[i
].isOptional
) {
5183 src
= mputprintf(src
,
5184 "if (single_value->field_%s.is_omit() ||"
5185 " single_value->field_%s.is_bound()) return TRUE;\n",
5186 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
5188 src
= mputprintf(src
,
5189 "if (single_value->field_%s.is_bound()) return TRUE;\n",
5190 sdef
->elements
[i
].name
);
5193 src
= mputstr(src
, "return FALSE;\n"
5197 def
= mputstr(def
, "boolean is_value() const;\n");
5199 src
= mputprintf(src
, "boolean %s_template::is_value() const\n"
5201 "if (template_selection != SPECIFIC_VALUE || is_ifpresent) "
5202 "return FALSE;\n", name
);
5203 for (i
= 0; i
< sdef
->nElements
; i
++) {
5204 if (sdef
->elements
[i
].isOptional
) {
5205 src
= mputprintf(src
,
5206 "if (!single_value->field_%s.is_omit() &&"
5207 " !single_value->field_%s.is_value()) return FALSE;\n",
5208 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
5210 src
= mputprintf(src
,
5211 "if (!single_value->field_%s.is_value()) return FALSE;\n",
5212 sdef
->elements
[i
].name
);
5215 src
= mputstr(src
, "return TRUE;\n"
5218 /* clean_up function */
5219 def
= mputstr(def
, "void clean_up();\n");
5220 src
= mputprintf(src
,
5221 "void %s_template::clean_up()\n"
5223 "switch (template_selection) {\n"
5224 "case SPECIFIC_VALUE:\n"
5225 "delete single_value;\n"
5227 "case VALUE_LIST:\n"
5228 "case COMPLEMENTED_LIST:\n"
5229 "delete [] value_list.list_value;\n"
5233 "template_selection = UNINITIALIZED_TEMPLATE;\n"
5236 /* valueof operation */
5237 def
= mputprintf(def
, "%s valueof() const;\n", name
);
5239 src
= mputprintf(src
, "%s %s_template::valueof() const\n"
5241 "if (template_selection != SPECIFIC_VALUE || is_ifpresent)\n"
5242 "TTCN_error(\"Performing valueof or send operation on a non-specific "
5243 "template of type %s.\");\n"
5244 "%s ret_val;\n", name
, name
, dispname
, name
);
5245 for (i
= 0; i
< sdef
->nElements
; i
++) {
5246 if (sdef
->elements
[i
].isOptional
) {
5247 src
= mputprintf(src
,
5248 "if (single_value->field_%s.is_omit()) "
5249 "ret_val.%s() = OMIT_VALUE;\n"
5251 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
5253 src
= mputprintf(src
, "if (single_value->field_%s.is_bound()) {\n"
5254 "ret_val.%s() = single_value->field_%s.valueof();\n"
5256 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
5258 src
= mputstr(src
, "return ret_val;\n"
5261 /* void set_type(template_sel, int) function */
5263 "void set_type(template_sel template_type, "
5264 "unsigned int list_length);\n");
5266 src
= mputprintf(src
,
5267 "void %s_template::set_type(template_sel template_type, "
5268 "unsigned int list_length)\n"
5270 "if (template_type != VALUE_LIST "
5271 "&& template_type != COMPLEMENTED_LIST)\n"
5272 "TTCN_error(\"Setting an invalid list for a template of type %s.\");\n"
5274 "set_selection(template_type);\n"
5275 "value_list.n_values = list_length;\n"
5276 "value_list.list_value = new %s_template[list_length];\n"
5277 "}\n\n", name
, dispname
, name
);
5279 /* list_item(int) function */
5281 def
= mputprintf(def
,
5282 "%s_template& list_item(unsigned int list_index) const;\n", name
);
5284 src
= mputprintf(src
,
5285 "%s_template& %s_template::list_item(unsigned int list_index) const\n"
5287 "if (template_selection != VALUE_LIST "
5288 "&& template_selection != COMPLEMENTED_LIST)\n"
5289 "TTCN_error(\"Accessing a list element of a non-list template of "
5291 "if (list_index >= value_list.n_values)\n"
5292 "TTCN_error(\"Index overflow in a value list template of type "
5294 "return value_list.list_value[list_index];\n"
5295 "}\n\n", name
, name
, dispname
, dispname
);
5297 /* template field access functions (non-const & const) */
5298 for (i
= 0; i
< sdef
->nElements
; i
++) {
5299 def
= mputprintf(def
, "%s_template& %s();\n",
5300 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
5301 src
= mputprintf(src
, "%s_template& %s_template::%s()\n"
5304 "return single_value->field_%s;\n"
5306 sdef
->elements
[i
].type
, name
, sdef
->elements
[i
].name
,
5307 sdef
->elements
[i
].name
);
5308 def
= mputprintf(def
, "const %s_template& %s() const;\n",
5309 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
5310 src
= mputprintf(src
, "const %s_template& %s_template::%s() const\n"
5312 "if (template_selection != SPECIFIC_VALUE)\n"
5313 "TTCN_error(\"Accessing field %s of a non-specific "
5314 "template of type %s.\");\n"
5315 "return single_value->field_%s;\n"
5317 sdef
->elements
[i
].type
, name
, sdef
->elements
[i
].name
,
5318 sdef
->elements
[i
].dispname
, dispname
, sdef
->elements
[i
].name
);
5321 /* sizeof operation */
5322 def
= mputstr(def
, "int size_of() const;\n");
5323 src
= mputprintf(src
,
5324 "int %s_template::size_of() const\n"
5326 " if (is_ifpresent) TTCN_error(\"Performing sizeof() operation on a "
5327 "template of type %s which has an ifpresent attribute.\");\n"
5328 " switch (template_selection)\n"
5330 " case SPECIFIC_VALUE:\n",
5332 mandatory_fields_count
= 0;
5333 for (i
= 0; i
< sdef
->nElements
; i
++)
5334 if (!sdef
->elements
[i
].isOptional
) mandatory_fields_count
++;
5335 if(sdef
->nElements
== mandatory_fields_count
){
5336 src
= mputprintf(src
," return %lu;\n",
5337 (unsigned long) mandatory_fields_count
);
5339 src
= mputprintf(src
,
5341 " int ret_val = %lu;\n", (unsigned long) mandatory_fields_count
);
5342 for (i
= 0; i
< sdef
->nElements
; i
++)
5343 if (sdef
->elements
[i
].isOptional
)
5344 src
= mputprintf(src
,
5345 " if (single_value->field_%s.is_present()) ret_val++;\n",
5346 sdef
->elements
[i
].name
);
5348 " return ret_val;\n"
5351 src
= mputprintf(src
,
5353 " case VALUE_LIST:\n"
5355 " if (value_list.n_values<1)\n"
5356 " TTCN_error(\"Internal error: Performing sizeof() operation on a "
5357 "template of type %s containing an empty list.\");\n"
5358 " int item_size = value_list.list_value[0].size_of();\n"
5359 " for (unsigned int l_idx = 1; l_idx < value_list.n_values; l_idx++)\n"
5361 " if (value_list.list_value[l_idx].size_of()!=item_size)\n"
5362 " TTCN_error(\"Performing sizeof() operation on a template "
5363 "of type %s containing a value list with different sizes.\");\n"
5365 " return item_size;\n"
5367 " case OMIT_VALUE:\n"
5368 " TTCN_error(\"Performing sizeof() operation on a template of type %s "
5369 "containing omit value.\");\n"
5370 " case ANY_VALUE:\n"
5371 " case ANY_OR_OMIT:\n"
5372 " TTCN_error(\"Performing sizeof() operation on a template of type %s "
5373 "containing */? value.\");\n"
5374 " case COMPLEMENTED_LIST:\n"
5375 " TTCN_error(\"Performing sizeof() operation on a template of type %s "
5376 "containing complemented list.\");\n"
5378 " TTCN_error(\"Performing sizeof() operation on an "
5379 "uninitialized/unsupported template of type %s.\");\n"
5383 dispname
,dispname
,dispname
,dispname
,dispname
,dispname
);
5386 def
= mputstr(def
, "void log() const;\n");
5387 src
= mputprintf(src
,
5388 "void %s_template::log() const\n"
5390 "switch (template_selection) {\n"
5391 "case SPECIFIC_VALUE:\n", name
);
5392 for (i
= 0; i
< sdef
->nElements
; i
++) {
5393 src
= mputstr(src
, "TTCN_Logger::log_event_str(\"");
5394 if (i
== 0) src
= mputc(src
, '{');
5395 else src
= mputc(src
, ',');
5396 src
= mputprintf(src
, " %s := \");\n"
5397 "single_value->field_%s.log();\n",
5398 sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
);
5401 "TTCN_Logger::log_event_str(\" }\");\n"
5403 "case COMPLEMENTED_LIST:\n"
5404 "TTCN_Logger::log_event_str(\"complement \");\n"
5405 "case VALUE_LIST:\n"
5406 "TTCN_Logger::log_char('(');\n"
5407 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
5409 "if (list_count > 0) TTCN_Logger::log_event_str(\", \");\n"
5410 "value_list.list_value[list_count].log();\n"
5412 "TTCN_Logger::log_char(')');\n"
5417 "log_ifpresent();\n"
5420 /* log_match function */
5421 def
= mputprintf(def
, "void log_match(const %s& match_value, "
5422 "boolean legacy = FALSE) const;\n", name
);
5423 src
= mputprintf(src
,
5424 "void %s_template::log_match(const %s& match_value, boolean legacy) const\n"
5426 "if(TTCN_Logger::VERBOSITY_COMPACT"
5427 " == TTCN_Logger::get_matching_verbosity()){\n"
5428 "if(match(match_value, legacy)){\n"
5429 "TTCN_Logger::print_logmatch_buffer();\n"
5430 "TTCN_Logger::log_event_str(\" matched\");\n"
5432 "if (template_selection == SPECIFIC_VALUE) {\n"
5433 "size_t previous_size = TTCN_Logger::get_logmatch_buffer_len();\n"
5435 for (i
= 0; i
< sdef
->nElements
; i
++) {
5436 if (sdef
->elements
[i
].isOptional
){
5437 src
= mputprintf(src
,
5438 "if (match_value.%s().ispresent()){\n"
5439 "if(!single_value->field_%s.match(match_value.%s(), legacy)){\n"
5440 "TTCN_Logger::log_logmatch_info(\".%s\");\n"
5441 "single_value->field_%s.log_match(match_value.%s(), legacy);\n"
5442 "TTCN_Logger::set_logmatch_buffer_len(previous_size);\n"
5445 "if (!single_value->field_%s.match_omit(legacy)){\n "
5446 "TTCN_Logger::log_logmatch_info(\".%s := omit with \");\n"
5447 "TTCN_Logger::print_logmatch_buffer();\n"
5448 "single_value->field_%s.log();\n"
5449 "TTCN_Logger::log_event_str(\" unmatched\");\n"
5450 "TTCN_Logger::set_logmatch_buffer_len(previous_size);\n"
5453 , sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
5454 sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
,
5455 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
5456 sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
,
5457 sdef
->elements
[i
].name
);
5459 src
= mputprintf(src
,
5460 "if(!single_value->field_%s.match(match_value.%s(), legacy)){\n"
5461 "TTCN_Logger::log_logmatch_info(\".%s\");\n"
5462 "single_value->field_%s.log_match(match_value.%s(), legacy);\n"
5463 "TTCN_Logger::set_logmatch_buffer_len(previous_size);\n"
5464 "}\n",sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
5465 sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
,
5466 sdef
->elements
[i
].name
);
5470 src
= mputstr(src
,"}else {\n"
5471 "TTCN_Logger::print_logmatch_buffer();\n"
5472 "match_value.log();\n"
5473 "TTCN_Logger::log_event_str(\" with \");\n"
5475 "TTCN_Logger::log_event_str(\" unmatched\");\n"
5480 "if (template_selection == SPECIFIC_VALUE) {\n");
5481 for (i
= 0; i
< sdef
->nElements
; i
++) {
5482 src
= mputstr(src
, "TTCN_Logger::log_event_str(\"");
5483 if (i
== 0) src
= mputc(src
, '{');
5484 else src
= mputc(src
, ',');
5485 src
= mputprintf(src
, " %s := \");\n", sdef
->elements
[i
].dispname
);
5486 if (sdef
->elements
[i
].isOptional
) src
= mputprintf(src
,
5487 "if (match_value.%s().ispresent()) "
5488 "single_value->field_%s.log_match(match_value.%s(), legacy);\n"
5490 "TTCN_Logger::log_event_str(\"omit with \");\n"
5491 "single_value->field_%s.log();\n"
5492 "if (single_value->field_%s.match_omit(legacy)) "
5493 "TTCN_Logger::log_event_str(\" matched\");\n"
5494 "else TTCN_Logger::log_event_str(\" unmatched\");\n"
5496 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
5497 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
5498 sdef
->elements
[i
].name
);
5499 else src
= mputprintf(src
,
5500 "single_value->field_%s.log_match(match_value.%s(), legacy);\n",
5501 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
5504 "TTCN_Logger::log_event_str(\" }\");\n"
5506 "match_value.log();\n"
5507 "TTCN_Logger::log_event_str(\" with \");\n"
5509 "if (match(match_value, legacy)) TTCN_Logger::log_event_str(\" matched\");\n"
5510 "else TTCN_Logger::log_event_str(\" unmatched\");\n"
5514 /*encode_text function*/
5515 def
= mputstr(def
, "void encode_text(Text_Buf& text_buf) const;\n");
5516 src
= mputprintf(src
,
5517 "void %s_template::encode_text(Text_Buf& text_buf) const\n"
5519 "encode_text_base(text_buf);\n"
5520 "switch (template_selection) {\n"
5521 "case SPECIFIC_VALUE:\n", name
);
5522 for (i
= 0; i
< sdef
->nElements
; i
++) {
5523 src
= mputprintf(src
, "single_value->field_%s.encode_text(text_buf);\n",
5524 sdef
->elements
[i
].name
);
5526 src
= mputprintf(src
,
5527 "case OMIT_VALUE:\n"
5529 "case ANY_OR_OMIT:\n"
5531 "case VALUE_LIST:\n"
5532 "case COMPLEMENTED_LIST:\n"
5533 "text_buf.push_int(value_list.n_values);\n"
5534 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
5536 "value_list.list_value[list_count].encode_text(text_buf);\n"
5539 "TTCN_error(\"Text encoder: Encoding an uninitialized/unsupported "
5540 "template of type %s.\");\n"
5544 /*decode_text function*/
5545 def
= mputstr(def
, "void decode_text(Text_Buf& text_buf);\n");
5546 src
= mputprintf(src
,
5547 "void %s_template::decode_text(Text_Buf& text_buf)\n"
5550 "decode_text_base(text_buf);\n"
5551 "switch (template_selection) {\n"
5552 "case SPECIFIC_VALUE:\n"
5553 "single_value = new single_value_struct;\n", name
);
5554 for (i
= 0; i
< sdef
->nElements
; i
++) {
5555 src
= mputprintf(src
, "single_value->field_%s.decode_text(text_buf);\n",
5556 sdef
->elements
[i
].name
);
5558 src
= mputprintf(src
,
5559 "case OMIT_VALUE:\n"
5561 "case ANY_OR_OMIT:\n"
5563 "case VALUE_LIST:\n"
5564 "case COMPLEMENTED_LIST:\n"
5565 "value_list.n_values = text_buf.pull_int().get_val();\n"
5566 "value_list.list_value = new %s_template[value_list.n_values];\n"
5567 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
5569 "value_list.list_value[list_count].decode_text(text_buf);\n"
5572 "TTCN_error(\"Text decoder: An unknown/unsupported selection was "
5573 "received in a template of type %s.\");\n"
5575 "}\n\n", name
, dispname
);
5578 def
= mputstr(def
, "void set_param(Module_Param& param);\n");
5579 src
= mputprintf(src
,
5580 "void %s_template::set_param(Module_Param& param)\n"
5582 " if (dynamic_cast<Module_Param_Name*>(param.get_id()) != NULL &&\n"
5583 " param.get_id()->next_name()) {\n"
5584 // Haven't reached the end of the module parameter name
5585 // => the name refers to one of the fields, not to the whole record
5586 " char* param_field = param.get_id()->get_current_name();\n"
5587 " if (param_field[0] >= '0' && param_field[0] <= '9') {\n"
5588 " param.error(\"Unexpected array index in module parameter, expected a valid field\"\n"
5589 " \" name for %s template type `%s'\");\n"
5591 " ", name
, kind_str
, dispname
);
5592 for (i
= 0; i
< sdef
->nElements
; i
++) {
5593 src
= mputprintf(src
,
5594 "if (strcmp(\"%s\", param_field) == 0) {\n"
5595 " %s().set_param(param);\n"
5598 sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
);
5600 src
= mputprintf(src
,
5601 "param.error(\"Field `%%s' not found in %s template type `%s'\", param_field);\n"
5603 " param.basic_check(Module_Param::BC_TEMPLATE, \"%s template\");\n"
5604 " Module_Param_Ptr mp = ¶m;\n"
5605 " if (param.get_type() == Module_Param::MP_Reference) {\n"
5606 " mp = param.get_referenced_param();\n"
5608 " switch (mp->get_type()) {\n"
5609 " case Module_Param::MP_Omit:\n"
5610 " *this = OMIT_VALUE;\n"
5612 " case Module_Param::MP_Any:\n"
5613 " *this = ANY_VALUE;\n"
5615 " case Module_Param::MP_AnyOrNone:\n"
5616 " *this = ANY_OR_OMIT;\n"
5618 " case Module_Param::MP_List_Template:\n"
5619 " case Module_Param::MP_ComplementList_Template: {\n"
5620 " %s_template temp;\n"
5621 " temp.set_type(mp->get_type()==Module_Param::MP_List_Template ? "
5622 "VALUE_LIST : COMPLEMENTED_LIST, mp->get_size());\n"
5623 " for (size_t p_i=0; p_i<mp->get_size(); p_i++) {\n"
5624 " temp.list_item(p_i).set_param(*mp->get_elem(p_i));\n"
5628 " case Module_Param::MP_Value_List:\n"
5629 " if (%lu<mp->get_size()) {\n"
5630 " param.error(\"%s template of type %s has %lu fields but list value has %%d fields\", (int)mp->get_size());\n"
5632 kind_str
, dispname
, kind_str
, name
, (unsigned long)sdef
->nElements
, kind_str
, dispname
, (unsigned long)sdef
->nElements
);
5633 for (i
= 0; i
< sdef
->nElements
; ++i
) {
5634 src
= mputprintf(src
,
5635 " if (mp->get_size()>%lu && mp->get_elem(%lu)->get_type()!=Module_Param::MP_NotUsed) %s().set_param(*mp->get_elem(%lu));\n",
5636 (unsigned long)i
, (unsigned long)i
, sdef
->elements
[i
].name
, (unsigned long)i
);
5640 " case Module_Param::MP_Assignment_List: {\n"
5641 " Vector<bool> value_used(mp->get_size());\n"
5642 " value_used.resize(mp->get_size(), false);\n");
5643 for (i
= 0; i
< sdef
->nElements
; ++i
) {
5644 src
= mputprintf(src
,
5645 " for (size_t val_idx=0; val_idx<mp->get_size(); val_idx++) {\n"
5646 " Module_Param* const curr_param = mp->get_elem(val_idx);\n"
5647 " if (!strcmp(curr_param->get_id()->get_name(), \"%s\")) {\n"
5648 " if (curr_param->get_type()!=Module_Param::MP_NotUsed) {\n"
5649 " %s().set_param(*curr_param);\n"
5651 " value_used[val_idx]=true;\n"
5654 , sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
);
5656 src
= mputprintf(src
,
5657 " for (size_t val_idx=0; val_idx<mp->get_size(); val_idx++) if (!value_used[val_idx]) {\n"
5658 " mp->get_elem(val_idx)->error(\"Non existent field name in type %s: %%s\", mp->get_elem(val_idx)->get_id()->get_name());\n"
5663 " param.type_error(\"%s template\", \"%s\");\n"
5665 " is_ifpresent = param.get_ifpresent() || mp->get_ifpresent();\n"
5666 "}\n\n", dispname
, kind_str
, dispname
);
5669 def
= mputstr(def
, "Module_Param* get_param(Module_Param_Name& param_name) const;\n");
5670 src
= mputprintf(src
,
5671 "Module_Param* %s_template::get_param(Module_Param_Name& param_name) const\n"
5673 " if (param_name.next_name()) {\n"
5674 // Haven't reached the end of the module parameter name
5675 // => the name refers to one of the fields, not to the whole record
5676 " char* param_field = param_name.get_current_name();\n"
5677 " if (param_field[0] >= '0' && param_field[0] <= '9') {\n"
5678 " TTCN_error(\"Unexpected array index in module parameter reference, \"\n"
5679 " \"expected a valid field name for %s template type `%s'\");\n"
5681 " ", name
, kind_str
, dispname
);
5682 for (i
= 0; i
< sdef
->nElements
; i
++) {
5683 src
= mputprintf(src
,
5684 "if (strcmp(\"%s\", param_field) == 0) {\n"
5685 " return %s().get_param(param_name);\n"
5687 sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
);
5689 src
= mputprintf(src
,
5690 "TTCN_error(\"Field `%%s' not found in %s type `%s'\", param_field);\n"
5692 " Module_Param* mp = NULL;\n"
5693 " switch (template_selection) {\n"
5694 " case UNINITIALIZED_TEMPLATE:\n"
5695 " mp = new Module_Param_Unbound();\n"
5697 " case OMIT_VALUE:\n"
5698 " mp = new Module_Param_Omit();\n"
5700 " case ANY_VALUE:\n"
5701 " mp = new Module_Param_Any();\n"
5703 " case ANY_OR_OMIT:\n"
5704 " mp = new Module_Param_AnyOrNone();\n"
5706 " case SPECIFIC_VALUE: {\n"
5707 " mp = new Module_Param_Assignment_List();\n"
5708 , kind_str
, dispname
);
5709 for (i
= 0; i
< sdef
->nElements
; i
++) {
5710 src
= mputprintf(src
,
5711 " Module_Param* mp_field_%s = single_value->field_%s.get_param(param_name);\n"
5712 " mp_field_%s->set_id(new Module_Param_FieldName(mcopystr(\"%s\")));\n"
5713 " mp->add_elem(mp_field_%s);\n"
5714 , sdef
->elements
[i
].name
, sdef
->elements
[i
].name
5715 , sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
5716 , sdef
->elements
[i
].name
);
5720 " case VALUE_LIST:\n"
5721 " case COMPLEMENTED_LIST: {\n"
5722 " if (template_selection == VALUE_LIST) {\n"
5723 " mp = new Module_Param_List_Template();\n"
5726 " mp = new Module_Param_ComplementList_Template();\n"
5728 " for (size_t i = 0; i < value_list.n_values; ++i) {\n"
5729 " mp->add_elem(value_list.list_value[i].get_param(param_name));\n"
5735 " if (is_ifpresent) {\n"
5736 " mp->set_ifpresent();\n"
5741 /* check template restriction */
5742 def
= mputstr(def
, "void check_restriction(template_res t_res, "
5743 "const char* t_name=NULL, boolean legacy = FALSE) const;\n");
5744 src
= mputprintf(src
,
5745 "void %s_template::check_restriction("
5746 "template_res t_res, const char* t_name, boolean legacy) const\n"
5748 "if (template_selection==UNINITIALIZED_TEMPLATE) return;\n"
5749 "switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {\n"
5751 "if (template_selection==OMIT_VALUE) return;\n"
5753 "if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;\n",
5755 for (i
= 0; i
< sdef
->nElements
; i
++) {
5756 src
= mputprintf(src
, "single_value->field_%s.check_restriction("
5757 "t_res, t_name ? t_name : \"%s\");\n",
5758 sdef
->elements
[i
].name
, dispname
);
5760 src
= mputprintf(src
,
5762 "case TR_PRESENT:\n"
5763 "if (!match_omit(legacy)) return;\n"
5768 "TTCN_error(\"Restriction `%%s' on template of type %%s "
5769 "violated.\", get_res_name(t_res), t_name ? t_name : \"%s\");\n"
5772 defCommonRecordTemplate(name
, &def
, &src
);
5774 def
= mputstr(def
, "};\n\n");
5776 output
->header
.class_defs
= mputstr(output
->header
.class_defs
, def
);
5779 output
->source
.methods
= mputstr(output
->source
.methods
, src
);
5783 static void defEmptyRecordClass(const struct_def
*sdef
,
5784 output_struct
*output
)
5786 const char *name
= sdef
->name
, *dispname
= sdef
->dispname
;
5787 char *def
= NULL
, *src
= NULL
;
5788 boolean ber_needed
= sdef
->isASN1
&& enable_ber();
5789 boolean raw_needed
= sdef
->hasRaw
&& enable_raw();
5790 boolean text_needed
= sdef
->hasText
&& enable_text();
5791 boolean xer_needed
= sdef
->hasXer
&& enable_xer();
5792 boolean json_needed
= sdef
->hasJson
&& enable_json();
5794 def
= mputprintf(def
,
5796 "// written by %s in " __FILE__
" at line %d\n"
5798 "class %s : public Base_Type {\n"
5799 "boolean bound_flag;\n"
5802 , __FUNCTION__
, __LINE__
5807 def
= mputprintf(def
, "%s();\n", name
);
5808 src
= mprintf("%s::%s()\n"
5810 "bound_flag = FALSE;\n"
5811 "}\n\n", name
, name
);
5813 /* ctor from NULL_VALUE (i.e. {}) */
5814 def
= mputprintf(def
, "%s(null_type other_value);\n", name
);
5815 src
= mputprintf(src
, "%s::%s(null_type)\n"
5817 "bound_flag = TRUE;\n"
5818 "}\n\n", name
, name
);
5821 def
= mputprintf(def
, "%s(const %s& other_value);\n", name
, name
);
5822 src
= mputprintf(src
, "%s::%s(const %s& other_value)\n"
5824 "other_value.must_bound(\"Copying an unbound value of "
5826 "bound_flag = TRUE;\n"
5827 "}\n\n", name
, name
, name
, dispname
);
5829 /* assignment op: from NULL_VALUE */
5830 def
= mputprintf(def
, "%s& operator=(null_type other_value);\n", name
);
5831 src
= mputprintf(src
, "%s& %s::operator=(null_type)\n"
5833 "bound_flag = TRUE;\n"
5835 "}\n\n", name
, name
);
5837 /* assignment op: from itself */
5838 def
= mputprintf(def
, "%s& operator=(const %s& other_value);\n", name
,
5840 src
= mputprintf(src
, "%s& %s::operator=(const %s& other_value)\n"
5842 "other_value.must_bound(\"Assignment of an unbound value of type "
5844 "bound_flag = TRUE;\n"
5846 "}\n\n", name
, name
, name
, dispname
);
5848 /* comparison op: with NULL_VALUE */
5849 def
= mputstr(def
, "boolean operator==(null_type other_value) const;\n");
5850 src
= mputprintf(src
,
5851 "boolean %s::operator==(null_type) const\n"
5853 "must_bound(\"Comparison of an unbound value of type %s.\");\n"
5855 "}\n\n", name
, dispname
);
5857 /* comparison op: with itself */
5858 def
= mputprintf(def
, "boolean operator==(const %s& other_value) const;\n",
5860 src
= mputprintf(src
,
5861 "boolean %s::operator==(const %s& other_value) const\n"
5863 "must_bound(\"Comparison of an unbound value of type %s.\");\n"
5864 "other_value.must_bound(\"Comparison of an unbound value of type "
5867 "}\n\n", name
, name
, dispname
, dispname
);
5869 /* non-equal operators */
5870 def
= mputprintf(def
,
5871 "inline boolean operator!=(null_type other_value) const "
5872 "{ return !(*this == other_value); }\n"
5873 "inline boolean operator!=(const %s& other_value) const "
5874 "{ return !(*this == other_value); }\n", name
);
5877 /* is_bound function */
5878 def
= mputstr(def
, "inline boolean is_bound() const "
5879 "{ return bound_flag; }\n");
5881 /* is_present function */
5883 "inline boolean is_present() const { return is_bound(); }\n");
5885 /* is_value function */
5886 def
= mputstr(def
, "inline boolean is_value() const "
5887 "{ return bound_flag; }\n");
5889 /* clean_up function */
5890 def
= mputstr(def
, "inline void clean_up() "
5891 "{ bound_flag = FALSE; }\n");
5893 /* must_bound function */
5894 def
= mputstr(def
, "inline void must_bound(const char *err_msg) const "
5895 "{ if (!bound_flag) TTCN_error(\"%s\", err_msg); }\n");
5898 def
= mputstr(def
, "void log() const;\n");
5899 src
= mputprintf(src
, "void %s::log() const\n"
5901 "if (bound_flag) TTCN_Logger::log_event_str(\"{ }\");\n"
5902 "else TTCN_Logger::log_event_unbound();\n"
5905 /* set_param function */
5906 def
= mputstr(def
, "void set_param(Module_Param& param);\n");
5907 src
= mputprintf(src
, "void %s::set_param(Module_Param& param)\n"
5909 " param.basic_check(Module_Param::BC_VALUE, \"empty record/set value (i.e. { })\");\n"
5910 " Module_Param_Ptr mp = ¶m;\n"
5911 " if (param.get_type() == Module_Param::MP_Reference) {\n"
5912 " mp = param.get_referenced_param();\n"
5914 " if (mp->get_type()!=Module_Param::MP_Value_List || mp->get_size()>0) {\n"
5915 " param.type_error(\"empty record/set value (i.e. { })\", \"%s\");\n"
5917 " bound_flag = TRUE;\n"
5918 "}\n\n", name
, dispname
);
5920 /* get param function */
5921 def
= mputstr(def
, "Module_Param* get_param(Module_Param_Name& param_name) const;\n");
5922 src
= mputprintf(src
,
5923 "Module_Param* %s::get_param(Module_Param_Name& /* param_name */) const\n"
5925 " if (!is_bound()) {\n"
5926 " return new Module_Param_Unbound();\n"
5928 " return new Module_Param_Value_List();\n"
5931 /* encode_text function */
5932 def
= mputstr(def
, "void encode_text(Text_Buf& text_buf) const;\n");
5933 src
= mputprintf(src
, "void %s::encode_text(Text_Buf& /*text_buf*/) const\n"
5935 "must_bound(\"Text encoder: Encoding an unbound value of type %s.\");\n"
5936 "}\n\n", name
, dispname
);
5938 /* decode_text function */
5939 def
= mputstr(def
, "void decode_text(Text_Buf& text_buf);\n");
5940 src
= mputprintf(src
, "void %s::decode_text(Text_Buf& /*text_buf*/)\n"
5942 "bound_flag = TRUE;\n"
5945 if(ber_needed
|| raw_needed
|| text_needed
|| xer_needed
|| json_needed
)
5946 def_encdec(name
, &def
, &src
, ber_needed
, raw_needed
,
5947 text_needed
, xer_needed
, json_needed
, FALSE
);
5951 /* BER_encode_TLV() */
5954 "ASN_BER_TLV_t* %s::BER_encode_TLV(const TTCN_Typedescriptor_t& p_td,"
5955 " unsigned p_coding) const\n"
5957 " BER_chk_descr(p_td);\n"
5958 " ASN_BER_TLV_t *new_tlv=ASN_BER_TLV_t::construct(NULL);\n"
5959 " new_tlv=ASN_BER_V2TLV(new_tlv, p_td, p_coding);\n"
5960 " return new_tlv;\n"
5966 /* BER_decode_TLV() */
5969 "boolean %s::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,"
5970 " const ASN_BER_TLV_t& p_tlv, unsigned L_form)\n"
5972 " BER_chk_descr(p_td);\n"
5973 " ASN_BER_TLV_t stripped_tlv;\n"
5974 " BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv);\n"
5975 " TTCN_EncDec_ErrorContext ec_0(\"While decoding '%s' type: \");\n"
5976 " stripped_tlv.chk_constructed_flag(TRUE);\n"
5977 " bound_flag=TRUE;\n"
5981 , name
, sdef
->dispname
5983 } /* if ber_needed */
5985 src
= mputprintf(src
,
5986 "int %s::TEXT_encode(const TTCN_Typedescriptor_t& p_td,"
5987 "TTCN_Buffer& p_buf) const{\n"
5988 " int encoded_length=0;\n"
5989 " if(p_td.text->begin_encode){\n"
5990 " p_buf.put_cs(*p_td.text->begin_encode);\n"
5991 " encoded_length+=p_td.text->begin_encode->lengthof();\n"
5993 " if(!bound_flag) {\n"
5994 " TTCN_EncDec_ErrorContext::error\n"
5995 " (TTCN_EncDec::ET_UNBOUND, \"Encoding an unbound value.\");\n"
5997 " if(p_td.text->end_encode){\n"
5998 " p_buf.put_cs(*p_td.text->end_encode);\n"
5999 " encoded_length+=p_td.text->end_encode->lengthof();\n"
6001 " return encoded_length;\n"
6005 src
= mputprintf(src
,
6006 "int %s::TEXT_decode(const TTCN_Typedescriptor_t& p_td,"
6007 " TTCN_Buffer& p_buf, Limit_Token_List& limit, boolean no_err, boolean){\n"
6008 " bound_flag = TRUE;\n"
6009 " int decoded_length=0;\n"
6010 " if(p_td.text->begin_decode){\n"
6012 " if((tl=p_td.text->begin_decode->match_begin(p_buf))<0){\n"
6013 " if(no_err)return -1;\n"
6014 " TTCN_EncDec_ErrorContext::error\n"
6015 " (TTCN_EncDec::ET_TOKEN_ERR, \"The specified token '%%s'"
6016 " not found for '%%s': \",(const char*)*(p_td.text->begin_decode)"
6020 " decoded_length+=tl;\n"
6021 " p_buf.increase_pos(tl);\n"
6023 " if(p_td.text->end_decode){\n"
6025 " if((tl=p_td.text->end_decode->match_begin(p_buf))<0){\n"
6026 " if(no_err)return -1;\n"
6027 " TTCN_EncDec_ErrorContext::error\n"
6028 " (TTCN_EncDec::ET_TOKEN_ERR, \"The specified token '%%s'"
6029 " not found for '%%s': \",(const char*)*(p_td.text->end_decode)"
6033 " decoded_length+=tl;\n"
6034 " p_buf.increase_pos(tl);\n"
6036 " return decoded_length;\n"
6044 src
= mputprintf(src
,
6045 "int %s::RAW_encode(const TTCN_Typedescriptor_t& p_td, "
6046 "RAW_enc_tree& /*myleaf*/) const\n"
6048 "if (!bound_flag) TTCN_EncDec_ErrorContext::error"
6049 "(TTCN_EncDec::ET_UNBOUND, \"Encoding an unbound value of "
6050 "type %%s.\", p_td.name);\n"
6054 src
= mputprintf(src
,
6055 "int %s::RAW_decode(const TTCN_Typedescriptor_t& p_td, "
6056 "TTCN_Buffer& p_buf, int, raw_order_t, boolean, int, boolean)\n"
6058 "bound_flag = TRUE;\n"
6059 "return p_buf.increase_pos_padd(p_td.raw->prepadding) + "
6060 "p_buf.increase_pos_padd(p_td.raw->padding);\n"
6064 if (xer_needed
) { /* XERSTUFF codegen for empty record/SEQUENCE */
6066 "boolean %s::can_start(const char *p_name, const char *p_uri, "
6067 "const XERdescriptor_t& p_td, unsigned int p_flavor) {\n"
6068 " boolean e_xer = is_exer(p_flavor);\n"
6069 " if (e_xer && (p_td.xer_bits & UNTAGGED)) return false;\n"
6070 " else return check_name(p_name, p_td, e_xer) && (!e_xer || check_namespace(p_uri, p_td));\n"
6075 src
= mputprintf(src
,
6076 "int %s::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, "
6077 "unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const{\n"
6078 " int encoded_length=(int)p_buf.get_len();\n"
6079 " int is_indented = !is_canonical(p_flavor);\n"
6080 " int e_xer = is_exer(p_flavor);\n"
6081 " if (is_indented) do_indent(p_buf, p_indent);\n"
6082 " p_buf.put_c('<');\n"
6083 " if (e_xer) write_ns_prefix(p_td, p_buf);\n"
6084 " p_buf.put_s((size_t)p_td.namelens[e_xer]-2, (cbyte*)p_td.names[e_xer]);\n"
6085 " p_buf.put_s(2 + is_indented, (cbyte*)\"/>\\n\");\n"
6086 " return (int)p_buf.get_len() - encoded_length;\n"
6089 src
= mputprintf(src
,
6091 "// written by %s in " __FILE__
" at %d\n"
6093 "int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader, "
6094 "unsigned int p_flavor, embed_values_dec_struct_t*)\n"
6096 " int e_xer = is_exer(p_flavor);\n"
6097 " bound_flag = true;\n"
6098 " int rd_ok, depth=-1;\n"
6099 " for (rd_ok=p_reader.Ok(); rd_ok==1; rd_ok=p_reader.Read()) {\n"
6100 " int type = p_reader.NodeType();\n"
6101 " if (type==XML_READER_TYPE_ELEMENT) {\n"
6102 " verify_name(p_reader, p_td, e_xer);\n"
6103 " depth=p_reader.Depth();\n"
6104 " if (p_reader.IsEmptyElement()) {\n"
6105 " rd_ok = p_reader.Read(); break;\n"
6107 " else if ((p_flavor & XER_MASK) == XER_CANONICAL) {\n"
6108 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, "
6109 "\"Expected an empty element tag\");\n"
6112 " else if (type == XML_READER_TYPE_END_ELEMENT && depth != -1) {\n"
6113 " verify_end(p_reader, p_td, depth, e_xer);\n"
6114 " rd_ok = p_reader.Read(); break;\n"
6120 , __FUNCTION__
, __LINE__
6126 src
= mputprintf(src
,
6127 "int %s::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const\n"
6129 " if (!is_bound()) {\n"
6130 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,\n"
6131 " \"Encoding an unbound value of type %s.\");\n"
6134 " return p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL) + \n"
6135 " p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);\n"
6140 src
= mputprintf(src
,
6141 "int %s::JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok, boolean p_silent)\n"
6143 " json_token_t token = JSON_TOKEN_NONE;\n"
6144 " int dec_len = p_tok.get_next_token(&token, NULL, NULL);\n"
6145 " if (JSON_TOKEN_ERROR == token) {\n"
6146 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, \"\");\n"
6147 " return JSON_ERROR_FATAL;\n"
6149 " else if (JSON_TOKEN_OBJECT_START != token) {\n"
6150 " return JSON_ERROR_INVALID_TOKEN;\n"
6152 " dec_len += p_tok.get_next_token(&token, NULL, NULL);\n"
6153 " if (JSON_TOKEN_OBJECT_END != token) {\n"
6154 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_STATIC_OBJECT_END_TOKEN_ERROR, \"\");\n"
6155 " return JSON_ERROR_FATAL;\n"
6157 " bound_flag = true;\n\n"
6158 " return dec_len;\n"
6163 /* closing class definition */
6164 def
= mputstr(def
, "};\n\n");
6166 output
->header
.class_defs
= mputstr(output
->header
.class_defs
, def
);
6169 output
->source
.methods
= mputstr(output
->source
.methods
, src
);
6172 output
->header
.function_prototypes
=
6173 mputprintf(output
->header
.function_prototypes
,
6174 "extern boolean operator==(null_type null_value, const %s& "
6175 "other_value);\n", name
);
6176 output
->source
.function_bodies
=
6177 mputprintf(output
->source
.function_bodies
,
6178 "boolean operator==(null_type, const %s& other_value)\n"
6180 "other_value.must_bound(\"Comparison of an unbound value of type "
6183 "}\n\n", name
, dispname
);
6185 output
->header
.function_prototypes
=
6186 mputprintf(output
->header
.function_prototypes
,
6187 "inline boolean operator!=(null_type null_value, const %s& "
6189 "{ return !(null_value == other_value); }\n", name
);
6192 static void defEmptyRecordTemplate(const char *name
, const char *dispname
,
6193 output_struct
*output
)
6195 char *def
= NULL
, *src
= NULL
;
6197 /* class definition */
6198 def
= mprintf("class %s_template : public Base_Template {\n"
6200 "unsigned int n_values;\n"
6201 "%s_template *list_value;\n"
6202 "} value_list;\n", name
, name
);
6204 /* copy_template function */
6205 def
= mputprintf(def
, "void copy_template(const %s_template& "
6206 "other_value);\n\n", name
);
6207 src
= mputprintf(src
,
6208 "void %s_template::copy_template(const %s_template& other_value)\n"
6210 "set_selection(other_value);\n"
6211 "switch (template_selection) {\n"
6212 "case OMIT_VALUE:\n"
6214 "case ANY_OR_OMIT:\n"
6215 "case SPECIFIC_VALUE:\n"
6217 "case VALUE_LIST:\n"
6218 "case COMPLEMENTED_LIST:\n"
6219 "value_list.n_values = other_value.value_list.n_values;\n"
6220 "value_list.list_value = new %s_template[value_list.n_values];\n"
6221 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
6223 "value_list.list_value[list_count].copy_template("
6224 "other_value.value_list.list_value[list_count]);\n"
6227 "TTCN_error(\"Copying an uninitialized/unsupported template of type "
6231 "}\n\n", name
, name
, name
, dispname
);
6234 def
= mputprintf(def
, "public:\n"
6235 "%s_template();\n", name
);
6236 src
= mputprintf(src
, "%s_template::%s_template()\n"
6238 "}\n\n", name
, name
);
6240 /* ctor for generic wildcards */
6241 def
= mputprintf(def
, "%s_template(template_sel other_value);\n", name
);
6242 src
= mputprintf(src
, "%s_template::%s_template(template_sel other_value)\n"
6243 " : Base_Template(other_value)\n"
6245 "check_single_selection(other_value);\n"
6246 "}\n\n", name
, name
);
6248 /* ctor for value {} */
6249 def
= mputprintf(def
, "%s_template(null_type other_value);\n", name
);
6250 src
= mputprintf(src
, "%s_template::%s_template(null_type)\n"
6251 " : Base_Template(SPECIFIC_VALUE)\n"
6253 "}\n\n", name
, name
);
6255 /* ctor for specific value */
6256 def
= mputprintf(def
, "%s_template(const %s& other_value);\n", name
, name
);
6257 src
= mputprintf(src
, "%s_template::%s_template(const %s& other_value)\n"
6258 " : Base_Template(SPECIFIC_VALUE)\n"
6260 "other_value.must_bound(\"Creating a template from an unbound value of "
6262 "}\n\n", name
, name
, name
, dispname
);
6264 /* ctor for optional value */
6265 def
= mputprintf(def
, "%s_template(const OPTIONAL<%s>& other_value);\n",
6267 src
= mputprintf(src
, "%s_template::%s_template(const OPTIONAL<%s>& "
6270 "switch (other_value.get_selection()) {\n"
6271 "case OPTIONAL_PRESENT:\n"
6272 "set_selection(SPECIFIC_VALUE);\n"
6274 "case OPTIONAL_OMIT:\n"
6275 "set_selection(OMIT_VALUE);\n"
6278 "TTCN_error(\"Creating a template of type %s from an unbound optional "
6281 "}\n\n", name
, name
, name
, dispname
);
6284 def
= mputprintf(def
, "%s_template(const %s_template& other_value);\n",
6286 src
= mputprintf(src
, "%s_template::%s_template(const %s_template& "
6288 ": Base_Template()" /* yes, the base class _default_ constructor */
6290 "copy_template(other_value);\n"
6291 "}\n\n", name
, name
, name
);
6294 def
= mputprintf(def
, "~%s_template();\n", name
);
6295 src
= mputprintf(src
, "%s_template::~%s_template()\n"
6298 "}\n\n", name
, name
);
6300 /* clean_up function */
6301 def
= mputstr(def
, "void clean_up();\n");
6302 src
= mputprintf(src
, "void %s_template::clean_up()\n"
6304 "if (template_selection == VALUE_LIST || "
6305 "template_selection == COMPLEMENTED_LIST)\n"
6306 "delete [] value_list.list_value;\n"
6307 "template_selection = UNINITIALIZED_TEMPLATE;\n"
6310 /* assignment op for generic wildcards */
6311 def
= mputprintf(def
, "%s_template& operator=(template_sel other_value);\n",
6313 src
= mputprintf(src
, "%s_template& %s_template::operator=(template_sel "
6316 "check_single_selection(other_value);\n"
6318 "set_selection(other_value);\n"
6320 "}\n\n", name
, name
);
6322 /* assignment op for value {} */
6323 def
= mputprintf(def
, "%s_template& operator=(null_type other_value);\n",
6325 src
= mputprintf(src
, "%s_template& %s_template::operator=(null_type)\n"
6328 "set_selection(SPECIFIC_VALUE);\n"
6330 "}\n\n", name
, name
);
6332 /* assignment op for specific value */
6333 def
= mputprintf(def
, "%s_template& operator=(const %s& other_value);\n",
6335 src
= mputprintf(src
, "%s_template& %s_template::operator=(const %s& "
6338 "other_value.must_bound(\"Assignment of an unbound value of type %s "
6339 "to a template.\");\n"
6341 "set_selection(SPECIFIC_VALUE);\n"
6343 "}\n\n", name
, name
, name
, dispname
);
6345 /* assignment op for optional value */
6346 def
= mputprintf(def
, "%s_template& operator=(const OPTIONAL<%s>& "
6347 "other_value);\n", name
, name
);
6348 src
= mputprintf(src
, "%s_template& %s_template::operator="
6349 "(const OPTIONAL<%s>& other_value)\n"
6352 "switch (other_value.get_selection()) {\n"
6353 "case OPTIONAL_PRESENT:\n"
6354 "set_selection(SPECIFIC_VALUE);\n"
6356 "case OPTIONAL_OMIT:\n"
6357 "set_selection(OMIT_VALUE);\n"
6360 "TTCN_error(\"Assignment of an unbound optional field to a template "
6364 "}\n\n", name
, name
, name
, dispname
);
6366 /* assignment op for itself */
6367 def
= mputprintf(def
, "%s_template& operator=(const %s_template& "
6368 "other_value);\n", name
, name
);
6369 src
= mputprintf(src
, "%s_template& %s_template::operator="
6370 "(const %s_template& other_value)\n"
6372 "if (&other_value != this) {\n"
6374 "set_selection(other_value);\n"
6377 "}\n\n", name
, name
, name
);
6379 /* match operation with {} */
6380 def
= mputstr(def
, "boolean match(null_type other_value, boolean legacy "
6381 "= FALSE) const;\n");
6382 src
= mputprintf(src
, "boolean %s_template::match(null_type other_value,"
6385 "switch (template_selection) {\n"
6387 "case ANY_OR_OMIT:\n"
6388 "case SPECIFIC_VALUE:\n"
6390 "case OMIT_VALUE:\n"
6392 "case VALUE_LIST:\n"
6393 "case COMPLEMENTED_LIST:\n"
6394 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
6396 "if (value_list.list_value[list_count].match(other_value)) "
6397 "return template_selection == VALUE_LIST;\n"
6398 "return template_selection == COMPLEMENTED_LIST;\n"
6400 "TTCN_error(\"Matching an uninitialized/unsupported template of "
6404 "}\n\n", name
, dispname
);
6406 /* match operation with specific value */
6407 def
= mputprintf(def
, "boolean match(const %s& other_value, boolean legacy "
6408 "= FALSE) const;\n", name
);
6409 src
= mputprintf(src
, "boolean %s_template::match(const %s& other_value, "
6412 "if (!other_value.is_bound()) return FALSE;"
6413 "return match(NULL_VALUE);\n"
6414 "}\n\n", name
, name
);
6416 /* valueof operation */
6417 def
= mputprintf(def
, "%s valueof() const;\n", name
);
6418 src
= mputprintf(src
, "%s %s_template::valueof() const\n"
6420 "if (template_selection != SPECIFIC_VALUE || is_ifpresent) "
6421 "TTCN_error(\"Performing a valueof or send operation on a "
6422 "non-specific template of type %s.\");\n"
6423 "return NULL_VALUE;\n"
6424 "}\n\n", name
, name
, dispname
);
6426 /* void set_type(template_sel, int) function */
6428 "void set_type(template_sel template_type, "
6429 "unsigned int list_length);\n");
6431 src
= mputprintf(src
,
6432 "void %s_template::set_type(template_sel template_type, "
6433 "unsigned int list_length)\n"
6435 "if (template_type != VALUE_LIST "
6436 "&& template_type != COMPLEMENTED_LIST)\n"
6437 "TTCN_error(\"Setting an invalid list for a template of type %s.\");\n"
6439 "set_selection(template_type);\n"
6440 "value_list.n_values = list_length;\n"
6441 "value_list.list_value = new %s_template[list_length];\n"
6442 "}\n\n", name
, dispname
, name
);
6444 /* list_item(int) function */
6446 def
= mputprintf(def
,
6447 "%s_template& list_item(unsigned int list_index) const;\n", name
);
6449 src
= mputprintf(src
,
6450 "%s_template& %s_template::list_item(unsigned int list_index) const\n"
6452 "if (template_selection != VALUE_LIST "
6453 "&& template_selection != COMPLEMENTED_LIST)\n"
6454 "TTCN_error(\"Accessing a list element of a non-list template of "
6456 "if (list_index >= value_list.n_values)\n"
6457 "TTCN_error(\"Index overflow in a value list template of type "
6459 "return value_list.list_value[list_index];\n"
6460 "}\n\n", name
, name
, dispname
, dispname
);
6463 def
= mputstr(def
, "void log() const;\n");
6464 src
= mputprintf(src
, "void %s_template::log() const\n"
6466 "switch (template_selection) {\n"
6467 "case SPECIFIC_VALUE:\n"
6468 "TTCN_Logger::log_event_str(\"{ }\");\n"
6470 "case COMPLEMENTED_LIST:\n"
6471 "TTCN_Logger::log_event_str(\"complement \");\n"
6472 "case VALUE_LIST:\n"
6473 "TTCN_Logger::log_char('(');\n"
6474 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
6476 "if (list_count > 0) TTCN_Logger::log_event_str(\", \");\n"
6477 "value_list.list_value[list_count].log();\n"
6479 "TTCN_Logger::log_char(')');\n"
6484 "log_ifpresent();\n"
6487 /* log_match function */
6488 def
= mputprintf(def
, "void log_match(const %s& match_value, "
6489 "boolean legacy = FALSE) const;\n", name
);
6490 src
= mputprintf(src
, "void %s_template::log_match(const %s& match_value, "
6493 "match_value.log();\n"
6494 "TTCN_Logger::log_event_str(\" with \");\n"
6496 "if (match(match_value)) TTCN_Logger::log_event_str(\" matched\");\n"
6497 "else TTCN_Logger::log_event_str(\" unmatched\");\n"
6498 "}\n\n", name
, name
);
6500 /* encode_text function */
6501 def
= mputstr(def
, "void encode_text(Text_Buf& text_buf) const;\n");
6502 src
= mputprintf(src
, "void %s_template::encode_text(Text_Buf& text_buf) "
6505 "encode_text_base(text_buf);\n"
6506 "switch (template_selection) {\n"
6507 "case OMIT_VALUE:\n"
6509 "case ANY_OR_OMIT:\n"
6510 "case SPECIFIC_VALUE:\n"
6512 "case VALUE_LIST:\n"
6513 "case COMPLEMENTED_LIST:\n"
6514 "text_buf.push_int(value_list.n_values);\n"
6515 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
6517 "value_list.list_value[list_count].encode_text(text_buf);\n"
6520 "TTCN_error(\"Text encoder: Encoding an uninitialized/unsupported "
6521 "template of type %s.\");\n"
6523 "}\n\n", name
, dispname
);
6525 /* decode_text function */
6526 def
= mputstr(def
, "void decode_text(Text_Buf& text_buf);\n");
6527 src
= mputprintf(src
, "void %s_template::decode_text(Text_Buf& text_buf)\n"
6530 "decode_text_base(text_buf);\n"
6531 "switch (template_selection) {\n"
6532 "case OMIT_VALUE:\n"
6534 "case ANY_OR_OMIT:\n"
6535 "case SPECIFIC_VALUE:\n"
6537 "case VALUE_LIST:\n"
6538 "case COMPLEMENTED_LIST:\n"
6539 "value_list.n_values = text_buf.pull_int().get_val();\n"
6540 "value_list.list_value = new %s_template[value_list.n_values];\n"
6541 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
6543 "value_list.list_value[list_count].decode_text(text_buf);\n"
6546 "TTCN_error(\"Text decoder: An unknown/unsupported selection was "
6547 "received in a template of type %s.\");\n"
6549 "}\n\n", name
, name
, dispname
);
6552 def
= mputstr(def
, "void set_param(Module_Param& param);\n");
6553 src
= mputprintf(src
,
6554 "void %s_template::set_param(Module_Param& param)\n"
6556 " param.basic_check(Module_Param::BC_TEMPLATE, \"empty record/set template\");\n"
6557 " Module_Param_Ptr mp = ¶m;\n"
6558 " if (param.get_type() == Module_Param::MP_Reference) {\n"
6559 " mp = param.get_referenced_param();\n"
6561 " switch (mp->get_type()) {\n"
6562 " case Module_Param::MP_Omit:\n"
6563 " *this = OMIT_VALUE;\n"
6565 " case Module_Param::MP_Any:\n"
6566 " *this = ANY_VALUE;\n"
6568 " case Module_Param::MP_AnyOrNone:\n"
6569 " *this = ANY_OR_OMIT;\n"
6571 " case Module_Param::MP_List_Template:\n"
6572 " case Module_Param::MP_ComplementList_Template: {\n"
6573 " %s_template temp;\n"
6574 " temp.set_type(mp->get_type()==Module_Param::MP_List_Template ? "
6575 "VALUE_LIST : COMPLEMENTED_LIST, mp->get_size());\n"
6576 " for (size_t p_i=0; p_i<mp->get_size(); p_i++) {\n"
6577 " temp.list_item(p_i).set_param(*mp->get_elem(p_i));\n"
6581 " case Module_Param::MP_Value_List:\n"
6582 " if (mp->get_size()>0) param.type_error(\"empty record/set template\", \"%s\");\n"
6583 " *this = NULL_VALUE;\n"
6586 " param.type_error(\"empty record/set template\", \"%s\");\n"
6588 " is_ifpresent = param.get_ifpresent() || mp->get_ifpresent();\n"
6589 "}\n\n", name
, name
, dispname
, dispname
);
6592 def
= mputstr(def
, "Module_Param* get_param(Module_Param_Name& param_name) const;\n");
6593 src
= mputprintf(src
,
6594 "Module_Param* %s_template::get_param(Module_Param_Name& param_name) const\n"
6596 " Module_Param* mp = NULL;\n"
6597 " switch (template_selection) {\n"
6598 " case UNINITIALIZED_TEMPLATE:\n"
6599 " mp = new Module_Param_Unbound();\n"
6601 " case OMIT_VALUE:\n"
6602 " mp = new Module_Param_Omit();\n"
6604 " case ANY_VALUE:\n"
6605 " mp = new Module_Param_Any();\n"
6607 " case ANY_OR_OMIT:\n"
6608 " mp = new Module_Param_AnyOrNone();\n"
6610 " case SPECIFIC_VALUE:\n"
6611 " mp = new Module_Param_Value_List();\n"
6613 " case VALUE_LIST:\n"
6614 " case COMPLEMENTED_LIST: {\n"
6615 " if (template_selection == VALUE_LIST) {\n"
6616 " mp = new Module_Param_List_Template();\n"
6619 " mp = new Module_Param_ComplementList_Template();\n"
6621 " for (size_t i = 0; i < value_list.n_values; ++i) {\n"
6622 " mp->add_elem(value_list.list_value[i].get_param(param_name));\n"
6628 " if (is_ifpresent) {\n"
6629 " mp->set_ifpresent();\n"
6634 /* check template restriction */
6635 def
= mputstr(def
, "void check_restriction(template_res t_res, "
6636 "const char* t_name=NULL, boolean legacy = FALSE) const;\n");
6637 src
= mputprintf(src
,
6638 "void %s_template::check_restriction("
6639 "template_res t_res, const char* t_name, boolean legacy) const\n"
6641 "if (template_selection==UNINITIALIZED_TEMPLATE) return;\n"
6642 "switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {\n"
6644 "if (template_selection==OMIT_VALUE) return;\n"
6646 "if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;\n"
6648 "case TR_PRESENT:\n"
6649 "if (!match_omit(legacy)) return;\n"
6654 "TTCN_error(\"Restriction `%%s' on template of type %%s "
6655 "violated.\", get_res_name(t_res), t_name ? t_name : \"%s\");\n"
6656 "}\n\n", name
, dispname
);
6658 defCommonRecordTemplate(name
, &def
, &src
);
6660 def
= mputstr(def
, "};\n\n");
6662 output
->header
.class_defs
= mputstr(output
->header
.class_defs
, def
);
6665 output
->source
.methods
= mputstr(output
->source
.methods
, src
);
6669 static void defCommonRecordTemplate(const char *name
,
6670 char **def
, char **src
)
6672 /* TTCN-3 ispresent() function */
6673 *def
= mputstr(*def
, "boolean is_present(boolean legacy = FALSE) const;\n");
6674 *src
= mputprintf(*src
,
6675 "boolean %s_template::is_present(boolean legacy) const\n"
6677 "if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;\n"
6678 "return !match_omit(legacy);\n"
6682 *def
= mputstr(*def
, "boolean match_omit(boolean legacy = FALSE) const;\n");
6683 *src
= mputprintf(*src
,
6684 "boolean %s_template::match_omit(boolean legacy) const\n"
6686 "if (is_ifpresent) return TRUE;\n"
6687 "switch (template_selection) {\n"
6688 "case OMIT_VALUE:\n"
6689 "case ANY_OR_OMIT:\n"
6691 "case VALUE_LIST:\n"
6692 "case COMPLEMENTED_LIST:\n"
6694 "for (unsigned int l_idx=0; l_idx<value_list.n_values; l_idx++)\n"
6695 "if (value_list.list_value[l_idx].match_omit())\n"
6696 "return template_selection==VALUE_LIST;\n"
6697 "return template_selection==COMPLEMENTED_LIST;\n"
6698 "} // else fall through\n"
6706 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
6708 void defRecordClass2(const struct_def
*sdef
, output_struct
*output
)
6711 size_t optional_num
= 0;
6712 const char *name
= sdef
->name
;
6713 char *def
= NULL
, *src
= NULL
;
6715 boolean xer_needed
= sdef
->hasXer
&& enable_xer();
6716 boolean raw_needed
= sdef
->hasRaw
&& enable_raw();
6717 boolean has_optional
= FALSE
;
6718 boolean has_default
= FALSE
;
6720 const char* base_class
= (sdef
->nElements
==0) ? "Empty_Record_Type" : "Record_Type";
6722 /* class declaration code */
6723 output
->header
.class_decls
= mputprintf(output
->header
.class_decls
,
6724 "class %s;\n", name
);
6726 /* class definition and source code */
6727 def
=mputprintf(def
, "class %s : public %s {\n", name
, base_class
);
6730 for (i
= 0; i
< sdef
->nElements
; i
++) {
6731 if(sdef
->elements
[i
].isOptional
) {
6733 def
= mputprintf(def
, " OPTIONAL<%s> field_%s;\n",
6734 sdef
->elements
[i
].type
,
6735 sdef
->elements
[i
].name
);
6737 def
= mputprintf(def
, " %s field_%s;\n",
6738 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
6741 if (sdef
->nElements
) {
6742 def
= mputprintf(def
, " Base_Type* fld_vec[%lu];\n", (unsigned long)sdef
->nElements
);
6745 /* default constructor */
6746 if (sdef
->nElements
==0) {
6747 def
= mputprintf(def
, "public:\n"
6749 src
= mputprintf(src
,
6750 "%s::%s() : Empty_Record_Type() {}\n\n",
6753 def
= mputstr(def
, " void init_vec();\n");
6754 src
= mputprintf(src
, "void %s::init_vec() { ", name
);
6755 for (i
= 0; i
< sdef
->nElements
; i
++) {
6756 src
= mputprintf(src
, "fld_vec[%lu]=&field_%s; ",
6757 (unsigned long)i
, sdef
->elements
[i
].name
);
6759 src
= mputstr(src
, " }\n\n");
6761 def
= mputprintf(def
, "public:\n"
6763 src
= mputprintf(src
,
6764 "%s::%s() : Record_Type() { init_vec(); }\n\n", name
, name
);
6767 /* copy constructor */
6768 if (sdef
->nElements
) {
6769 def
= mputprintf(def
, " %s(const %s& other_value);\n", name
, name
);
6770 src
= mputprintf(src
, "%s::%s(const %s& other_value) : Record_Type(other_value)\n", name
, name
, name
);
6771 src
= mputstr(src
, "{\n"
6772 " if(!other_value.is_bound()) "
6773 "TTCN_error(\"Copying an unbound record/set value.\");\n"
6774 "bound_flag = TRUE;\n");
6775 for (i
= 0; i
< sdef
->nElements
; i
++) {
6776 src
= mputprintf(src
,
6777 "if (other_value.field_%s.is_bound() )\n"
6778 " field_%s = other_value.field_%s;\n",
6779 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
6780 sdef
->elements
[i
].name
);
6783 src
= mputstr(src
, "init_vec();\n"
6786 def
= mputprintf(def
, " %s(const %s& other_value): %s(other_value) {}\n", name
, name
, base_class
);
6789 if (sdef
->nElements
>0) { /* constructor by fields */
6790 def
= mputprintf(def
, " %s(", name
);
6791 src
= mputprintf(src
, "%s::%s(", name
, name
);
6792 for (i
= 0; i
< sdef
->nElements
; i
++) {
6794 if (i
> 0) tmp
= mputstr(tmp
, ",\n ");
6795 if (sdef
->elements
[i
].isOptional
)
6798 "const OPTIONAL<%s>& par_%s",
6799 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
6804 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
6805 def
= mputstr(def
, tmp
);
6806 src
= mputstr(src
, tmp
);
6809 def
= mputstr(def
, ");\n");
6810 src
= mputprintf(src
, ") : ");
6811 for (i
= 0; i
< sdef
->nElements
; i
++) {
6812 if (i
> 0) src
= mputstr(src
, ",\n ");
6813 src
= mputprintf(src
, "field_%s(par_%s)", sdef
->elements
[i
].name
,
6814 sdef
->elements
[i
].name
);
6816 src
= mputstr(src
, "\n"
6819 "bound_flag = TRUE;\n"
6821 } else { /* constructor from null */
6822 def
= mputprintf(def
, " %s(null_type) {bound_flag = TRUE;}\n", name
);
6825 /* assignment operators */
6826 def
= mputprintf(def
, "inline %s& operator=(const %s& other_value) "
6827 "{ set_value(&other_value); return *this; }\n\n", name
, name
);
6828 if (sdef
->nElements
== 0) {
6829 def
= mputprintf(def
, "inline %s& operator=(null_type) "
6830 "{ bound_flag = TRUE; return *this; }\n", name
);
6834 def
= mputprintf(def
, "inline boolean operator==(const %s& other_value) "
6835 "const { return is_equal(&other_value); }\n", name
);
6837 def
= mputprintf(def
,
6838 " inline boolean operator!=(const %s& other_value) const\n"
6839 " { return !is_equal(&other_value); }\n\n", name
);
6841 for (i
= 0; i
< sdef
->nElements
; i
++) {
6842 if(sdef
->elements
[i
].isOptional
)
6845 " inline OPTIONAL<%s>& %s()\n"
6846 " {return field_%s;}\n"
6847 " inline const OPTIONAL<%s>& %s() const\n"
6848 " {return field_%s;}\n",
6849 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
,
6850 sdef
->elements
[i
].name
,
6851 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
,
6852 sdef
->elements
[i
].name
);
6853 else def
= mputprintf
6855 " inline %s& %s()\n"
6856 " {return field_%s;}\n"
6857 " inline const %s& %s() const\n"
6858 " {return field_%s;}\n",
6859 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
,
6860 sdef
->elements
[i
].name
, sdef
->elements
[i
].type
,
6861 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
6865 /* override virtual functions where needed */
6866 def
= mputprintf(def
,
6867 "Base_Type* clone() const { return new %s(*this); }\n"
6868 "const TTCN_Typedescriptor_t* get_descriptor() const;\n"
6869 "boolean is_set() const { return %s; }\n",
6871 (sdef
->kind
==SET
) ? "TRUE" : "FALSE");
6872 src
= mputprintf(src
,
6873 "const TTCN_Typedescriptor_t* %s::get_descriptor() const { return &%s_descr_; }\n",
6876 if (sdef
->nElements
> 0) {
6878 /* field access functions */
6879 def
= mputprintf(def
,
6880 "Base_Type* get_at(int index_value) { return fld_vec[index_value]; }\n"
6881 "const Base_Type* get_at(int index_value) const { return fld_vec[index_value]; }\n\n"
6882 "int get_count() const { return %lu; }\n", (unsigned long)sdef
->nElements
);
6884 /* override if there are optional fields */
6886 def
= mputprintf(def
,
6887 "int optional_count() const { return %lu; }\n", (unsigned long)optional_num
);
6890 if (sdef
->opentype_outermost
)
6891 def
= mputstr(def
, "boolean is_opentype_outermost() const { return TRUE; }\n");
6893 /* FIXME: use static member in Record_Type and initialize somewhere */
6894 if (default_as_optional
)
6895 def
= mputstr(def
, "boolean default_as_optional() const { return TRUE; }\n");
6897 for (i
= 0; i
< sdef
->nElements
; i
++) {
6898 if (sdef
->elements
[i
].isOptional
) {
6899 has_optional
= TRUE
;
6904 for (i
= 0; i
< sdef
->nElements
; i
++) {
6905 if (sdef
->elements
[i
].isDefault
) {
6911 "static const TTCN_Typedescriptor_t* fld_descriptors[];\n"
6912 "const TTCN_Typedescriptor_t* fld_descr(int p_index) const;\n\n"
6913 "static const char* fld_names[];\n"
6914 "const char* fld_name(int p_index) const;\n\n");
6916 src
= mputprintf(src
, "const TTCN_Typedescriptor_t* %s::fld_descriptors[] = ", name
);
6917 for (i
= 0; i
< sdef
->nElements
; i
++) {
6918 src
= mputprintf(src
, "%c &%s_descr_",
6919 (i
? ',' : '{'), sdef
->elements
[i
].typedescrname
);
6921 src
= mputstr(src
, " };\n");
6922 src
= mputprintf(src
,
6923 "const TTCN_Typedescriptor_t* %s::fld_descr(int p_index) const "
6924 "{ return fld_descriptors[p_index]; }\n\n", name
);
6926 src
= mputprintf(src
, "const char* %s::fld_names[] = ", name
);
6927 for (i
= 0; i
< sdef
->nElements
; i
++) {
6928 src
= mputprintf(src
, "%c \"%s\"",
6929 (i
? ',' : '{'), sdef
->elements
[i
].dispname
);
6931 src
= mputstr(src
, " };\n");
6933 src
= mputprintf(src
,
6934 "const char* %s::fld_name(int p_index) const "
6935 "{ return fld_names[p_index]; }\n\n", name
);
6939 "static const int optional_indexes[];\n"
6940 "const int* get_optional_indexes() const;\n\n");
6941 src
= mputprintf(src
, "const int %s::optional_indexes[] = { ", name
);
6942 for (i
= 0; i
< sdef
->nElements
; i
++) {
6943 if (sdef
->elements
[i
].isOptional
) {
6944 src
= mputprintf(src
, "%lu, ", (unsigned long)i
);
6947 src
= mputstr(src
, "-1 };\n");
6948 src
= mputprintf(src
,
6949 "const int* %s::get_optional_indexes() const "
6950 "{ return optional_indexes; }\n\n", name
);
6955 "static const default_struct default_indexes[];\n"
6956 "const default_struct* get_default_indexes() const;\n");
6957 src
= mputprintf(src
, "const Record_Type::default_struct %s::default_indexes[] = { ", name
);
6958 for (i
= 0; i
< sdef
->nElements
; i
++) {
6959 if (sdef
->elements
[i
].isDefault
) {
6960 src
= mputprintf(src
, "{%lu,&%s}, ",
6961 (unsigned long)i
, sdef
->elements
[i
].defvalname
);
6964 src
= mputstr(src
, "{-1,NULL} };\n");
6965 src
= mputprintf(src
,
6966 "const Record_Type::default_struct* %s::get_default_indexes() const "
6967 "{ return default_indexes; }\n", name
);
6971 struct raw_option_struct
*raw_options
;
6972 boolean haslengthto
, haspointer
, hascrosstag
, has_ext_bit
;
6973 boolean generate_raw_function
= FALSE
;
6975 raw_options
= (struct raw_option_struct
*)
6976 Malloc(sdef
->nElements
* sizeof(*raw_options
));
6978 set_raw_options(sdef
, raw_options
, &haslengthto
,
6979 &haspointer
, &hascrosstag
, &has_ext_bit
);
6981 /* set the value of generate_raw_function: if the coding/decoding is too
6982 complex for this type then generate the functions, otherwise generate
6983 helper functions only which are called by the default RAW enc/dec
6985 if (haslengthto
|| haspointer
|| hascrosstag
) {
6986 generate_raw_function
= TRUE
;
6987 goto check_generate_end
;
6989 for (i
= 0; i
< sdef
->nElements
; i
++) {
6990 if (raw_options
[i
].lengthto
|| raw_options
[i
].lengthof
||
6991 raw_options
[i
].lengthoffield
|| raw_options
[i
].pointerto
||
6992 raw_options
[i
].pointerof
|| raw_options
[i
].ptrbase
||
6993 raw_options
[i
].extbitgroup
|| raw_options
[i
].tag_type
||
6994 raw_options
[i
].delayed_decode
|| raw_options
[i
].nof_dependent_fields
6995 || raw_options
[i
].dependent_fields
) {
6996 generate_raw_function
= TRUE
;
6997 goto check_generate_end
;
7000 for (i
= 0; i
< sdef
->nElements
; i
++) {
7001 if (raw_options
[i
].lengthof
|| raw_options
[i
].lengthoffield
||
7002 raw_options
[i
].nof_dependent_fields
||
7003 raw_options
[i
].dependent_fields
) {
7004 generate_raw_function
= TRUE
;
7005 goto check_generate_end
;
7008 if (sdef
->raw
.ext_bit_goup_num
|| sdef
->raw
.ext_bit_groups
||
7009 sdef
->raw
.lengthto
|| sdef
->raw
.lengthindex
||
7010 sdef
->raw
.taglist
.nElements
|| sdef
->raw
.crosstaglist
.nElements
||
7011 sdef
->raw
.presence
.fieldnum
|| sdef
->raw
.presence
.fields
||
7012 sdef
->raw
.member_name
) {
7013 generate_raw_function
= TRUE
;
7014 goto check_generate_end
;
7016 for (i
= 0; i
< sdef
->nElements
; i
++) {
7017 if (sdef
->elements
[i
].hasRaw
) {
7018 generate_raw_function
= TRUE
;
7019 goto check_generate_end
;
7024 if (generate_raw_function
) {
7025 def
= mputprintf(def
,
7026 "int RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree&) const;\n"
7027 "virtual int RAW_encode_negtest(const Erroneous_descriptor_t *, const TTCN_Typedescriptor_t&, RAW_enc_tree&) const;\n"
7028 "int RAW_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, "
7029 "int, raw_order_t, boolean no_err = FALSE, "
7030 "int sel_field = -1, boolean first_call = TRUE);\n");
7031 src
= generate_raw_coding(src
, sdef
, raw_options
, haspointer
,
7032 hascrosstag
, has_ext_bit
);
7033 } else { /* generate helper functions for the default RAW enc/dec */
7035 def
= mputstr(def
,"boolean raw_has_ext_bit() const { return TRUE; }\n");
7037 for (i
= 0; i
< sdef
->nElements
; i
++) {
7038 Free(raw_options
[i
].lengthoffield
);
7039 Free(raw_options
[i
].dependent_fields
);
7042 } /* if (raw_needed) */
7044 if (xer_needed
) { /* XERSTUFF codegen for record/SEQUENCE in RT2 */
7045 size_t num_attributes
= 0;
7047 /* XER descriptors needed because of the xer antipattern */
7049 "static const XERdescriptor_t* xer_descriptors[];\n"
7050 "const XERdescriptor_t* xer_descr(int p_index) const;\n"
7051 "virtual boolean can_start_v(const char *name, const char *prefix, "
7052 "XERdescriptor_t const& xd, unsigned int flavor);\n"
7053 "static boolean can_start (const char *name, const char *prefix, "
7054 "XERdescriptor_t const& xd, unsigned int flavor);\n");
7055 src
= mputprintf(src
, "const XERdescriptor_t* %s::xer_descriptors[] = ", name
);
7056 for (i
= 0; i
< sdef
->nElements
; i
++) {
7057 src
= mputprintf(src
, "%c &%s_xer_",
7058 (i
? ',' : '{'), sdef
->elements
[i
].typegen
);
7060 src
= mputstr(src
, " };\n");
7061 src
= mputprintf(src
,
7062 "const XERdescriptor_t* %s::xer_descr(int p_index) const "
7063 "{ return xer_descriptors[p_index]; }\n"
7064 /* The virtual can_start_v hands off to the static can_start.
7065 * We must make a virtual call in Record_Type::XER_decode because
7066 * we don't know the actual type (derived from Record_Type) */
7067 "boolean %s::can_start_v(const char *p_name, const char *p_uri, "
7068 "XERdescriptor_t const& p_td, unsigned int p_flavor)\n"
7069 "{ return can_start(p_name, p_uri, p_td, p_flavor); }\n"
7070 "boolean %s::can_start(const char *p_name, const char *p_uri, "
7071 "XERdescriptor_t const& p_td, unsigned int p_flavor) {\n"
7072 " boolean e_xer = is_exer(p_flavor);\n"
7073 " 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"
7074 , name
, name
, name
);
7075 for (i
= 0; i
< sdef
->nElements
; i
++) {
7076 src
= mputprintf(src
,
7077 " else if (%s::can_start(p_name, p_uri, %s_xer_, p_flavor)) return true;\n"
7078 , sdef
->elements
[i
].type
, sdef
->elements
[i
].typegen
);
7083 /* end of antipattern */
7085 /* calculate num_attributes in compile time */
7086 for ( i
=0; i
< sdef
->nElements
; ++i
) {
7087 if (sdef
->elements
[i
].xerAttribute
7088 ||(sdef
->elements
[i
].xerAnyKind
& ANY_ATTRIB_BIT
)) ++num_attributes
;
7089 else if (num_attributes
) break;
7092 /* generate helper virtual functions for XER encdec */
7093 if (num_attributes
) {
7094 def
= mputprintf(def
,
7095 "int get_xer_num_attr() const { return %lu; }\n",
7096 (unsigned long)num_attributes
);
7099 else { /* XER not needed */
7101 "boolean can_start_v(const char *, const char *, XERdescriptor_t const&, unsigned int)\n"
7102 "{ return FALSE; }\n"
7104 } /* if (xer_needed) */
7105 } /* if (sdef->nElements > 0) */
7107 /* end of class definition */
7108 def
= mputstr(def
, "};\n\n");
7110 output
->header
.class_defs
= mputstr(output
->header
.class_defs
, def
);
7113 output
->source
.methods
= mputstr(output
->source
.methods
, src
);
7117 void defRecordTemplate2(const struct_def
*sdef
, output_struct
*output
)
7120 const char *name
= sdef
->name
;
7121 char *def
= NULL
, *src
= NULL
;
7123 const char* base_class
= (sdef
->nElements
==0) ? "Empty_Record_Template" : "Record_Template";
7125 /* class declaration */
7126 output
->header
.class_decls
= mputprintf(output
->header
.class_decls
,
7127 "class %s_template;\n", name
);
7129 /* template class definition */
7130 def
= mputprintf(def
, "class %s_template : public %s {\n", name
, base_class
);
7132 if (sdef
->nElements
>0) {
7133 /* set_specific function (used in field access members) */
7134 def
= mputstr(def
, "void set_specific();\n");
7135 src
= mputprintf(src
, "void %s_template::set_specific()\n"
7137 "if (template_selection != SPECIFIC_VALUE) {\n"
7140 "single_value.n_elements = %lu;\n"
7141 "single_value.value_elements = (Base_Template**)allocate_pointers(single_value.n_elements);\n"
7142 "set_selection(SPECIFIC_VALUE);\n",
7143 name
, sdef
->nElements
? "boolean was_any = (template_selection == ANY_VALUE || template_selection == ANY_OR_OMIT);\n" : "",
7144 (unsigned long)sdef
->nElements
);
7145 for (i
= 0; i
< sdef
->nElements
; i
++) {
7146 src
= mputprintf(src
,
7147 "single_value.value_elements[%d] = was_any ? new %s_template(%s) : new %s_template;\n",
7148 i
, sdef
->elements
[i
].type
,
7149 sdef
->elements
[i
].isOptional
? "ANY_OR_OMIT" : "ANY_VALUE",
7150 sdef
->elements
[i
].type
);
7157 /* default constructor */
7158 def
= mputprintf(def
, "public:\n"
7159 "%s_template(): %s() {}\n", name
, base_class
);
7161 if (sdef
->nElements
==0) {
7162 /* ctor for value {} */
7163 def
= mputprintf(def
, "%s_template(null_type) : "
7164 "Empty_Record_Template() { set_selection(SPECIFIC_VALUE); }\n",
7168 /* constructor t1_template(template_sel other_value) */
7169 def
= mputprintf(def
, "%s_template(template_sel other_value): "
7170 "%s(other_value) {}\n", name
, base_class
);
7172 /* constructor t1_template(const t1& other_value) */
7173 def
= mputprintf(def
, "%s_template(const %s& other_value): "
7174 "%s() { copy_value(&other_value); }\n",
7175 name
, name
, base_class
);
7177 /* constructor t1_template(const OPTIONAL<t1>& other_value) */
7178 def
= mputprintf(def
, "%s_template(const OPTIONAL<%s>& other_value): "
7179 "%s() { copy_optional(&other_value); }\n",
7180 name
, name
, base_class
);
7182 /* copy constructor */
7183 def
= mputprintf(def
, "%s_template(const %s_template& other_value): %s() "
7184 "{ copy_template(other_value); }\n", name
, name
, base_class
);
7186 /* assignment operator <- template_sel */
7187 def
= mputprintf(def
, "%s_template& operator=(template_sel other_value);\n",
7189 src
= mputprintf(src
,
7190 "%s_template& %s_template::operator=(template_sel other_value)\n"
7192 "check_single_selection(other_value);\n"
7194 "set_selection(other_value);\n"
7196 "}\n\n", name
, name
);
7198 /* assignment operator <- value */
7199 def
= mputprintf(def
, "%s_template& operator=(const %s& other_value);\n",
7201 src
= mputprintf(src
,
7202 "%s_template& %s_template::operator=(const %s& other_value)\n"
7205 "copy_value(&other_value);\n"
7207 "}\n\n", name
, name
, name
);
7209 /* assignment operator <- optional value */
7210 def
= mputprintf(def
, "%s_template& operator=(const OPTIONAL<%s>& "
7211 "other_value);\n", name
, name
);
7212 src
= mputprintf(src
,
7213 "%s_template& %s_template::operator=(const OPTIONAL<%s>& other_value)\n"
7216 "copy_optional(&other_value);\n"
7218 "}\n\n", name
, name
, name
);
7220 /* assignment operator <- template*/
7221 def
= mputprintf(def
,
7222 "%s_template& operator=(const %s_template& other_value);\n",
7224 src
= mputprintf(src
,
7225 "%s_template& %s_template::operator=(const %s_template& other_value)\n"
7227 "if (&other_value != this) {\n"
7229 "copy_template(other_value);\n"
7232 "}\n\n", name
, name
, name
);
7234 if (sdef
->nElements
==0) {
7235 /* assignment op for value {} */
7236 def
= mputprintf(def
, "%s_template& operator=(null_type other_value);\n",
7238 src
= mputprintf(src
, "%s_template& %s_template::operator=(null_type)\n"
7241 "set_selection(SPECIFIC_VALUE);\n"
7243 "}\n\n", name
, name
);
7246 /* match operation (template matching) */
7247 def
= mputprintf(def
, "inline boolean match(const %s& other_value, "
7248 "boolean legacy = FALSE) const "
7249 "{ return matchv(&other_value, legacy); }\n", name
);
7252 def
= mputprintf(def
, "inline void log_match(const %s& match_value, "
7253 "boolean legacy = FALSE) const "
7254 "{ log_matchv(&match_value, legacy); }\n", name
);
7256 /* valueof operation */
7257 def
= mputprintf(def
, "%s valueof() const;\n", name
);
7259 src
= mputprintf(src
, "%s %s_template::valueof() const\n"
7262 "valueofv(&ret_val);\n"
7264 "}\n\n", name
, name
, name
);
7266 /* list_item(int) function */
7268 def
= mputprintf(def
,
7269 "inline %s_template& list_item(unsigned int list_index) const "
7270 "{ return *(static_cast<%s_template*>(get_list_item(list_index))); }\n", name
, name
);
7272 if (sdef
->nElements
>0) {
7273 /* template field access functions (non-const & const) */
7274 for (i
= 0; i
< sdef
->nElements
; i
++) {
7275 def
= mputprintf(def
,
7276 "%s_template& %s();\n"
7277 "const %s_template& %s() const;\n",
7278 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
,
7279 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
7280 src
= mputprintf(src
,
7281 "%s_template& %s_template::%s() { return *(static_cast<%s_template*>(get_at(%d))); }\n"
7282 "const %s_template& %s_template::%s() const { return *(static_cast<const %s_template*>(get_at(%d))); }\n",
7283 sdef
->elements
[i
].type
, name
, sdef
->elements
[i
].name
, sdef
->elements
[i
].type
, i
,
7284 sdef
->elements
[i
].type
, name
, sdef
->elements
[i
].name
, sdef
->elements
[i
].type
, i
);
7288 /* virtual functions */
7289 def
= mputprintf(def
,
7290 "%s* create() const { return new %s_template; }\n"
7291 "const TTCN_Typedescriptor_t* get_descriptor() const;\n",
7293 src
= mputprintf(src
,
7294 "const TTCN_Typedescriptor_t* %s_template::get_descriptor() const { return &%s_descr_; }\n",
7297 if (sdef
->nElements
>0) {
7298 def
= mputprintf(def
, "const char* fld_name(int p_index) const;\n");
7299 src
= mputprintf(src
,
7300 "const char* %s_template::fld_name(int p_index) const { return %s::fld_names[p_index]; }\n",
7304 def
= mputstr(def
, "};\n\n");
7306 output
->header
.class_defs
= mputstr(output
->header
.class_defs
, def
);
7309 output
->source
.methods
= mputstr(output
->source
.methods
, src
);