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"
11 #include "datatypes.h"
16 #include "ttcn3/compiler.h"
18 /** used in the RAW_decode functions generation to store information
19 * about the temporal variables
20 * type is the type of the variable
21 * typedescr is the type's descriptor
22 * start_pos is where the decoding should begin
23 * it is >= 0 if known at compile time, otherwise -1
24 * use_counter stores how many times this type will be used
25 * if it is >1 than we create the variable "globally" so that that
26 * we don't need to create it again in the next component's decode try
27 * if it is ==1 than it is a local variable only referred at one place
28 * we create it only where it is needed, so if at runtime the decoding
29 * comes to a conclusion before the use of this variable, then its
30 * overhead won't slow down the decoding
31 * decoded_for_element is the index of the element in the union for which
32 * this variable was last used for
33 * if it is -1 if the variable hasn't been decoded yet
34 * only in this case it is needed to generate the code to do the decoding
35 * if it is >=0 than we use it generate the conditions
36 * if it doesn't equal to the actual component's index, then we have to
37 * generate the condition and the decoding... parts to it.
38 * if it equals the actual component's index, then we only add its test
39 * to the actual condition
43 const char* typedescr
;
46 int decoded_for_element
;
49 void defUnionClass(struct_def
const *sdef
, output_struct
*output
)
52 const char *name
= sdef
->name
, *dispname
= sdef
->dispname
;
53 const char *at_field
= sdef
->kind
==ANYTYPE
? "AT_" : "";
54 /* at_field is used to prefix the name of accessor member functions
55 * for the anytype, otherwise the generated "INTEGER()" will look like
56 * a constructor, upsetting the C++ compiler. AT_INTEGER() is ok. */
57 char *def
= NULL
, *src
= NULL
;
58 boolean ber_needed
= sdef
->isASN1
&& enable_ber();
59 boolean raw_needed
= sdef
->hasRaw
&& enable_raw();
60 boolean text_needed
= sdef
->hasText
&& enable_text();
61 boolean xer_needed
= sdef
->hasXer
&& enable_xer();
62 boolean json_needed
= sdef
->hasJson
&& enable_json();
64 char *selection_type
, *unbound_value
, *selection_prefix
;
65 selection_type
= mcopystr("union_selection_type");
66 unbound_value
= mcopystr("UNBOUND_VALUE");
67 selection_prefix
= mcopystr("ALT");
70 /* class declaration */
71 output
->header
.class_decls
= mputprintf(output
->header
.class_decls
,
74 /* class definition and source code */
76 /* class header and data fields*/
79 "// written by defUnionClass in " __FILE__
" at %d\n"
81 "class %s : public Base_Type {\n"
86 /* selection type (enum) definition */
87 def
= mputstr(def
, "public:\n"
88 "enum union_selection_type { UNBOUND_VALUE = 0");
89 for (i
= 0; i
< sdef
->nElements
; i
++) {
90 def
= mputprintf(def
, ", ALT_%s = %lu", sdef
->elements
[i
].name
,
91 (unsigned long) (i
+ 1));
93 def
= mputstr(def
, " };\n"
96 def
= mputprintf(def
, "%s union_selection;\n"
97 "union {\n", selection_type
);
98 for (i
= 0; i
< sdef
->nElements
; i
++) {
99 def
= mputprintf(def
, "%s *field_%s;\n", sdef
->elements
[i
].type
,
100 sdef
->elements
[i
].name
);
102 def
= mputstr(def
, "};\n");
104 if(ber_needed
&& sdef
->ot
) {
105 def
=mputstr(def
, "ASN_BER_TLV_t tlv_opentype;\n");
109 def
=mputstr(def
, "Erroneous_descriptor_t* err_descr;\n");
112 /* copy_value function */
113 def
= mputprintf(def
, "void copy_value(const %s& other_value);\n", name
);
114 src
= mputprintf(src
, "void %s::copy_value(const %s& other_value)\n"
116 "switch (other_value.union_selection) {\n", name
, name
);
117 for (i
= 0; i
< sdef
->nElements
; i
++) {
118 src
= mputprintf(src
, "case %s_%s:\n"
119 "field_%s = new %s(*other_value.field_%s);\n"
120 "break;\n", selection_prefix
, sdef
->elements
[i
].name
,
121 sdef
->elements
[i
].name
, sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
123 src
= mputprintf(src
, "default:\n"
124 "TTCN_error(\"Assignment of an unbound union value of type %s.\");\n"
126 "union_selection = other_value.union_selection;\n", dispname
);
129 src
= mputstr(src
, "err_descr = other_value.err_descr;\n");
132 src
= mputstr(src
, "}\n\n");
134 /* default constructor */
135 def
= mputprintf(def
, "\npublic:\n"
137 src
= mputprintf(src
, "%s::%s()%s\n"
139 "union_selection = %s;\n"
141 use_runtime_2
? ": err_descr(NULL)" : "",
144 /* copy constructor */
145 def
= mputprintf(def
, "%s(const %s& other_value);\n", name
, name
);
146 src
= mputprintf(src
, "%s::%s(const %s& other_value)\n"
147 ": Base_Type()" /* call the *default* constructor as before */
149 "copy_value(other_value);\n"
150 "}\n\n", name
, name
, name
);
153 def
= mputprintf(def
, "~%s();\n", name
);
154 src
= mputprintf(src
, "%s::~%s()\n"
157 "}\n\n", name
, name
);
159 /* assignment operator */
160 def
= mputprintf(def
, "%s& operator=(const %s& other_value);\n", name
, name
);
161 src
= mputprintf(src
, "%s& %s::operator=(const %s& other_value)\n"
163 "if (this != &other_value) {\n"
165 "copy_value(other_value);\n"
168 "}\n\n", name
, name
, name
);
170 /* comparison operator */
171 def
= mputprintf(def
, "boolean operator==(const %s& other_value) const;\n",
173 src
= mputprintf(src
, "boolean %s::operator==(const %s& other_value) const\n"
175 "if (union_selection == %s) TTCN_error(\"The left operand of comparison "
176 "is an unbound value of union type %s.\");\n"
177 "if (other_value.union_selection == %s) TTCN_error(\"The right operand of "
178 "comparison is an unbound value of union type %s.\");\n"
179 "if (union_selection != other_value.union_selection) return FALSE;\n"
180 "switch (union_selection) {\n", name
, name
, unbound_value
, dispname
,
181 unbound_value
, dispname
);
182 for (i
= 0; i
< sdef
->nElements
; i
++) {
183 src
= mputprintf(src
, "case %s_%s:\n"
184 "return *field_%s == *other_value.field_%s;\n", selection_prefix
,
185 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
187 src
= mputstr(src
, "default:\n"
192 /* != and () operator */
193 def
= mputprintf(def
, "inline boolean operator!=(const %s& other_value) "
194 "const { return !(*this == other_value); }\n", name
);
196 /* field access functions */
197 for (i
= 0; i
< sdef
->nElements
; i
++) {
198 def
= mputprintf(def
, "%s& %s%s();\n", sdef
->elements
[i
].type
,
199 at_field
, sdef
->elements
[i
].name
);
200 src
= mputprintf(src
, "%s& %s::%s%s()\n"
202 "if (union_selection != %s_%s) {\n"
204 "field_%s = new %s;\n"
205 "union_selection = %s_%s;\n"
207 "return *field_%s;\n"
208 "}\n\n", sdef
->elements
[i
].type
, name
, at_field
, sdef
->elements
[i
].name
,
209 selection_prefix
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
210 sdef
->elements
[i
].type
, selection_prefix
, sdef
->elements
[i
].name
,
211 sdef
->elements
[i
].name
);
213 def
= mputprintf(def
, "const %s& %s%s() const;\n", sdef
->elements
[i
].type
,
214 at_field
, sdef
->elements
[i
].name
);
215 src
= mputprintf(src
, "const %s& %s::%s%s() const\n"
217 "if (union_selection != %s_%s) TTCN_error(\"Using non-selected field "
218 "%s in a value of union type %s.\");\n"
219 "return *field_%s;\n"
221 sdef
->elements
[i
].type
, name
, at_field
, sdef
->elements
[i
].name
, selection_prefix
,
222 sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
, dispname
,
223 sdef
->elements
[i
].name
);
226 /* get_selection function */
227 def
= mputprintf(def
, "inline %s get_selection() const "
228 "{ return union_selection; }\n", selection_type
);
230 /* ischosen function */
231 def
= mputprintf(def
, "boolean ischosen(%s checked_selection) const;\n",
233 src
= mputprintf(src
, "boolean %s::ischosen(%s checked_selection) const\n"
235 "if (checked_selection == %s) TTCN_error(\"Internal error: Performing "
236 "ischosen() operation on an invalid field of union type %s.\");\n"
237 "if (union_selection == %s) TTCN_error(\"Performing ischosen() operation "
238 "on an unbound value of union type %s.\");\n"
239 "return union_selection == checked_selection;\n"
240 "}\n\n", name
, selection_type
, unbound_value
, dispname
, unbound_value
,
243 /* is_bound function */
244 def
= mputstr (def
, "boolean is_bound() const;\n");
245 src
= mputprintf(src
, "boolean %s::is_bound() const\n"
247 " return union_selection != %s;\n"
248 "}\n\n", name
, unbound_value
);
250 /* is_value function */
251 def
= mputstr (def
, "boolean is_value() const;\n");
252 src
= mputprintf(src
, "boolean %s::is_value() const\n"
254 "switch (union_selection) {\n"
255 "case %s: return FALSE;\n",
256 name
, unbound_value
);
257 for (i
= 0; i
< sdef
->nElements
; ++i
) {
258 src
= mputprintf(src
, "case %s_%s: return field_%s->is_value();\n",
259 selection_prefix
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
261 src
= mputstr(src
, "default: TTCN_error(\"Invalid selection in union is_bound\");"
265 /* clean_up function */
266 def
= mputstr (def
, "void clean_up();\n");
267 src
= mputprintf(src
, "void %s::clean_up()\n"
269 "switch (union_selection) {\n",
271 for (i
= 0; i
< sdef
->nElements
; ++i
) {
272 src
= mputprintf(src
, "case %s_%s:\n"
273 " delete field_%s;\n"
275 selection_prefix
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
277 src
= mputprintf(src
, "default:\n"
280 "union_selection = %s;\n"
281 "}\n\n", unbound_value
);
285 "boolean is_equal(const Base_Type* other_value) const;\n"
286 "void set_value(const Base_Type* other_value);\n"
287 "Base_Type* clone() const;\n"
288 "const TTCN_Typedescriptor_t* get_descriptor() const;\n"
289 "void set_err_descr(Erroneous_descriptor_t* p_err_descr) { err_descr=p_err_descr; }\n"
290 "Erroneous_descriptor_t* get_err_descr() const { return err_descr; }\n");
291 src
= mputprintf(src
,
292 "boolean %s::is_equal(const Base_Type* other_value) const "
293 "{ return *this == *(static_cast<const %s*>(other_value)); }\n"
294 "void %s::set_value(const Base_Type* other_value) "
295 "{ *this = *(static_cast<const %s*>(other_value)); }\n"
296 "Base_Type* %s::clone() const { return new %s(*this); }\n"
297 "const TTCN_Typedescriptor_t* %s::get_descriptor() const "
298 "{ return &%s_descr_; }\n",
305 "inline boolean is_present() const { return is_bound(); }\n");
309 def
= mputstr(def
, "void log() const;\n");
310 src
= mputprintf(src
, "void %s::log() const\n"
312 "switch (union_selection) {\n", name
);
313 for (i
= 0; i
< sdef
->nElements
; i
++) {
314 src
= mputprintf(src
, "case %s_%s:\n"
315 "TTCN_Logger::log_event_str(\"{ %s := \");\n"
317 "TTCN_Logger::log_event_str(\" }\");\n"
318 "break;\n", selection_prefix
, sdef
->elements
[i
].name
,
319 sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
);
321 src
= mputstr(src
, "default:\n"
322 "TTCN_Logger::log_event_unbound();\n"
325 src
= mputstr(src
, "if (err_descr) err_descr->log();\n");
327 src
= mputstr(src
, "}\n\n");
329 /* set_param function */
330 def
= mputstr(def
, "void set_param(Module_Param& param);\n");
331 src
= mputprintf(src
, "void %s::set_param(Module_Param& param)\n"
333 " if (dynamic_cast<Module_Param_Name*>(param.get_id()) != NULL &&\n"
334 " param.get_id()->next_name()) {\n"
335 // Haven't reached the end of the module parameter name
336 // => the name refers to one of the fields, not to the whole union
337 " char* param_field = param.get_id()->get_current_name();\n"
338 " if (param_field[0] >= '0' && param_field[0] <= '9') {\n"
339 " param.error(\"Unexpected array index in module parameter, expected a valid field\"\n"
340 " \" name for union type `%s'\");\n"
342 " ", name
, dispname
);
343 for (i
= 0; i
< sdef
->nElements
; i
++) {
344 src
= mputprintf(src
,
345 "if (strcmp(\"%s\", param_field) == 0) {\n"
346 " %s%s().set_param(param);\n"
349 sdef
->elements
[i
].dispname
, at_field
, sdef
->elements
[i
].name
);
351 src
= mputprintf(src
,
352 "param.error(\"Field `%%s' not found in union type `%s'\", param_field);\n"
354 " param.basic_check(Module_Param::BC_VALUE, \"union value\");\n"
355 " Module_Param_Ptr mp = ¶m;\n"
356 " if (param.get_type() == Module_Param::MP_Reference) {\n"
357 " mp = param.get_referenced_param();\n"
359 " if (mp->get_type()==Module_Param::MP_Value_List && mp->get_size()==0) return;\n"
360 " if (mp->get_type()!=Module_Param::MP_Assignment_List) {\n"
361 " param.error(\"union value with field name was expected\");\n"
363 " Module_Param* mp_last = mp->get_elem(mp->get_size()-1);\n", dispname
);
365 for (i
= 0; i
< sdef
->nElements
; i
++) {
366 src
= mputprintf(src
,
367 " if (!strcmp(mp_last->get_id()->get_name(), \"%s\")) {\n"
368 " %s%s().set_param(*mp_last);\n"
370 " }\n", sdef
->elements
[i
].dispname
, at_field
, sdef
->elements
[i
].name
);
372 src
= mputprintf(src
,
373 " mp_last->error(\"Field %%s does not exist in type %s.\", mp_last->get_id()->get_name());\n"
376 /* get param function */
377 def
= mputstr(def
, "Module_Param* get_param(Module_Param_Name& param_name) const;\n");
378 src
= mputprintf(src
,
379 "Module_Param* %s::get_param(Module_Param_Name& param_name) const\n"
381 " if (!is_bound()) {\n"
382 " return new Module_Param_Unbound();\n"
384 " if (param_name.next_name()) {\n"
385 // Haven't reached the end of the module parameter name
386 // => the name refers to one of the fields, not to the whole union
387 " char* param_field = param_name.get_current_name();\n"
388 " if (param_field[0] >= '0' && param_field[0] <= '9') {\n"
389 " TTCN_error(\"Unexpected array index in module parameter reference, \"\n"
390 " \"expected a valid field name for union type `%s'\");\n"
392 " ", name
, dispname
);
393 for (i
= 0; i
< sdef
->nElements
; i
++) {
394 src
= mputprintf(src
,
395 "if (strcmp(\"%s\", param_field) == 0) {\n"
396 " return %s%s().get_param(param_name);\n"
398 sdef
->elements
[i
].dispname
, at_field
, sdef
->elements
[i
].name
);
400 src
= mputprintf(src
,
401 "TTCN_error(\"Field `%%s' not found in union type `%s'\", param_field);\n"
403 " Module_Param* mp_field = NULL;\n"
404 " switch(union_selection) {\n"
406 for (i
= 0; i
< sdef
->nElements
; ++i
) {
407 src
= mputprintf(src
,
409 " mp_field = field_%s->get_param(param_name);\n"
410 " mp_field->set_id(new Module_Param_FieldName(mcopystr(\"%s\")));\n"
412 , selection_prefix
, sdef
->elements
[i
].name
413 , sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
);
419 " Module_Param_Assignment_List* mp = new Module_Param_Assignment_List();\n"
420 " mp->add_elem(mp_field);\n"
424 /* set implicit omit function, recursive */
425 def
= mputstr(def
, " void set_implicit_omit();\n");
426 src
= mputprintf(src
,
427 "void %s::set_implicit_omit()\n{\n"
428 "switch (union_selection) {\n", name
);
429 for (i
= 0; i
< sdef
->nElements
; i
++) {
430 src
= mputprintf(src
,
432 "field_%s->set_implicit_omit(); break;\n",
433 selection_prefix
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
435 src
= mputstr(src
, "default: break;\n}\n}\n\n");
437 /* encode_text function */
438 def
= mputstr(def
, "void encode_text(Text_Buf& text_buf) const;\n");
439 src
= mputprintf(src
, "void %s::encode_text(Text_Buf& text_buf) const\n"
441 "text_buf.push_int(union_selection);\n"
442 "switch (union_selection) {\n", name
);
443 for (i
= 0; i
< sdef
->nElements
; i
++) {
444 src
= mputprintf(src
, "case %s_%s:\n"
445 "field_%s->encode_text(text_buf);\n"
446 "break;\n", selection_prefix
, sdef
->elements
[i
].name
,
447 sdef
->elements
[i
].name
);
449 src
= mputprintf(src
, "default:\n"
450 "TTCN_error(\"Text encoder: Encoding an unbound value of union type "
455 /* decode_text function */
456 def
= mputstr(def
, "void decode_text(Text_Buf& text_buf);\n");
457 src
= mputprintf(src
, "void %s::decode_text(Text_Buf& text_buf)\n"
459 "switch ((%s)text_buf.pull_int().get_val()) {\n", name
, selection_type
);
460 for (i
= 0; i
< sdef
->nElements
; i
++) {
461 src
= mputprintf(src
, "case %s_%s:\n"
462 "%s%s().decode_text(text_buf);\n"
463 "break;\n", selection_prefix
, sdef
->elements
[i
].name
,
464 at_field
, sdef
->elements
[i
].name
);
466 src
= mputprintf(src
, "default:\n"
467 "TTCN_error(\"Text decoder: Unrecognized union selector was received "
472 if(ber_needed
|| raw_needed
|| text_needed
|| xer_needed
|| json_needed
)
473 def_encdec(name
, &def
, &src
, ber_needed
, raw_needed
, text_needed
,
474 xer_needed
, json_needed
, TRUE
);
478 def
= mputstr(def
, "private:\n"
479 "boolean BER_decode_set_selection(const ASN_BER_TLV_t& p_tlv);\n"
481 "boolean BER_decode_isMyMsg(const TTCN_Typedescriptor_t& p_td, "
482 "const ASN_BER_TLV_t& p_tlv);\n");
484 /* BER_encode_TLV() */
485 src
= mputprintf(src
,
487 "// written by %s in " __FILE__
" at %d\n"
489 "ASN_BER_TLV_t *%s::BER_encode_TLV("
490 "const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const\n"
493 , __FUNCTION__
, __LINE__
498 " if (err_descr) return BER_encode_TLV_negtest(err_descr, p_td, p_coding);\n");
501 " BER_chk_descr(p_td);\n"
502 " ASN_BER_TLV_t *new_tlv;\n"
503 " TTCN_EncDec_ErrorContext ec_0(\"Alternative '\");\n"
504 " TTCN_EncDec_ErrorContext ec_1;\n"
505 " switch (union_selection) {\n");
506 for (i
= 0; i
< sdef
->nElements
; i
++) {
507 src
= mputprintf(src
, " case %s_%s:\n"
508 " ec_1.set_msg(\"%s': \");\n"
509 " new_tlv = field_%s->BER_encode_TLV(%s_descr_, p_coding);\n"
510 " break;\n", selection_prefix
, sdef
->elements
[i
].name
,
511 sdef
->elements
[i
].dispname
,
512 sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
);
514 src
= mputprintf(src
, " case %s:\n"
515 " new_tlv = BER_encode_chk_bound(FALSE);\n"
518 " TTCN_EncDec_ErrorContext::error_internal(\"Unknown selection.\");\n"
521 " return ASN_BER_V2TLV(new_tlv, p_td, p_coding);\n"
522 "}\n\n", unbound_value
);
524 if (use_runtime_2
) { /* BER_encode_TLV_negtest() */
526 "ASN_BER_TLV_t* BER_encode_TLV_negtest(const Erroneous_descriptor_t* p_err_descr, const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const;\n");
527 src
= mputprintf(src
,
528 "ASN_BER_TLV_t *%s::BER_encode_TLV_negtest(const Erroneous_descriptor_t* p_err_descr, "
529 "const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const\n"
531 " BER_chk_descr(p_td);\n"
532 " ASN_BER_TLV_t *new_tlv = NULL;\n"
533 " TTCN_EncDec_ErrorContext ec_0(\"Alternative '\");\n"
534 " TTCN_EncDec_ErrorContext ec_1;\n"
535 " const Erroneous_values_t* err_vals = NULL;\n"
536 " const Erroneous_descriptor_t* emb_descr = NULL;\n"
537 " switch (union_selection) {\n", name
);
538 for (i
= 0; i
< sdef
->nElements
; i
++) {
539 src
= mputprintf(src
, " case %s_%s:\n"
540 " err_vals = p_err_descr->get_field_err_values(%d);\n"
541 " emb_descr = p_err_descr->get_field_emb_descr(%d);\n"
542 " if (err_vals && err_vals->value) {\n"
543 " if (err_vals->value->errval) {\n"
544 " ec_1.set_msg(\"%s'(erroneous value): \");\n"
545 " if (err_vals->value->raw) {\n"
546 " new_tlv = err_vals->value->errval->BER_encode_negtest_raw();\n"
548 " if (err_vals->value->type_descr==NULL) TTCN_error(\"internal error: erroneous value typedescriptor missing\");\n"
549 " new_tlv = err_vals->value->errval->BER_encode_TLV(*err_vals->value->type_descr, p_coding);\n"
553 " ec_1.set_msg(\"%s': \");\n"
554 " if (emb_descr) new_tlv = field_%s->BER_encode_TLV_negtest(emb_descr, %s_descr_, p_coding);\n"
555 " else new_tlv = field_%s->BER_encode_TLV(%s_descr_, p_coding);\n"
557 " break;\n", selection_prefix
, sdef
->elements
[i
].name
,
558 (int)i
, (int)i
, sdef
->elements
[i
].dispname
, sdef
->elements
[i
].dispname
,
559 sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
,
560 sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
);
562 src
= mputprintf(src
, " case %s:\n"
563 " new_tlv = BER_encode_chk_bound(FALSE);\n"
566 " TTCN_EncDec_ErrorContext::error_internal(\"Unknown selection.\");\n"
569 " if (new_tlv==NULL) new_tlv=ASN_BER_TLV_t::construct(NULL);\n"
570 " return ASN_BER_V2TLV(new_tlv, p_td, p_coding);\n"
571 "}\n\n", unbound_value
);
574 /* BER_decode_set_selection() */
575 src
= mputprintf(src
, "boolean %s::BER_decode_set_selection("
576 "const ASN_BER_TLV_t& p_tlv)\n"
578 " clean_up();\n", name
);
579 for (i
= 0; i
< sdef
->nElements
; i
++) {
580 src
= mputprintf(src
, " field_%s = new %s;\n"
581 " union_selection = %s_%s;\n"
582 " if (field_%s->BER_decode_isMyMsg(%s_descr_, p_tlv)) return TRUE;\n"
583 " delete field_%s;\n", sdef
->elements
[i
].name
, sdef
->elements
[i
].type
,
584 selection_prefix
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
585 sdef
->elements
[i
].typedescrname
, sdef
->elements
[i
].name
);
587 src
= mputprintf(src
, " union_selection = %s;\n"
589 "}\n\n", unbound_value
);
591 /* BER_decode_isMyMsg() */
592 src
= mputprintf(src
, "boolean %s::BER_decode_isMyMsg("
593 "const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv)\n"
595 " if (p_td.ber->n_tags == 0) {\n"
597 " return tmp_type.BER_decode_set_selection(p_tlv);\n"
598 " } else return Base_Type::BER_decode_isMyMsg(p_td, p_tlv);\n"
599 "}\n\n", name
, name
);
601 /* BER_decode_TLV() */
602 src
= mputprintf(src
, "boolean %s::BER_decode_TLV("
603 "const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, "
606 " BER_chk_descr(p_td);\n"
607 " ASN_BER_TLV_t stripped_tlv;\n"
608 " BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv);\n"
609 " TTCN_EncDec_ErrorContext ec_0(\"While decoding '%s' type: \");\n",
612 src
= mputprintf(src
, " if (!BER_decode_TLV_CHOICE(*p_td.ber, "
613 "stripped_tlv, L_form, tlv_opentype)) {\n"
614 " tlv_opentype.Tlen = 0;\n"
618 " union_selection = %s;\n", unbound_value
);
620 src
= mputstr(src
, " ASN_BER_TLV_t tmp_tlv;\n"
621 " if (!BER_decode_TLV_CHOICE(*p_td.ber, stripped_tlv, L_form, "
623 "!BER_decode_CHOICE_selection(BER_decode_set_selection(tmp_tlv), "
624 "tmp_tlv)) return FALSE;\n"
625 " TTCN_EncDec_ErrorContext ec_1(\"Alternative '\");\n"
626 " TTCN_EncDec_ErrorContext ec_2;\n"
627 " switch (union_selection) {\n");
628 for(i
= 0; i
< sdef
->nElements
; i
++) {
629 src
= mputprintf(src
, " case %s_%s:\n"
630 " ec_2.set_msg(\"%s': \");\n"
631 " field_%s->BER_decode_TLV(%s_descr_, tmp_tlv, L_form);\n"
632 " break;\n", selection_prefix
, sdef
->elements
[i
].name
,
633 sdef
->elements
[i
].dispname
,
634 sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
);
636 src
= mputstr(src
, " default:\n"
639 if (sdef
->opentype_outermost
) {
641 " TTCN_EncDec_ErrorContext ec_1(\"While decoding opentypes: \");\n"
642 " TTCN_Type_list p_typelist;\n"
643 " BER_decode_opentypes(p_typelist, L_form);\n");
644 } /* if sdef->opentype_outermost */
646 src
= mputstr(src
, " return TRUE;\n"
649 if (sdef
->ot
|| sdef
->has_opentypes
) { /* theoretically, these are
651 /* BER_decode_opentypes() */
652 def
= mputstr(def
, "void BER_decode_opentypes("
653 "TTCN_Type_list& p_typelist, unsigned L_form);\n");
654 src
= mputprintf(src
, "void %s::BER_decode_opentypes("
655 "TTCN_Type_list& p_typelist, unsigned L_form)\n"
658 AtNotationList_t
*anl
= &sdef
->ot
->anl
;
659 OpentypeAlternativeList_t
*oal
= &sdef
->ot
->oal
;
660 src
= mputprintf(src
,
661 " if (union_selection != %s) return;\n"
662 " TTCN_EncDec_ErrorContext ec_0(\"While decoding open type '%s': "
663 "\");\n", unbound_value
, dispname
);
664 if (oal
->nElements
> 0) {
667 /* variable declarations - the referenced components */
668 for (anl_i
= 0; anl_i
< anl
->nElements
; anl_i
++) {
669 AtNotation_t
*an
= anl
->elements
+ anl_i
;
670 src
= mputprintf(src
, " const %s& f_%lu = static_cast<const %s*>"
671 "(p_typelist.get_nth(%lu))->%s;\n", an
->type_name
,
672 (unsigned long) (anl_i
+ 1), an
->parent_typename
,
673 (unsigned long) an
->parent_level
, an
->sourcecode
);
675 src
= mputstr(src
, " {\n"
676 " TTCN_EncDec_ErrorContext ec_1(\"Alternative '\");\n"
677 " TTCN_EncDec_ErrorContext ec_2;\n");
678 s2
= mprintf("%*s", (int)(anl
->nElements
+ 2) * 2, "");
679 for (oal_i
= 0; oal_i
< oal
->nElements
; oal_i
++) {
681 OpentypeAlternative_t
*oa
= oal
->elements
+ oal_i
;
683 for (if_level
= 0; if_level
< anl
->nElements
; if_level
++)
684 if (oa
->const_valuenames
[if_level
]) break;
685 for (i
= anl
->nElements
; i
> if_level
; i
--)
686 src
= mputprintf(src
, "%*s}\n", (int)(i
+ 1) * 2, "");
689 for (anl_i
= if_level
; anl_i
< anl
->nElements
; anl_i
++) {
690 src
= mputprintf(src
, "%*s%sif (f_%lu == %s) {\n",
691 (int)(anl_i
+ 2) * 2, "",
692 oal_i
&& anl_i
<= if_level
? "else " : "",
693 (unsigned long) (anl_i
+ 1), oa
->const_valuenames
[anl_i
]);
695 src
= mputprintf(src
, "%sunion_selection = %s_%s;\n"
696 "%sfield_%s = new %s;\n"
697 "%sec_2.set_msg(\"%s': \");\n"
698 "%sfield_%s->BER_decode_TLV(%s_descr_, tlv_opentype, L_form);\n",
699 s2
, selection_prefix
, oa
->alt
, s2
, oa
->alt
, oa
->alt_typename
, s2
,
700 oa
->alt_dispname
, s2
, oa
->alt
, oa
->alt_typedescrname
);
703 if (oal
->nElements
> 0)
704 for (i
= anl
->nElements
; i
> 0; i
--)
705 src
= mputprintf(src
, "%*s}\n", (int)(i
+1)*2, "");
706 src
= mputprintf(src
, " }\n"
707 " if (union_selection == %s) {\n"
708 " ec_0.error(TTCN_EncDec::ET_DEC_OPENTYPE, \"Cannot decode "
709 "open type: broken component relation constraint.\");\n"
710 " if (TTCN_EncDec::get_error_behavior("
711 "TTCN_EncDec::ET_DEC_OPENTYPE) != TTCN_EncDec::EB_IGNORE) {\n"
712 " TTCN_Logger::log_str(TTCN_WARNING, \"The value%s of"
713 " constraining component%s:\");\n", unbound_value
,
714 anl
->nElements
> 1 ? "s" : "", anl
->nElements
> 1 ? "s" : "");
715 for (anl_i
= 0; anl_i
< anl
->nElements
; anl_i
++) {
716 AtNotation_t
*an
= anl
->elements
+ anl_i
;
717 src
= mputprintf(src
,
718 " TTCN_Logger::begin_event(TTCN_WARNING);\n"
719 " TTCN_Logger::log_event_str(\"Component '%s': \");\n"
721 " TTCN_Logger::end_event();\n", an
->dispname
,
722 (unsigned long) (anl_i
+ 1));
724 src
= mputstr(src
, " }\n"
726 } /* if oal->nElements>0 */
728 src
= mputstr(src
, " ec_0.error(TTCN_EncDec::ET_DEC_OPENTYPE, "
729 "\"Cannot decode open type: the constraining object set is "
731 } /* oal->nElements==0 */
733 else { /* if !sdef->ot (but has_opentypes) */
735 " p_typelist.push(this);\n"
736 " TTCN_EncDec_ErrorContext ec_0(\"Alternative '\");\n"
737 " TTCN_EncDec_ErrorContext ec_1;\n"
738 " switch (union_selection) {\n");
739 for (i
= 0; i
< sdef
->nElements
; i
++) {
740 src
= mputprintf(src
, " case %s_%s:\n"
741 " ec_1.set_msg(\"%s': \");\n"
742 " field_%s->BER_decode_opentypes(p_typelist, L_form);\n"
743 " break;\n", selection_prefix
, sdef
->elements
[i
].name
,
744 sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
);
746 src
= mputstr(src
, " default:\n"
749 " p_typelist.pop();\n");
750 } /* if has opentypes */
751 src
= mputstr(src
, "}\n"
753 } /* if sdef->ot || sdef->has_opentypes */
754 } /* if ber_needed */
757 size_t nTemp_variables
= 0;
758 temporal_variable
* temp_variable_list
= NULL
;
759 int* tag_type
= (int*) Malloc(sdef
->nElements
*sizeof(int));
760 memset(tag_type
, 0, sdef
->nElements
* sizeof(int));
761 if (sdef
->hasRaw
) { /* fill tag_type. 0-No tag, >0 index of the tag + 1 */
762 for (i
= 0; i
< sdef
->raw
.taglist
.nElements
; i
++) {
763 if (sdef
->raw
.taglist
.list
[i
].nElements
) {
764 boolean found
= FALSE
;
766 for (v
= 0; v
< sdef
->raw
.taglist
.list
[i
].nElements
; v
++) {
767 if (sdef
->raw
.taglist
.list
[i
].fields
[v
].start_pos
>= 0) {
773 tag_type
[sdef
->raw
.taglist
.list
[i
].fieldnum
] = i
+ 1;
775 tag_type
[sdef
->raw
.taglist
.list
[i
].fieldnum
] = -i
- 1;
779 src
= mputprintf(src
, "int %s::RAW_decode(\n"
780 "const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, \n"
781 "raw_order_t top_bit_ord, boolean no_err, int sel_field, boolean)\n"
783 " int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);\n"
784 " limit-=prepaddlength;\n"
785 " int decoded_length=0;\n"
786 " int starting_pos=p_buf.get_pos_bit();\n"
787 " if(sel_field!=-1){\n"
788 " switch(sel_field){\n", name
);
789 for (i
= 0; i
< sdef
->nElements
; i
++) {
790 src
= mputprintf(src
,
792 " decoded_length = %s().RAW_decode(%s_descr_, p_buf, limit, "
793 "top_bit_ord, no_err);\n"
794 " break;\n", (unsigned long) i
, sdef
->elements
[i
].name
,
795 sdef
->elements
[i
].typedescrname
);
797 src
= mputstr(src
, " default: break;\n"
799 " return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + "
802 /* only generate this variable if it will be used */
803 for (i
= 0; i
< sdef
->nElements
; i
++) {
804 if ((tag_type
[i
] > 0)
805 && (sdef
->raw
.taglist
.list
+ tag_type
[i
] - 1)->nElements
) {
806 src
= mputstr(src
, " boolean already_failed = FALSE;\n"
807 " raw_order_t local_top_order;\n");
812 /* precalculate what we know about the temporal variables*/
813 for (i
= 0; i
< sdef
->nElements
; i
++) {
814 if ((tag_type
[i
] > 0)
815 && (sdef
->raw
.taglist
.list
+ tag_type
[i
] - 1)->nElements
) {
816 rawAST_coding_taglist
* cur_choice
= sdef
->raw
.taglist
.list
+ tag_type
[i
] - 1;
818 for (j
= 0; j
< cur_choice
->nElements
; j
++) {
819 rawAST_coding_field_list
*fieldlist
= cur_choice
->fields
+ j
;
820 if (fieldlist
->start_pos
>= 0) {
822 boolean found
= FALSE
;
823 for (k
= 0; k
< nTemp_variables
; k
++) {
824 if (temp_variable_list
[k
].start_pos
== fieldlist
->start_pos
825 && !strcmp(temp_variable_list
[k
].typedescr
,
826 fieldlist
->fields
[fieldlist
->nElements
- 1].typedescr
)) {
827 temp_variable_list
[k
].use_counter
++;
828 fieldlist
->temporal_variable_index
= k
;
835 = (temporal_variable
*) Realloc(temp_variable_list
,
836 (nTemp_variables
+ 1) * sizeof(*temp_variable_list
));
837 temp_variable_list
[nTemp_variables
].type
838 = fieldlist
->fields
[fieldlist
->nElements
- 1].type
;
839 temp_variable_list
[nTemp_variables
].typedescr
840 = fieldlist
->fields
[fieldlist
->nElements
- 1].typedescr
;
841 temp_variable_list
[nTemp_variables
].start_pos
842 = fieldlist
->start_pos
;
843 temp_variable_list
[nTemp_variables
].use_counter
= 1;
844 temp_variable_list
[nTemp_variables
].decoded_for_element
846 fieldlist
->temporal_variable_index
= nTemp_variables
;
854 for (i
= 0; i
< nTemp_variables
; i
++) {
855 if (temp_variable_list
[i
].use_counter
> 1) {
856 src
= mputprintf(src
, " %s temporal_%lu;\n"
857 " int decoded_%lu_length;\n", temp_variable_list
[i
].type
,
858 (unsigned long) i
, (unsigned long) i
);
862 for (i
= 0; i
< sdef
->nElements
; i
++) { /* fields with tag */
863 if ((tag_type
[i
] > 0)
864 && (sdef
->raw
.taglist
.list
+ tag_type
[i
] - 1)->nElements
) {
865 rawAST_coding_taglist
* cur_choice
= sdef
->raw
.taglist
.list
868 src
= mputstr(src
, " already_failed = FALSE;\n");
869 /* first check the fields we can precode
870 * try to decode those key variables whose position we know
871 * this way we might be able to step over bad values faster
873 for (j
= 0; j
< cur_choice
->nElements
; j
++) {
874 rawAST_coding_field_list
*cur_field_list
= cur_choice
->fields
+ j
;
875 if (cur_field_list
->start_pos
>= 0) {
877 size_t variable_index
= cur_field_list
->temporal_variable_index
;
878 if (temp_variable_list
[variable_index
].decoded_for_element
== i
) continue;
879 src
= mputstr(src
, " if (!already_failed) {\n");
880 if (temp_variable_list
[variable_index
].use_counter
== 1) {
881 src
= mputprintf(src
, " %s temporal_%lu;\n"
882 " int decoded_%lu_length;\n",
883 temp_variable_list
[variable_index
].type
,
884 (unsigned long) variable_index
, (unsigned long) variable_index
);
886 if (temp_variable_list
[variable_index
].decoded_for_element
888 src
= mputstr(src
, " ");
889 for (k
= cur_field_list
->nElements
- 1; k
> 0; k
--) {
890 src
= mputprintf(src
,
891 " if(%s_descr_.raw->top_bit_order==TOP_BIT_RIGHT)"
892 "local_top_order=ORDER_MSB;\n"
893 " else if(%s_descr_.raw->top_bit_order==TOP_BIT_LEFT)"
894 "local_top_order=ORDER_LSB;\n"
895 " else", cur_field_list
->fields
[k
- 1].typedescr
,
896 cur_field_list
->fields
[k
- 1].typedescr
);
898 src
= mputprintf(src
, " local_top_order=top_bit_ord;\n"
899 " p_buf.set_pos_bit(starting_pos + %d);\n"
900 " decoded_%lu_length = temporal_%lu.RAW_decode("
901 "%s_descr_, p_buf, limit, top_bit_ord, TRUE);\n",
902 cur_field_list
->start_pos
, (unsigned long) variable_index
,
903 (unsigned long) variable_index
,
904 temp_variable_list
[variable_index
].typedescr
);
906 temp_variable_list
[variable_index
].decoded_for_element
= i
;
907 src
= mputprintf(src
, " if (decoded_%lu_length > 0) {\n"
908 " if (temporal_%lu == %s", (unsigned long) variable_index
,
909 (unsigned long) variable_index
, cur_field_list
->value
);
910 for (k
= j
+ 1; k
< cur_choice
->nElements
; k
++) {
911 if (cur_choice
->fields
[k
].temporal_variable_index
913 src
= mputprintf(src
, " || temporal_%lu == %s",
914 (unsigned long) variable_index
, cur_choice
->fields
[k
].value
);
917 src
= mputprintf(src
, ") {\n"
918 " p_buf.set_pos_bit(starting_pos);\n"
919 " decoded_length = %s().RAW_decode(%s_descr_, p_buf, "
920 "limit, top_bit_ord, TRUE);\n"
921 " if (decoded_length > 0) {\n", sdef
->elements
[i
].name
,
922 sdef
->elements
[i
].typedescrname
);
923 src
= mputstr(src
, " if (");
924 src
= genRawFieldChecker(src
, cur_choice
, TRUE
);
925 src
= mputstr(src
, ") {\n"
926 " return decoded_length + "
927 "p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;\n"
928 " }else already_failed = TRUE;\n"
935 /* if there is one tag key whose position we don't know
936 * and we couldn't decide yet if the element can be decoded or not
937 * than we have to decode it.
938 * note that this is not actually a cycle because of the break
940 for (j
= 0; j
< cur_choice
->nElements
; j
++) {
941 if (cur_choice
->fields
[j
].start_pos
< 0) {
942 src
= mputprintf(src
, " if (already_failed) {\n"
943 " p_buf.set_pos_bit(starting_pos);\n"
944 " decoded_length = %s().RAW_decode(%s_descr_, p_buf, limit, "
945 "top_bit_ord, TRUE);\n"
946 " if (decoded_length > 0) {\n", sdef
->elements
[i
].name
,
947 sdef
->elements
[i
].typedescrname
);
948 src
= mputstr(src
, " if (");
949 src
= genRawFieldChecker(src
, cur_choice
, TRUE
);
950 src
= mputstr(src
, ") {\n"
951 " return decoded_length + "
952 "p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;\n"
961 Free(temp_variable_list
);
962 for (i
= 0; i
< sdef
->nElements
; i
++) { /* fields with only variable tag */
963 if ((tag_type
[i
] < 0)
964 && (sdef
->raw
.taglist
.list
- tag_type
[i
] - 1)->nElements
) {
965 rawAST_coding_taglist
* cur_choice
= sdef
->raw
.taglist
.list
967 src
= mputprintf(src
, " p_buf.set_pos_bit(starting_pos);\n"
968 " decoded_length = %s().RAW_decode(%s_descr_, p_buf, limit, "
969 "top_bit_ord, TRUE);\n"
970 " if (decoded_length >= 0) {\n", sdef
->elements
[i
].name
,
971 sdef
->elements
[i
].typedescrname
);
972 src
= mputstr(src
, " if (");
973 src
= genRawFieldChecker(src
, cur_choice
, TRUE
);
974 src
= mputstr(src
, ") {\n"
975 " return decoded_length + "
976 "p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;\n"
981 for (i
= 0; i
< sdef
->nElements
; i
++) { /* fields without tag */
983 src
= mputprintf(src
, " p_buf.set_pos_bit(starting_pos);\n"
984 " decoded_length = %s().RAW_decode(%s_descr_, p_buf, limit, "
985 "top_bit_ord, TRUE);\n"
986 " if (decoded_length >= 0) {\n", sdef
->elements
[i
].name
,
987 sdef
->elements
[i
].typedescrname
);
988 src
= mputstr(src
, " return decoded_length + "
989 "p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;\n"
993 src
= mputstr(src
, " }\n"
998 src
= mputprintf(src
, "int %s::RAW_encode("
999 "const TTCN_Typedescriptor_t&%s, RAW_enc_tree& myleaf) const\n"
1000 "{\n", name
, use_runtime_2
? " p_td" : "");
1001 if (use_runtime_2
) {
1002 src
= mputstr(src
, " if (err_descr) return RAW_encode_negtest(err_descr, p_td, myleaf);\n");
1004 src
= mputprintf(src
,
1005 " int encoded_length = 0;\n"
1006 " myleaf.isleaf = FALSE;\n"
1007 " myleaf.body.node.num_of_nodes = %lu;"
1008 " myleaf.body.node.nodes = init_nodes_of_enc_tree(%lu);\n"
1009 " memset(myleaf.body.node.nodes, 0, %lu * sizeof(RAW_enc_tree *));\n"
1010 " switch (union_selection) {\n", (unsigned long)sdef
->nElements
,
1011 (unsigned long)sdef
->nElements
, (unsigned long)sdef
->nElements
);
1012 for (i
= 0; i
< sdef
->nElements
; i
++) {
1013 int t_type
= tag_type
[i
] > 0 ? tag_type
[i
] : -tag_type
[i
];
1014 src
= mputprintf(src
, " case %s_%s:\n"
1015 " myleaf.body.node.nodes[%lu] = new RAW_enc_tree(TRUE, &myleaf, "
1016 "&myleaf.curr_pos, %lu, %s_descr_.raw);\n"
1017 " encoded_length = field_%s->RAW_encode(%s_descr_, "
1018 "*myleaf.body.node.nodes[%lu]);\n"
1019 " myleaf.body.node.nodes[%lu]->coding_descr = &%s_descr_;\n",
1020 selection_prefix
, sdef
->elements
[i
].name
, (unsigned long) i
,
1021 (unsigned long) i
, sdef
->elements
[i
].typedescrname
,
1022 sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
,
1023 (unsigned long) i
, (unsigned long) i
, sdef
->elements
[i
].typedescrname
);
1024 if (t_type
&& (sdef
->raw
.taglist
.list
+ t_type
- 1)->nElements
) {
1025 rawAST_coding_taglist
* cur_choice
= sdef
->raw
.taglist
.list
+ t_type
- 1;
1026 src
= mputstr(src
, " if (");
1027 src
= genRawFieldChecker(src
, cur_choice
, FALSE
);
1028 src
= mputstr(src
, ") {\n");
1029 src
= genRawTagChecker(src
, cur_choice
);
1030 src
= mputstr(src
, " }\n");
1032 src
= mputstr(src
, " break;\n");
1034 src
= mputstr(src
, " default:\n"
1035 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "
1036 "\"Encoding an unbound value.\");\n"
1038 " return encoded_length;\n"
1040 if (use_runtime_2
) {
1041 def
= mputstr(def
, "int RAW_encode_negtest(const Erroneous_descriptor_t *, "
1042 "const TTCN_Typedescriptor_t&, RAW_enc_tree&) const;\n");
1043 src
= mputprintf(src
, "int %s::RAW_encode_negtest(const Erroneous_descriptor_t *p_err_descr, "
1044 "const TTCN_Typedescriptor_t& /*p_td*/, RAW_enc_tree& myleaf) const\n"
1046 " const Erroneous_values_t *err_vals = NULL;\n"
1047 " const Erroneous_descriptor_t *emb_descr = NULL;\n"
1048 " int encoded_length = 0;\n"
1049 " myleaf.isleaf = FALSE;\n"
1050 " myleaf.body.node.num_of_nodes = %lu;\n"
1051 " myleaf.body.node.nodes = init_nodes_of_enc_tree(%lu);\n"
1052 " memset(myleaf.body.node.nodes, 0, %lu * sizeof(RAW_enc_tree *));\n"
1053 " switch (union_selection) {\n", name
, (unsigned long)sdef
->nElements
,
1054 (unsigned long)sdef
->nElements
, (unsigned long)sdef
->nElements
);
1055 for (i
= 0; i
< sdef
->nElements
; i
++) {
1056 int t_type
= tag_type
[i
] > 0 ? tag_type
[i
] : -tag_type
[i
];
1057 src
= mputprintf(src
,
1059 selection_prefix
, sdef
->elements
[i
].name
);
1060 if (t_type
&& (sdef
->raw
.taglist
.list
+ t_type
- 1)->nElements
) {
1061 src
= mputstr(src
, " bool negtest_confl_tag = false;\n");
1063 src
= mputprintf(src
,
1064 " err_vals = p_err_descr->get_field_err_values(%d);\n"
1065 " emb_descr = p_err_descr->get_field_emb_descr(%d);\n"
1066 " if (err_vals && err_vals->value) {\n"
1067 " if (err_vals->value->raw) {\n"
1068 " myleaf.body.node.nodes[%lu] =\n"
1069 " new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, %lu, "
1070 "err_vals->value->errval->get_descriptor()->raw);\n"
1071 " encoded_length = err_vals->value->errval->RAW_encode_negtest_raw(*myleaf.body.node.nodes[%lu]);\n"
1072 " myleaf.body.node.nodes[%lu]->coding_descr = err_vals->value->errval->get_descriptor();\n"
1074 " if (err_vals->value->errval) {\n"
1075 " if (err_vals->value->type_descr == NULL)\n"
1076 " TTCN_error(\"internal error: erroneous value typedescriptor missing\");\n"
1077 " myleaf.body.node.nodes[%lu] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, %lu, err_vals->value->type_descr->raw);\n"
1078 " encoded_length = err_vals->value->errval->RAW_encode(*err_vals->value->type_descr, *myleaf.body.node.nodes[%lu]);\n"
1079 " myleaf.body.node.nodes[%lu]->coding_descr = err_vals->value->type_descr;\n"
1083 (unsigned long)i
, (unsigned long)i
,
1084 (unsigned long)i
, (unsigned long)i
, (unsigned long)i
,
1085 (unsigned long)i
, (unsigned long)i
, (unsigned long)i
);
1086 if (t_type
&& (sdef
->raw
.taglist
.list
+ t_type
- 1)->nElements
) {
1088 src
= mputprintf(src
, " negtest_confl_tag = true;\n");
1090 src
= mputprintf(src
,
1092 " myleaf.body.node.nodes[%lu] = new RAW_enc_tree(TRUE, "
1093 "&myleaf, &myleaf.curr_pos, %lu, %s_descr_.raw);\n"
1094 " if (emb_descr) {\n",
1095 (unsigned long)i
, (unsigned long)i
, sdef
->elements
[i
].typedescrname
);
1096 if (t_type
&& (sdef
->raw
.taglist
.list
+ t_type
- 1)->nElements
) {
1098 src
= mputprintf(src
, " negtest_confl_tag = true;\n");
1100 src
= mputprintf(src
,
1101 " encoded_length = field_%s->RAW_encode_negtest(emb_descr, %s_descr_, *myleaf.body.node.nodes[%lu]);\n"
1102 " } else encoded_length = field_%s->RAW_encode(%s_descr_, *myleaf.body.node.nodes[%lu]);\n"
1103 " myleaf.body.node.nodes[%lu]->coding_descr = &%s_descr_;\n"
1105 sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
,
1106 (unsigned long)i
, sdef
->elements
[i
].name
,
1107 sdef
->elements
[i
].typedescrname
, (unsigned long)i
, (unsigned long)i
,
1108 sdef
->elements
[i
].typedescrname
);
1109 if (t_type
&& (sdef
->raw
.taglist
.list
+ t_type
- 1)->nElements
) {
1110 rawAST_coding_taglist
*cur_choice
= sdef
->raw
.taglist
.list
+ t_type
- 1;
1111 src
= mputprintf(src
,
1112 " if (negtest_confl_tag) {\n"
1113 " TTCN_EncDec_ErrorContext e_c;\n"
1114 " e_c.set_msg(\"Field '%s': \");\n"
1115 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1116 " \"Conflicting negative testing attributes, TAG attribute "
1117 "will be ignored\");\n"
1119 " if (!negtest_confl_tag && (", sdef
->elements
[i
].name
);
1120 src
= genRawFieldChecker(src
, cur_choice
, FALSE
);
1121 src
= mputstr(src
, ")) {\n");
1122 src
= genRawTagChecker(src
, cur_choice
);
1123 src
= mputstr(src
, " }\n");
1125 src
= mputstr(src
, " break; }\n");
1127 src
= mputstr(src
, " default:\n"
1128 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "
1129 "\"Encoding an unbound value.\");\n"
1131 " return encoded_length;\n"
1135 } /* if raw_needed */
1138 src
= mputprintf(src
, "int %s::TEXT_encode("
1139 "const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const\n"
1141 if (use_runtime_2
) {
1142 src
= mputstr(src
, " if (err_descr) return TEXT_encode_negtest(err_descr, p_td, p_buf);\n");
1144 src
= mputstr(src
, " int encoded_length=0;\n"
1145 " if (p_td.text->begin_encode) {\n"
1146 " p_buf.put_cs(*p_td.text->begin_encode);\n"
1147 " encoded_length += p_td.text->begin_encode->lengthof();\n"
1149 " switch(union_selection){\n");
1150 for (i
= 0; i
< sdef
->nElements
; i
++) {
1151 src
= mputprintf(src
, " case %s_%s:\n"
1152 " encoded_length += field_%s->TEXT_encode(%s_descr_,p_buf);\n"
1153 " break;\n", selection_prefix
, sdef
->elements
[i
].name
,
1154 sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
);
1156 src
= mputstr(src
, " default:\n"
1157 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "
1158 "\"Encoding an unbound value.\");\n"
1161 " if (p_td.text->end_encode) {\n"
1162 " p_buf.put_cs(*p_td.text->end_encode);\n"
1163 " encoded_length += p_td.text->end_encode->lengthof();\n"
1165 " return encoded_length;\n"
1167 if (use_runtime_2
) {/*TEXT_encde_negtest()*/
1169 "int TEXT_encode_negtest(const Erroneous_descriptor_t* p_err_descr, const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const;\n");
1170 src
= mputprintf(src
, "int %s::TEXT_encode_negtest("
1171 "const Erroneous_descriptor_t* p_err_descr, const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const\n"
1173 " int encoded_length=0;\n"
1174 " const Erroneous_values_t* err_vals = NULL;\n"
1175 " const Erroneous_descriptor_t* emb_descr = NULL;\n"
1176 " if (p_td.text->begin_encode) {\n"
1177 " p_buf.put_cs(*p_td.text->begin_encode);\n"
1178 " encoded_length += p_td.text->begin_encode->lengthof();\n"
1180 " switch(union_selection){\n", name
);
1181 for (i
= 0; i
< sdef
->nElements
; i
++) {
1182 src
= mputprintf(src
, " case %s_%s:\n"
1183 " err_vals = p_err_descr->get_field_err_values(%d);\n"
1184 " emb_descr = p_err_descr->get_field_emb_descr(%d);\n"
1185 " if (err_vals && err_vals->value){\n"
1186 " if (err_vals->value->errval) {\n"
1187 " if(err_vals->value->raw){\n"
1188 " encoded_length += err_vals->value->errval->encode_raw(p_buf);\n"
1190 " if (err_vals->value->type_descr==NULL) TTCN_error(\"internal error: erroneous value typedescriptor missing\");\n"
1191 " encoded_length += err_vals->value->errval->TEXT_encode(*err_vals->value->type_descr,p_buf);\n"
1195 " if (emb_descr) encoded_length += field_%s->TEXT_encode_negtest(emb_descr,%s_descr_,p_buf);\n"
1196 " else field_%s->TEXT_encode(%s_descr_,p_buf);\n"
1198 " break;\n", selection_prefix
, sdef
->elements
[i
].name
,(int)i
,(int)i
,
1199 sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
, sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
);
1201 src
= mputstr(src
, " default:\n"
1202 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "
1203 "\"Encoding an unbound value.\");\n"
1206 " if (p_td.text->end_encode) {\n"
1207 " p_buf.put_cs(*p_td.text->end_encode);\n"
1208 " encoded_length += p_td.text->end_encode->lengthof();\n"
1210 " return encoded_length;\n"
1214 src
= mputprintf(src
, "int %s::TEXT_decode("
1215 "const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, "
1216 "Limit_Token_List& limit, boolean no_err, boolean)\n"
1218 " int decoded_length = 0;\n"
1219 " if(p_td.text->begin_decode){\n"
1220 " int tl = p_td.text->begin_decode->match_begin(p_buf);\n"
1222 " decoded_length += tl;\n"
1223 " p_buf.increase_pos(tl);\n"
1225 " if (no_err) return -1;\n"
1226 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR, "
1227 "\"The specified token '%%s' not found for '%%s': \", "
1228 "(const char*)(*p_td.text->begin_decode), p_td.name);\n"
1232 " if (p_buf.get_read_len() < 1 && no_err) return -1;\n"
1235 " boolean found = FALSE;\n"
1236 " if (p_td.text->end_decode) {\n"
1237 " limit.add_token(p_td.text->end_decode);\n"
1239 " }\n", name
, sdef
->nElements
> 1 ? " size_t pos = p_buf.get_pos();\n" : "");
1240 if (sdef
->nElements
> 0) {
1241 src
= mputprintf(src
,
1242 " int str_len = %s().TEXT_decode(%s_descr_, p_buf, limit, true);\n"
1243 " if (str_len >= 0) found = TRUE;\n", sdef
->elements
[0].name
,
1244 sdef
->elements
[0].typedescrname
);
1246 for (i
= 1; i
< sdef
->nElements
; i
++) {
1247 src
= mputprintf(src
, " if (!found) {\n"
1248 " p_buf.set_pos(pos);\n"
1249 " str_len = %s().TEXT_decode(%s_descr_, p_buf, limit, true);\n"
1250 " if (str_len >= 0) found = TRUE;\n"
1251 " }\n", sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
);
1253 src
= mputstr(src
, " limit.remove_tokens(ml);\n"
1255 " decoded_length += str_len;\n"
1256 " if (p_td.text->end_decode) {\n"
1257 " int tl = p_td.text->end_decode->match_begin(p_buf);\n"
1259 " decoded_length += tl;\n"
1260 " p_buf.increase_pos(tl);\n"
1262 " if (no_err) return -1;\n"
1263 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR, "
1264 "\"The specified token '%s' not found for '%s': \", "
1265 "(const char*)(*p_td.text->end_decode), p_td.name);\n"
1269 " if (no_err) return -1;\n"
1270 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR, "
1271 "\"No union member found for '%s': \", p_td.name);\n"
1274 " return decoded_length;\n"
1278 if (xer_needed
) { /* XERSTUFF encoder functions for union */
1280 "char **collect_ns(const XERdescriptor_t& p_td, size_t& num, bool& def_ns) const;\n");
1283 "boolean %s::can_start(const char *name, const char *uri,"
1284 " const XERdescriptor_t& xd, unsigned int flavor) {\n"
1285 " boolean exer = is_exer(flavor);\n"
1286 " if (!exer || (!(xd.xer_bits & UNTAGGED) && !(flavor & (USE_NIL|(exer ? XER_LIST : XER_RECOF))))) "
1287 /* If the union has no own tag, there is nothing to check. */
1288 "return check_name(name, xd, exer)" /* if false, return immediately */
1289 " && (!exer || (flavor & USE_TYPE_ATTR) || check_namespace(uri, xd));\n"
1290 /* else check the ns, unless Basic XER (which has no namespaces, ever)
1291 * or USE_TYPE (where we only have a name from the type id attribute) */
1294 src
= mputstr(src
, " flavor &= ~XER_RECOF;\n");
1296 /* An untagged union can start with the start tag of any alternative */
1297 for (i
= 0; i
< sdef
->nElements
; i
++) {
1299 " if (%s::can_start(name, uri, %s_xer_, flavor)) return true;\n"
1300 , sdef
->elements
[i
].type
, sdef
->elements
[i
].typegen
1303 src
= mputstr(src
, " return false;\n}\n\n");
1305 src
= mputprintf(src
,
1306 "char ** %s::collect_ns(const XERdescriptor_t& p_td, size_t& num, bool& def_ns) const {\n"
1307 " size_t num_collected;\n"
1308 " char **collected_ns = Base_Type::collect_ns(p_td, num_collected, def_ns);\n"
1309 /* Two-level new memory allocated */
1311 " size_t num_new;\n"
1312 " boolean need_type = FALSE;\n"
1314 " bool def_ns_1 = false;\n"
1315 " switch (union_selection) {\n"
1318 for (i
= 0; i
< sdef
->nElements
; i
++) {
1319 src
= mputprintf(src
,
1321 " new_ns = field_%s->collect_ns(%s_xer_, num_new, def_ns_1);\n"
1322 " def_ns = def_ns || def_ns_1;\n" /* alas, no ||= */
1323 " merge_ns(collected_ns, num_collected, new_ns, num_new);\n"
1324 /* merge_ns() deallocated new_ns and duplicated strings,
1325 * copied the new ones into the expanded new_ns */
1326 , selection_prefix
, sdef
->elements
[i
].name
1327 , sdef
->elements
[i
].name
1328 , sdef
->elements
[i
].typegen
1330 /* Type id attribute not needed for the first field in case of USE-TYPE */
1331 if (sdef
->xerUseUnion
|| i
> 0) src
= mputprintf(src
,
1332 " need_type = (%s_xer_.namelens[1] > 2);\n"
1333 , sdef
->elements
[i
].typegen
);
1334 src
= mputstr(src
, " break;\n");
1338 " default: break;\n"
1340 " if ((p_td.xer_bits & USE_TYPE_ATTR) && !(p_td.xer_bits & XER_ATTRIBUTE) && need_type) {\n"
1341 /* control ns for type attribute */
1342 " collected_ns = (char**)Realloc(collected_ns, sizeof(char*) * ++num_collected);\n"
1343 " const namespace_t *c_ns = p_td.my_module->get_controlns();\n"
1344 " collected_ns[num_collected-1] = mprintf(\" xmlns:%s='%s'\", c_ns->px, c_ns->ns);\n"
1348 /* Probably a TC_Error thrown from field_%s->collect_ns() if e.g.
1349 * encoding an unbound value. */
1350 " while (num_collected > 0) Free(collected_ns[--num_collected]);\n"
1351 " Free(collected_ns);\n"
1354 " num = num_collected;\n"
1355 " return collected_ns;\n"
1359 src
= mputprintf(src
, /* XERSTUFF XER_encode for union */
1360 "int %s::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, "
1361 "unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const\n"
1364 " if (%s==union_selection) {\n"
1365 " TTCN_error(\"Attempt to XER-encode an unbound union value.\");\n"
1368 " TTCN_EncDec_ErrorContext ec_0(\"Alternative '\");\n"
1369 " TTCN_EncDec_ErrorContext ec_1;\n"
1370 " int encoded_length=(int)p_buf.get_len();\n"
1372 , (use_runtime_2
? " if (err_descr) return XER_encode_negtest"
1373 "(err_descr, p_td, p_buf, p_flavor, p_indent, 0);\n" : "")
1377 if (sdef
->xerUseTypeAttr
) {
1379 " const boolean e_xer = is_exer(p_flavor);\n"
1380 " char *type_atr = NULL;\n"
1381 " if (e_xer && (p_td.xer_bits & USE_TYPE_ATTR)) {\n"
1382 " char *type_name = 0;\n"
1383 " const namespace_t *control_ns;\n"
1384 " switch (union_selection) {\n");
1385 /* In case of USE-TYPE the first field won't need the type attribute */
1386 int start_at
= sdef
->xerUseUnion
? 0 : 1;
1387 for (i
= start_at
; i
< sdef
->nElements
; i
++) {
1388 src
= mputprintf(src
,
1390 " if (%s_xer_.my_module != 0 && %s_xer_.ns_index != -1 &&\n"
1391 " %s_xer_.namelens[1] > 2) {\n"
1392 /* add the namespace prefix to the type attribute (if the name is not empty) */
1393 " const namespace_t *my_ns = %s_xer_.my_module->get_ns(%s_xer_.ns_index);\n"
1394 " if (my_ns->px[0] != 0) {\n"
1395 " type_name = mprintf(\"%%s:\", my_ns->px);\n"
1398 " type_name = mputstrn(type_name, %s_xer_.names[1], %s_xer_.namelens[1] - 2);\n"
1400 , selection_prefix
, sdef
->elements
[i
].name
1401 , sdef
->elements
[i
].typegen
, sdef
->elements
[i
].typegen
1402 , sdef
->elements
[i
].typegen
, sdef
->elements
[i
].typegen
1403 , sdef
->elements
[i
].typegen
, sdef
->elements
[i
].typegen
1404 , sdef
->elements
[i
].typegen
1405 , i
< sdef
->nElements
- 1 ? "goto write_atr;" : "" /* no break */
1408 src
= mputprintf(src
,
1409 "%s" /* label only if more than two elements total */
1410 " if (mstrlen(type_name) > 0) {\n" /* 38.3.8, no atr if NAME AS "" */
1411 " control_ns = p_td.my_module->get_controlns();\n"
1412 " type_atr = mcopystr(\" \");\n"
1413 " type_atr = mputstr(type_atr, control_ns->px);\n"
1414 " type_atr = mputstr(type_atr, \":type='\");\n"
1415 " type_atr = mputstr(type_atr, type_name);\n"
1416 " type_atr = mputc (type_atr, '\\'');\n"
1417 " Free(type_name);\n"
1420 " default: break;\n"
1422 " p_flavor &= ~XER_RECOF;\n"
1423 " }\n" /* if e_xer */
1424 , (sdef
->nElements
> start_at
+ 1 ? "write_atr:\n" : "")
1428 } /* if UseTypeAttr */
1429 src
= mputprintf(src
,
1430 " unsigned int flavor_1 = p_flavor;\n"
1431 " if (is_exer(p_flavor)) flavor_1 &= ~XER_RECOF;\n"
1432 " bool omit_tag = begin_xml(p_td, p_buf, flavor_1, p_indent, false, "
1433 "(collector_fn)&%s::collect_ns%s);\n"
1435 , sdef
->xerUseTypeAttr
? ", type_atr" : "");
1436 src
= mputprintf(src
,
1437 " unsigned int flavor_0 = (p_flavor & XER_MASK)%s;\n"
1438 " switch (union_selection) {\n"
1439 , sdef
->xerUseTypeAttr
? " | USE_TYPE_ATTR" : "");
1440 for (i
= 0; i
< sdef
->nElements
; i
++) {
1441 src
= mputprintf(src
, " case %s_%s:\n"
1442 " ec_1.set_msg(\"%s': \");\n"
1443 " field_%s->XER_encode(%s_xer_, p_buf, flavor_0, "
1444 "p_indent + (!p_indent || !omit_tag), 0);\n"
1446 selection_prefix
, sdef
->elements
[i
].name
,
1447 sdef
->elements
[i
].dispname
,
1448 sdef
->elements
[i
].name
, sdef
->elements
[i
].typegen
);
1450 src
= mputprintf(src
, " case %s:\n"
1451 " (void)flavor_0;\n" /* warning reduction for empty union */
1455 if (sdef
->xerUseTypeAttr
) {
1456 src
= mputstr(src
, " if (p_buf.get_data()[p_buf.get_len()-1] != '\\n') flavor_1 |= SIMPLE_TYPE;\n");
1459 " end_xml(p_td, p_buf, flavor_1, p_indent, 0);\n"
1460 " return (int)p_buf.get_len() - encoded_length;\n"
1463 if (use_runtime_2
) {
1465 "int XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr, "
1466 "const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, "
1467 "unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const;\n");
1468 src
= mputprintf(src
, /* XERSTUFF XER_encode for union */
1469 "int %s::XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr, "
1470 "const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, "
1471 "unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const\n"
1473 " if (%s==union_selection) {\n"
1474 " TTCN_error(\"Attempt to XER-encode an unbound union value.\");\n"
1477 " TTCN_EncDec_ErrorContext ec_0(\"Alternative '\");\n"
1478 " TTCN_EncDec_ErrorContext ec_1;\n"
1479 " int encoded_length=(int)p_buf.get_len();\n"
1483 if (sdef
->xerUseTypeAttr
) {
1485 " const boolean e_xer = is_exer(p_flavor);\n"
1486 " char *type_atr = NULL;\n"
1487 " if (e_xer && (p_td.xer_bits & USE_TYPE_ATTR)) {\n"
1488 " char *type_name = 0;\n"
1489 " const namespace_t *control_ns;\n"
1490 " switch (union_selection) {\n");
1491 int start_at
= sdef
->xerUseUnion
? 0 : 1;
1492 for (i
= start_at
; i
< sdef
->nElements
; i
++) {
1493 src
= mputprintf(src
,
1495 " if (%s_xer_.my_module != 0 && %s_xer_.ns_index != -1 &&\n"
1496 " %s_xer_.namelens[1] > 2) {\n"
1497 /* add the namespace prefix to the type attribute (if the name is not empty) */
1498 " const namespace_t *my_ns = %s_xer_.my_module->get_ns(%s_xer_.ns_index);\n"
1499 " if (my_ns->px[0] != 0) {\n"
1500 " type_name = mprintf(\"%%s:\", my_ns->px);\n"
1503 " type_name = mputstrn(type_name, %s_xer_.names[1], %s_xer_.namelens[1] - 2);\n"
1505 , selection_prefix
, sdef
->elements
[i
].name
1506 , sdef
->elements
[i
].typegen
, sdef
->elements
[i
].typegen
1507 , sdef
->elements
[i
].typegen
, sdef
->elements
[i
].typegen
1508 , sdef
->elements
[i
].typegen
, sdef
->elements
[i
].typegen
1509 , sdef
->elements
[i
].typegen
1510 , i
< sdef
->nElements
- 1 ? "goto write_atr;" : "" /* no break */
1513 src
= mputprintf(src
,
1514 "%s" /* label only if more than two elements total */
1515 " if (mstrlen(type_name) > 0) {\n" /* 38.3.8, no atr if NAME AS "" */
1516 " control_ns = p_td.my_module->get_controlns();\n"
1517 " type_atr = mcopystr(\" \");\n"
1518 " type_atr = mputstr(type_atr, control_ns->px);\n"
1519 " type_atr = mputstr(type_atr, \":type='\");\n"
1520 " type_atr = mputstr(type_atr, type_name);\n"
1521 " type_atr = mputc (type_atr, '\\'');\n"
1522 " Free(type_name);\n"
1525 " default: break;\n"
1527 " p_flavor &= ~XER_RECOF;\n"
1528 " }\n" /* if e_xer */
1529 , (sdef
->nElements
> start_at
+ 1 ? "write_atr:\n" : "")
1531 } /* if UseTypeAttr */
1533 src
= mputprintf(src
,
1534 " bool omit_tag = begin_xml(p_td, p_buf, p_flavor, p_indent, false, "
1535 "(collector_fn)&%s::collect_ns%s);\n"
1537 , sdef
->xerUseTypeAttr
? ", type_atr" : "");
1538 /* begin_xml will Free type_atr */
1539 src
= mputprintf(src
,
1540 " unsigned int flavor_0 = (p_flavor & XER_MASK)%s;\n"
1541 " const Erroneous_values_t* err_vals = NULL;\n"
1542 " const Erroneous_descriptor_t* emb_descr = NULL;\n"
1543 " switch (union_selection) {\n"
1544 , sdef
->xerUseTypeAttr
? " | USE_TYPE_ATTR" : "");
1545 for (i
= 0; i
< sdef
->nElements
; i
++) {
1546 src
= mputprintf(src
, " case %s_%s:\n"
1547 " err_vals = p_err_descr->get_field_err_values(%lu);\n"
1548 " emb_descr = p_err_descr->get_field_emb_descr(%lu);\n"
1549 " if (err_vals && err_vals->value) {\n"
1550 " if (err_vals->value->errval) {\n"
1551 " ec_1.set_msg(\"%s'(erroneous value): \");\n"
1552 " if (err_vals->value->raw) {\n"
1553 " err_vals->value->errval->encode_raw(p_buf);\n"
1555 " if (err_vals->value->type_descr==NULL) TTCN_error"
1556 "(\"internal error: erroneous value typedescriptor missing\");\n"
1557 " else err_vals->value->errval->XER_encode("
1558 "*err_vals->value->type_descr->xer, p_buf, flavor_0, "
1559 "p_indent + (!p_indent || !omit_tag), 0);\n"
1563 " ec_1.set_msg(\"%s': \");\n"
1564 " if (emb_descr) field_%s->XER_encode_negtest(emb_descr, "
1565 "%s_xer_, p_buf, flavor_0, p_indent + (!p_indent || !omit_tag), 0);\n"
1566 " else field_%s->XER_encode(%s_xer_, p_buf, flavor_0, "
1567 "p_indent + (!p_indent || !omit_tag), 0);\n"
1570 selection_prefix
, sdef
->elements
[i
].name
, /* case label */
1571 (unsigned long)i
, (unsigned long)i
,
1572 sdef
->elements
[i
].dispname
, /* set_msg (erroneous) */
1573 sdef
->elements
[i
].dispname
, /* set_msg */
1574 sdef
->elements
[i
].name
, sdef
->elements
[i
].typegen
,
1575 sdef
->elements
[i
].name
, sdef
->elements
[i
].typegen
/* field_%s, %s_descr */
1578 src
= mputprintf(src
, " case %s:\n"
1579 " (void)flavor_0;\n" /* warning reduction for empty union */
1582 " end_xml(p_td, p_buf, p_flavor, p_indent, 0);\n"
1583 " return (int)p_buf.get_len() - encoded_length;\n"
1589 src
= mputprintf(src
, "// %s has%s%s%s%s%s%s%s%s%s\n"
1590 "// written by %s in " __FILE__
" at %d\n"
1592 , (sdef
->xerUntagged
? " UNTAGGED" : "")
1593 , (sdef
->xerUntaggedOne
? "1" : "")
1594 , (sdef
->xerUseNilPossible
? " USE_NIL?" : "")
1595 , (sdef
->xerUseOrderPossible
? " USE_ORDER?" : "")
1596 , (sdef
->xerUseQName
? " USE_QNAME" : "")
1597 , (sdef
->xerUseTypeAttr
? " USE_TYPE_ATTR" : "")
1598 , (sdef
->xerUseUnion
? " USE-UNION" : "")
1599 , (sdef
->xerHasNamespaces
? " namespace" : "")
1600 , (sdef
->xerEmbedValuesPossible
? " EMBED?" : "")
1601 , __FUNCTION__
, __LINE__
1604 src
= mputprintf(src
, /* XERSTUFF decoder functions for union */
1605 "int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader,"
1606 " unsigned int p_flavor, embed_values_dec_struct_t*)\n"
1608 " int e_xer = is_exer(p_flavor);\n"
1609 " int type = 0;\n" /* None */
1610 " int rd_ok=1, xml_depth=-1;\n"
1612 " int xerbits = p_td.xer_bits;\n"
1613 " if (p_flavor & XER_TOPLEVEL) xerbits &= ~UNTAGGED;\n"
1614 " if (xerbits & USE_TYPE_ATTR) p_flavor &= ~XER_RECOF;\n"
1615 " boolean own_tag = !(e_xer && ((xerbits & (ANY_ELEMENT | UNTAGGED)) "
1616 "|| (p_flavor & (USE_NIL|(e_xer ? XER_LIST : XER_RECOF)))));\n"
1617 " if ((e_xer || !is_record_of(p_flavor)) && own_tag)\n"
1618 /* Loop until the start tag */
1619 " %sfor (rd_ok = p_reader.Ok(); rd_ok == 1; rd_ok = p_reader.Read()) {\n"
1620 " type = p_reader.NodeType();\n"
1621 " if (type == XML_READER_TYPE_ELEMENT) {\n"
1622 " verify_name(p_reader, p_td, e_xer);\n"
1623 " xml_depth = p_reader.Depth();\n"
1625 , sdef
->xerUseTypeAttr
? " char * typeatr = 0;\n" : ""
1626 , sdef
->xerUseUnion
? " boolean attribute = (p_td.xer_bits & XER_ATTRIBUTE) ? true : false;\n" : ""
1627 , sdef
->xerUseUnion
? "if (!attribute) " : ""
1629 if (sdef
->xerUseTypeAttr
) {
1630 src
= mputprintf(src
,
1631 " int other_attributes = 0;\n"
1633 " for (rd_ok = p_reader.MoveToFirstAttribute(); rd_ok == 1;"
1634 " rd_ok = p_reader.MoveToNextAttribute()) {\n"
1635 " if (p_reader.IsNamespaceDecl()) continue;\n"
1636 " const char *attr_name = (const char*)p_reader.Name();\n"
1637 " if (!strcmp(attr_name, \"%s:type\"))\n"
1639 " typeatr = mcopystr((const char*)p_reader.Value());\n"
1641 " else ++other_attributes;\n"
1643 " rd_ok = p_reader.MoveToElement() | 1;\n"
1644 , sdef
->control_ns_prefix
);
1645 if (!sdef
->xerUseUnion
) {
1646 /* USE-TYPE: No type attribute means the first alternative */
1647 src
= mputprintf(src
,
1648 " if (typeatr == NULL) {\n"
1649 " typeatr = mcopystrn(%s_xer_.names[1], %s_xer_.namelens[1] - 2);\n"
1651 , sdef
->elements
[0].typegen
1652 , sdef
->elements
[0].typegen
);
1655 " }\n" /* if exer */);
1658 src
= mputprintf(src
,
1659 " if (!(e_xer && (p_td.xer_bits & USE_TYPE_ATTR)%s)\n"
1660 " && !p_reader.IsEmptyElement()) rd_ok = p_reader.Read();\n"
1664 " unsigned int flavor_1 = (p_flavor & XER_MASK);\n" /* also, not toplevel */
1665 /* Loop until the content. Normally an element, unless UNTAGGED
1666 * USE-UNION or some other shenanigans. */
1667 " %s%sfor (rd_ok = p_reader.Ok(); rd_ok == 1; rd_ok = p_reader.Read()) {\n"
1668 " type = p_reader.NodeType();\n"
1669 " %sif (type == XML_READER_TYPE_ELEMENT) break;\n"
1670 " else if (type == XML_READER_TYPE_END_ELEMENT) break;\n"
1673 " TTCN_EncDec_ErrorContext ec_1(\"Alternative '\");\n"
1674 " TTCN_EncDec_ErrorContext ec_2;\n"
1675 " const char *elem_name;\n"
1676 " const char *ns_uri = 0;\n"
1677 , sdef
->xerUseTypeAttr
? " && other_attributes > 0" : ""
1678 , sdef
->xerUseTypeAttr
? "if (!e_xer) " : ""
1679 , sdef
->xerUseUnion
? "if (!attribute) " : ""
1680 , sdef
->xerUseTypeAttr
?
1681 "if (e_xer) { if (type == XML_READER_TYPE_TEXT) break; }\n"
1685 if (sdef
->xerUseTypeAttr
) {
1687 " if (e_xer) {\n" /* USE-TYPE => no XML element, use typeatr */
1688 " char *token_1 = strtok(typeatr, \":\");\n" /* extract the namespace (if any) */
1689 " char *token_2 = strtok(NULL, \":\");\n"
1690 " if (token_2) {\n" /* namespace found */
1691 " elem_name = token_2;\n"
1692 " ns_uri = get_ns_uri_from_prefix(token_1, p_td);\n"
1694 " else {\n" /* no namespace */
1695 " elem_name = token_1;\n"
1697 " flavor_1 |= USE_TYPE_ATTR;\n"
1699 " else" /* no newline, gobbles up the next {} */);
1703 " elem_name = (const char*)p_reader.LocalName();\n"
1704 " ns_uri = (const char*)p_reader.NamespaceUri();\n"
1707 if (sdef
->xerUseUnion
) {
1709 " int matched = -1;\n"
1710 " if (typeatr == NULL) flavor_1 |= EXIT_ON_ERROR;\n"
1712 /* TODO unify the two alternatives */
1713 for (i
= 0; i
< sdef
->nElements
; i
++) {
1714 src
= mputprintf(src
,
1715 /* If decoding EXER, there is no tag to apply check_name
1718 " if ((e_xer && (typeatr == NULL || !(p_td.xer_bits & USE_TYPE_ATTR))) "
1719 "|| can_start(elem_name, ns_uri, %s_xer_, flavor_1)) {\n"
1720 " ec_2.set_msg(\"%s': \");\n"
1721 " if (%s==union_selection) {\n"
1723 " %s().XER_decode(%s_xer_, p_reader, flavor_1, 0);\n"
1725 " if (field_%s->is_bound()) break; else clean_up();\n"
1727 sdef
->elements
[i
].typegen
,
1728 sdef
->elements
[i
].dispname
,
1729 unbound_value
, (int)i
,
1730 sdef
->elements
[i
].name
, sdef
->elements
[i
].typegen
,
1731 sdef
->elements
[i
].name
);
1734 " if (typeatr == NULL) {\n"
1735 /* No type attribute found and none of the fields managed to decode the value (USE-UNION only) */
1736 " ec_1.set_msg(\" \");\n"
1737 " ec_2.set_msg(\" \");\n"
1738 " const char* value = (const char*)p_reader.Value();\n"
1739 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n"
1740 " \"'%s' could not be decoded by any of the union's fields.\", value);\n"
1741 " } else if (matched >= 0) {\n"
1742 /* Alternative found, but it couldn't be decoded */
1743 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n"
1744 " \"Failed to decode field.\");\n"
1746 /* Type attribute found, but it didn't match any of the fields */
1747 " ec_1.set_msg(\" \");\n"
1748 " ec_2.set_msg(\" \");\n"
1749 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n"
1750 " \"'%s' does not match any alternative.\", elem_name);\n"
1752 " if (xml_depth >= 0) for (; rd_ok == 1 "
1753 "&& p_reader.Depth() > xml_depth; rd_ok = p_reader.Read()) ;\n"
1755 " }\n"); /* for ever */
1757 else /* not USE-UNION */
1759 if (sdef
->exerMaybeEmptyIndex
>= 0) {
1760 /* There is a field which can be empty XML. Add code to detect this
1761 * and jump to the appropriate field which can decode "nothing". */
1763 " if (type!=XML_READER_TYPE_ELEMENT || "
1764 "(own_tag && p_reader.IsEmptyElement())) goto empty_xml;\n");
1765 /* If the choice itself is untagged, then an empty element belongs to
1766 * one of the fields and does not mean that the choice is empty */
1768 /* FIXME some hashing should be implemented */
1769 /* The field which can be empty should be checked last, otherwise we create an infinity loop with memory bomb.
1770 * So move that field to the last elseif branch*/
1771 for (i
= 0; i
< sdef
->nElements
; i
++) {
1772 if(sdef
->exerMaybeEmptyIndex
!= i
){
1773 src
= mputprintf(src
,
1774 " %sif (%s::can_start(elem_name, ns_uri, %s_xer_, flavor_1) || (%s_xer_.xer_bits & ANY_ELEMENT)) {\n"
1775 " ec_2.set_msg(\"%s': \");\n"
1776 " if (e_xer && (%s_xer_.xer_bits & BLOCKED)) {\n"
1777 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n"
1778 " \"Attempting to decode blocked or abstract field.\");\n"
1780 " %s%s().XER_decode(%s_xer_, p_reader, flavor_1, 0);\n"
1781 " if (!%s%s().is_bound()) {\n"
1782 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, \"Failed to decode field.\");\n"
1785 i
&& !(i
==1 && sdef
->exerMaybeEmptyIndex
==0) ? "else " : "", /* print "if(" if generate code for the first field or if the first field is the MaybeEmpty field and we generate the code for the second one*/
1786 sdef
->elements
[i
].type
, sdef
->elements
[i
].typegen
, sdef
->elements
[i
].typegen
,
1787 sdef
->elements
[i
].dispname
,
1788 sdef
->elements
[i
].typegen
,
1789 at_field
, sdef
->elements
[i
].name
, sdef
->elements
[i
].typegen
,
1790 at_field
, sdef
->elements
[i
].name
);
1793 if(sdef
->exerMaybeEmptyIndex
>=0 ){
1794 i
=sdef
->exerMaybeEmptyIndex
;
1795 src
= mputprintf(src
,
1796 " %sif ((e_xer && (type==XML_READER_TYPE_END_ELEMENT || !own_tag)) || %s::can_start(elem_name, ns_uri, %s_xer_, flavor_1) || (%s_xer_.xer_bits & ANY_ELEMENT)) {\n"
1797 "empty_xml: ec_2.set_msg(\"%s': \");\n"
1798 " if (e_xer && (%s_xer_.xer_bits & BLOCKED)) {\n"
1799 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n"
1800 " \"Attempting to decode blocked or abstract field.\");\n"
1802 " %s%s().XER_decode(%s_xer_, p_reader, flavor_1, 0);\n"
1803 " if (!%s%s().is_bound()) {\n"
1804 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, \"Failed to decode field.\");\n"
1807 sdef
->nElements
>0 ? "else " : "",
1808 sdef
->elements
[i
].type
, sdef
->elements
[i
].typegen
, sdef
->elements
[i
].typegen
,
1809 sdef
->elements
[i
].dispname
,
1810 sdef
->elements
[i
].typegen
,
1811 at_field
, sdef
->elements
[i
].name
, sdef
->elements
[i
].typegen
,
1812 at_field
, sdef
->elements
[i
].name
);
1814 if (!sdef
->isOptional
) {
1817 " ec_1.set_msg(\" \");\n"
1818 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, "
1819 "\"'%s' does not match any alternative\", elem_name);\n"
1820 " if (xml_depth >= 0) for (; rd_ok == 1 "
1821 "&& p_reader.Depth() > xml_depth; rd_ok = p_reader.Read()) ;\n"
1827 src
= mputprintf(src
,
1828 " }\n" /* end if(rd_ok) */
1829 " if (%s(e_xer || !is_record_of(p_flavor)) && own_tag)\n"
1830 " for (; rd_ok == 1; rd_ok = p_reader.Read()) {\n"
1831 " type = p_reader.NodeType();\n"
1832 " if (type == XML_READER_TYPE_END_ELEMENT) {\n"
1833 " verify_end(p_reader, p_td, xml_depth, e_xer);\n"
1834 " rd_ok = p_reader.Read(); // one last time\n"
1840 "}\n\n", sdef
->xerUseUnion
? "!attribute && " : "",
1841 sdef
->xerUseTypeAttr
? " Free(typeatr);\n" : "");
1845 src
= mputprintf(src
,
1846 "int %s::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const\n"
1848 if (!sdef
->jsonAsValue
) {
1849 src
= mputstr(src
, " int enc_len = p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL);\n\n");
1851 src
= mputstr(src
, " int enc_len = 0;\n\n");
1853 src
= mputstr(src
, " switch(union_selection) {\n");
1855 for (i
= 0; i
< sdef
->nElements
; ++i
) {
1856 src
= mputprintf(src
, " case %s_%s:\n", selection_prefix
, sdef
->elements
[i
].name
);
1857 if (!sdef
->jsonAsValue
) {
1858 src
= mputprintf(src
, " enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, \"%s\");\n"
1859 , sdef
->elements
[i
].jsonAlias
? sdef
->elements
[i
].jsonAlias
: sdef
->elements
[i
].dispname
);
1861 src
= mputprintf(src
,
1862 " enc_len += field_%s->JSON_encode(%s_descr_, p_tok);\n"
1864 , sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
);
1866 src
= mputprintf(src
,
1868 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, \n"
1869 " \"Encoding an unbound value of type %s.\");\n"
1873 if (!sdef
->jsonAsValue
) {
1874 src
= mputstr(src
, " enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);\n");
1877 " return enc_len;\n"
1881 src
= mputprintf(src
,
1882 "int %s::JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok, boolean p_silent)\n"
1884 " json_token_t j_token = JSON_TOKEN_NONE;\n"
1886 if (sdef
->jsonAsValue
) {
1888 " size_t buf_pos = p_tok.get_buf_pos();\n"
1889 " p_tok.get_next_token(&j_token, NULL, NULL);\n"
1890 " int ret_val = 0;\n"
1891 " switch(j_token) {\n"
1892 " case JSON_TOKEN_NUMBER: {\n");
1893 for (i
= 0; i
< sdef
->nElements
; ++i
) {
1894 if (JSON_NUMBER
& sdef
->elements
[i
].jsonValueType
) {
1895 src
= mputprintf(src
,
1896 " p_tok.set_buf_pos(buf_pos);\n"
1897 " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, true);\n"
1898 " if (0 <= ret_val) {\n"
1899 " return ret_val;\n"
1901 , at_field
, sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
);
1905 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"number\");\n"
1907 " return JSON_ERROR_FATAL;\n"
1909 " case JSON_TOKEN_STRING: {\n");
1910 for (i
= 0; i
< sdef
->nElements
; ++i
) {
1911 if (JSON_STRING
& sdef
->elements
[i
].jsonValueType
) {
1912 src
= mputprintf(src
,
1913 " p_tok.set_buf_pos(buf_pos);\n"
1914 " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, true);\n"
1915 " if (0 <= ret_val) {\n"
1916 " return ret_val;\n"
1918 , at_field
, sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
);
1922 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"string\");\n"
1924 " return JSON_ERROR_FATAL;\n"
1926 " case JSON_TOKEN_LITERAL_TRUE:\n"
1927 " case JSON_TOKEN_LITERAL_FALSE: {\n");
1928 for (i
= 0; i
< sdef
->nElements
; ++i
) {
1929 if (JSON_BOOLEAN
& sdef
->elements
[i
].jsonValueType
) {
1930 src
= mputprintf(src
,
1931 " p_tok.set_buf_pos(buf_pos);\n"
1932 " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, true);\n"
1933 " if (0 <= ret_val) {\n"
1934 " return ret_val;\n"
1936 , at_field
, sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
);
1940 " char* literal_str = mprintf(\"literal (%s)\",\n"
1941 " (JSON_TOKEN_LITERAL_TRUE == j_token) ? \"true\" : \"false\");\n"
1942 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, literal_str);\n"
1943 " Free(literal_str);\n"
1945 " return JSON_ERROR_FATAL;\n"
1947 " case JSON_TOKEN_ARRAY_START: {\n");
1948 for (i
= 0; i
< sdef
->nElements
; ++i
) {
1949 if (JSON_ARRAY
& sdef
->elements
[i
].jsonValueType
) {
1950 src
= mputprintf(src
,
1951 " p_tok.set_buf_pos(buf_pos);\n"
1952 " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, true);\n"
1953 " if (0 <= ret_val) {\n"
1954 " return ret_val;\n"
1956 , at_field
, sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
);
1960 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"array\");\n"
1962 " return JSON_ERROR_FATAL;\n"
1964 " case JSON_TOKEN_OBJECT_START: {\n");
1965 for (i
= 0; i
< sdef
->nElements
; ++i
) {
1966 if (JSON_OBJECT
& sdef
->elements
[i
].jsonValueType
) {
1967 src
= mputprintf(src
,
1968 " p_tok.set_buf_pos(buf_pos);\n"
1969 " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, true);\n"
1970 " if (0 <= ret_val) {\n"
1971 " return ret_val;\n"
1973 , at_field
, sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
);
1977 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"object\");\n"
1979 " return JSON_ERROR_FATAL;\n"
1981 " case JSON_TOKEN_LITERAL_NULL: {\n");
1982 for (i
= 0; i
< sdef
->nElements
; ++i
) {
1983 if (JSON_NULL
& sdef
->elements
[i
].jsonValueType
) {
1984 src
= mputprintf(src
,
1985 " p_tok.set_buf_pos(buf_pos);\n"
1986 " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, true);\n"
1987 " if (0 <= ret_val) {\n"
1988 " return ret_val;\n"
1990 , at_field
, sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
);
1995 // the caller might be able to decode the null value if it's an optional field
1996 // only return an invalid token error, not a fatal error
1997 " return JSON_ERROR_INVALID_TOKEN;\n"
1999 " case JSON_TOKEN_ERROR:\n"
2000 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, \"\");\n"
2001 " return JSON_ERROR_FATAL;\n"
2003 " return JSON_ERROR_INVALID_TOKEN;\n"
2007 } else { // not "as value"
2008 src
= mputprintf(src
,
2009 " int dec_len = p_tok.get_next_token(&j_token, NULL, NULL);\n"
2010 " if (JSON_TOKEN_ERROR == j_token) {\n"
2011 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, \"\");\n"
2012 " return JSON_ERROR_FATAL;\n"
2014 " else if (JSON_TOKEN_OBJECT_START != j_token) {\n"
2015 " return JSON_ERROR_INVALID_TOKEN;\n"
2017 " char* fld_name = 0;\n"
2018 " size_t name_len = 0;"
2019 " dec_len += p_tok.get_next_token(&j_token, &fld_name, &name_len);\n"
2020 " if (JSON_TOKEN_NAME != j_token) {\n"
2021 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_NAME_TOKEN_ERROR);\n"
2022 " return JSON_ERROR_FATAL;\n"
2024 " union_selection = %s;\n "
2026 for (i
= 0; i
< sdef
->nElements
; ++i
) {
2027 src
= mputprintf(src
,
2028 "if (0 == strncmp(fld_name, \"%s\", name_len)) {\n"
2029 " int ret_val = %s%s().JSON_decode(%s_descr_, p_tok, p_silent);\n"
2030 " if (0 > ret_val) {\n"
2031 " if (JSON_ERROR_INVALID_TOKEN) {\n"
2032 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, \"%s\");\n"
2034 " return JSON_ERROR_FATAL;\n"
2036 " dec_len += ret_val;\n"
2039 , sdef
->elements
[i
].jsonAlias
? sdef
->elements
[i
].jsonAlias
: sdef
->elements
[i
].dispname
2040 , at_field
, sdef
->elements
[i
].name
, sdef
->elements
[i
].typedescrname
2041 , sdef
->elements
[i
].dispname
);
2045 " char* fld_name2 = mcopystrn(fld_name, name_len);\n"
2046 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_INVALID_NAME_ERROR, fld_name2);\n"
2047 " Free(fld_name2);\n"
2048 " return JSON_ERROR_FATAL;\n"
2051 " dec_len += p_tok.get_next_token(&j_token, NULL, NULL);\n"
2052 " if (JSON_TOKEN_OBJECT_END != j_token) {\n"
2053 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_STATIC_OBJECT_END_TOKEN_ERROR, \"\");\n"
2054 " return JSON_ERROR_FATAL;\n"
2056 " return dec_len;\n"
2061 /* end of class definition */
2062 def
= mputstr(def
, "};\n\n");
2064 output
->header
.class_defs
= mputstr(output
->header
.class_defs
, def
);
2067 output
->source
.methods
= mputstr(output
->source
.methods
, src
);
2070 Free(selection_type
);
2071 Free(unbound_value
);
2072 Free(selection_prefix
);
2076 void defUnionTemplate(const struct_def
*sdef
, output_struct
*output
)
2079 const char *name
= sdef
->name
, *dispname
= sdef
->dispname
;
2080 const char *at_field
= sdef
->kind
==ANYTYPE
? "AT_" : "";
2081 char *def
= NULL
, *src
= NULL
;
2083 char *selection_type
, *unbound_value
, *selection_prefix
;
2084 selection_type
= mprintf("%s::union_selection_type", name
);
2085 unbound_value
= mprintf("%s::UNBOUND_VALUE", name
);
2086 selection_prefix
= mprintf("%s::ALT", name
);
2088 /* template class */
2090 output
->header
.class_decls
= mputprintf(output
->header
.class_decls
,
2091 "class %s_template;\n", name
);
2093 /* template class header and data members */
2094 def
= mputprintf(def
, "class %s_template : public Base_Template {\n"
2097 "%s union_selection;\n"
2098 "union {\n", name
, selection_type
);
2099 for (i
= 0; i
< sdef
->nElements
; i
++) {
2100 def
= mputprintf(def
, "%s_template *field_%s;\n",
2101 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
2103 def
= mputprintf(def
, "};\n"
2106 "unsigned int n_values;\n"
2107 "%s_template *list_value;\n"
2110 if (use_runtime_2
) {
2112 "Erroneous_descriptor_t* err_descr;\n");
2115 /* copy_value function */
2116 def
= mputprintf(def
, "void copy_value(const %s& other_value);\n\n", name
);
2117 src
= mputprintf(src
, "void %s_template::copy_value(const %s& other_value)\n"
2119 "single_value.union_selection = other_value.get_selection();\n"
2120 "switch (single_value.union_selection) {\n", name
, name
);
2121 for (i
= 0; i
<sdef
->nElements
; i
++) {
2122 src
= mputprintf(src
, "case %s_%s:\n"
2123 "single_value.field_%s = new %s_template(other_value.%s%s());\n"
2124 "break;\n", selection_prefix
, sdef
->elements
[i
].name
,
2125 sdef
->elements
[i
].name
, sdef
->elements
[i
].type
,
2126 at_field
, sdef
->elements
[i
].name
);
2128 src
= mputprintf(src
, "default:\n"
2129 "TTCN_error(\"Initializing a template with an unbound value of type "
2132 "set_selection(SPECIFIC_VALUE);\n"
2135 use_runtime_2
? "err_descr = other_value.get_err_descr();\n" : "");
2137 /* copy_template function */
2138 def
= mputprintf(def
, "void copy_template(const %s_template& "
2139 "other_value);\n", name
);
2140 src
= mputprintf(src
, "void %s_template::copy_template(const "
2141 "%s_template& other_value)\n"
2143 "switch (other_value.template_selection) {\n"
2144 "case SPECIFIC_VALUE:\n"
2145 "single_value.union_selection = "
2146 "other_value.single_value.union_selection;\n"
2147 "switch (single_value.union_selection) {\n", name
, name
);
2148 for (i
= 0; i
< sdef
->nElements
; i
++) {
2149 src
= mputprintf(src
, "case %s_%s:\n"
2150 "single_value.field_%s = "
2151 "new %s_template(*other_value.single_value.field_%s);\n"
2152 "break;\n", selection_prefix
, sdef
->elements
[i
].name
,
2153 sdef
->elements
[i
].name
, sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
2155 src
= mputprintf(src
, "default:\n"
2156 "TTCN_error(\"Internal error: Invalid union selector in a specific value "
2157 "when copying a template of type %s.\");\n"
2159 "case OMIT_VALUE:\n"
2161 "case ANY_OR_OMIT:\n"
2163 "case VALUE_LIST:\n"
2164 "case COMPLEMENTED_LIST:\n"
2165 "value_list.n_values = other_value.value_list.n_values;\n"
2166 "value_list.list_value = new %s_template[value_list.n_values];\n"
2167 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
2169 "value_list.list_value[list_count].copy_template("
2170 "other_value.value_list.list_value[list_count]);\n"
2173 "TTCN_error(\"Copying an uninitialized template of union type %s.\");\n"
2175 "set_selection(other_value);\n"
2177 "}\n\n", dispname
, name
, dispname
,
2178 use_runtime_2
? "err_descr = other_value.err_descr;\n" : "");
2180 /* default constructor */
2181 def
= mputprintf(def
, "\npublic:\n"
2182 "%s_template();\n", name
);
2183 src
= mputprintf(src
, "%s_template::%s_template()%s\n"
2185 "}\n\n", name
, name
,
2186 use_runtime_2
? ": err_descr(NULL)" : "");
2188 /* constructor (template_sel) */
2189 def
= mputprintf(def
, "%s_template(template_sel other_value);\n", name
);
2190 src
= mputprintf(src
, "%s_template::%s_template(template_sel other_value)\n"
2191 " : Base_Template(other_value)%s\n"
2193 "check_single_selection(other_value);\n"
2194 "}\n\n", name
, name
,
2195 use_runtime_2
? ", err_descr(NULL)" : "");
2197 /* constructor (value) */
2198 def
= mputprintf(def
, "%s_template(const %s& other_value);\n", name
, name
);
2199 src
= mputprintf(src
, "%s_template::%s_template(const %s& other_value)\n"
2201 "copy_value(other_value);\n"
2202 "}\n\n", name
, name
, name
);
2204 /* constructor (optional value) */
2205 def
= mputprintf(def
, "%s_template(const OPTIONAL<%s>& other_value);\n", name
,
2207 src
= mputprintf(src
, "%s_template::%s_template(const OPTIONAL<%s>& "
2210 "switch (other_value.get_selection()) {\n"
2211 "case OPTIONAL_PRESENT:\n"
2212 "copy_value((const %s&)other_value);\n"
2214 "case OPTIONAL_OMIT:\n"
2215 "set_selection(OMIT_VALUE);\n"
2219 "TTCN_error(\"Creating a template of union type %s from an unbound "
2220 "optional field.\");\n"
2222 "}\n\n", name
, name
, name
, name
,
2223 use_runtime_2
? "err_descr = NULL;\n" : "",
2226 /* copy constructor */
2227 def
= mputprintf(def
, "%s_template(const %s_template& other_value);\n", name
,
2229 src
= mputprintf(src
, "%s_template::%s_template(const %s_template& "
2231 ": Base_Template()" /* yes, the base class _default_ constructor */
2233 "copy_template(other_value);\n"
2234 "}\n\n", name
, name
, name
);
2237 def
= mputprintf(def
, "~%s_template();\n", name
);
2238 src
= mputprintf(src
, "%s_template::~%s_template()\n"
2241 "}\n\n", name
, name
);
2243 /* clean_up function */
2244 def
= mputstr(def
, "void clean_up();\n");
2245 src
= mputprintf(src
, "void %s_template::clean_up()\n"
2247 "switch (template_selection) {\n"
2248 "case SPECIFIC_VALUE:\n"
2249 "switch (single_value.union_selection) {\n", name
);
2250 for (i
= 0; i
< sdef
->nElements
; i
++) {
2251 src
= mputprintf(src
, "case %s_%s:\n"
2252 "delete single_value.field_%s;\n",
2253 selection_prefix
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
2254 if (i
< sdef
->nElements
- 1) src
= mputstr(src
, "break;\n");
2256 src
= mputstr(src
, "default:\n"
2260 "case VALUE_LIST:\n"
2261 "case COMPLEMENTED_LIST:\n"
2262 "delete [] value_list.list_value;\n"
2266 "template_selection = UNINITIALIZED_TEMPLATE;\n"
2269 /* assignment operator (template_sel) */
2270 def
= mputprintf(def
, "%s_template& operator=(template_sel other_value);\n",
2272 src
= mputprintf(src
,
2273 "%s_template& %s_template::operator=(template_sel "
2276 "check_single_selection(other_value);\n"
2278 "set_selection(other_value);\n"
2281 "}\n\n", name
, name
, use_runtime_2
? "err_descr = NULL;\n" : "");
2283 /* assignment operator (value) */
2284 def
= mputprintf(def
, "%s_template& operator=(const %s& other_value);\n",
2286 src
= mputprintf(src
, "%s_template& %s_template::operator=(const %s& "
2290 "copy_value(other_value);\n"
2292 "}\n\n", name
, name
, name
);
2294 /* assignment operator <- optional value */
2295 def
= mputprintf(def
, "%s_template& operator=(const OPTIONAL<%s>& "
2296 "other_value);\n", name
, name
);
2297 src
= mputprintf(src
,
2298 "%s_template& %s_template::operator=(const OPTIONAL<%s>& other_value)\n"
2301 "switch (other_value.get_selection()) {\n"
2302 "case OPTIONAL_PRESENT:\n"
2303 "copy_value((const %s&)other_value);\n"
2305 "case OPTIONAL_OMIT:\n"
2306 "set_selection(OMIT_VALUE);\n"
2310 "TTCN_error(\"Assignment of an unbound optional field to a template of "
2311 "union type %s.\");\n"
2314 "}\n\n", name
, name
, name
, name
,
2315 use_runtime_2
? "err_descr = NULL;\n" : "", dispname
);
2317 /* assignment operator (template) */
2318 def
= mputprintf(def
, "%s_template& operator=(const %s_template& "
2319 "other_value);\n", name
, name
);
2320 src
= mputprintf(src
,
2321 "%s_template& %s_template::operator=(const %s_template& other_value)\n"
2323 "if (&other_value != this) {\n"
2325 "copy_template(other_value);\n"
2328 "}\n\n", name
, name
, name
);
2330 /* match function */
2331 def
= mputprintf(def
, "boolean match(const %s& other_value, boolean legacy "
2332 "= FALSE) const;\n", name
);
2333 src
= mputprintf(src
, "boolean %s_template::match(const %s& other_value, "
2334 "boolean legacy) const\n"
2336 "if (!other_value.is_bound()) return FALSE;\n"
2337 "switch (template_selection) {\n"
2339 "case ANY_OR_OMIT:\n"
2341 "case OMIT_VALUE:\n"
2343 "case SPECIFIC_VALUE:\n"
2345 "%s value_selection = other_value.get_selection();\n"
2346 "if (value_selection == %s) return FALSE;\n"
2347 "if (value_selection != single_value.union_selection) return FALSE;\n"
2348 "switch (value_selection) {\n", name
, name
, selection_type
, unbound_value
);
2349 for (i
= 0; i
< sdef
->nElements
; i
++) {
2350 src
= mputprintf(src
, "case %s_%s:\n"
2351 "return single_value.field_%s->match(other_value.%s%s(), legacy);\n",
2352 selection_prefix
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
2353 at_field
, sdef
->elements
[i
].name
);
2355 src
= mputprintf(src
, "default:\n"
2356 "TTCN_error(\"Internal error: Invalid selector in a specific value when "
2357 "matching a template of union type %s.\");\n"
2360 "case VALUE_LIST:\n"
2361 "case COMPLEMENTED_LIST:\n"
2362 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
2364 "if (value_list.list_value[list_count].match(other_value, legacy)) "
2365 "return template_selection == VALUE_LIST;\n"
2366 "return template_selection == COMPLEMENTED_LIST;\n"
2368 "TTCN_error (\"Matching an uninitialized template of union type %s.\");\n"
2371 "}\n\n", dispname
, dispname
);
2374 def
= mputstr(def
, "boolean is_value() const;");
2375 src
= mputprintf(src
, "boolean %s_template::is_value() const\n"
2377 "if (template_selection != SPECIFIC_VALUE || is_ifpresent) return false;\n"
2378 "switch (single_value.union_selection) {\n"
2380 for (i
= 0; i
< sdef
->nElements
; i
++) {
2381 src
= mputprintf(src
, "case %s_%s:\n"
2382 "return single_value.field_%s->is_value();\n", selection_prefix
,
2383 sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
2385 src
= mputprintf(src
, "default:\n"
2386 "TTCN_error(\"Internal error: Invalid selector in a specific value when "
2387 "performing is_value operation on a template of union type %s.\");\n"
2391 /* valueof member function */
2392 def
= mputprintf(def
, "%s valueof() const;\n", name
);
2393 src
= mputprintf(src
, "%s %s_template::valueof() const\n"
2395 "if (template_selection != SPECIFIC_VALUE || is_ifpresent)\n"
2396 "TTCN_error(\"Performing valueof or send operation on a non-specific "
2397 "template of union type %s.\");\n"
2399 "switch (single_value.union_selection) {\n", name
, name
, dispname
, name
);
2400 for (i
= 0; i
< sdef
->nElements
; i
++) {
2401 src
= mputprintf(src
, "case %s_%s:\n"
2402 "ret_val.%s%s() = single_value.field_%s->valueof();\n"
2403 "break;\n", selection_prefix
, sdef
->elements
[i
].name
,
2404 at_field
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
2406 src
= mputprintf(src
, "default:\n"
2407 "TTCN_error(\"Internal error: Invalid selector in a specific value when "
2408 "performing valueof operation on a template of union type %s.\");\n"
2413 use_runtime_2
? "ret_val.set_err_descr(err_descr);\n" : "");
2415 /* list_item(int) function */
2416 def
= mputprintf(def
, "%s_template& list_item(unsigned int list_index) "
2418 src
= mputprintf(src
,
2419 "%s_template& %s_template::list_item(unsigned int list_index) const\n"
2421 "if (template_selection != VALUE_LIST && "
2422 "template_selection != COMPLEMENTED_LIST) TTCN_error(\"Internal error: "
2423 "Accessing a list element of a non-list template of union type %s.\");\n"
2424 "if (list_index >= value_list.n_values) "
2425 "TTCN_error(\"Internal error: Index overflow in a value list template "
2426 "of union type %s.\");\n"
2427 "return value_list.list_value[list_index];\n"
2428 "}\n", name
, name
, dispname
, dispname
);
2430 /* void set_type(template_sel, int) function */
2431 def
= mputstr(def
, "void set_type(template_sel template_type, "
2432 "unsigned int list_length);\n");
2433 src
= mputprintf(src
,
2434 "void %s_template::set_type(template_sel template_type, "
2435 "unsigned int list_length)\n"
2437 "if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST) "
2438 "TTCN_error (\"Internal error: Setting an invalid list for a template "
2439 "of union type %s.\");\n"
2441 "set_selection(template_type);\n"
2442 "value_list.n_values = list_length;\n"
2443 "value_list.list_value = new %s_template[list_length];\n"
2444 "}\n\n", name
, dispname
, name
);
2446 /* field access functions */
2447 for (i
= 0; i
< sdef
->nElements
; i
++) {
2448 def
= mputprintf(def
, "%s_template& %s%s();\n", sdef
->elements
[i
].type
,
2449 at_field
, sdef
->elements
[i
].name
);
2450 src
= mputprintf(src
, "%s_template& %s_template::%s%s()\n"
2452 "if (template_selection != SPECIFIC_VALUE || "
2453 "single_value.union_selection != %s_%s) {\n"
2454 "template_sel old_selection = template_selection;\n"
2456 "if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) "
2457 "single_value.field_%s = new %s_template(ANY_VALUE);\n"
2458 "else single_value.field_%s = new %s_template;\n"
2459 "single_value.union_selection = %s_%s;\n"
2460 "set_selection(SPECIFIC_VALUE);\n"
2462 "return *single_value.field_%s;\n"
2463 "}\n\n", sdef
->elements
[i
].type
, name
, at_field
, sdef
->elements
[i
].name
,
2464 selection_prefix
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
,
2465 sdef
->elements
[i
].type
, sdef
->elements
[i
].name
, sdef
->elements
[i
].type
,
2466 selection_prefix
, sdef
->elements
[i
].name
, sdef
->elements
[i
].name
);
2468 def
= mputprintf(def
, "const %s_template& %s%s() const;\n",
2469 sdef
->elements
[i
].type
, at_field
, sdef
->elements
[i
].name
);
2470 src
= mputprintf(src
, "const %s_template& %s_template::%s%s() const\n"
2472 "if (template_selection != SPECIFIC_VALUE) TTCN_error(\"Accessing field "
2473 "%s in a non-specific template of union type %s.\");\n"
2474 "if (single_value.union_selection != %s_%s) "
2475 "TTCN_error(\"Accessing non-selected field %s in a template of union "
2477 "return *single_value.field_%s;\n"
2478 "}\n\n", sdef
->elements
[i
].type
, name
, at_field
, sdef
->elements
[i
].name
,
2479 sdef
->elements
[i
].dispname
, dispname
, selection_prefix
,
2480 sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
, dispname
,
2481 sdef
->elements
[i
].name
);
2484 /* ischosen function */
2485 def
= mputprintf(def
, "boolean ischosen(%s checked_selection) const;\n",
2487 src
= mputprintf(src
, "boolean %s_template::ischosen(%s checked_selection) "
2490 "if (checked_selection == %s) TTCN_error(\"Internal error: Performing "
2491 "ischosen() operation on an invalid field of union type %s.\");\n"
2492 "switch (template_selection) {\n"
2493 "case SPECIFIC_VALUE:\n"
2494 "if (single_value.union_selection == %s) TTCN_error(\"Internal error: "
2495 "Invalid selector in a specific value when performing ischosen() "
2496 "operation on a template of union type %s.\");\n"
2497 "return single_value.union_selection == checked_selection;\n"
2498 "case VALUE_LIST:\n"
2500 "if (value_list.n_values < 1)\n"
2501 "TTCN_error(\"Internal error: Performing ischosen() operation on a "
2502 "template of union type %s containing an empty list.\");\n"
2503 "boolean ret_val = "
2504 "value_list.list_value[0].ischosen(checked_selection);\n"
2505 "boolean all_same = TRUE;\n"
2506 "for (unsigned int list_count = 1; list_count < value_list.n_values; "
2508 "if (value_list.list_value[list_count].ischosen(checked_selection) != "
2510 "all_same = FALSE;\n"
2514 "if (all_same) return ret_val;\n"
2517 "case ANY_OR_OMIT:\n"
2518 "case OMIT_VALUE:\n"
2519 "case COMPLEMENTED_LIST:\n"
2520 "TTCN_error(\"Performing ischosen() operation on a template of union type "
2521 "%s, which does not determine unambiguously the chosen field of the "
2522 "matching values.\");\n"
2524 "TTCN_error(\"Performing ischosen() operation on an uninitialized "
2525 "template of union type %s\");\n"
2528 "}\n\n", name
, selection_type
, unbound_value
, dispname
, unbound_value
,
2529 dispname
, dispname
, dispname
, dispname
);
2531 if (use_runtime_2
) {
2533 "void set_err_descr(Erroneous_descriptor_t* p_err_descr) { err_descr=p_err_descr; }\n");
2534 /** virtual stuff */
2536 "void valueofv(Base_Type* value) const;\n"
2537 "void set_value(template_sel other_value);\n"
2538 "void copy_value(const Base_Type* other_value);\n"
2539 "Base_Template* clone() const;\n"
2540 "const TTCN_Typedescriptor_t* get_descriptor() const;\n"
2541 "boolean matchv(const Base_Type* other_value, boolean legacy) const;\n"
2542 "void log_matchv(const Base_Type* match_value, boolean legacy) const;\n");
2543 src
= mputprintf(src
,
2544 "void %s_template::valueofv(Base_Type* value) const "
2545 "{ *(static_cast<%s*>(value)) = valueof(); }\n"
2546 "void %s_template::set_value(template_sel other_value) "
2547 "{ *this = other_value; }\n"
2548 "void %s_template::copy_value(const Base_Type* other_value) "
2549 "{ *this = *(static_cast<const %s*>(other_value)); }\n"
2550 "Base_Template* %s_template::clone() const "
2551 "{ return new %s_template(*this); }\n"
2552 "const TTCN_Typedescriptor_t* %s_template::get_descriptor() const "
2553 "{ return &%s_descr_; }\n"
2554 "boolean %s_template::matchv(const Base_Type* other_value, "
2555 "boolean legacy) const "
2556 "{ return match(*(static_cast<const %s*>(other_value)), legacy); }\n"
2557 "void %s_template::log_matchv(const Base_Type* match_value, "
2558 "boolean legacy) const "
2559 " { log_match(*(static_cast<const %s*>(match_value)), legacy); }\n",
2570 def
= mputstr(def
, "void log() const;\n");
2571 src
= mputprintf(src
,"void %s_template::log() const\n"
2573 "switch (template_selection) {\n"
2574 "case SPECIFIC_VALUE:\n"
2575 "switch (single_value.union_selection) {\n", name
);
2576 for (i
= 0; i
< sdef
->nElements
; i
++) {
2577 src
= mputprintf(src
, "case %s_%s:\n"
2578 "TTCN_Logger::log_event_str(\"{ %s := \");\n"
2579 "single_value.field_%s->log();\n"
2580 "TTCN_Logger::log_event_str(\" }\");\n"
2581 "break;\n", selection_prefix
, sdef
->elements
[i
].name
,
2582 sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
);
2584 src
= mputstr(src
, "default:\n"
2585 "TTCN_Logger::log_event_str(\"<invalid selector>\");\n"
2588 "case COMPLEMENTED_LIST:\n"
2589 "TTCN_Logger::log_event_str(\"complement \");\n"
2590 "case VALUE_LIST:\n"
2591 "TTCN_Logger::log_char('(');\n"
2592 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
2594 "if (list_count > 0) TTCN_Logger::log_event_str(\", \");\n"
2595 "value_list.list_value[list_count].log();\n"
2597 "TTCN_Logger::log_char(')');\n"
2602 "log_ifpresent();\n");
2603 if (use_runtime_2
) {
2604 src
= mputstr(src
, "if (err_descr) err_descr->log();\n");
2606 src
= mputstr(src
, "}\n\n");
2608 /* log_match function */
2609 def
= mputprintf(def
, "void log_match(const %s& match_value, "
2610 "boolean legacy = FALSE) const;\n", name
);
2611 src
= mputprintf(src
,
2612 "void %s_template::log_match(const %s& match_value, boolean legacy) const\n"
2614 "if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity() "
2615 "&& match(match_value, legacy)){\n"
2616 "TTCN_Logger::print_logmatch_buffer();\n"
2617 "TTCN_Logger::log_event_str(\" matched\");\n"
2620 "if (template_selection == SPECIFIC_VALUE && "
2621 "single_value.union_selection == match_value.get_selection()) {\n"
2622 "switch (single_value.union_selection) {\n", name
, name
);
2623 for (i
= 0; i
< sdef
->nElements
; i
++) {
2624 src
= mputprintf(src
, "case %s_%s:\n"
2625 "if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){\n"
2626 "TTCN_Logger::log_logmatch_info(\".%s\");\n"
2627 "single_value.field_%s->log_match(match_value.%s%s(), legacy);\n"
2629 "TTCN_Logger::log_event_str(\"{ %s := \");\n"
2630 "single_value.field_%s->log_match(match_value.%s%s(), legacy);\n"
2631 "TTCN_Logger::log_event_str(\" }\");\n"
2633 "break;\n", selection_prefix
, sdef
->elements
[i
].name
,
2634 sdef
->elements
[i
].dispname
,
2635 sdef
->elements
[i
].name
, at_field
, sdef
->elements
[i
].name
,
2636 sdef
->elements
[i
].dispname
, sdef
->elements
[i
].name
,
2637 at_field
, sdef
->elements
[i
].name
);
2639 src
= mputstr(src
, "default:\n"
2640 "TTCN_Logger::print_logmatch_buffer();\n"
2641 "TTCN_Logger::log_event_str(\"<invalid selector>\");\n"
2644 "TTCN_Logger::print_logmatch_buffer();\n"
2645 "match_value.log();\n"
2646 "TTCN_Logger::log_event_str(\" with \");\n"
2648 "if (match(match_value, legacy)) TTCN_Logger::log_event_str(\" matched\");\n"
2649 "else TTCN_Logger::log_event_str(\" unmatched\");\n"
2653 /* encode_text function */
2654 def
= mputstr(def
, "void encode_text(Text_Buf& text_buf) const;\n");
2655 src
= mputprintf(src
,
2656 "void %s_template::encode_text(Text_Buf& text_buf) const\n"
2658 "encode_text_base(text_buf);\n"
2659 "switch (template_selection) {\n"
2660 "case SPECIFIC_VALUE:\n"
2661 "text_buf.push_int(single_value.union_selection);\n"
2662 "switch (single_value.union_selection) {\n", name
);
2663 for (i
= 0; i
< sdef
->nElements
; i
++) {
2664 src
= mputprintf(src
, "case %s_%s:\n"
2665 "single_value.field_%s->encode_text(text_buf);\n"
2666 "break;\n", selection_prefix
, sdef
->elements
[i
].name
,
2667 sdef
->elements
[i
].name
);
2669 src
= mputprintf(src
, "default:\n"
2670 "TTCN_error(\"Internal error: Invalid selector in a specific value when "
2671 "encoding a template of union type %s.\");\n"
2673 "case OMIT_VALUE:\n"
2675 "case ANY_OR_OMIT:\n"
2677 "case VALUE_LIST:\n"
2678 "case COMPLEMENTED_LIST:\n"
2679 "text_buf.push_int(value_list.n_values);\n"
2680 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
2682 "value_list.list_value[list_count].encode_text(text_buf);\n"
2685 "TTCN_error(\"Text encoder: Encoding an uninitialized template of type "
2688 "}\n\n", dispname
, dispname
);
2690 /* decode_text function */
2691 def
= mputstr(def
, "void decode_text(Text_Buf& text_buf);\n");
2692 src
= mputprintf(src
, "void %s_template::decode_text(Text_Buf& text_buf)\n"
2695 "decode_text_base(text_buf);\n"
2696 "switch (template_selection) {\n"
2697 "case SPECIFIC_VALUE:\n"
2699 "single_value.union_selection = %s;\n"
2700 "%s new_selection = (%s)text_buf.pull_int().get_val();\n"
2701 "switch (new_selection) {\n", name
, unbound_value
, selection_type
,
2703 for (i
= 0; i
< sdef
->nElements
; i
++) {
2704 src
= mputprintf(src
, "case %s_%s:\n"
2705 "single_value.field_%s = new %s_template;\n"
2706 "single_value.field_%s->decode_text(text_buf);\n"
2707 "break;\n", selection_prefix
, sdef
->elements
[i
].name
,
2708 sdef
->elements
[i
].name
, sdef
->elements
[i
].type
, sdef
->elements
[i
].name
);
2710 src
= mputprintf(src
, "default:\n"
2711 "TTCN_error(\"Text decoder: Unrecognized union selector was received for "
2712 "a template of type %s.\");\n"
2714 "single_value.union_selection = new_selection;\n"
2716 "case OMIT_VALUE:\n"
2718 "case ANY_OR_OMIT:\n"
2720 "case VALUE_LIST:\n"
2721 "case COMPLEMENTED_LIST:\n"
2722 "value_list.n_values = text_buf.pull_int().get_val();\n"
2723 "value_list.list_value = new %s_template[value_list.n_values];\n"
2724 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
2726 "value_list.list_value[list_count].decode_text(text_buf);\n"
2729 "TTCN_error(\"Text decoder: Unrecognized selector was received in a "
2730 "template of type %s.\");\n"
2732 "}\n\n", dispname
, name
, dispname
);
2734 /* TTCN-3 ispresent() function */
2735 def
= mputstr(def
, "boolean is_present(boolean legacy = FALSE) const;\n");
2736 src
= mputprintf(src
,
2737 "boolean %s_template::is_present(boolean legacy) const\n"
2739 "if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;\n"
2740 "return !match_omit(legacy);\n"
2744 def
= mputstr(def
, "boolean match_omit(boolean legacy = FALSE) const;\n");
2745 src
= mputprintf(src
,
2746 "boolean %s_template::match_omit(boolean legacy) const\n"
2748 "if (is_ifpresent) return TRUE;\n"
2749 "switch (template_selection) {\n"
2750 "case OMIT_VALUE:\n"
2751 "case ANY_OR_OMIT:\n"
2753 "case VALUE_LIST:\n"
2754 "case COMPLEMENTED_LIST:\n"
2756 "for (unsigned int v_idx=0; v_idx<value_list.n_values; v_idx++)\n"
2757 "if (value_list.list_value[v_idx].match_omit())\n"
2758 "return template_selection==VALUE_LIST;\n"
2759 "return template_selection==COMPLEMENTED_LIST;\n"
2760 "} // else fall through\n"
2768 def
= mputstr(def
, "void set_param(Module_Param& param);\n");
2769 src
= mputprintf(src
,
2770 "void %s_template::set_param(Module_Param& param)\n"
2772 " if (dynamic_cast<Module_Param_Name*>(param.get_id()) != NULL &&\n"
2773 " param.get_id()->next_name()) {\n"
2774 // Haven't reached the end of the module parameter name
2775 // => the name refers to one of the fields, not to the whole union
2776 " char* param_field = param.get_id()->get_current_name();\n"
2777 " if (param_field[0] >= '0' && param_field[0] <= '9') {\n"
2778 " param.error(\"Unexpected array index in module parameter, expected a valid field\"\n"
2779 " \" name for union template type `%s'\");\n"
2781 " ", name
, dispname
);
2782 for (i
= 0; i
< sdef
->nElements
; i
++) {
2783 src
= mputprintf(src
,
2784 "if (strcmp(\"%s\", param_field) == 0) {\n"
2785 " %s%s().set_param(param);\n"
2788 sdef
->elements
[i
].dispname
, at_field
, sdef
->elements
[i
].name
);
2790 src
= mputprintf(src
,
2791 "param.error(\"Field `%%s' not found in union template type `%s'\", param_field);\n"
2793 " param.basic_check(Module_Param::BC_TEMPLATE, \"union template\");\n"
2794 " Module_Param_Ptr mp = ¶m;\n"
2795 " if (param.get_type() == Module_Param::MP_Reference) {\n"
2796 " mp = param.get_referenced_param();\n"
2798 " switch (mp->get_type()) {\n"
2799 " case Module_Param::MP_Omit:\n"
2800 " *this = OMIT_VALUE;\n"
2802 " case Module_Param::MP_Any:\n"
2803 " *this = ANY_VALUE;\n"
2805 " case Module_Param::MP_AnyOrNone:\n"
2806 " *this = ANY_OR_OMIT;\n"
2808 " case Module_Param::MP_List_Template:\n"
2809 " case Module_Param::MP_ComplementList_Template: {\n"
2810 " %s_template temp;\n"
2811 " temp.set_type(mp->get_type()==Module_Param::MP_List_Template ? "
2812 "VALUE_LIST : COMPLEMENTED_LIST, mp->get_size());\n"
2813 " for (size_t p_i=0; p_i<mp->get_size(); p_i++) {\n"
2814 " temp.list_item(p_i).set_param(*mp->get_elem(p_i));\n"
2818 " case Module_Param::MP_Value_List:\n"
2819 " if (mp->get_size()==0) break;\n" /* for backward compatibility */
2820 " param.type_error(\"union template\", \"%s\");\n"
2822 " case Module_Param::MP_Assignment_List: {\n"
2823 " Module_Param* mp_last = mp->get_elem(mp->get_size()-1);\n",
2824 dispname
, name
, dispname
);
2825 for (i
= 0; i
< sdef
->nElements
; i
++) {
2826 src
= mputprintf(src
,
2827 " if (!strcmp(mp_last->get_id()->get_name(), \"%s\")) {\n"
2828 " %s%s().set_param(*mp_last);\n"
2830 " }\n", sdef
->elements
[i
].dispname
, at_field
, sdef
->elements
[i
].name
);
2832 src
= mputprintf(src
,
2833 " mp_last->error(\"Field %%s does not exist in type %s.\", mp_last->get_id()->get_name());\n"
2836 " param.type_error(\"union template\", \"%s\");\n"
2838 " is_ifpresent = param.get_ifpresent() || mp->get_ifpresent();\n"
2839 "}\n\n", dispname
, dispname
);
2842 def
= mputstr(def
, "Module_Param* get_param(Module_Param_Name& param_name) const;\n");
2843 src
= mputprintf(src
,
2844 "Module_Param* %s_template::get_param(Module_Param_Name& param_name) const\n"
2846 " if (param_name.next_name()) {\n"
2847 // Haven't reached the end of the module parameter name
2848 // => the name refers to one of the fields, not to the whole union
2849 " char* param_field = param_name.get_current_name();\n"
2850 " if (param_field[0] >= '0' && param_field[0] <= '9') {\n"
2851 " TTCN_error(\"Unexpected array index in module parameter reference, \"\n"
2852 " \"expected a valid field name for union template type `%s'\");\n"
2854 " ", name
, dispname
);
2855 for (i
= 0; i
< sdef
->nElements
; i
++) {
2856 src
= mputprintf(src
,
2857 "if (strcmp(\"%s\", param_field) == 0) {\n"
2858 " return %s%s().get_param(param_name);\n"
2860 sdef
->elements
[i
].dispname
, at_field
, sdef
->elements
[i
].name
);
2862 src
= mputprintf(src
,
2863 "TTCN_error(\"Field `%%s' not found in union type `%s'\", param_field);\n"
2865 " Module_Param* mp = NULL;\n"
2866 " switch (template_selection) {\n"
2867 " case UNINITIALIZED_TEMPLATE:\n"
2868 " mp = new Module_Param_Unbound();\n"
2870 " case OMIT_VALUE:\n"
2871 " mp = new Module_Param_Omit();\n"
2873 " case ANY_VALUE:\n"
2874 " mp = new Module_Param_Any();\n"
2876 " case ANY_OR_OMIT:\n"
2877 " mp = new Module_Param_AnyOrNone();\n"
2879 " case SPECIFIC_VALUE: {\n"
2880 " Module_Param* mp_field = NULL;\n"
2881 " switch(single_value.union_selection) {\n"
2883 for (i
= 0; i
< sdef
->nElements
; ++i
) {
2884 src
= mputprintf(src
,
2886 " mp_field = single_value.field_%s->get_param(param_name);\n"
2887 " mp_field->set_id(new Module_Param_FieldName(mcopystr(\"%s\")));\n"
2889 , selection_prefix
, sdef
->elements
[i
].name
2890 , sdef
->elements
[i
].name
, sdef
->elements
[i
].dispname
);
2896 " mp = new Module_Param_Assignment_List();\n"
2897 " mp->add_elem(mp_field);\n"
2899 " case VALUE_LIST:\n"
2900 " case COMPLEMENTED_LIST: {\n"
2901 " if (template_selection == VALUE_LIST) {\n"
2902 " mp = new Module_Param_List_Template();\n"
2905 " mp = new Module_Param_ComplementList_Template();\n"
2907 " for (size_t i = 0; i < value_list.n_values; ++i) {\n"
2908 " mp->add_elem(value_list.list_value[i].get_param(param_name));\n"
2914 " if (is_ifpresent) {\n"
2915 " mp->set_ifpresent();\n"
2920 /* check template restriction */
2921 def
= mputstr(def
, "void check_restriction(template_res t_res, "
2922 "const char* t_name=NULL, boolean legacy = FALSE) const;\n");
2923 src
= mputprintf(src
,
2924 "void %s_template::check_restriction("
2925 "template_res t_res, const char* t_name, boolean legacy) const\n"
2927 "if (template_selection==UNINITIALIZED_TEMPLATE) return;\n"
2928 "switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {\n"
2930 "if (template_selection==OMIT_VALUE) return;\n"
2932 "if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;\n"
2933 "switch (single_value.union_selection) {\n"
2935 for (i
= 0; i
< sdef
->nElements
; i
++) {
2936 src
= mputprintf(src
, "case %s_%s:\n"
2937 "single_value.field_%s->check_restriction("
2938 "t_res, t_name ? t_name : \"%s\");\n"
2940 selection_prefix
, sdef
->elements
[i
].name
,
2941 sdef
->elements
[i
].name
, dispname
);
2943 src
= mputprintf(src
, "default:\n"
2944 "TTCN_error(\"Internal error: Invalid selector in a specific value when "
2945 "performing check_restriction operation on a template of union type %s.\");\n"
2947 "case TR_PRESENT:\n"
2948 "if (!match_omit(legacy)) return;\n"
2953 "TTCN_error(\"Restriction `%%s' on template of type %%s violated.\", "
2954 "get_res_name(t_res), t_name ? t_name : \"%s\");\n"
2955 "}\n\n", dispname
, dispname
);
2957 def
= mputstr(def
, "};\n\n");
2959 output
->header
.class_defs
= mputstr(output
->header
.class_defs
, def
);
2962 output
->source
.methods
= mputstr(output
->source
.methods
, src
);
2965 Free(selection_type
);
2966 Free(unbound_value
);
2967 Free(selection_prefix
);