Update README.linux
[deliverable/titan.core.git] / compiler2 / union.c
CommitLineData
970ed795
EL
1///////////////////////////////////////////////////////////////////////////////
2// Copyright (c) 2000-2014 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///////////////////////////////////////////////////////////////////////////////
8#include <string.h>
9
10#include "../common/memory.h"
11#include "datatypes.h"
12#include "union.h"
13#include "encdec.h"
14
15#include "main.hh"
16#include "ttcn3/compiler.h"
17
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
40 */
41typedef struct{
42 const char* type;
43 const char* typedescr;
44 int start_pos;
45 int use_counter;
46 int decoded_for_element;
47}temporal_variable;
48
49void defUnionClass(struct_def const *sdef, output_struct *output)
50{
51 size_t i;
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();
63
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");
68
69
70 /* class declaration */
71 output->header.class_decls = mputprintf(output->header.class_decls,
72 "class %s;\n", name);
73
74 /* class definition and source code */
75
76 /* class header and data fields*/
77 def = mputprintf(def,
78#ifndef NDEBUG
79 "// written by defUnionClass in " __FILE__ " at %d\n"
80#endif
81 "class %s : public Base_Type {\n"
82#ifndef NDEBUG
83 , __LINE__
84#endif
85 , name);
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));
92 }
93 def = mputstr(def, " };\n"
94 "private:\n");
95
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);
101 }
102 def = mputstr(def, "};\n");
103
104 if(ber_needed && sdef->ot) {
105 def=mputstr(def, "ASN_BER_TLV_t tlv_opentype;\n");
106 }
107
108 if (use_runtime_2) {
109 def=mputstr(def, "Erroneous_descriptor_t* err_descr;\n");
110 }
111
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"
115 "{\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);
122 }
123 src = mputprintf(src, "default:\n"
124 "TTCN_error(\"Assignment of an unbound union value of type %s.\");\n"
125 "}\n"
126 "union_selection = other_value.union_selection;\n", dispname);
127
128 if (use_runtime_2) {
129 src = mputstr(src, "err_descr = other_value.err_descr;\n");
130 }
131
132 src = mputstr(src, "}\n\n");
133
134 /* default constructor */
135 def = mputprintf(def, "\npublic:\n"
136 "%s();\n", name);
137 src = mputprintf(src, "%s::%s()%s\n"
138 "{\n"
139 "union_selection = %s;\n"
140 "}\n\n", name, name,
141 use_runtime_2 ? ": err_descr(NULL)" : "",
142 unbound_value);
143
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 */
148 "{\n"
149 "copy_value(other_value);\n"
150 "}\n\n", name, name, name);
151
152 /* destructor */
153 def = mputprintf(def, "~%s();\n", name);
154 src = mputprintf(src, "%s::~%s()\n"
155 "{\n"
156 "clean_up();\n"
157 "}\n\n", name, name);
158
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"
162 "{\n"
163 "if (this != &other_value) {\n"
164 "clean_up();\n"
165 "copy_value(other_value);\n"
166 "}\n"
167 "return *this;\n"
168 "}\n\n", name, name, name);
169
170 /* comparison operator */
171 def = mputprintf(def, "boolean operator==(const %s& other_value) const;\n",
172 name);
173 src = mputprintf(src, "boolean %s::operator==(const %s& other_value) const\n"
174 "{\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);
186 }
187 src = mputstr(src, "default:\n"
188 "return FALSE;\n"
189 "}\n"
190 "}\n\n");
191
192 /* != and () operator */
193 def = mputprintf(def, "inline boolean operator!=(const %s& other_value) "
194 "const { return !(*this == other_value); }\n", name);
195
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"
201 "{\n"
202 "if (union_selection != %s_%s) {\n"
203 "clean_up();\n"
204 "field_%s = new %s;\n"
205 "union_selection = %s_%s;\n"
206 "}\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);
212
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"
216 "{\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"
220 "}\n\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);
224 }
225
226 /* get_selection function */
227 def = mputprintf(def, "inline %s get_selection() const "
228 "{ return union_selection; }\n", selection_type);
229
230 /* ischosen function */
231 def = mputprintf(def, "boolean ischosen(%s checked_selection) const;\n",
232 selection_type);
233 src = mputprintf(src, "boolean %s::ischosen(%s checked_selection) const\n"
234 "{\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,
241 dispname);
242
243 /* is_bound function */
244 def = mputstr (def, "boolean is_bound() const;\n");
245 src = mputprintf(src, "boolean %s::is_bound() const\n"
246 "{\n"
247 " return union_selection != %s;\n"
248 "}\n\n", name, unbound_value);
249
250 /* is_value function */
251 def = mputstr (def, "boolean is_value() const;\n");
252 src = mputprintf(src, "boolean %s::is_value() const\n"
253 "{\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);
260 }
261 src = mputstr(src, "default: TTCN_error(\"Invalid selection in union is_bound\");"
262 "}\n"
263 "}\n\n");
264
265 /* clean_up function */
266 def = mputstr (def, "void clean_up();\n");
267 src = mputprintf(src, "void %s::clean_up()\n"
268 "{\n"
269 "switch (union_selection) {\n",
270 name);
271 for (i = 0; i < sdef->nElements; ++i) {
272 src = mputprintf(src, "case %s_%s:\n"
273 " delete field_%s;\n"
274 " break;\n",
275 selection_prefix, sdef->elements[i].name, sdef->elements[i].name);
276 }
277 src = mputprintf(src, "default:\n"
278 " break;\n"
279 "}\n"
280 "union_selection = %s;\n"
281 "}\n\n", unbound_value);
282
283 if (use_runtime_2) {
284 def = mputstr(def,
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",
299 name, name,
300 name, name,
301 name, name,
302 name, name);
303 } else {
304 def = mputstr(def,
305 "inline boolean is_present() const { return is_bound(); }\n");
306 }
307
308 /* log function */
309 def = mputstr(def, "void log() const;\n");
310 src = mputprintf(src, "void %s::log() const\n"
311 "{\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"
316 "field_%s->log();\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);
320 }
321 src = mputstr(src, "default:\n"
322 "TTCN_Logger::log_event_unbound();\n"
323 "}\n");
324 if (use_runtime_2) {
325 src = mputstr(src, "if (err_descr) err_descr->log();\n");
326 }
327 src = mputstr(src, "}\n\n");
328
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"
332 "{\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"
341 " }\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"
347 " return;\n"
348 " } else ",
349 sdef->elements[i].dispname, at_field, sdef->elements[i].name);
350 }
351 src = mputprintf(src,
352 "param.error(\"Field `%%s' not found in union type `%s'\", param_field);\n"
353 " }\n"
354 " param.basic_check(Module_Param::BC_VALUE, \"union value\");\n"
355 " if (param.get_type()==Module_Param::MP_Value_List && param.get_size()==0) return;\n"
356 " if (param.get_type()!=Module_Param::MP_Assignment_List) {\n"
357 " param.error(\"union value with field name was expected\");\n"
358 " }\n"
359 " Module_Param* mp_last = param.get_elem(param.get_size()-1);\n", dispname);
360
361 for (i = 0; i < sdef->nElements; i++) {
362 src = mputprintf(src,
363 " if (!strcmp(mp_last->get_id()->get_name(), \"%s\")) {\n"
364 " %s%s().set_param(*mp_last);\n"
365 " return;\n"
366 " }\n", sdef->elements[i].dispname, at_field, sdef->elements[i].name);
367 }
368 src = mputprintf(src,
369 " mp_last->error(\"Field %%s does not exist in type %s.\", mp_last->get_id()->get_name());\n"
370 "}\n\n", dispname);
371
372 /* set implicit omit function, recursive */
373 def = mputstr(def, " void set_implicit_omit();\n");
374 src = mputprintf(src,
375 "void %s::set_implicit_omit()\n{\n"
376 "switch (union_selection) {\n", name);
377 for (i = 0; i < sdef->nElements; i++) {
378 src = mputprintf(src,
379 "case %s_%s:\n"
380 "field_%s->set_implicit_omit(); break;\n",
381 selection_prefix, sdef->elements[i].name, sdef->elements[i].name);
382 }
383 src = mputstr(src, "default: break;\n}\n}\n\n");
384
385 /* encode_text function */
386 def = mputstr(def, "void encode_text(Text_Buf& text_buf) const;\n");
387 src = mputprintf(src, "void %s::encode_text(Text_Buf& text_buf) const\n"
388 "{\n"
389 "text_buf.push_int(union_selection);\n"
390 "switch (union_selection) {\n", name);
391 for (i = 0; i < sdef->nElements; i++) {
392 src = mputprintf(src, "case %s_%s:\n"
393 "field_%s->encode_text(text_buf);\n"
394 "break;\n", selection_prefix, sdef->elements[i].name,
395 sdef->elements[i].name);
396 }
397 src = mputprintf(src, "default:\n"
398 "TTCN_error(\"Text encoder: Encoding an unbound value of union type "
399 "%s.\");\n"
400 "}\n"
401 "}\n\n", dispname);
402
403 /* decode_text function */
404 def = mputstr(def, "void decode_text(Text_Buf& text_buf);\n");
405 src = mputprintf(src, "void %s::decode_text(Text_Buf& text_buf)\n"
406 "{\n"
407 "switch ((%s)text_buf.pull_int().get_val()) {\n", name, selection_type);
408 for (i = 0; i < sdef->nElements; i++) {
409 src = mputprintf(src, "case %s_%s:\n"
410 "%s%s().decode_text(text_buf);\n"
411 "break;\n", selection_prefix, sdef->elements[i].name,
412 at_field, sdef->elements[i].name);
413 }
414 src = mputprintf(src, "default:\n"
415 "TTCN_error(\"Text decoder: Unrecognized union selector was received "
416 "for type %s.\");\n"
417 "}\n"
418 "}\n\n", dispname);
419
420 if(ber_needed || raw_needed || text_needed || xer_needed || json_needed)
421 def_encdec(name, &def, &src, ber_needed, raw_needed, text_needed,
422 xer_needed, json_needed, TRUE);
423
424 /* BER functions */
425 if(ber_needed) {
426 def = mputstr(def, "private:\n"
427 "boolean BER_decode_set_selection(const ASN_BER_TLV_t& p_tlv);\n"
428 "public:\n"
429 "boolean BER_decode_isMyMsg(const TTCN_Typedescriptor_t& p_td, "
430 "const ASN_BER_TLV_t& p_tlv);\n");
431
432 /* BER_encode_TLV() */
433 src = mputprintf(src,
434#ifndef NDEBUG
435 "// written by %s in " __FILE__ " at %d\n"
436#endif
437 "ASN_BER_TLV_t *%s::BER_encode_TLV("
438 "const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const\n"
439 "{\n"
440#ifndef NDEBUG
441 , __FUNCTION__, __LINE__
442#endif
443 , name);
444 if (use_runtime_2) {
445 src = mputstr(src,
446 " if (err_descr) return BER_encode_TLV_negtest(err_descr, p_td, p_coding);\n");
447 }
448 src = mputstr(src,
449 " BER_chk_descr(p_td);\n"
450 " ASN_BER_TLV_t *new_tlv;\n"
451 " TTCN_EncDec_ErrorContext ec_0(\"Alternative '\");\n"
452 " TTCN_EncDec_ErrorContext ec_1;\n"
453 " switch (union_selection) {\n");
454 for (i = 0; i < sdef->nElements; i++) {
455 src = mputprintf(src, " case %s_%s:\n"
456 " ec_1.set_msg(\"%s': \");\n"
457 " new_tlv = field_%s->BER_encode_TLV(%s_descr_, p_coding);\n"
458 " break;\n", selection_prefix, sdef->elements[i].name,
459 sdef->elements[i].dispname,
460 sdef->elements[i].name, sdef->elements[i].typedescrname);
461 } /* for i */
462 src = mputprintf(src, " case %s:\n"
463 " new_tlv = BER_encode_chk_bound(FALSE);\n"
464 " break;\n"
465 " default:\n"
466 " TTCN_EncDec_ErrorContext::error_internal(\"Unknown selection.\");\n"
467 " new_tlv = NULL;\n"
468 " }\n" /* switch */
469 " return ASN_BER_V2TLV(new_tlv, p_td, p_coding);\n"
470 "}\n\n", unbound_value);
471
472 if (use_runtime_2) { /* BER_encode_TLV_negtest() */
473 def = mputstr(def,
474 "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");
475 src = mputprintf(src,
476 "ASN_BER_TLV_t *%s::BER_encode_TLV_negtest(const Erroneous_descriptor_t* p_err_descr, "
477 "const TTCN_Typedescriptor_t& p_td, unsigned p_coding) const\n"
478 "{\n"
479 " BER_chk_descr(p_td);\n"
480 " ASN_BER_TLV_t *new_tlv = NULL;\n"
481 " TTCN_EncDec_ErrorContext ec_0(\"Alternative '\");\n"
482 " TTCN_EncDec_ErrorContext ec_1;\n"
483 " const Erroneous_values_t* err_vals = NULL;\n"
484 " const Erroneous_descriptor_t* emb_descr = NULL;\n"
485 " switch (union_selection) {\n", name);
486 for (i = 0; i < sdef->nElements; i++) {
487 src = mputprintf(src, " case %s_%s:\n"
488 " err_vals = p_err_descr->get_field_err_values(%d);\n"
489 " emb_descr = p_err_descr->get_field_emb_descr(%d);\n"
490 " if (err_vals && err_vals->value) {\n"
491 " if (err_vals->value->errval) {\n"
492 " ec_1.set_msg(\"%s'(erroneous value): \");\n"
493 " if (err_vals->value->raw) {\n"
494 " new_tlv = err_vals->value->errval->BER_encode_negtest_raw();\n"
495 " } else {\n"
496 " if (err_vals->value->type_descr==NULL) TTCN_error(\"internal error: erroneous value typedescriptor missing\");\n"
497 " new_tlv = err_vals->value->errval->BER_encode_TLV(*err_vals->value->type_descr, p_coding);\n"
498 " }\n"
499 " }\n"
500 " } else {\n"
501 " ec_1.set_msg(\"%s': \");\n"
502 " if (emb_descr) new_tlv = field_%s->BER_encode_TLV_negtest(emb_descr, %s_descr_, p_coding);\n"
503 " else new_tlv = field_%s->BER_encode_TLV(%s_descr_, p_coding);\n"
504 " }\n"
505 " break;\n", selection_prefix, sdef->elements[i].name,
506 (int)i, (int)i, sdef->elements[i].dispname, sdef->elements[i].dispname,
507 sdef->elements[i].name, sdef->elements[i].typedescrname,
508 sdef->elements[i].name, sdef->elements[i].typedescrname);
509 } /* for i */
510 src = mputprintf(src, " case %s:\n"
511 " new_tlv = BER_encode_chk_bound(FALSE);\n"
512 " break;\n"
513 " default:\n"
514 " TTCN_EncDec_ErrorContext::error_internal(\"Unknown selection.\");\n"
515 " new_tlv = NULL;\n"
516 " }\n" /* switch */
517 " if (new_tlv==NULL) new_tlv=ASN_BER_TLV_t::construct(NULL);\n"
518 " return ASN_BER_V2TLV(new_tlv, p_td, p_coding);\n"
519 "}\n\n", unbound_value);
520 }
521
522 /* BER_decode_set_selection() */
523 src = mputprintf(src, "boolean %s::BER_decode_set_selection("
524 "const ASN_BER_TLV_t& p_tlv)\n"
525 "{\n"
526 " clean_up();\n", name);
527 for (i = 0; i < sdef->nElements; i++) {
528 src = mputprintf(src, " field_%s = new %s;\n"
529 " union_selection = %s_%s;\n"
530 " if (field_%s->BER_decode_isMyMsg(%s_descr_, p_tlv)) return TRUE;\n"
531 " delete field_%s;\n", sdef->elements[i].name, sdef->elements[i].type,
532 selection_prefix, sdef->elements[i].name, sdef->elements[i].name,
533 sdef->elements[i].typedescrname, sdef->elements[i].name);
534 } /* for i */
535 src = mputprintf(src, " union_selection = %s;\n"
536 " return FALSE;\n"
537 "}\n\n", unbound_value);
538
539 /* BER_decode_isMyMsg() */
540 src = mputprintf(src, "boolean %s::BER_decode_isMyMsg("
541 "const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv)\n"
542 "{\n"
543 " if (p_td.ber->n_tags == 0) {\n"
544 " %s tmp_type;\n"
545 " return tmp_type.BER_decode_set_selection(p_tlv);\n"
546 " } else return Base_Type::BER_decode_isMyMsg(p_td, p_tlv);\n"
547 "}\n\n", name, name);
548
549 /* BER_decode_TLV() */
550 src = mputprintf(src, "boolean %s::BER_decode_TLV("
551 "const TTCN_Typedescriptor_t& p_td, const ASN_BER_TLV_t& p_tlv, "
552 "unsigned L_form)\n"
553 "{\n"
554 " BER_chk_descr(p_td);\n"
555 " ASN_BER_TLV_t stripped_tlv;\n"
556 " BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv);\n"
557 " TTCN_EncDec_ErrorContext ec_0(\"While decoding '%s' type: \");\n",
558 name, dispname);
559 if (sdef->ot) {
560 src = mputprintf(src, " if (!BER_decode_TLV_CHOICE(*p_td.ber, "
561 "stripped_tlv, L_form, tlv_opentype)) {\n"
562 " tlv_opentype.Tlen = 0;\n"
563 " return FALSE;\n"
564 " }\n"
565 " clean_up();\n"
566 " union_selection = %s;\n", unbound_value);
567 } else {
568 src = mputstr(src, " ASN_BER_TLV_t tmp_tlv;\n"
569 " if (!BER_decode_TLV_CHOICE(*p_td.ber, stripped_tlv, L_form, "
570 "tmp_tlv) || "
571 "!BER_decode_CHOICE_selection(BER_decode_set_selection(tmp_tlv), "
572 "tmp_tlv)) return FALSE;\n"
573 " TTCN_EncDec_ErrorContext ec_1(\"Alternative '\");\n"
574 " TTCN_EncDec_ErrorContext ec_2;\n"
575 " switch (union_selection) {\n");
576 for(i = 0; i < sdef->nElements; i++) {
577 src = mputprintf(src, " case %s_%s:\n"
578 " ec_2.set_msg(\"%s': \");\n"
579 " field_%s->BER_decode_TLV(%s_descr_, tmp_tlv, L_form);\n"
580 " break;\n", selection_prefix, sdef->elements[i].name,
581 sdef->elements[i].dispname,
582 sdef->elements[i].name, sdef->elements[i].typedescrname);
583 } /* for i */
584 src = mputstr(src, " default:\n"
585 " return FALSE;\n"
586 " }\n");
587 if (sdef->opentype_outermost) {
588 src = mputstr(src,
589 " TTCN_EncDec_ErrorContext ec_1(\"While decoding opentypes: \");\n"
590 " TTCN_Type_list p_typelist;\n"
591 " BER_decode_opentypes(p_typelist, L_form);\n");
592 } /* if sdef->opentype_outermost */
593 }
594 src = mputstr(src, " return TRUE;\n"
595 "}\n\n");
596
597 if (sdef->ot || sdef->has_opentypes) { /* theoretically, these are
598 mutually exlusive */
599 /* BER_decode_opentypes() */
600 def = mputstr(def, "void BER_decode_opentypes("
601 "TTCN_Type_list& p_typelist, unsigned L_form);\n");
602 src = mputprintf(src, "void %s::BER_decode_opentypes("
603 "TTCN_Type_list& p_typelist, unsigned L_form)\n"
604 "{\n", name);
605 if (sdef->ot) {
606 AtNotationList_t *anl = &sdef->ot->anl;
607 OpentypeAlternativeList_t *oal = &sdef->ot->oal;
608 src = mputprintf(src,
609 " if (union_selection != %s) return;\n"
610 " TTCN_EncDec_ErrorContext ec_0(\"While decoding open type '%s': "
611 "\");\n", unbound_value, dispname);
612 if (oal->nElements > 0) {
613 size_t oal_i, anl_i;
614 char *s2;
615 /* variable declarations - the referenced components */
616 for (anl_i = 0; anl_i < anl->nElements; anl_i++) {
617 AtNotation_t *an = anl->elements + anl_i;
618 src = mputprintf(src, " const %s& f_%lu = static_cast<const %s*>"
619 "(p_typelist.get_nth(%lu))->%s;\n", an->type_name,
620 (unsigned long) (anl_i + 1), an->parent_typename,
621 (unsigned long) an->parent_level, an->sourcecode);
622 } /* for anl_i */
623 src = mputstr(src, " {\n"
624 " TTCN_EncDec_ErrorContext ec_1(\"Alternative '\");\n"
625 " TTCN_EncDec_ErrorContext ec_2;\n");
626 s2 = mprintf("%*s", (int)(anl->nElements + 2) * 2, "");
627 for (oal_i = 0; oal_i < oal->nElements; oal_i++) {
628 size_t if_level;
629 OpentypeAlternative_t *oa = oal->elements + oal_i;
630 if (oal_i > 0) {
631 for (if_level = 0; if_level < anl->nElements; if_level++)
632 if (oa->const_valuenames[if_level]) break;
633 for (i = anl->nElements; i > if_level; i--)
634 src = mputprintf(src, "%*s}\n", (int)(i + 1) * 2, "");
635 } /* if oal_i */
636 else if_level = 0;
637 for (anl_i = if_level; anl_i < anl->nElements; anl_i++) {
638 src = mputprintf(src, "%*s%sif (f_%lu == %s) {\n",
639 (int)(anl_i + 2) * 2, "",
640 oal_i && anl_i <= if_level ? "else " : "",
641 (unsigned long) (anl_i + 1), oa->const_valuenames[anl_i]);
642 } /* for anl_i */
643 src = mputprintf(src, "%sunion_selection = %s_%s;\n"
644 "%sfield_%s = new %s;\n"
645 "%sec_2.set_msg(\"%s': \");\n"
646 "%sfield_%s->BER_decode_TLV(%s_descr_, tlv_opentype, L_form);\n",
647 s2, selection_prefix, oa->alt, s2, oa->alt, oa->alt_typename, s2,
648 oa->alt_dispname, s2, oa->alt, oa->alt_typedescrname);
649 } /* for oal_i */
650 Free(s2);
651 if (oal->nElements > 0)
652 for (i = anl->nElements; i > 0; i--)
653 src = mputprintf(src, "%*s}\n", (int)(i+1)*2, "");
654 src = mputprintf(src, " }\n"
655 " if (union_selection == %s) {\n"
656 " ec_0.error(TTCN_EncDec::ET_DEC_OPENTYPE, \"Cannot decode "
657 "open type: broken component relation constraint.\");\n"
658 " if (TTCN_EncDec::get_error_behavior("
659 "TTCN_EncDec::ET_DEC_OPENTYPE) != TTCN_EncDec::EB_IGNORE) {\n"
660 " TTCN_Logger::log_str(TTCN_WARNING, \"The value%s of"
661 " constraining component%s:\");\n", unbound_value,
662 anl->nElements > 1 ? "s" : "", anl->nElements > 1 ? "s" : "");
663 for (anl_i = 0; anl_i < anl->nElements; anl_i++) {
664 AtNotation_t *an = anl->elements + anl_i;
665 src = mputprintf(src,
666 " TTCN_Logger::begin_event(TTCN_WARNING);\n"
667 " TTCN_Logger::log_event_str(\"Component '%s': \");\n"
668 " f_%lu.log();\n"
669 " TTCN_Logger::end_event();\n", an->dispname,
670 (unsigned long) (anl_i + 1));
671 } /* for anl_i */
672 src = mputstr(src, " }\n"
673 " }\n");
674 } /* if oal->nElements>0 */
675 else {
676 src = mputstr(src, " ec_0.error(TTCN_EncDec::ET_DEC_OPENTYPE, "
677 "\"Cannot decode open type: the constraining object set is "
678 "empty.\");\n");
679 } /* oal->nElements==0 */
680 } /* if sdef->ot */
681 else { /* if !sdef->ot (but has_opentypes) */
682 src = mputstr(src,
683 " p_typelist.push(this);\n"
684 " TTCN_EncDec_ErrorContext ec_0(\"Alternative '\");\n"
685 " TTCN_EncDec_ErrorContext ec_1;\n"
686 " switch (union_selection) {\n");
687 for (i = 0; i < sdef->nElements; i++) {
688 src = mputprintf(src, " case %s_%s:\n"
689 " ec_1.set_msg(\"%s': \");\n"
690 " field_%s->BER_decode_opentypes(p_typelist, L_form);\n"
691 " break;\n", selection_prefix, sdef->elements[i].name,
692 sdef->elements[i].dispname, sdef->elements[i].name);
693 } /* for i */
694 src = mputstr(src, " default:\n"
695 " break;\n"
696 " }\n"
697 " p_typelist.pop();\n");
698 } /* if has opentypes */
699 src = mputstr(src, "}\n"
700 "\n");
701 } /* if sdef->ot || sdef->has_opentypes */
702 } /* if ber_needed */
703
704 if (raw_needed) {
705 size_t nTemp_variables = 0;
706 temporal_variable* temp_variable_list = NULL;
707 int* tag_type = (int*) Malloc(sdef->nElements*sizeof(int));
708 memset(tag_type, 0, sdef->nElements * sizeof(int));
709 if (sdef->hasRaw) { /* fill tag_type. 0-No tag, >0 index of the tag + 1 */
710 for (i = 0; i < sdef->raw.taglist.nElements; i++) {
711 if (sdef->raw.taglist.list[i].nElements) {
712 boolean found = FALSE;
713 size_t v;
714 for (v = 0; v < sdef->raw.taglist.list[i].nElements; v++) {
715 if (sdef->raw.taglist.list[i].fields[v].start_pos >= 0) {
716 found = TRUE;
717 break;
718 }
719 }
720 if (found)
721 tag_type[sdef->raw.taglist.list[i].fieldnum] = i + 1;
722 else
723 tag_type[sdef->raw.taglist.list[i].fieldnum] = -i - 1;
724 }
725 }
726 }
727 src = mputprintf(src, "int %s::RAW_decode(\n"
728 "const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, int limit, \n"
729 "raw_order_t top_bit_ord, boolean no_err, int sel_field, boolean)\n"
730 "{\n"
731 " int prepaddlength=p_buf.increase_pos_padd(p_td.raw->prepadding);\n"
732 " limit-=prepaddlength;\n"
733 " int decoded_length=0;\n"
734 " int starting_pos=p_buf.get_pos_bit();\n"
735 " if(sel_field!=-1){\n"
736 " switch(sel_field){\n", name);
737 for (i = 0; i < sdef->nElements; i++) {
738 src = mputprintf(src,
739 " case %lu:\n"
740 " decoded_length = %s().RAW_decode(%s_descr_, p_buf, limit, "
741 "top_bit_ord, no_err);\n"
742 " break;\n", (unsigned long) i, sdef->elements[i].name,
743 sdef->elements[i].typedescrname);
744 }
745 src = mputstr(src, " default: break;\n"
746 " }\n"
747 " return decoded_length + p_buf.increase_pos_padd(p_td.raw->padding) + "
748 "prepaddlength;\n"
749 " } else {\n");
750 /* only generate this variable if it will be used */
751 for (i = 0; i < sdef->nElements; i++) {
752 if ((tag_type[i] > 0)
753 && (sdef->raw.taglist.list + tag_type[i] - 1)->nElements) {
754 src = mputstr(src, " boolean already_failed = FALSE;\n"
755 " raw_order_t local_top_order;\n");
756 break;
757 }
758 }
759
760 /* precalculate what we know about the temporal variables*/
761 for (i = 0; i < sdef->nElements; i++) {
762 if ((tag_type[i] > 0)
763 && (sdef->raw.taglist.list + tag_type[i] - 1)->nElements) {
764 rawAST_coding_taglist* cur_choice = sdef->raw.taglist.list + tag_type[i] - 1;
765 size_t j;
766 for (j = 0; j < cur_choice->nElements; j++) {
767 rawAST_coding_field_list *fieldlist = cur_choice->fields + j;
768 if (fieldlist->start_pos >= 0) {
769 size_t k;
770 boolean found = FALSE;
771 for (k = 0; k < nTemp_variables; k++) {
772 if (temp_variable_list[k].start_pos == fieldlist->start_pos
773 && !strcmp(temp_variable_list[k].typedescr,
774 fieldlist->fields[fieldlist->nElements - 1].typedescr)) {
775 temp_variable_list[k].use_counter++;
776 fieldlist->temporal_variable_index = k;
777 found = TRUE;
778 break;
779 }
780 }
781 if (!found) {
782 temp_variable_list
783 = (temporal_variable*) Realloc(temp_variable_list,
784 (nTemp_variables + 1) * sizeof(*temp_variable_list));
785 temp_variable_list[nTemp_variables].type
786 = fieldlist->fields[fieldlist->nElements - 1].type;
787 temp_variable_list[nTemp_variables].typedescr
788 = fieldlist->fields[fieldlist->nElements - 1].typedescr;
789 temp_variable_list[nTemp_variables].start_pos
790 = fieldlist->start_pos;
791 temp_variable_list[nTemp_variables].use_counter = 1;
792 temp_variable_list[nTemp_variables].decoded_for_element
793 = -1;
794 fieldlist->temporal_variable_index = nTemp_variables;
795 nTemp_variables++;
796 }
797 }
798 }
799 }
800 }
801
802 for (i = 0; i < nTemp_variables; i++) {
803 if (temp_variable_list[i].use_counter > 1) {
804 src = mputprintf(src, " %s temporal_%lu;\n"
805 " int decoded_%lu_length;\n", temp_variable_list[i].type,
806 (unsigned long) i, (unsigned long) i);
807 }
808 }
809
810 for (i = 0; i < sdef->nElements; i++) { /* fields with tag */
811 if ((tag_type[i] > 0)
812 && (sdef->raw.taglist.list + tag_type[i] - 1)->nElements) {
813 rawAST_coding_taglist* cur_choice = sdef->raw.taglist.list
814 + tag_type[i] - 1;
815 size_t j;
816 src = mputstr(src, " already_failed = FALSE;\n");
817 /* first check the fields we can precode
818 * try to decode those key variables whose position we know
819 * this way we might be able to step over bad values faster
820 */
821 for (j = 0; j < cur_choice->nElements; j++) {
822 rawAST_coding_field_list *cur_field_list = cur_choice->fields + j;
823 if (cur_field_list->start_pos >= 0) {
824 size_t k;
825 size_t variable_index = cur_field_list->temporal_variable_index;
826 if (temp_variable_list[variable_index].decoded_for_element == i) continue;
827 src = mputstr(src, " if (!already_failed) {\n");
828 if (temp_variable_list[variable_index].use_counter == 1) {
829 src = mputprintf(src, " %s temporal_%lu;\n"
830 " int decoded_%lu_length;\n",
831 temp_variable_list[variable_index].type,
832 (unsigned long) variable_index, (unsigned long) variable_index);
833 }
834 if (temp_variable_list[variable_index].decoded_for_element
835 == -1) {
836 src = mputstr(src, " ");
837 for (k = cur_field_list->nElements - 1; k > 0; k--) {
838 src = mputprintf(src,
839 " if(%s_descr_.raw->top_bit_order==TOP_BIT_RIGHT)"
840 "local_top_order=ORDER_MSB;\n"
841 " else if(%s_descr_.raw->top_bit_order==TOP_BIT_LEFT)"
842 "local_top_order=ORDER_LSB;\n"
843 " else", cur_field_list->fields[k - 1].typedescr,
844 cur_field_list->fields[k - 1].typedescr);
845 }
846 src = mputprintf(src, " local_top_order=top_bit_ord;\n"
847 " p_buf.set_pos_bit(starting_pos + %d);\n"
848 " decoded_%lu_length = temporal_%lu.RAW_decode("
849 "%s_descr_, p_buf, limit, top_bit_ord, TRUE);\n",
850 cur_field_list->start_pos, (unsigned long) variable_index,
851 (unsigned long) variable_index,
852 temp_variable_list[variable_index].typedescr);
853 }
854 temp_variable_list[variable_index].decoded_for_element = i;
855 src = mputprintf(src, " if (decoded_%lu_length > 0) {\n"
856 " if (temporal_%lu == %s", (unsigned long) variable_index,
857 (unsigned long) variable_index, cur_field_list->value);
858 for (k = j + 1; k < cur_choice->nElements; k++) {
859 if (cur_choice->fields[k].temporal_variable_index
860 == variable_index) {
861 src = mputprintf(src, " || temporal_%lu == %s",
862 (unsigned long) variable_index, cur_choice->fields[k].value);
863 }
864 }
865 src = mputprintf(src, ") {\n"
866 " p_buf.set_pos_bit(starting_pos);\n"
867 " decoded_length = %s().RAW_decode(%s_descr_, p_buf, "
868 "limit, top_bit_ord, TRUE);\n"
869 " if (decoded_length > 0) {\n", sdef->elements[i].name,
870 sdef->elements[i].typedescrname);
871 src = mputstr(src, " if (");
872 src = genRawFieldChecker(src, cur_choice, TRUE);
873 src = mputstr(src, ") {\n"
874 " return decoded_length + "
875 "p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;\n"
876 " }else already_failed = TRUE;\n"
877 " }\n"
878 " }\n"
879 " }\n"
880 " }\n");
881 }
882 }
883 /* if there is one tag key whose position we don't know
884 * and we couldn't decide yet if the element can be decoded or not
885 * than we have to decode it.
886 * note that this is not actually a cycle because of the break
887 */
888 for (j = 0; j < cur_choice->nElements; j++) {
889 if (cur_choice->fields[j].start_pos < 0) {
890 src = mputprintf(src, " if (already_failed) {\n"
891 " p_buf.set_pos_bit(starting_pos);\n"
892 " decoded_length = %s().RAW_decode(%s_descr_, p_buf, limit, "
893 "top_bit_ord, TRUE);\n"
894 " if (decoded_length > 0) {\n", sdef->elements[i].name,
895 sdef->elements[i].typedescrname);
896 src = mputstr(src, " if (");
897 src = genRawFieldChecker(src, cur_choice, TRUE);
898 src = mputstr(src, ") {\n"
899 " return decoded_length + "
900 "p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;\n"
901 " }\n"
902 " }\n"
903 " }\n");
904 break;
905 }
906 }
907 }
908 }
909 Free(temp_variable_list);
910 for (i = 0; i < sdef->nElements; i++) { /* fields with only variable tag */
911 if ((tag_type[i] < 0)
912 && (sdef->raw.taglist.list - tag_type[i] - 1)->nElements) {
913 rawAST_coding_taglist* cur_choice = sdef->raw.taglist.list
914 - tag_type[i] - 1;
915 src = mputprintf(src, " p_buf.set_pos_bit(starting_pos);\n"
916 " decoded_length = %s().RAW_decode(%s_descr_, p_buf, limit, "
917 "top_bit_ord, TRUE);\n"
918 " if (decoded_length >= 0) {\n", sdef->elements[i].name,
919 sdef->elements[i].typedescrname);
920 src = mputstr(src, " if (");
921 src = genRawFieldChecker(src, cur_choice, TRUE);
922 src = mputstr(src, ") {\n"
923 " return decoded_length + "
924 "p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;\n"
925 " }\n"
926 " }\n");
927 }
928 }/**/
929 for (i = 0; i < sdef->nElements; i++) { /* fields without tag */
930 if (!tag_type[i]) {
931 src = mputprintf(src, " p_buf.set_pos_bit(starting_pos);\n"
932 " decoded_length = %s().RAW_decode(%s_descr_, p_buf, limit, "
933 "top_bit_ord, TRUE);\n"
934 " if (decoded_length >= 0) {\n", sdef->elements[i].name,
935 sdef->elements[i].typedescrname);
936 src = mputstr(src, " return decoded_length + "
937 "p_buf.increase_pos_padd(p_td.raw->padding) + prepaddlength;\n"
938 " }\n");
939 }
940 }/**/
941 src = mputstr(src, " }\n"
942 " clean_up();\n"
943 " return -1;\n"
944 "}\n\n");
945 /* encoder */
946 src = mputprintf(src, "int %s::RAW_encode("
947 "const TTCN_Typedescriptor_t&%s, RAW_enc_tree& myleaf) const\n"
948 "{\n", name, use_runtime_2 ? " p_td" : "");
949 if (use_runtime_2) {
950 src = mputstr(src, " if (err_descr) return RAW_encode_negtest(err_descr, p_td, myleaf);\n");
951 }
952 src = mputprintf(src,
953 " int encoded_length = 0;\n"
954 " myleaf.isleaf = FALSE;\n"
955 " myleaf.body.node.num_of_nodes = %lu;"
956 " myleaf.body.node.nodes = init_nodes_of_enc_tree(%lu);\n"
957 " memset(myleaf.body.node.nodes, 0, %lu * sizeof(RAW_enc_tree *));\n"
958 " switch (union_selection) {\n", (unsigned long)sdef->nElements,
959 (unsigned long)sdef->nElements, (unsigned long)sdef->nElements);
960 for (i = 0; i < sdef->nElements; i++) {
961 int t_type = tag_type[i] > 0 ? tag_type[i] : -tag_type[i];
962 src = mputprintf(src, " case %s_%s:\n"
963 " myleaf.body.node.nodes[%lu] = new RAW_enc_tree(TRUE, &myleaf, "
964 "&myleaf.curr_pos, %lu, %s_descr_.raw);\n"
965 " encoded_length = field_%s->RAW_encode(%s_descr_, "
966 "*myleaf.body.node.nodes[%lu]);\n"
967 " myleaf.body.node.nodes[%lu]->coding_descr = &%s_descr_;\n",
968 selection_prefix, sdef->elements[i].name, (unsigned long) i,
969 (unsigned long) i, sdef->elements[i].typedescrname,
970 sdef->elements[i].name, sdef->elements[i].typedescrname,
971 (unsigned long) i, (unsigned long) i, sdef->elements[i].typedescrname);
972 if (t_type && (sdef->raw.taglist.list + t_type - 1)->nElements) {
973 rawAST_coding_taglist* cur_choice = sdef->raw.taglist.list + t_type - 1;
974 src = mputstr(src, " if (");
975 src = genRawFieldChecker(src, cur_choice, FALSE);
976 src = mputstr(src, ") {\n");
977 src = genRawTagChecker(src, cur_choice);
978 src = mputstr(src, " }\n");
979 }
980 src = mputstr(src, " break;\n");
981 }
982 src = mputstr(src, " default:\n"
983 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "
984 "\"Encoding an unbound value.\");\n"
985 " }\n"
986 " return encoded_length;\n"
987 "}\n\n");
988 if (use_runtime_2) {
989 def = mputstr(def, "int RAW_encode_negtest(const Erroneous_descriptor_t *, "
990 "const TTCN_Typedescriptor_t&, RAW_enc_tree&) const;\n");
991 src = mputprintf(src, "int %s::RAW_encode_negtest(const Erroneous_descriptor_t *p_err_descr, "
992 "const TTCN_Typedescriptor_t& /*p_td*/, RAW_enc_tree& myleaf) const\n"
993 "{\n"
994 " const Erroneous_values_t *err_vals = NULL;\n"
995 " const Erroneous_descriptor_t *emb_descr = NULL;\n"
996 " int encoded_length = 0;\n"
997 " myleaf.isleaf = FALSE;\n"
998 " myleaf.body.node.num_of_nodes = %lu;\n"
999 " myleaf.body.node.nodes = init_nodes_of_enc_tree(%lu);\n"
1000 " memset(myleaf.body.node.nodes, 0, %lu * sizeof(RAW_enc_tree *));\n"
1001 " switch (union_selection) {\n", name, (unsigned long)sdef->nElements,
1002 (unsigned long)sdef->nElements, (unsigned long)sdef->nElements);
1003 for (i = 0; i < sdef->nElements; i++) {
1004 int t_type = tag_type[i] > 0 ? tag_type[i] : -tag_type[i];
1005 src = mputprintf(src,
1006 " case %s_%s: {\n",
1007 selection_prefix, sdef->elements[i].name);
1008 if (t_type && (sdef->raw.taglist.list + t_type - 1)->nElements) {
1009 src = mputstr(src, " bool negtest_confl_tag = false;\n");
1010 }
1011 src = mputprintf(src,
1012 " err_vals = p_err_descr->get_field_err_values(%d);\n"
1013 " emb_descr = p_err_descr->get_field_emb_descr(%d);\n"
1014 " if (err_vals && err_vals->value) {\n"
1015 " if (err_vals->value->raw) {\n"
1016 " myleaf.body.node.nodes[%lu] =\n"
1017 " new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, %lu, "
1018 "err_vals->value->errval->get_descriptor()->raw);\n"
1019 " encoded_length = err_vals->value->errval->RAW_encode_negtest_raw(*myleaf.body.node.nodes[%lu]);\n"
1020 " myleaf.body.node.nodes[%lu]->coding_descr = err_vals->value->errval->get_descriptor();\n"
1021 " } else {\n"
1022 " if (err_vals->value->errval) {\n"
1023 " if (err_vals->value->type_descr == NULL)\n"
1024 " TTCN_error(\"internal error: erroneous value typedescriptor missing\");\n"
1025 " myleaf.body.node.nodes[%lu] = new RAW_enc_tree(TRUE, &myleaf, &myleaf.curr_pos, %lu, err_vals->value->type_descr->raw);\n"
1026 " encoded_length = err_vals->value->errval->RAW_encode(*err_vals->value->type_descr, *myleaf.body.node.nodes[%lu]);\n"
1027 " myleaf.body.node.nodes[%lu]->coding_descr = err_vals->value->type_descr;\n"
1028 " }\n"
1029 " }\n",
1030 (int)i, (int)i,
1031 (unsigned long)i, (unsigned long)i,
1032 (unsigned long)i, (unsigned long)i, (unsigned long)i,
1033 (unsigned long)i, (unsigned long)i, (unsigned long)i);
1034 if (t_type && (sdef->raw.taglist.list + t_type - 1)->nElements) {
1035 /* Avoid TAGs. */
1036 src = mputprintf(src, " negtest_confl_tag = true;\n");
1037 }
1038 src = mputprintf(src,
1039 " } else {\n"
1040 " myleaf.body.node.nodes[%lu] = new RAW_enc_tree(TRUE, "
1041 "&myleaf, &myleaf.curr_pos, %lu, %s_descr_.raw);\n"
1042 " if (emb_descr) {\n",
1043 (unsigned long)i, (unsigned long)i, sdef->elements[i].typedescrname);
1044 if (t_type && (sdef->raw.taglist.list + t_type - 1)->nElements) {
1045 /* Avoid TAGs. */
1046 src = mputprintf(src, " negtest_confl_tag = true;\n");
1047 }
1048 src = mputprintf(src,
1049 " encoded_length = field_%s->RAW_encode_negtest(emb_descr, %s_descr_, *myleaf.body.node.nodes[%lu]);\n"
1050 " } else encoded_length = field_%s->RAW_encode(%s_descr_, *myleaf.body.node.nodes[%lu]);\n"
1051 " myleaf.body.node.nodes[%lu]->coding_descr = &%s_descr_;\n"
1052 " }\n",
1053 sdef->elements[i].name, sdef->elements[i].typedescrname,
1054 (unsigned long)i, sdef->elements[i].name,
1055 sdef->elements[i].typedescrname, (unsigned long)i, (unsigned long)i,
1056 sdef->elements[i].typedescrname);
1057 if (t_type && (sdef->raw.taglist.list + t_type - 1)->nElements) {
1058 rawAST_coding_taglist *cur_choice = sdef->raw.taglist.list + t_type - 1;
1059 src = mputprintf(src,
1060 " if (negtest_confl_tag) {\n"
1061 " TTCN_EncDec_ErrorContext e_c;\n"
1062 " e_c.set_msg(\"Field '%s': \");\n"
1063 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_NEGTEST_CONFL,\n"
1064 " \"Conflicting negative testing attributes, TAG attribute "
1065 "will be ignored\");\n"
1066 " }\n"
1067 " if (!negtest_confl_tag && (", sdef->elements[i].name);
1068 src = genRawFieldChecker(src, cur_choice, FALSE);
1069 src = mputstr(src, ")) {\n");
1070 src = genRawTagChecker(src, cur_choice);
1071 src = mputstr(src, " }\n");
1072 }
1073 src = mputstr(src, " break; }\n");
1074 }
1075 src = mputstr(src, " default:\n"
1076 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "
1077 "\"Encoding an unbound value.\");\n"
1078 " }\n"
1079 " return encoded_length;\n"
1080 "}\n\n");
1081 }
1082 Free(tag_type);
1083 } /* if raw_needed */
1084
1085 if (text_needed) {
1086 src = mputprintf(src, "int %s::TEXT_encode("
1087 "const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const\n"
1088 "{\n", name);
1089 if (use_runtime_2) {
1090 src = mputstr(src, " if (err_descr) return TEXT_encode_negtest(err_descr, p_td, p_buf);\n");
1091 }
1092 src = mputstr(src, " int encoded_length=0;\n"
1093 " if (p_td.text->begin_encode) {\n"
1094 " p_buf.put_cs(*p_td.text->begin_encode);\n"
1095 " encoded_length += p_td.text->begin_encode->lengthof();\n"
1096 " }\n"
1097 " switch(union_selection){\n");
1098 for (i = 0; i < sdef->nElements; i++) {
1099 src = mputprintf(src, " case %s_%s:\n"
1100 " encoded_length += field_%s->TEXT_encode(%s_descr_,p_buf);\n"
1101 " break;\n", selection_prefix, sdef->elements[i].name,
1102 sdef->elements[i].name, sdef->elements[i].typedescrname);
1103 }
1104 src = mputstr(src, " default:\n"
1105 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "
1106 "\"Encoding an unbound value.\");\n"
1107 " break;\n"
1108 " }\n"
1109 " if (p_td.text->end_encode) {\n"
1110 " p_buf.put_cs(*p_td.text->end_encode);\n"
1111 " encoded_length += p_td.text->end_encode->lengthof();\n"
1112 " }\n"
1113 " return encoded_length;\n"
1114 "}\n\n");
1115 if (use_runtime_2) {/*TEXT_encde_negtest()*/
1116 def = mputstr(def,
1117 "int TEXT_encode_negtest(const Erroneous_descriptor_t* p_err_descr, const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const;\n");
1118 src = mputprintf(src, "int %s::TEXT_encode_negtest("
1119 "const Erroneous_descriptor_t* p_err_descr, const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const\n"
1120 "{\n"
1121 " int encoded_length=0;\n"
1122 " const Erroneous_values_t* err_vals = NULL;\n"
1123 " const Erroneous_descriptor_t* emb_descr = NULL;\n"
1124 " if (p_td.text->begin_encode) {\n"
1125 " p_buf.put_cs(*p_td.text->begin_encode);\n"
1126 " encoded_length += p_td.text->begin_encode->lengthof();\n"
1127 " }\n"
1128 " switch(union_selection){\n", name);
1129 for (i = 0; i < sdef->nElements; i++) {
1130 src = mputprintf(src, " case %s_%s:\n"
1131 " err_vals = p_err_descr->get_field_err_values(%d);\n"
1132 " emb_descr = p_err_descr->get_field_emb_descr(%d);\n"
1133 " if (err_vals && err_vals->value){\n"
1134 " if (err_vals->value->errval) {\n"
1135 " if(err_vals->value->raw){\n"
1136 " encoded_length += err_vals->value->errval->encode_raw(p_buf);\n"
1137 " }else{\n"
1138 " if (err_vals->value->type_descr==NULL) TTCN_error(\"internal error: erroneous value typedescriptor missing\");\n"
1139 " encoded_length += err_vals->value->errval->TEXT_encode(*err_vals->value->type_descr,p_buf);\n"
1140 " }\n"
1141 " }\n"
1142 " }else{\n"
1143 " if (emb_descr) encoded_length += field_%s->TEXT_encode_negtest(emb_descr,%s_descr_,p_buf);\n"
1144 " else field_%s->TEXT_encode(%s_descr_,p_buf);\n"
1145 " }\n"
1146 " break;\n", selection_prefix, sdef->elements[i].name,(int)i,(int)i,
1147 sdef->elements[i].name, sdef->elements[i].typedescrname, sdef->elements[i].name, sdef->elements[i].typedescrname);
1148 }
1149 src = mputstr(src, " default:\n"
1150 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, "
1151 "\"Encoding an unbound value.\");\n"
1152 " break;\n"
1153 " }\n"
1154 " if (p_td.text->end_encode) {\n"
1155 " p_buf.put_cs(*p_td.text->end_encode);\n"
1156 " encoded_length += p_td.text->end_encode->lengthof();\n"
1157 " }\n"
1158 " return encoded_length;\n"
1159 "}\n\n");
1160 }
1161
1162 src = mputprintf(src, "int %s::TEXT_decode("
1163 "const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, "
1164 "Limit_Token_List& limit, boolean no_err, boolean)\n"
1165 "{\n"
1166 " int decoded_length = 0;\n"
1167 " if(p_td.text->begin_decode){\n"
1168 " int tl = p_td.text->begin_decode->match_begin(p_buf);\n"
1169 " if (tl >= 0) {\n"
1170 " decoded_length += tl;\n"
1171 " p_buf.increase_pos(tl);\n"
1172 " } else {\n"
1173 " if (no_err) return -1;\n"
1174 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR, "
1175 "\"The specified token '%%s' not found for '%%s': \", "
1176 "(const char*)(*p_td.text->begin_decode), p_td.name);\n"
1177 " return 0;\n"
1178 " }\n"
1179 " }\n"
1180 " if (p_buf.get_read_len() < 1 && no_err) return -1;\n"
1181 "%s"
1182 " int ml = 0;\n"
1183 " boolean found = FALSE;\n"
1184 " if (p_td.text->end_decode) {\n"
1185 " limit.add_token(p_td.text->end_decode);\n"
1186 " ml++;\n"
1187 " }\n", name, sdef->nElements > 1 ? " size_t pos = p_buf.get_pos();\n" : "");
1188 if (sdef->nElements > 0) {
1189 src = mputprintf(src,
1190 " int str_len = %s().TEXT_decode(%s_descr_, p_buf, limit, true);\n"
1191 " if (str_len >= 0) found = TRUE;\n", sdef->elements[0].name,
1192 sdef->elements[0].typedescrname);
1193 }
1194 for (i = 1; i < sdef->nElements; i++) {
1195 src = mputprintf(src, " if (!found) {\n"
1196 " p_buf.set_pos(pos);\n"
1197 " str_len = %s().TEXT_decode(%s_descr_, p_buf, limit, true);\n"
1198 " if (str_len >= 0) found = TRUE;\n"
1199 " }\n", sdef->elements[i].name, sdef->elements[i].typedescrname);
1200 }
1201 src = mputstr(src, " limit.remove_tokens(ml);\n"
1202 " if (found) {\n"
1203 " decoded_length += str_len;\n"
1204 " if (p_td.text->end_decode) {\n"
1205 " int tl = p_td.text->end_decode->match_begin(p_buf);\n"
1206 " if (tl >= 0){\n"
1207 " decoded_length += tl;\n"
1208 " p_buf.increase_pos(tl);\n"
1209 " } else {\n"
1210 " if (no_err) return -1;\n"
1211 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR, "
1212 "\"The specified token '%s' not found for '%s': \", "
1213 "(const char*)(*p_td.text->end_decode), p_td.name);\n"
1214 " }\n"
1215 " }\n"
1216 " } else {\n"
1217 " if (no_err) return -1;\n"
1218 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TOKEN_ERR, "
1219 "\"No union member found for '%s': \", p_td.name);\n"
1220 " clean_up();\n"
1221 " }\n"
1222 " return decoded_length;\n"
1223 "}\n");
1224 }
1225
1226 if (xer_needed) { /* XERSTUFF encoder functions for union */
1227 def = mputstr(def,
1228 "char **collect_ns(const XERdescriptor_t& p_td, size_t& num, bool& def_ns) const;\n");
1229
1230 src=mputprintf(src,
1231 "boolean %s::can_start(const char *name, const char *uri,"
1232 " const XERdescriptor_t& xd, unsigned int flavor) {\n"
1233 " boolean exer = is_exer(flavor);\n"
1234 " if (!exer || (!(xd.xer_bits & UNTAGGED) && !(flavor & (USE_NIL|(exer ? XER_LIST : XER_RECOF))))) "
1235 /* If the union has no own tag, there is nothing to check. */
1236 "return check_name(name, xd, exer)" /* if false, return immediately */
1237 " && (!exer || (flavor & USE_TYPE_ATTR) || check_namespace(uri, xd));\n"
1238 /* else check the ns, unless Basic XER (which has no namespaces, ever)
1239 * or USE_TYPE (where we only have a name from the type id attribute) */
1240 , name
1241 );
1242 src = mputstr(src, " flavor &= ~XER_RECOF;\n");
1243
1244 /* An untagged union can start with the start tag of any alternative */
1245 for (i = 0; i < sdef->nElements; i++) {
1246 src=mputprintf(src,
1247 " if (%s::can_start(name, uri, %s_xer_, flavor)) return true;\n"
1248 , sdef->elements[i].type, sdef->elements[i].typegen
1249 );
1250 }
1251 src = mputstr(src, " return false;\n}\n\n");
1252
1253 src = mputprintf(src,
1254 "char ** %s::collect_ns(const XERdescriptor_t& p_td, size_t& num, bool& def_ns) const {\n"
1255 " size_t num_collected;\n"
1256 " char **collected_ns = Base_Type::collect_ns(p_td, num_collected, def_ns);\n"
1257 /* Two-level new memory allocated */
1258 " char **new_ns;\n"
1259 " size_t num_new;\n"
1260 " boolean need_type = FALSE;\n"
1261 " try {\n"
1262 " bool def_ns_1 = false;\n"
1263 " switch (union_selection) {\n"
1264 , name
1265 );
1266 for (i = 0; i < sdef->nElements; i++) {
1267 src = mputprintf(src,
1268 " case %s_%s:\n"
1269 " new_ns = field_%s->collect_ns(%s_xer_, num_new, def_ns_1);\n"
1270 " def_ns = def_ns || def_ns_1;\n" /* alas, no ||= */
1271 " merge_ns(collected_ns, num_collected, new_ns, num_new);\n"
1272 /* merge_ns() deallocated new_ns and duplicated strings,
1273 * copied the new ones into the expanded new_ns */
1274 , selection_prefix, sdef->elements[i].name
1275 , sdef->elements[i].name
1276 , sdef->elements[i].typegen
1277 );
1278 /* Type id attribute not needed for the first field in case of USE-TYPE */
1279 if (sdef->xerUseUnion || i > 0) src = mputprintf(src,
1280 " need_type = (%s_xer_.namelens[1] > 2);\n"
1281 , sdef->elements[i].typegen);
1282 src = mputstr(src, " break;\n");
1283 }
1284
1285 src = mputstr(src,
1286 " default: break;\n"
1287 " }\n" /* switch */
1288 " if ((p_td.xer_bits & USE_TYPE_ATTR) && !(p_td.xer_bits & XER_ATTRIBUTE) && need_type) {\n"
1289 /* control ns for type attribute */
1290 " collected_ns = (char**)Realloc(collected_ns, sizeof(char*) * ++num_collected);\n"
1291 " const namespace_t *c_ns = p_td.my_module->get_controlns();\n"
1292 " collected_ns[num_collected-1] = mprintf(\" xmlns:%s='%s'\", c_ns->px, c_ns->ns);\n"
1293 " }\n"
1294 " }\n"
1295 " catch (...) {\n"
1296 /* Probably a TC_Error thrown from field_%s->collect_ns() if e.g.
1297 * encoding an unbound value. */
1298 " while (num_collected > 0) Free(collected_ns[--num_collected]);\n"
1299 " Free(collected_ns);\n"
1300 " throw;\n"
1301 " }\n"
1302 " num = num_collected;\n"
1303 " return collected_ns;\n"
1304 "}\n\n"
1305 );
1306
1307 src = mputprintf(src, /* XERSTUFF XER_encode for union */
1308 "int %s::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, "
af710487 1309 "unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const\n"
970ed795
EL
1310 "{\n"
1311 "%s"
1312 " if (%s==union_selection) {\n"
1313 " TTCN_error(\"Attempt to XER-encode an unbound union value.\");\n"
1314 " return 0;\n"
1315 " }\n"
1316 " TTCN_EncDec_ErrorContext ec_0(\"Alternative '\");\n"
1317 " TTCN_EncDec_ErrorContext ec_1;\n"
1318 " int encoded_length=(int)p_buf.get_len();\n"
1319 , name
1320 , (use_runtime_2 ? " if (err_descr) return XER_encode_negtest"
af710487 1321 "(err_descr, p_td, p_buf, p_flavor, p_indent, 0);\n" : "")
970ed795
EL
1322 , unbound_value
1323 );
1324
1325 if (sdef->xerUseTypeAttr) {
1326 src = mputstr(src,
1327 " const boolean e_xer = is_exer(p_flavor);\n"
1328 " char *type_atr = NULL;\n"
1329 " unsigned short name_len = 0;\n"
1330 " if (e_xer && (p_td.xer_bits & USE_TYPE_ATTR)) {\n"
1331 " const char *type_name = 0;\n"
1332 " const namespace_t *control_ns;\n"
1333 " switch (union_selection) {\n");
1334 /* In case of USE-TYPE the first field won't need the type attribute */
1335 int start_at = sdef->xerUseUnion ? 0 : 1;
1336 for (i = start_at; i < sdef->nElements; i++) {
1337 src = mputprintf(src,
1338 " case %s_%s:\n"
1339 " type_name = %s_xer_.names[1];\n"
1340 " name_len = %s_xer_.namelens[1] - 2;\n"
1341 " %s\n"
1342 , selection_prefix, sdef->elements[i].name
1343 , sdef->elements[i].typegen
1344 , sdef->elements[i].typegen
1345 , i < sdef->nElements - 1 ? "goto write_atr;" : "" /* no break */
1346 );
1347 }
1348 src = mputprintf(src,
1349 "%s" /* label only if more than two elements total */
1350 " if (name_len > 0) {\n" /* 38.3.8, no atr if NAME AS "" */
1351 " control_ns = p_td.my_module->get_controlns();\n"
1352 " type_atr = mcopystr(\" \");\n"
1353 " type_atr = mputstr (type_atr, control_ns->px);\n"
1354 " type_atr = mputstr (type_atr, \":type='\");\n"
1355 " type_atr = mputstrn(type_atr, type_name, name_len);\n"
1356 " type_atr = mputc (type_atr, '\\'');\n"
1357 " }\n"
1358 " break;\n"
1359 " default: break;\n"
1360 " }\n" /* switch */
1361 " p_flavor &= ~XER_RECOF;\n"
1362 " }\n" /* if e_xer */
1363 , (sdef->nElements > start_at + 1 ? "write_atr:\n" : "")
1364
1365
1366 );
1367 } /* if UseTypeAttr */
1368 src = mputprintf(src,
1369 " unsigned int flavor_1 = p_flavor;\n"
1370 " if (is_exer(p_flavor)) flavor_1 &= ~XER_RECOF;\n"
1371 " bool omit_tag = begin_xml(p_td, p_buf, flavor_1, p_indent, false, "
1372 "(collector_fn)&%s::collect_ns%s);\n"
1373 , sdef->name
1374 , sdef->xerUseTypeAttr ? ", type_atr" : "");
1375 src = mputprintf(src,
1376 " unsigned int flavor_0 = (p_flavor & XER_MASK)%s;\n"
1377 " switch (union_selection) {\n"
1378 , sdef->xerUseTypeAttr ? " | USE_TYPE_ATTR" : "");
1379 for (i = 0; i < sdef->nElements; i++) {
1380 src = mputprintf(src, " case %s_%s:\n"
1381 " ec_1.set_msg(\"%s': \");\n"
1382 " field_%s->XER_encode(%s_xer_, p_buf, flavor_0, "
af710487 1383 "p_indent + (!p_indent || !omit_tag), 0);\n"
970ed795
EL
1384 " break;\n",
1385 selection_prefix, sdef->elements[i].name,
1386 sdef->elements[i].dispname,
1387 sdef->elements[i].name, sdef->elements[i].typegen);
1388 }
1389 src = mputprintf(src, " case %s:\n"
1390 " (void)flavor_0;\n" /* warning reduction for empty union */
1391 " break;\n"
1392 " } //switch\n"
1393 , unbound_value);
1394 if (sdef->xerUseTypeAttr) {
1395 src = mputstr(src, " if (p_buf.get_data()[p_buf.get_len()-1] != '\\n') flavor_1 |= SIMPLE_TYPE;\n");
1396 }
1397 src = mputstr(src,
1398 " end_xml(p_td, p_buf, flavor_1, p_indent, 0);\n"
1399 " return (int)p_buf.get_len() - encoded_length;\n"
1400 "}\n\n");
1401
1402 if (use_runtime_2) {
1403 def = mputstr(def,
1404 "int XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr, "
1405 "const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, "
af710487 1406 "unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const;\n");
970ed795
EL
1407 src = mputprintf(src, /* XERSTUFF XER_encode for union */
1408 "int %s::XER_encode_negtest(const Erroneous_descriptor_t* p_err_descr, "
1409 "const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, "
af710487 1410 "unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const\n"
970ed795
EL
1411 "{\n"
1412 " if (%s==union_selection) {\n"
1413 " TTCN_error(\"Attempt to XER-encode an unbound union value.\");\n"
1414 " return 0;\n"
1415 " }\n"
1416 " TTCN_EncDec_ErrorContext ec_0(\"Alternative '\");\n"
1417 " TTCN_EncDec_ErrorContext ec_1;\n"
1418 " int encoded_length=(int)p_buf.get_len();\n"
1419 , name
1420 , unbound_value
1421 );
1422 if (sdef->xerUseTypeAttr) {
1423 src = mputstr(src,
1424 " const boolean e_xer = is_exer(p_flavor);\n"
1425 " char *type_atr = NULL;\n"
1426 " unsigned short name_len = 0;\n"
1427 " if (e_xer && (p_td.xer_bits & USE_TYPE_ATTR)) {\n"
1428 " const char *type_name = 0;\n"
1429 " const namespace_t *control_ns;\n"
1430 " switch (union_selection) {\n");
1431 int start_at = sdef->xerUseUnion ? 0 : 1;
1432 for (i = start_at; i < sdef->nElements; i++) {
1433 src = mputprintf(src,
1434 " case %s_%s:\n"
1435 " type_name = %s_xer_.names[1];\n"
1436 " name_len = %s_xer_.namelens[1] - 2;\n"
1437 " %s\n"
1438 , selection_prefix, sdef->elements[i].name
1439 , sdef->elements[i].typegen
1440 , sdef->elements[i].typegen
1441 , i < sdef->nElements - 1 ? "goto write_atr;" : "" /* no break */
1442 );
1443 }
1444 src = mputprintf(src,
1445 "%s" /* label only if more than two elements total */
1446 " if (name_len > 0) {\n" /* 38.3.8, no atr if NAME AS "" */
1447 " control_ns = p_td.my_module->get_controlns();\n"
1448 " type_atr = mcopystr(\" \");\n"
1449 " type_atr = mputstr (type_atr, control_ns->px);\n"
1450 " type_atr = mputstr (type_atr, \":type='\");\n"
1451 " type_atr = mputstrn(type_atr, type_name, name_len);\n"
1452 " type_atr = mputc (type_atr, '\\'');\n"
1453 " }\n"
1454 " break;\n"
1455 " default: break;\n"
1456 " }\n" /* switch */
1457 " p_flavor &= ~XER_RECOF;\n"
1458 " }\n" /* if e_xer */
1459 , (sdef->nElements > start_at + 1 ? "write_atr:\n" : "")
1460 );
1461 } /* if UseTypeAttr */
1462
1463 src = mputprintf(src,
1464 " bool omit_tag = begin_xml(p_td, p_buf, p_flavor, p_indent, false, "
1465 "(collector_fn)&%s::collect_ns%s);\n"
1466 , sdef->name
1467 , sdef->xerUseTypeAttr ? ", type_atr" : "");
1468 /* begin_xml will Free type_atr */
1469 src = mputprintf(src,
1470 " unsigned int flavor_0 = (p_flavor & XER_MASK)%s;\n"
1471 " const Erroneous_values_t* err_vals = NULL;\n"
1472 " const Erroneous_descriptor_t* emb_descr = NULL;\n"
1473 " switch (union_selection) {\n"
1474 , sdef->xerUseTypeAttr ? " | USE_TYPE_ATTR" : "");
1475 for (i = 0; i < sdef->nElements; i++) {
1476 src = mputprintf(src, " case %s_%s:\n"
1477 " err_vals = p_err_descr->get_field_err_values(%lu);\n"
1478 " emb_descr = p_err_descr->get_field_emb_descr(%lu);\n"
1479 " if (err_vals && err_vals->value) {\n"
1480 " if (err_vals->value->errval) {\n"
1481 " ec_1.set_msg(\"%s'(erroneous value): \");\n"
1482 " if (err_vals->value->raw) {\n"
1483 " err_vals->value->errval->encode_raw(p_buf);\n"
1484 " } else {\n"
1485 " if (err_vals->value->type_descr==NULL) TTCN_error"
1486 "(\"internal error: erroneous value typedescriptor missing\");\n"
1487 " else err_vals->value->errval->XER_encode("
1488 "*err_vals->value->type_descr->xer, p_buf, flavor_0, "
af710487 1489 "p_indent + (!p_indent || !omit_tag), 0);\n"
970ed795
EL
1490 " }\n"
1491 " }\n"
1492 " } else {\n"
1493 " ec_1.set_msg(\"%s': \");\n"
1494 " if (emb_descr) field_%s->XER_encode_negtest(emb_descr, "
af710487 1495 "%s_xer_, p_buf, flavor_0, p_indent + (!p_indent || !omit_tag), 0);\n"
970ed795 1496 " else field_%s->XER_encode(%s_xer_, p_buf, flavor_0, "
af710487 1497 "p_indent + (!p_indent || !omit_tag), 0);\n"
970ed795
EL
1498 " }\n"
1499 " break;\n",
1500 selection_prefix, sdef->elements[i].name, /* case label */
1501 (unsigned long)i, (unsigned long)i,
1502 sdef->elements[i].dispname, /* set_msg (erroneous) */
1503 sdef->elements[i].dispname, /* set_msg */
1504 sdef->elements[i].name, sdef->elements[i].typegen,
1505 sdef->elements[i].name, sdef->elements[i].typegen /* field_%s, %s_descr */
1506 );
1507 }
1508 src = mputprintf(src, " case %s:\n"
1509 " (void)flavor_0;\n" /* warning reduction for empty union */
1510 " break;\n"
1511 " } //switch\n"
1512 " end_xml(p_td, p_buf, p_flavor, p_indent, 0);\n"
1513 " return (int)p_buf.get_len() - encoded_length;\n"
1514 "}\n\n"
1515 , unbound_value);
1516 }
1517
1518#ifndef NDEBUG
1519 src = mputprintf(src, "// %s has%s%s%s%s%s%s%s%s%s\n"
1520 "// written by %s in " __FILE__ " at %d\n"
1521 , name
1522 , (sdef->xerUntagged ? " UNTAGGED" : "")
1523 , (sdef->xerUntaggedOne ? "1" : "")
1524 , (sdef->xerUseNilPossible ? " USE_NIL?" : "")
1525 , (sdef->xerUseOrderPossible ? " USE_ORDER?" : "")
1526 , (sdef->xerUseQName ? " USE_QNAME" : "")
1527 , (sdef->xerUseTypeAttr ? " USE_TYPE_ATTR" : "")
1528 , (sdef->xerUseUnion ? " USE-UNION" : "")
1529 , (sdef->xerHasNamespaces ? " namespace" : "")
1530 , (sdef->xerEmbedValuesPossible ? " EMBED?" : "")
1531 , __FUNCTION__, __LINE__
1532 );
1533#endif
1534 src = mputprintf(src, /* XERSTUFF decoder functions for union */
1535 "int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader,"
af710487 1536 " unsigned int p_flavor, embed_values_dec_struct_t*)\n"
970ed795
EL
1537 "{\n"
1538 " int e_xer = is_exer(p_flavor);\n"
1539 " int type = 0;\n" /* None */
1540 " int rd_ok=1, xml_depth=-1;\n"
1541 "%s%s"
1542 " int xerbits = p_td.xer_bits;\n"
1543 " if (p_flavor & XER_TOPLEVEL) xerbits &= ~UNTAGGED;\n"
1544 " if (xerbits & USE_TYPE_ATTR) p_flavor &= ~XER_RECOF;\n"
1545 " boolean own_tag = !(e_xer && ((xerbits & (ANY_ELEMENT | UNTAGGED)) "
1546 "|| (p_flavor & (USE_NIL|(e_xer ? XER_LIST : XER_RECOF)))));\n"
1547 " if ((e_xer || !is_record_of(p_flavor)) && own_tag)\n"
1548 /* Loop until the start tag */
1549 " %sfor (rd_ok = p_reader.Ok(); rd_ok == 1; rd_ok = p_reader.Read()) {\n"
1550 " type = p_reader.NodeType();\n"
1551 " if (type == XML_READER_TYPE_ELEMENT) {\n"
1552 " verify_name(p_reader, p_td, e_xer);\n"
1553 " xml_depth = p_reader.Depth();\n"
1554 , name
1555 , sdef->xerUseTypeAttr ? " char * typeatr = 0;\n" : ""
1556 , sdef->xerUseUnion ? " boolean attribute = (p_td.xer_bits & XER_ATTRIBUTE) ? true : false;\n" : ""
1557 , sdef->xerUseUnion ? "if (!attribute) " : ""
1558 );
1559 if (sdef->xerUseTypeAttr) {
1560 src = mputprintf(src,
1561 " int other_attributes = 0;\n"
1562 " if (e_xer) {\n"
1563 " for (rd_ok = p_reader.MoveToFirstAttribute(); rd_ok == 1;"
1564 " rd_ok = p_reader.MoveToNextAttribute()) {\n"
1565 " if (p_reader.IsNamespaceDecl()) continue;\n"
1566 " const char *attr_name = (const char*)p_reader.Name();\n"
1567 " if (!strcmp(attr_name, \"%s:type\"))\n"
1568 " {\n"
1569 " typeatr = mcopystr((const char*)p_reader.Value());\n"
1570 " }\n"
1571 " else ++other_attributes;\n"
1572 " }\n" /* for */
1573 " rd_ok = p_reader.MoveToElement() | 1;\n"
1574 , sdef->control_ns_prefix);
1575 if (!sdef->xerUseUnion) {
1576 /* USE-TYPE: No type attribute means the first alternative */
1577 src = mputprintf(src,
1578 " if (typeatr == NULL) {\n"
1579 " typeatr = mcopystr(%s_xer_.names[1]);\n"
1580 " typeatr = mtruncstr(typeatr, %s_xer_.namelens[1] - 2);\n"
1581 " }\n"
1582 , sdef->elements[0].typegen
1583 , sdef->elements[0].typegen);
1584 }
1585 src = mputstr(src,
1586 " }\n" /* if exer */);
1587 }
1588
1589 src = mputprintf(src,
1590 " if (!(e_xer && (p_td.xer_bits & USE_TYPE_ATTR)%s)\n"
1591 " && !p_reader.IsEmptyElement()) rd_ok = p_reader.Read();\n"
1592 " break;\n"
1593 " }\n"
1594 " }\n"
1595 " unsigned int flavor_1 = (p_flavor & XER_MASK);\n" /* also, not toplevel */
1596 /* Loop until the content. Normally an element, unless UNTAGGED
1597 * USE-UNION or some other shenanigans. */
1598 " %s%sfor (rd_ok = p_reader.Ok(); rd_ok == 1; rd_ok = p_reader.Read()) {\n"
1599 " type = p_reader.NodeType();\n"
1600 " %sif (type == XML_READER_TYPE_ELEMENT) break;\n"
1601 " else if (type == XML_READER_TYPE_END_ELEMENT) break;\n"
1602 " }\n"
1603 " if (rd_ok) {\n"
1604 " TTCN_EncDec_ErrorContext ec_1(\"Alternative '\");\n"
1605 " TTCN_EncDec_ErrorContext ec_2;\n"
1606 " const char *elem_name;\n"
1607 " const char *ns_uri = 0;\n"
1608 , sdef->xerUseTypeAttr ? " && other_attributes > 0" : ""
1609 , sdef->xerUseTypeAttr ? "if (!e_xer) " : ""
1610 , sdef->xerUseUnion ? "if (!attribute) " : ""
1611 , sdef->xerUseTypeAttr ?
1612 "if (e_xer) { if (type == XML_READER_TYPE_TEXT) break; }\n"
1613 " else " : ""
1614 );
1615
1616 if (sdef->xerUseTypeAttr) {
1617 src = mputstr(src,
1618 " if (e_xer) {\n" /* USE-TYPE => no XML element, use typeatr */
1619 " elem_name = typeatr;\n"
1620 " flavor_1 |= USE_TYPE_ATTR;\n"
1621 " }\n"
1622 " else" /* no newline, gobbles up the next {} */);
1623 }
1624 src = mputstr(src,
1625 " {\n"
1626 " elem_name = (const char*)p_reader.LocalName();\n"
1627 " ns_uri = (const char*)p_reader.NamespaceUri();\n"
1628 " }\n");
1629
1630 if (sdef->xerUseUnion) {
1631 src = mputstr(src,
1632 " int matched = -1;\n"
1633 " if (typeatr == NULL) flavor_1 |= EXIT_ON_ERROR;\n"
1634 " for (;;) {\n");
1635 /* TODO unify the two alternatives */
1636 for (i = 0; i < sdef->nElements; i++) {
1637 src = mputprintf(src,
1638 /* If decoding EXER, there is no tag to apply check_name
1639 *
1640 */
1641 " if ((e_xer && (typeatr == NULL || !(p_td.xer_bits & USE_TYPE_ATTR))) "
1642 "|| can_start(elem_name, ns_uri, %s_xer_, flavor_1)) {\n"
1643 " ec_2.set_msg(\"%s': \");\n"
1644 " if (%s==union_selection) {\n"
1645 " matched = %d;\n"
af710487 1646 " %s().XER_decode(%s_xer_, p_reader, flavor_1, 0);\n"
970ed795
EL
1647 " }\n"
1648 " if (field_%s->is_bound()) break; else clean_up();\n"
1649 " }\n",
1650 sdef->elements[i].typegen,
1651 sdef->elements[i].dispname,
1652 unbound_value, (int)i,
1653 sdef->elements[i].name, sdef->elements[i].typegen,
1654 sdef->elements[i].name);
1655 }
1656 src = mputstr(src,
1657 " if (typeatr == NULL) {\n"
1658 /* No type attribute found and none of the fields managed to decode the value (USE-UNION only) */
1659 " ec_1.set_msg(\" \");\n"
1660 " ec_2.set_msg(\" \");\n"
1661 " const char* value = (const char*)p_reader.Value();\n"
1662 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n"
1663 " \"'%s' could not be decoded by any of the union's fields.\", value);\n"
1664 " } else if (matched >= 0) {\n"
1665 /* Alternative found, but it couldn't be decoded */
1666 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n"
1667 " \"Failed to decode field.\");\n"
1668 " } else {\n"
1669 /* Type attribute found, but it didn't match any of the fields */
1670 " ec_1.set_msg(\" \");\n"
1671 " ec_2.set_msg(\" \");\n"
1672 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,\n"
1673 " \"'%s' does not match any alternative.\", elem_name);\n"
1674 " }\n"
1675 " if (xml_depth >= 0) for (; rd_ok == 1 "
1676 "&& p_reader.Depth() > xml_depth; rd_ok = p_reader.Read()) ;\n"
1677 " break;\n"
1678 " }\n"); /* for ever */
1679 }
1680 else /* not USE-UNION */
1681 {
1682 if (sdef->exerMaybeEmptyIndex >= 0) {
1683 /* There is a field which can be empty XML. Add code to detect this
1684 * and jump to the appropriate field which can decode "nothing". */
1685 src = mputstr(src,
1686 " if (type!=XML_READER_TYPE_ELEMENT || "
1687 "(own_tag && p_reader.IsEmptyElement())) goto empty_xml;\n");
1688 /* If the choice itself is untagged, then an empty element belongs to
1689 * one of the fields and does not mean that the choice is empty */
1690 }
1691 /* FIXME some hashing should be implemented */
1692 /* The field which can be empty should be checked last, otherwise we create an infinity loop with memory bomb.
1693 * So move that field to the last elseif branch*/
1694 for (i = 0; i < sdef->nElements; i++) {
1695 if(sdef->exerMaybeEmptyIndex != i){
1696 src = mputprintf(src,
1697 " %sif (%s::can_start(elem_name, ns_uri, %s_xer_, flavor_1) || (%s_xer_.xer_bits & ANY_ELEMENT)) {\n"
1698 " ec_2.set_msg(\"%s': \");\n"
af710487 1699 " %s%s().XER_decode(%s_xer_, p_reader, flavor_1, 0);\n"
970ed795
EL
1700 " if (!%s%s().is_bound()) {\n"
1701 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, \"Failed to decode field.\");\n"
1702 " }\n"
1703 " }\n",
1704 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*/
1705 sdef->elements[i].type, sdef->elements[i].typegen, sdef->elements[i].typegen,
1706 sdef->elements[i].dispname,
1707 at_field, sdef->elements[i].name, sdef->elements[i].typegen,
1708 at_field, sdef->elements[i].name);
1709 }
1710 }
1711 if(sdef->exerMaybeEmptyIndex>=0 ){
1712 i=sdef->exerMaybeEmptyIndex;
1713 src = mputprintf(src,
1714 " %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"
1715 "empty_xml: ec_2.set_msg(\"%s': \");\n"
af710487 1716 " %s%s().XER_decode(%s_xer_, p_reader, flavor_1, 0);\n"
970ed795
EL
1717 " if (!%s%s().is_bound()) {\n"
1718 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, \"Failed to decode field.\");\n"
1719 " }\n"
1720 " }\n",
1721 sdef->nElements>0 ? "else " : "",
1722 sdef->elements[i].type, sdef->elements[i].typegen, sdef->elements[i].typegen,
1723 sdef->elements[i].dispname,
1724 at_field, sdef->elements[i].name, sdef->elements[i].typegen,
1725 at_field, sdef->elements[i].name);
1726 }
1727 src = mputstr(src,
1728 " else {\n"
1729 " ec_1.set_msg(\" \");\n"
1730 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG, "
1731 "\"'%s' does not match any alternative\", elem_name);\n"
1732 " if (xml_depth >= 0) for (; rd_ok == 1 "
1733 "&& p_reader.Depth() > xml_depth; rd_ok = p_reader.Read()) ;\n"
1734 " }\n"
1735 );
1736 }
1737
1738 src = mputprintf(src,
1739 " }\n" /* end if(rd_ok) */
1740 " if (%s(e_xer || !is_record_of(p_flavor)) && own_tag)\n"
1741 " for (; rd_ok == 1; rd_ok = p_reader.Read()) {\n"
1742 " type = p_reader.NodeType();\n"
1743 " if (type == XML_READER_TYPE_END_ELEMENT) {\n"
1744 " verify_end(p_reader, p_td, xml_depth, e_xer);\n"
1745 " rd_ok = p_reader.Read(); // one last time\n"
1746 " break;\n"
1747 " }\n"
1748 " }\n"
1749 "%s"
1750 " return 1;\n"
1751 "}\n\n", sdef->xerUseUnion ? "!attribute && " : "",
1752 sdef->xerUseTypeAttr ? " Free(typeatr);\n" : "");
1753 }
1754 if (json_needed) {
1755 // JSON encode
1756 src = mputprintf(src,
1757 "int %s::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const\n"
1758 "{\n", name);
1759 if (!sdef->jsonAsValue) {
1760 src = mputstr(src, " int enc_len = p_tok.put_next_token(JSON_TOKEN_OBJECT_START, NULL);\n\n");
1761 } else {
1762 src = mputstr(src, " int enc_len = 0;\n\n");
1763 }
1764 src = mputstr(src, " switch(union_selection) {\n");
1765
1766 for (i = 0; i < sdef->nElements; ++i) {
1767 src = mputprintf(src, " case %s_%s:\n", selection_prefix, sdef->elements[i].name);
1768 if (!sdef->jsonAsValue) {
1769 src = mputprintf(src, " enc_len += p_tok.put_next_token(JSON_TOKEN_NAME, \"%s\");\n"
1770 , sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname);
1771 }
1772 src = mputprintf(src,
1773 " enc_len += field_%s->JSON_encode(%s_descr_, p_tok);\n"
1774 " break;\n"
1775 , sdef->elements[i].name, sdef->elements[i].typedescrname);
1776 }
1777 src = mputprintf(src,
1778 " default:\n"
1779 " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND, \n"
1780 " \"Encoding an unbound value of type %s.\");\n"
1781 " return -1;\n"
1782 " }\n\n"
1783 , dispname);
1784 if (!sdef->jsonAsValue) {
1785 src = mputstr(src, " enc_len += p_tok.put_next_token(JSON_TOKEN_OBJECT_END, NULL);\n");
1786 }
1787 src = mputstr(src,
1788 " return enc_len;\n"
1789 "}\n\n");
1790
1791 // JSON decode
1792 src = mputprintf(src,
509718e0 1793 "int %s::JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok, boolean p_silent)\n"
970ed795 1794 "{\n"
509718e0 1795 " json_token_t j_token = JSON_TOKEN_NONE;\n"
970ed795
EL
1796 , name);
1797 if (sdef->jsonAsValue) {
1798 src = mputstr(src,
1799 " size_t buf_pos = p_tok.get_buf_pos();\n"
509718e0 1800 " p_tok.get_next_token(&j_token, NULL, NULL);\n"
970ed795 1801 " int ret_val = 0;\n"
509718e0 1802 " switch(j_token) {\n"
970ed795
EL
1803 " case JSON_TOKEN_NUMBER: {\n");
1804 for (i = 0; i < sdef->nElements; ++i) {
1805 if (JSON_NUMBER & sdef->elements[i].jsonValueType) {
1806 src = mputprintf(src,
1807 " p_tok.set_buf_pos(buf_pos);\n"
1808 " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, true);\n"
1809 " if (0 <= ret_val) {\n"
1810 " return ret_val;\n"
1811 " }\n"
1812 , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname);
1813 }
1814 }
1815 src = mputstr(src,
1816 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"number\");\n"
1817 " clean_up();\n"
1818 " return JSON_ERROR_FATAL;\n"
1819 " }\n"
1820 " case JSON_TOKEN_STRING: {\n");
1821 for (i = 0; i < sdef->nElements; ++i) {
1822 if (JSON_STRING & sdef->elements[i].jsonValueType) {
1823 src = mputprintf(src,
1824 " p_tok.set_buf_pos(buf_pos);\n"
1825 " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, true);\n"
1826 " if (0 <= ret_val) {\n"
1827 " return ret_val;\n"
1828 " }\n"
1829 , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname);
1830 }
1831 }
1832 src = mputstr(src,
1833 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"string\");\n"
1834 " clean_up();\n"
1835 " return JSON_ERROR_FATAL;\n"
1836 " }\n"
1837 " case JSON_TOKEN_LITERAL_TRUE:\n"
1838 " case JSON_TOKEN_LITERAL_FALSE:\n"
1839 " case JSON_TOKEN_LITERAL_NULL: {\n");
1840 for (i = 0; i < sdef->nElements; ++i) {
1841 if (JSON_LITERAL & sdef->elements[i].jsonValueType) {
1842 src = mputprintf(src,
1843 " p_tok.set_buf_pos(buf_pos);\n"
1844 " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, true);\n"
1845 " if (0 <= ret_val) {\n"
1846 " return ret_val;\n"
1847 " }\n"
1848 , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname);
1849 }
1850 }
1851 src = mputstr(src,
509718e0 1852 " char* literal_str = mprintf(\"literal (%s)\",\n"
1853 " (JSON_TOKEN_LITERAL_TRUE == j_token) ? \"true\" :\n"
1854 " ((JSON_TOKEN_LITERAL_FALSE == j_token) ? \"false\" : \"null\"));\n"
1855 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, literal_str);\n"
1856 " Free(literal_str);\n"
970ed795
EL
1857 " clean_up();\n"
1858 " return JSON_ERROR_FATAL;\n"
1859 " }\n"
1860 " case JSON_TOKEN_ARRAY_START: {\n");
1861 for (i = 0; i < sdef->nElements; ++i) {
1862 if (JSON_ARRAY & sdef->elements[i].jsonValueType) {
1863 src = mputprintf(src,
1864 " p_tok.set_buf_pos(buf_pos);\n"
1865 " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, true);\n"
1866 " if (0 <= ret_val) {\n"
1867 " return ret_val;\n"
1868 " }\n"
1869 , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname);
1870 }
1871 }
1872 src = mputstr(src,
1873 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"array\");\n"
1874 " clean_up();\n"
1875 " return JSON_ERROR_FATAL;\n"
1876 " }\n"
1877 " case JSON_TOKEN_OBJECT_START: {\n");
1878 for (i = 0; i < sdef->nElements; ++i) {
1879 if (JSON_OBJECT & sdef->elements[i].jsonValueType) {
1880 src = mputprintf(src,
1881 " p_tok.set_buf_pos(buf_pos);\n"
1882 " ret_val = %s%s().JSON_decode(%s_descr_, p_tok, true);\n"
1883 " if (0 <= ret_val) {\n"
1884 " return ret_val;\n"
1885 " }\n"
1886 , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname);
1887 }
1888 }
1889 src = mputstr(src,
1890 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_AS_VALUE_ERROR, \"object\");\n"
1891 " clean_up();\n"
1892 " return JSON_ERROR_FATAL;\n"
1893 " }\n"
1894 " case JSON_TOKEN_ERROR:\n"
1895 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, \"\");\n"
1896 " return JSON_ERROR_FATAL;\n"
1897 " default:\n"
1898 " return JSON_ERROR_INVALID_TOKEN;\n"
1899 " }\n"
1900 " return 0;\n"
1901 "}\n\n");
1902 } else { // not "as value"
1903 src = mputprintf(src,
509718e0 1904 " int dec_len = p_tok.get_next_token(&j_token, NULL, NULL);\n"
1905 " if (JSON_TOKEN_ERROR == j_token) {\n"
970ed795
EL
1906 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, \"\");\n"
1907 " return JSON_ERROR_FATAL;\n"
1908 " }\n"
509718e0 1909 " else if (JSON_TOKEN_OBJECT_START != j_token) {\n"
970ed795
EL
1910 " return JSON_ERROR_INVALID_TOKEN;\n"
1911 " }\n\n"
509718e0 1912 " char* fld_name = 0;\n"
970ed795 1913 " size_t name_len = 0;"
509718e0 1914 " dec_len += p_tok.get_next_token(&j_token, &fld_name, &name_len);\n"
1915 " if (JSON_TOKEN_NAME != j_token) {\n"
970ed795
EL
1916 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_NAME_TOKEN_ERROR);\n"
1917 " return JSON_ERROR_FATAL;\n"
1918 " } else {\n"
1919 " union_selection = %s;\n "
1920 , unbound_value);
1921 for (i = 0; i < sdef->nElements; ++i) {
1922 src = mputprintf(src,
509718e0 1923 "if (0 == strncmp(fld_name, \"%s\", name_len)) {\n"
970ed795
EL
1924 " int ret_val = %s%s().JSON_decode(%s_descr_, p_tok, p_silent);\n"
1925 " if (0 > ret_val) {\n"
1926 " if (JSON_ERROR_INVALID_TOKEN) {\n"
1927 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, \"%s\");\n"
1928 " }\n"
1929 " return JSON_ERROR_FATAL;\n"
1930 " } else {\n"
1931 " dec_len += ret_val;\n"
1932 " }\n"
1933 " } else "
1934 , sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname
1935 , at_field, sdef->elements[i].name, sdef->elements[i].typedescrname
1936 , sdef->elements[i].dispname);
1937 }
1938 src = mputstr(src,
1939 "{\n"
509718e0 1940 " char* fld_name2 = mcopystrn(fld_name, name_len);\n"
1941 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_INVALID_NAME_ERROR, fld_name2);\n"
1942 " Free(fld_name2);\n"
970ed795
EL
1943 " return JSON_ERROR_FATAL;\n"
1944 " }\n"
1945 " }\n\n"
509718e0 1946 " dec_len += p_tok.get_next_token(&j_token, NULL, NULL);\n"
1947 " if (JSON_TOKEN_OBJECT_END != j_token) {\n"
970ed795
EL
1948 " JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_STATIC_OBJECT_END_TOKEN_ERROR, \"\");\n"
1949 " return JSON_ERROR_FATAL;\n"
1950 " }\n\n"
1951 " return dec_len;\n"
1952 "}\n\n");
1953 }
1954 }
1955
1956 /* end of class definition */
1957 def = mputstr(def, "};\n\n");
1958
1959 output->header.class_defs = mputstr(output->header.class_defs, def);
1960 Free(def);
1961
1962 output->source.methods = mputstr(output->source.methods, src);
1963 Free(src);
1964
1965 Free(selection_type);
1966 Free(unbound_value);
1967 Free(selection_prefix);
1968}
1969
1970
1971void defUnionTemplate(const struct_def *sdef, output_struct *output)
1972{
1973 int i;
1974 const char *name = sdef->name, *dispname = sdef->dispname;
1975 const char *at_field = sdef->kind==ANYTYPE ? "AT_" : "";
1976 char *def = NULL, *src = NULL;
1977
1978 char *selection_type, *unbound_value, *selection_prefix;
1979 selection_type = mprintf("%s::union_selection_type", name);
1980 unbound_value = mprintf("%s::UNBOUND_VALUE", name);
1981 selection_prefix = mprintf("%s::ALT", name);
1982
1983 /* template class */
1984
1985 output->header.class_decls = mputprintf(output->header.class_decls,
1986 "class %s_template;\n", name);
1987
1988 /* template class header and data members */
1989 def = mputprintf(def, "class %s_template : public Base_Template {\n"
1990 "union {\n"
1991 "struct {\n"
1992 "%s union_selection;\n"
1993 "union {\n", name, selection_type);
1994 for (i = 0; i < sdef->nElements; i++) {
1995 def = mputprintf(def, "%s_template *field_%s;\n",
1996 sdef->elements[i].type, sdef->elements[i].name);
1997 }
1998 def = mputprintf(def, "};\n"
1999 "} single_value;\n"
2000 "struct {\n"
2001 "unsigned int n_values;\n"
2002 "%s_template *list_value;\n"
2003 "} value_list;\n"
2004 "};\n", name);
2005 if (use_runtime_2) {
2006 def = mputstr(def,
2007 "Erroneous_descriptor_t* err_descr;\n");
2008 }
2009
2010 /* copy_value function */
2011 def = mputprintf(def, "void copy_value(const %s& other_value);\n\n", name);
2012 src = mputprintf(src, "void %s_template::copy_value(const %s& other_value)\n"
2013 "{\n"
2014 "single_value.union_selection = other_value.get_selection();\n"
2015 "switch (single_value.union_selection) {\n", name, name);
2016 for (i = 0; i<sdef->nElements; i++) {
2017 src = mputprintf(src, "case %s_%s:\n"
2018 "single_value.field_%s = new %s_template(other_value.%s%s());\n"
2019 "break;\n", selection_prefix, sdef->elements[i].name,
2020 sdef->elements[i].name, sdef->elements[i].type,
2021 at_field, sdef->elements[i].name);
2022 }
2023 src = mputprintf(src, "default:\n"
2024 "TTCN_error(\"Initializing a template with an unbound value of type "
2025 "%s.\");\n"
2026 "}\n"
2027 "set_selection(SPECIFIC_VALUE);\n"
2028 "%s"
2029 "}\n\n", dispname,
2030 use_runtime_2 ? "err_descr = other_value.get_err_descr();\n" : "");
2031
2032 /* copy_template function */
2033 def = mputprintf(def, "void copy_template(const %s_template& "
2034 "other_value);\n", name);
2035 src = mputprintf(src, "void %s_template::copy_template(const "
2036 "%s_template& other_value)\n"
2037 "{\n"
2038 "switch (other_value.template_selection) {\n"
2039 "case SPECIFIC_VALUE:\n"
2040 "single_value.union_selection = "
2041 "other_value.single_value.union_selection;\n"
2042 "switch (single_value.union_selection) {\n", name, name);
2043 for (i = 0; i < sdef->nElements; i++) {
2044 src = mputprintf(src, "case %s_%s:\n"
2045 "single_value.field_%s = "
2046 "new %s_template(*other_value.single_value.field_%s);\n"
2047 "break;\n", selection_prefix, sdef->elements[i].name,
2048 sdef->elements[i].name, sdef->elements[i].type, sdef->elements[i].name);
2049 }
2050 src = mputprintf(src, "default:\n"
2051 "TTCN_error(\"Internal error: Invalid union selector in a specific value "
2052 "when copying a template of type %s.\");\n"
2053 "}\n"
2054 "case OMIT_VALUE:\n"
2055 "case ANY_VALUE:\n"
2056 "case ANY_OR_OMIT:\n"
2057 "break;\n"
2058 "case VALUE_LIST:\n"
2059 "case COMPLEMENTED_LIST:\n"
2060 "value_list.n_values = other_value.value_list.n_values;\n"
2061 "value_list.list_value = new %s_template[value_list.n_values];\n"
2062 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
2063 "list_count++)\n"
2064 "value_list.list_value[list_count].copy_template("
2065 "other_value.value_list.list_value[list_count]);\n"
2066 "break;\n"
2067 "default:\n"
2068 "TTCN_error(\"Copying an uninitialized template of union type %s.\");\n"
2069 "}\n"
2070 "set_selection(other_value);\n"
2071 "%s"
2072 "}\n\n", dispname, name, dispname,
2073 use_runtime_2 ? "err_descr = other_value.err_descr;\n" : "");
2074
2075 /* default constructor */
2076 def = mputprintf(def, "\npublic:\n"
2077 "%s_template();\n", name);
2078 src = mputprintf(src, "%s_template::%s_template()%s\n"
2079 "{\n"
2080 "}\n\n", name, name,
2081 use_runtime_2 ? ": err_descr(NULL)" : "");
2082
2083 /* constructor (template_sel) */
2084 def = mputprintf(def, "%s_template(template_sel other_value);\n", name);
2085 src = mputprintf(src, "%s_template::%s_template(template_sel other_value)\n"
2086 " : Base_Template(other_value)%s\n"
2087 "{\n"
2088 "check_single_selection(other_value);\n"
2089 "}\n\n", name, name,
2090 use_runtime_2 ? ", err_descr(NULL)" : "");
2091
2092 /* constructor (value) */
2093 def = mputprintf(def, "%s_template(const %s& other_value);\n", name, name);
2094 src = mputprintf(src, "%s_template::%s_template(const %s& other_value)\n"
2095 "{\n"
2096 "copy_value(other_value);\n"
2097 "}\n\n", name, name, name);
2098
2099 /* constructor (optional value) */
2100 def = mputprintf(def, "%s_template(const OPTIONAL<%s>& other_value);\n", name,
2101 name);
2102 src = mputprintf(src, "%s_template::%s_template(const OPTIONAL<%s>& "
2103 "other_value)\n"
2104 "{\n"
2105 "switch (other_value.get_selection()) {\n"
2106 "case OPTIONAL_PRESENT:\n"
2107 "copy_value((const %s&)other_value);\n"
2108 "break;\n"
2109 "case OPTIONAL_OMIT:\n"
2110 "set_selection(OMIT_VALUE);\n"
2111 "%s"
2112 "break;\n"
2113 "default:\n"
2114 "TTCN_error(\"Creating a template of union type %s from an unbound "
2115 "optional field.\");\n"
2116 "}\n"
2117 "}\n\n", name, name, name, name,
2118 use_runtime_2 ? "err_descr = NULL;\n" : "",
2119 dispname);
2120
2121 /* copy constructor */
2122 def = mputprintf(def, "%s_template(const %s_template& other_value);\n", name,
2123 name);
2124 src = mputprintf(src, "%s_template::%s_template(const %s_template& "
2125 "other_value)\n"
2126 ": Base_Template()" /* yes, the base class _default_ constructor */
2127 "{\n"
2128 "copy_template(other_value);\n"
2129 "}\n\n", name, name, name);
2130
2131 /* destructor */
2132 def = mputprintf(def, "~%s_template();\n", name);
2133 src = mputprintf(src, "%s_template::~%s_template()\n"
2134 "{\n"
2135 "clean_up();\n"
2136 "}\n\n", name, name);
2137
2138 /* clean_up function */
2139 def = mputstr(def, "void clean_up();\n");
2140 src = mputprintf(src, "void %s_template::clean_up()\n"
2141 "{\n"
2142 "switch (template_selection) {\n"
2143 "case SPECIFIC_VALUE:\n"
2144 "switch (single_value.union_selection) {\n", name);
2145 for (i = 0; i < sdef->nElements; i++) {
2146 src = mputprintf(src, "case %s_%s:\n"
2147 "delete single_value.field_%s;\n",
2148 selection_prefix, sdef->elements[i].name, sdef->elements[i].name);
2149 if (i < sdef->nElements - 1) src = mputstr(src, "break;\n");
2150 }
2151 src = mputstr(src, "default:\n"
2152 "break;\n"
2153 "}\n"
2154 "break;\n"
2155 "case VALUE_LIST:\n"
2156 "case COMPLEMENTED_LIST:\n"
2157 "delete [] value_list.list_value;\n"
2158 "default:\n"
2159 "break;\n"
2160 "}\n"
2161 "template_selection = UNINITIALIZED_TEMPLATE;\n"
2162 "}\n\n");
2163
2164 /* assignment operator (template_sel) */
2165 def = mputprintf(def, "%s_template& operator=(template_sel other_value);\n",
2166 name);
2167 src = mputprintf(src,
2168 "%s_template& %s_template::operator=(template_sel "
2169 "other_value)\n"
2170 "{\n"
2171 "check_single_selection(other_value);\n"
2172 "clean_up();\n"
2173 "set_selection(other_value);\n"
2174 "%s"
2175 "return *this;\n"
2176 "}\n\n", name, name, use_runtime_2 ? "err_descr = NULL;\n" : "");
2177
2178 /* assignment operator (value) */
2179 def = mputprintf(def, "%s_template& operator=(const %s& other_value);\n",
2180 name, name);
2181 src = mputprintf(src, "%s_template& %s_template::operator=(const %s& "
2182 "other_value)\n"
2183 "{\n"
2184 "clean_up();\n"
2185 "copy_value(other_value);\n"
2186 "return *this;\n"
2187 "}\n\n", name, name, name);
2188
2189 /* assignment operator <- optional value */
2190 def = mputprintf(def, "%s_template& operator=(const OPTIONAL<%s>& "
2191 "other_value);\n", name, name);
2192 src = mputprintf(src,
2193 "%s_template& %s_template::operator=(const OPTIONAL<%s>& other_value)\n"
2194 "{\n"
2195 "clean_up();\n"
2196 "switch (other_value.get_selection()) {\n"
2197 "case OPTIONAL_PRESENT:\n"
2198 "copy_value((const %s&)other_value);\n"
2199 "break;\n"
2200 "case OPTIONAL_OMIT:\n"
2201 "set_selection(OMIT_VALUE);\n"
2202 "%s"
2203 "break;\n"
2204 "default:\n"
2205 "TTCN_error(\"Assignment of an unbound optional field to a template of "
2206 "union type %s.\");\n"
2207 "}\n"
2208 "return *this;\n"
2209 "}\n\n", name, name, name, name,
2210 use_runtime_2 ? "err_descr = NULL;\n" : "", dispname);
2211
2212 /* assignment operator (template) */
2213 def = mputprintf(def, "%s_template& operator=(const %s_template& "
2214 "other_value);\n", name, name);
2215 src = mputprintf(src,
2216 "%s_template& %s_template::operator=(const %s_template& other_value)\n"
2217 "{\n"
2218 "if (&other_value != this) {\n"
2219 "clean_up();\n"
2220 "copy_template(other_value);\n"
2221 "}\n"
2222 "return *this;\n"
2223 "}\n\n", name, name, name);
2224
2225 /* match function */
2226 def = mputprintf(def, "boolean match(const %s& other_value) const;\n", name);
2227 src = mputprintf(src, "boolean %s_template::match(const %s& other_value) "
2228 "const\n"
2229 "{\n"
2230 "if (!other_value.is_bound()) return FALSE;\n"
2231 "switch (template_selection) {\n"
2232 "case ANY_VALUE:\n"
2233 "case ANY_OR_OMIT:\n"
2234 "return TRUE;\n"
2235 "case OMIT_VALUE:\n"
2236 "return FALSE;\n"
2237 "case SPECIFIC_VALUE:\n"
2238 "{\n"
2239 "%s value_selection = other_value.get_selection();\n"
2240 "if (value_selection == %s) return FALSE;\n"
2241 "if (value_selection != single_value.union_selection) return FALSE;\n"
2242 "switch (value_selection) {\n", name, name, selection_type, unbound_value);
2243 for (i = 0; i < sdef->nElements; i++) {
2244 src = mputprintf(src, "case %s_%s:\n"
2245 "return single_value.field_%s->match(other_value.%s%s());\n",
2246 selection_prefix, sdef->elements[i].name, sdef->elements[i].name,
2247 at_field, sdef->elements[i].name);
2248 }
2249 src = mputprintf(src, "default:\n"
2250 "TTCN_error(\"Internal error: Invalid selector in a specific value when "
2251 "matching a template of union type %s.\");\n"
2252 "}\n"
2253 "}\n"
2254 "case VALUE_LIST:\n"
2255 "case COMPLEMENTED_LIST:\n"
2256 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
2257 "list_count++)\n"
2258 "if (value_list.list_value[list_count].match(other_value)) "
2259 "return template_selection == VALUE_LIST;\n"
2260 "return template_selection == COMPLEMENTED_LIST;\n"
2261 "default:\n"
2262 "TTCN_error (\"Matching an uninitialized template of union type %s.\");\n"
2263 "}\n"
2264 "return FALSE;\n"
2265 "}\n\n", dispname, dispname);
2266
2267 /* isvalue */
2268 def = mputstr(def, "boolean is_value() const;");
2269 src = mputprintf(src, "boolean %s_template::is_value() const\n"
2270 "{\n"
2271 "if (template_selection != SPECIFIC_VALUE || is_ifpresent) return false;\n"
2272 "switch (single_value.union_selection) {\n"
2273 , name);
2274 for (i = 0; i < sdef->nElements; i++) {
2275 src = mputprintf(src, "case %s_%s:\n"
2276 "return single_value.field_%s->is_value();\n", selection_prefix,
2277 sdef->elements[i].name, sdef->elements[i].name);
2278 }
2279 src = mputprintf(src, "default:\n"
2280 "TTCN_error(\"Internal error: Invalid selector in a specific value when "
2281 "performing is_value operation on a template of union type %s.\");\n"
2282 "}\n"
2283 "}\n\n", dispname);
2284
2285 /* valueof member function */
2286 def = mputprintf(def, "%s valueof() const;\n", name);
2287 src = mputprintf(src, "%s %s_template::valueof() const\n"
2288 "{\n"
2289 "if (template_selection != SPECIFIC_VALUE || is_ifpresent)\n"
2290 "TTCN_error(\"Performing valueof or send operation on a non-specific "
2291 "template of union type %s.\");\n"
2292 "%s ret_val;\n"
2293 "switch (single_value.union_selection) {\n", name, name, dispname, name);
2294 for (i = 0; i < sdef->nElements; i++) {
2295 src = mputprintf(src, "case %s_%s:\n"
2296 "ret_val.%s%s() = single_value.field_%s->valueof();\n"
2297 "break;\n", selection_prefix, sdef->elements[i].name,
2298 at_field, sdef->elements[i].name, sdef->elements[i].name);
2299 }
2300 src = mputprintf(src, "default:\n"
2301 "TTCN_error(\"Internal error: Invalid selector in a specific value when "
2302 "performing valueof operation on a template of union type %s.\");\n"
2303 "}\n"
2304 "%s"
2305 "return ret_val;\n"
2306 "}\n\n", dispname,
2307 use_runtime_2 ? "ret_val.set_err_descr(err_descr);\n" : "");
2308
2309 /* list_item(int) function */
2310 def = mputprintf(def, "%s_template& list_item(unsigned int list_index) "
2311 "const;\n", name);
2312 src = mputprintf(src,
2313 "%s_template& %s_template::list_item(unsigned int list_index) const\n"
2314 "{\n"
2315 "if (template_selection != VALUE_LIST && "
2316 "template_selection != COMPLEMENTED_LIST) TTCN_error(\"Internal error: "
2317 "Accessing a list element of a non-list template of union type %s.\");\n"
2318 "if (list_index >= value_list.n_values) "
2319 "TTCN_error(\"Internal error: Index overflow in a value list template "
2320 "of union type %s.\");\n"
2321 "return value_list.list_value[list_index];\n"
2322 "}\n", name, name, dispname, dispname);
2323
2324 /* void set_type(template_sel, int) function */
2325 def = mputstr(def, "void set_type(template_sel template_type, "
2326 "unsigned int list_length);\n");
2327 src = mputprintf(src,
2328 "void %s_template::set_type(template_sel template_type, "
2329 "unsigned int list_length)\n"
2330 "{\n"
2331 "if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST) "
2332 "TTCN_error (\"Internal error: Setting an invalid list for a template "
2333 "of union type %s.\");\n"
2334 "clean_up();\n"
2335 "set_selection(template_type);\n"
2336 "value_list.n_values = list_length;\n"
2337 "value_list.list_value = new %s_template[list_length];\n"
2338 "}\n\n", name, dispname, name);
2339
2340 /* field access functions */
2341 for (i = 0; i < sdef->nElements; i++) {
2342 def = mputprintf(def, "%s_template& %s%s();\n", sdef->elements[i].type,
2343 at_field, sdef->elements[i].name);
2344 src = mputprintf(src, "%s_template& %s_template::%s%s()\n"
2345 "{\n"
2346 "if (template_selection != SPECIFIC_VALUE || "
2347 "single_value.union_selection != %s_%s) {\n"
2348 "template_sel old_selection = template_selection;\n"
2349 "clean_up();\n"
2350 "if (old_selection == ANY_VALUE || old_selection == ANY_OR_OMIT) "
2351 "single_value.field_%s = new %s_template(ANY_VALUE);\n"
2352 "else single_value.field_%s = new %s_template;\n"
2353 "single_value.union_selection = %s_%s;\n"
2354 "set_selection(SPECIFIC_VALUE);\n"
2355 "}\n"
2356 "return *single_value.field_%s;\n"
2357 "}\n\n", sdef->elements[i].type, name, at_field, sdef->elements[i].name,
2358 selection_prefix, sdef->elements[i].name, sdef->elements[i].name,
2359 sdef->elements[i].type, sdef->elements[i].name, sdef->elements[i].type,
2360 selection_prefix, sdef->elements[i].name, sdef->elements[i].name);
2361
2362 def = mputprintf(def, "const %s_template& %s%s() const;\n",
2363 sdef->elements[i].type, at_field, sdef->elements[i].name);
2364 src = mputprintf(src, "const %s_template& %s_template::%s%s() const\n"
2365 "{\n"
2366 "if (template_selection != SPECIFIC_VALUE) TTCN_error(\"Accessing field "
2367 "%s in a non-specific template of union type %s.\");\n"
2368 "if (single_value.union_selection != %s_%s) "
2369 "TTCN_error(\"Accessing non-selected field %s in a template of union "
2370 "type %s.\");\n"
2371 "return *single_value.field_%s;\n"
2372 "}\n\n", sdef->elements[i].type, name, at_field, sdef->elements[i].name,
2373 sdef->elements[i].dispname, dispname, selection_prefix,
2374 sdef->elements[i].name, sdef->elements[i].dispname, dispname,
2375 sdef->elements[i].name);
2376 }
2377
2378 /* ischosen function */
2379 def = mputprintf(def, "boolean ischosen(%s checked_selection) const;\n",
2380 selection_type);
2381 src = mputprintf(src, "boolean %s_template::ischosen(%s checked_selection) "
2382 "const\n"
2383 "{\n"
2384 "if (checked_selection == %s) TTCN_error(\"Internal error: Performing "
2385 "ischosen() operation on an invalid field of union type %s.\");\n"
2386 "switch (template_selection) {\n"
2387 "case SPECIFIC_VALUE:\n"
2388 "if (single_value.union_selection == %s) TTCN_error(\"Internal error: "
2389 "Invalid selector in a specific value when performing ischosen() "
2390 "operation on a template of union type %s.\");\n"
2391 "return single_value.union_selection == checked_selection;\n"
2392 "case VALUE_LIST:\n"
2393 "{\n"
2394 "if (value_list.n_values < 1)\n"
2395 "TTCN_error(\"Internal error: Performing ischosen() operation on a "
2396 "template of union type %s containing an empty list.\");\n"
2397 "boolean ret_val = "
2398 "value_list.list_value[0].ischosen(checked_selection);\n"
2399 "boolean all_same = TRUE;\n"
2400 "for (unsigned int list_count = 1; list_count < value_list.n_values; "
2401 "list_count++) {\n"
2402 "if (value_list.list_value[list_count].ischosen(checked_selection) != "
2403 "ret_val) {\n"
2404 "all_same = FALSE;\n"
2405 "break;\n"
2406 "}\n"
2407 "}\n"
2408 "if (all_same) return ret_val;\n"
2409 "}\n"
2410 "case ANY_VALUE:\n"
2411 "case ANY_OR_OMIT:\n"
2412 "case OMIT_VALUE:\n"
2413 "case COMPLEMENTED_LIST:\n"
2414 "TTCN_error(\"Performing ischosen() operation on a template of union type "
2415 "%s, which does not determine unambiguously the chosen field of the "
2416 "matching values.\");\n"
2417 "default:\n"
2418 "TTCN_error(\"Performing ischosen() operation on an uninitialized "
2419 "template of union type %s\");\n"
2420 "}\n"
2421 "return FALSE;\n"
2422 "}\n\n", name, selection_type, unbound_value, dispname, unbound_value,
2423 dispname, dispname, dispname, dispname);
2424
2425 if (use_runtime_2) {
2426 def = mputstr(def,
2427 "void set_err_descr(Erroneous_descriptor_t* p_err_descr) { err_descr=p_err_descr; }\n");
2428 /** virtual stuff */
2429 def = mputstr(def,
2430 "void valueofv(Base_Type* value) const;\n"
2431 "void set_value(template_sel other_value);\n"
2432 "void copy_value(const Base_Type* other_value);\n"
2433 "Base_Template* clone() const;\n"
2434 "const TTCN_Typedescriptor_t* get_descriptor() const;\n"
2435 "boolean matchv(const Base_Type* other_value) const;\n"
2436 "void log_matchv(const Base_Type* match_value) const;\n");
2437 src = mputprintf(src,
2438 "void %s_template::valueofv(Base_Type* value) const "
2439 "{ *(static_cast<%s*>(value)) = valueof(); }\n"
2440 "void %s_template::set_value(template_sel other_value) "
2441 "{ *this = other_value; }\n"
2442 "void %s_template::copy_value(const Base_Type* other_value) "
2443 "{ *this = *(static_cast<const %s*>(other_value)); }\n"
2444 "Base_Template* %s_template::clone() const "
2445 "{ return new %s_template(*this); }\n"
2446 "const TTCN_Typedescriptor_t* %s_template::get_descriptor() const "
2447 "{ return &%s_descr_; }\n"
2448 "boolean %s_template::matchv(const Base_Type* other_value) const "
2449 "{ return match(*(static_cast<const %s*>(other_value))); }\n"
2450 "void %s_template::log_matchv(const Base_Type* match_value) const "
2451 " { log_match(*(static_cast<const %s*>(match_value))); }\n",
2452 name, name,
2453 name,
2454 name, name,
2455 name, name,
2456 name, name,
2457 name, name,
2458 name, name);
2459 }
2460
2461 /* log function */
2462 def = mputstr(def, "void log() const;\n");
2463 src = mputprintf(src,"void %s_template::log() const\n"
2464 "{\n"
2465 "switch (template_selection) {\n"
2466 "case SPECIFIC_VALUE:\n"
2467 "switch (single_value.union_selection) {\n", name);
2468 for (i = 0; i < sdef->nElements; i++) {
2469 src = mputprintf(src, "case %s_%s:\n"
2470 "TTCN_Logger::log_event_str(\"{ %s := \");\n"
2471 "single_value.field_%s->log();\n"
2472 "TTCN_Logger::log_event_str(\" }\");\n"
2473 "break;\n", selection_prefix, sdef->elements[i].name,
2474 sdef->elements[i].dispname, sdef->elements[i].name);
2475 }
2476 src = mputstr(src, "default:\n"
2477 "TTCN_Logger::log_event_str(\"<invalid selector>\");\n"
2478 "}\n"
2479 "break;\n"
2480 "case COMPLEMENTED_LIST:\n"
2481 "TTCN_Logger::log_event_str(\"complement \");\n"
2482 "case VALUE_LIST:\n"
2483 "TTCN_Logger::log_char('(');\n"
2484 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
2485 "list_count++) {\n"
2486 "if (list_count > 0) TTCN_Logger::log_event_str(\", \");\n"
2487 "value_list.list_value[list_count].log();\n"
2488 "}\n"
2489 "TTCN_Logger::log_char(')');\n"
2490 "break;\n"
2491 "default:\n"
2492 "log_generic();\n"
2493 "}\n"
2494 "log_ifpresent();\n");
2495 if (use_runtime_2) {
2496 src = mputstr(src, "if (err_descr) err_descr->log();\n");
2497 }
2498 src = mputstr(src, "}\n\n");
2499
2500 /* log_match function */
2501 def = mputprintf(def, "void log_match(const %s& match_value) "
2502 "const;\n", name);
2503 src = mputprintf(src,
2504 "void %s_template::log_match(const %s& match_value) const\n"
2505 "{\n"
2506 "if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity() && match(match_value)){\n"
2507 "TTCN_Logger::print_logmatch_buffer();\n"
2508 "TTCN_Logger::log_event_str(\" matched\");\n"
2509 "return;\n"
2510 "}\n"
2511 "if (template_selection == SPECIFIC_VALUE && "
2512 "single_value.union_selection == match_value.get_selection()) {\n"
2513 "switch (single_value.union_selection) {\n", name, name);
2514 for (i = 0; i < sdef->nElements; i++) {
2515 src = mputprintf(src, "case %s_%s:\n"
2516 "if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){\n"
2517 "TTCN_Logger::log_logmatch_info(\".%s\");\n"
2518 "single_value.field_%s->log_match(match_value.%s%s());\n"
2519 "} else {\n"
2520 "TTCN_Logger::log_event_str(\"{ %s := \");\n"
2521 "single_value.field_%s->log_match(match_value.%s%s());\n"
2522 "TTCN_Logger::log_event_str(\" }\");\n"
2523 "}\n"
2524 "break;\n", selection_prefix, sdef->elements[i].name,
2525 sdef->elements[i].dispname,
2526 sdef->elements[i].name, at_field, sdef->elements[i].name,
2527 sdef->elements[i].dispname, sdef->elements[i].name,
2528 at_field, sdef->elements[i].name);
2529 }
2530 src = mputstr(src, "default:\n"
2531 "TTCN_Logger::print_logmatch_buffer();\n"
2532 "TTCN_Logger::log_event_str(\"<invalid selector>\");\n"
2533 "}\n"
2534 "} else {\n"
2535 "TTCN_Logger::print_logmatch_buffer();\n"
2536 "match_value.log();\n"
2537 "TTCN_Logger::log_event_str(\" with \");\n"
2538 "log();\n"
2539 "if (match(match_value)) TTCN_Logger::log_event_str(\" matched\");\n"
2540 "else TTCN_Logger::log_event_str(\" unmatched\");\n"
2541 "}\n"
2542 "}\n\n");
2543
2544 /* encode_text function */
2545 def = mputstr(def, "void encode_text(Text_Buf& text_buf) const;\n");
2546 src = mputprintf(src,
2547 "void %s_template::encode_text(Text_Buf& text_buf) const\n"
2548 "{\n"
2549 "encode_text_base(text_buf);\n"
2550 "switch (template_selection) {\n"
2551 "case SPECIFIC_VALUE:\n"
2552 "text_buf.push_int(single_value.union_selection);\n"
2553 "switch (single_value.union_selection) {\n", name);
2554 for (i = 0; i < sdef->nElements; i++) {
2555 src = mputprintf(src, "case %s_%s:\n"
2556 "single_value.field_%s->encode_text(text_buf);\n"
2557 "break;\n", selection_prefix, sdef->elements[i].name,
2558 sdef->elements[i].name);
2559 }
2560 src = mputprintf(src, "default:\n"
2561 "TTCN_error(\"Internal error: Invalid selector in a specific value when "
2562 "encoding a template of union type %s.\");\n"
2563 "}\n"
2564 "case OMIT_VALUE:\n"
2565 "case ANY_VALUE:\n"
2566 "case ANY_OR_OMIT:\n"
2567 "break;\n"
2568 "case VALUE_LIST:\n"
2569 "case COMPLEMENTED_LIST:\n"
2570 "text_buf.push_int(value_list.n_values);\n"
2571 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
2572 "list_count++)\n"
2573 "value_list.list_value[list_count].encode_text(text_buf);\n"
2574 "break;\n"
2575 "default:\n"
2576 "TTCN_error(\"Text encoder: Encoding an uninitialized template of type "
2577 "%s.\");\n"
2578 "}\n"
2579 "}\n\n", dispname, dispname);
2580
2581 /* decode_text function */
2582 def = mputstr(def, "void decode_text(Text_Buf& text_buf);\n");
2583 src = mputprintf(src, "void %s_template::decode_text(Text_Buf& text_buf)\n"
2584 "{\n"
2585 "clean_up();\n"
2586 "decode_text_base(text_buf);\n"
2587 "switch (template_selection) {\n"
2588 "case SPECIFIC_VALUE:\n"
2589 "{\n"
2590 "single_value.union_selection = %s;\n"
2591 "%s new_selection = (%s)text_buf.pull_int().get_val();\n"
2592 "switch (new_selection) {\n", name, unbound_value, selection_type,
2593 selection_type);
2594 for (i = 0; i < sdef->nElements; i++) {
2595 src = mputprintf(src, "case %s_%s:\n"
2596 "single_value.field_%s = new %s_template;\n"
2597 "single_value.field_%s->decode_text(text_buf);\n"
2598 "break;\n", selection_prefix, sdef->elements[i].name,
2599 sdef->elements[i].name, sdef->elements[i].type, sdef->elements[i].name);
2600 }
2601 src = mputprintf(src, "default:\n"
2602 "TTCN_error(\"Text decoder: Unrecognized union selector was received for "
2603 "a template of type %s.\");\n"
2604 "}\n"
2605 "single_value.union_selection = new_selection;\n"
2606 "}\n"
2607 "case OMIT_VALUE:\n"
2608 "case ANY_VALUE:\n"
2609 "case ANY_OR_OMIT:\n"
2610 "break;\n"
2611 "case VALUE_LIST:\n"
2612 "case COMPLEMENTED_LIST:\n"
2613 "value_list.n_values = text_buf.pull_int().get_val();\n"
2614 "value_list.list_value = new %s_template[value_list.n_values];\n"
2615 "for (unsigned int list_count = 0; list_count < value_list.n_values; "
2616 "list_count++)\n"
2617 "value_list.list_value[list_count].decode_text(text_buf);\n"
2618 "break;\n"
2619 "default:\n"
2620 "TTCN_error(\"Text decoder: Unrecognized selector was received in a "
2621 "template of type %s.\");\n"
2622 "}\n"
2623 "}\n\n", dispname, name, dispname);
2624
2625 /* TTCN-3 ispresent() function */
2626 def = mputstr(def, "boolean is_present() const;\n");
2627 src = mputprintf(src,
2628 "boolean %s_template::is_present() const\n"
2629 "{\n"
2630 "if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;\n"
2631 "return !match_omit();\n"
2632 "}\n\n", name);
2633
2634 /* match_omit() */
2635 def = mputstr(def, "boolean match_omit() const;\n");
2636 src = mputprintf(src,
2637 "boolean %s_template::match_omit() const\n"
2638 "{\n"
2639 "if (is_ifpresent) return TRUE;\n"
2640 "switch (template_selection) {\n"
2641 "case OMIT_VALUE:\n"
2642 "case ANY_OR_OMIT:\n"
2643 "return TRUE;\n"
2644 "case VALUE_LIST:\n"
2645 "case COMPLEMENTED_LIST:\n"
2646 "for (unsigned int v_idx=0; v_idx<value_list.n_values; v_idx++)\n"
2647 "if (value_list.list_value[v_idx].match_omit())\n"
2648 "return template_selection==VALUE_LIST;\n"
2649 "return template_selection==COMPLEMENTED_LIST;\n"
2650 "default:\n"
2651 "return FALSE;\n"
2652 "}\n"
2653 "return FALSE;\n"
2654 "}\n\n", name);
2655
2656 /* set_param() */
2657 def = mputstr(def, "void set_param(Module_Param& param);\n");
2658 src = mputprintf(src,
2659 "void %s_template::set_param(Module_Param& param)\n"
2660 "{\n"
2661 " if (dynamic_cast<Module_Param_Name*>(param.get_id()) != NULL &&\n"
2662 " param.get_id()->next_name()) {\n"
2663 // Haven't reached the end of the module parameter name
2664 // => the name refers to one of the fields, not to the whole union
2665 " char* param_field = param.get_id()->get_current_name();\n"
2666 " if (param_field[0] >= '0' && param_field[0] <= '9') {\n"
2667 " param.error(\"Unexpected array index in module parameter, expected a valid field\"\n"
2668 " \" name for union template type `%s'\");\n"
2669 " }\n"
2670 " ", name, dispname);
2671 for (i = 0; i < sdef->nElements; i++) {
2672 src = mputprintf(src,
2673 "if (strcmp(\"%s\", param_field) == 0) {\n"
2674 " %s%s().set_param(param);\n"
2675 " return;\n"
2676 " } else ",
2677 sdef->elements[i].dispname, at_field, sdef->elements[i].name);
2678 }
2679 src = mputprintf(src,
2680 "param.error(\"Field `%%s' not found in union template type `%s'\", param_field);\n"
2681 " }\n"
2682 " param.basic_check(Module_Param::BC_TEMPLATE, \"union template\");\n"
2683 " switch (param.get_type()) {\n"
2684 " case Module_Param::MP_Omit:\n"
2685 " *this = OMIT_VALUE;\n"
2686 " break;\n"
2687 " case Module_Param::MP_Any:\n"
2688 " *this = ANY_VALUE;\n"
2689 " break;\n"
2690 " case Module_Param::MP_AnyOrNone:\n"
2691 " *this = ANY_OR_OMIT;\n"
2692 " break;\n"
2693 " case Module_Param::MP_List_Template:\n"
2694 " case Module_Param::MP_ComplementList_Template:\n"
2695 " set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());\n"
2696 " for (size_t p_i=0; p_i<param.get_size(); p_i++) {\n"
2697 " list_item(p_i).set_param(*param.get_elem(p_i));\n"
2698 " }\n"
2699 " break;\n"
2700 " case Module_Param::MP_Value_List:\n"
2701 " if (param.get_size()==0) break;\n" /* for backward compatibility */
2702 " param.type_error(\"union template\", \"%s\");\n"
2703 " break;\n"
2704 " case Module_Param::MP_Assignment_List: {\n"
2705 " Module_Param* mp_last = param.get_elem(param.get_size()-1);\n",
2706 dispname, dispname);
2707 for (i = 0; i < sdef->nElements; i++) {
2708 src = mputprintf(src,
2709 " if (!strcmp(mp_last->get_id()->get_name(), \"%s\")) {\n"
2710 " %s%s().set_param(*mp_last);\n"
2711 " break;\n"
2712 " }\n", sdef->elements[i].dispname, at_field, sdef->elements[i].name);
2713 }
2714 src = mputprintf(src,
2715 " mp_last->error(\"Field %%s does not exist in type %s.\", mp_last->get_id()->get_name());\n"
2716 " } break;\n"
2717 " default:\n"
2718 " param.type_error(\"union template\", \"%s\");\n"
2719 " }\n"
2720 " is_ifpresent = param.get_ifpresent();\n"
2721 "}\n\n", dispname, dispname);
2722
2723 /* check template restriction */
2724 def = mputstr(def, "void check_restriction(template_res t_res, "
2725 "const char* t_name=NULL) const;\n");
2726 src = mputprintf(src,
2727 "void %s_template::check_restriction("
2728 "template_res t_res, const char* t_name) const\n"
2729 "{\n"
2730 "if (template_selection==UNINITIALIZED_TEMPLATE) return;\n"
2731 "switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {\n"
2732 "case TR_OMIT:\n"
2733 "if (template_selection==OMIT_VALUE) return;\n"
2734 "case TR_VALUE:\n"
2735 "if (template_selection!=SPECIFIC_VALUE || is_ifpresent) break;\n"
2736 "switch (single_value.union_selection) {\n"
2737 , name);
2738 for (i = 0; i < sdef->nElements; i++) {
2739 src = mputprintf(src, "case %s_%s:\n"
2740 "single_value.field_%s->check_restriction("
2741 "t_res, t_name ? t_name : \"%s\");\n"
2742 "return;\n",
2743 selection_prefix, sdef->elements[i].name,
2744 sdef->elements[i].name, dispname);
2745 }
2746 src = mputprintf(src, "default:\n"
2747 "TTCN_error(\"Internal error: Invalid selector in a specific value when "
2748 "performing check_restriction operation on a template of union type %s.\");\n"
2749 "}\n"
2750 "case TR_PRESENT:\n"
2751 "if (!match_omit()) return;\n"
2752 "break;\n"
2753 "default:\n"
2754 "return;\n"
2755 "}\n"
2756 "TTCN_error(\"Restriction `%%s' on template of type %%s violated.\", "
2757 "get_res_name(t_res), t_name ? t_name : \"%s\");\n"
2758 "}\n\n", dispname, dispname);
2759
2760 def = mputstr(def, "};\n\n");
2761
2762 output->header.class_defs = mputstr(output->header.class_defs, def);
2763 Free(def);
2764
2765 output->source.methods = mputstr(output->source.methods, src);
2766 Free(src);
2767
2768 Free(selection_type);
2769 Free(unbound_value);
2770 Free(selection_prefix);
2771}
This page took 0.13476 seconds and 5 git commands to generate.