asn.1 testcases have been added to modulpar reference test
[deliverable/titan.core.git] / core / Component.cc
1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Balasko, Jeno
10 * Baranyi, Botond
11 * Beres, Szabolcs
12 * Delic, Adam
13 * Forstner, Matyas
14 * Kovacs, Ferenc
15 * Raduly, Csaba
16 * Szabados, Kristof
17 * Szabo, Janos Zoltan – initial implementation
18 * Tatarka, Gabor
19 *
20 ******************************************************************************/
21 #include <string.h>
22
23 #include "../common/memory.h"
24
25 #include "Component.hh"
26 #include "Logger.hh"
27 #include "Parameters.h"
28 #include "Param_Types.hh"
29 #include "Runtime.hh"
30 #include "Optional.hh"
31
32 #include "../common/dbgnew.hh"
33
34 COMPONENT::COMPONENT()
35 {
36 component_value = UNBOUND_COMPREF;
37 }
38
39 COMPONENT::COMPONENT(component other_value)
40 {
41 component_value = other_value;
42 }
43
44 COMPONENT::COMPONENT(const COMPONENT& other_value)
45 : Base_Type(other_value)
46 {
47 if (other_value.component_value == UNBOUND_COMPREF)
48 TTCN_error("Copying an unbound component reference.");
49 component_value = other_value.component_value;
50 }
51
52 COMPONENT& COMPONENT::operator=(component other_value)
53 {
54 component_value = other_value;
55 return *this;
56 }
57
58 COMPONENT& COMPONENT::operator=(const COMPONENT& other_value)
59 {
60 if (other_value.component_value == UNBOUND_COMPREF)
61 TTCN_error("Assignment of an unbound component reference.");
62 component_value = other_value.component_value;
63 return *this;
64 }
65
66 boolean COMPONENT::operator==(component other_value) const
67 {
68 if (component_value == UNBOUND_COMPREF) TTCN_error("The left operand of "
69 "comparison is an unbound component reference.");
70 return component_value == other_value;
71 }
72
73 boolean COMPONENT::operator==(const COMPONENT& other_value) const
74 {
75 if (component_value == UNBOUND_COMPREF) TTCN_error("The left operand of "
76 "comparison is an unbound component reference.");
77 if (other_value.component_value == UNBOUND_COMPREF) TTCN_error("The right "
78 "operand of comparison is an unbound component reference.");
79 return component_value == other_value.component_value;
80 }
81
82 COMPONENT::operator component() const
83 {
84 if (component_value == UNBOUND_COMPREF) TTCN_error("Using the value of an "
85 "unbound component reference.");
86 return component_value;
87 }
88
89 void COMPONENT::log() const
90 {
91 if (component_value != UNBOUND_COMPREF)
92 log_component_reference(component_value);
93 else TTCN_Logger::log_event_unbound();
94 }
95
96 alt_status COMPONENT::done() const
97 {
98 if (component_value == UNBOUND_COMPREF) TTCN_error("Performing done "
99 "operation on an unbound component reference.");
100 return TTCN_Runtime::component_done(component_value);
101 }
102
103 alt_status COMPONENT::killed() const
104 {
105 if (component_value == UNBOUND_COMPREF) TTCN_error("Performing killed "
106 "operation on an unbound component reference.");
107 return TTCN_Runtime::component_killed(component_value);
108 }
109
110 boolean COMPONENT::running() const
111 {
112 if (component_value == UNBOUND_COMPREF) TTCN_error("Performing running "
113 "operation on an unbound component reference.");
114 return TTCN_Runtime::component_running(component_value);
115 }
116
117 boolean COMPONENT::alive() const
118 {
119 if (component_value == UNBOUND_COMPREF) TTCN_error("Performing alive "
120 "operation on an unbound component reference.");
121 return TTCN_Runtime::component_alive(component_value);
122 }
123
124 void COMPONENT::stop() const
125 {
126 if (component_value == UNBOUND_COMPREF) TTCN_error("Performing stop "
127 "operation on an unbound component reference.");
128 TTCN_Runtime::stop_component(component_value);
129 }
130
131 void COMPONENT::kill() const
132 {
133 if (component_value == UNBOUND_COMPREF) TTCN_error("Performing kill "
134 "operation on an unbound component reference.");
135 TTCN_Runtime::kill_component(component_value);
136 }
137
138 void COMPONENT::set_param(Module_Param& param) {
139 param.basic_check(Module_Param::BC_VALUE, "component reference (integer or null) value");
140 Module_Param_Ptr mp = &param;
141 if (param.get_type() == Module_Param::MP_Reference) {
142 mp = param.get_referenced_param();
143 }
144 if (Ttcn_String_Parsing::happening()) {
145 // accept all component values in case it's a string2ttcn operation
146 switch (mp->get_type()) {
147 case Module_Param::MP_Integer:
148 component_value = (component)mp->get_integer()->get_val();
149 break;
150 case Module_Param::MP_Ttcn_Null:
151 component_value = NULL_COMPREF;
152 break;
153 case Module_Param::MP_Ttcn_mtc:
154 component_value = MTC_COMPREF;
155 break;
156 case Module_Param::MP_Ttcn_system:
157 component_value = SYSTEM_COMPREF;
158 break;
159 default:
160 param.type_error("component reference (integer or null) value");
161 }
162 }
163 else {
164 // only accept the null value if it's a module parameter
165 if (Module_Param::MP_Ttcn_Null != mp->get_type()) {
166 param.error("Only the 'null' value is allowed for module parameters of type 'component'.");
167 }
168 component_value = NULL_COMPREF;
169 }
170 }
171
172 Module_Param* COMPONENT::get_param(Module_Param_Name& /* param_name */) const
173 {
174 if (!is_bound()) {
175 return new Module_Param_Unbound();
176 }
177 return new Module_Param_Ttcn_Null();
178 }
179
180 void COMPONENT::encode_text(Text_Buf& text_buf) const
181 {
182 if (component_value == UNBOUND_COMPREF) TTCN_error("Text encoder: Encoding "
183 "an unbound component reference.");
184 text_buf.push_int((int)component_value);
185 switch (component_value) {
186 case NULL_COMPREF:
187 case MTC_COMPREF:
188 case SYSTEM_COMPREF:
189 break;
190 default:
191 text_buf.push_string(get_component_name(component_value));
192 break;
193 }
194 }
195
196 void COMPONENT::decode_text(Text_Buf& text_buf)
197 {
198 component_value = (component)text_buf.pull_int().get_val();
199 switch (component_value) {
200 case NULL_COMPREF:
201 case MTC_COMPREF:
202 case SYSTEM_COMPREF:
203 break;
204 default:
205 char *component_name = text_buf.pull_string();
206 register_component_name(component_value, component_name);
207 delete [] component_name;
208 break;
209 }
210 }
211
212 boolean operator==(component component_value, const COMPONENT& other_value)
213 {
214 if (other_value.component_value == UNBOUND_COMPREF) TTCN_error("The right "
215 "operand of comparison is an unbound component reference.");
216 return component_value == other_value.component_value;
217 }
218
219 unsigned int COMPONENT::n_component_names = 0;
220 struct COMPONENT::component_name_struct {
221 component component_reference;
222 char *component_name;
223 } *COMPONENT::component_names = NULL;
224
225 void COMPONENT::register_component_name(component component_reference,
226 const char *component_name)
227 {
228 if (self.component_value == component_reference) {
229 // the own name of the component will not be registered,
230 // but check whether we got the right string
231 const char *local_name = TTCN_Runtime::get_component_name();
232 if (component_name == NULL || component_name[0] == '\0') {
233 if (local_name != NULL) {
234 TTCN_error("Internal error: Trying to register the component "
235 "reference of this PTC without any name, but this "
236 "component has name %s.", local_name);
237 }
238 } else {
239 if (local_name == NULL) {
240 TTCN_error("Internal error: Trying to register the component "
241 "reference of this PTC with name %s, but this component "
242 "does not have name.", component_name);
243 } else if (strcmp(component_name, local_name)) {
244 TTCN_error("Internal error: Trying to register the component "
245 "reference of this PTC with name %s, but this component "
246 "has name %s.", component_name, local_name);
247 }
248 }
249 return;
250 }
251 unsigned int min = 0;
252 if (n_component_names > 0) {
253 // perform a binary search to find the place for the component reference
254 unsigned int max = n_component_names - 1;
255 while (min < max) {
256 unsigned int mid = min + (max - min) / 2;
257 if (component_names[mid].component_reference < component_reference)
258 min = mid + 1;
259 else if (component_names[mid].component_reference ==
260 component_reference) {
261 min = mid;
262 break;
263 } else max = mid;
264 }
265 if (component_names[min].component_reference == component_reference) {
266 // the component reference is already registered
267 const char *stored_name = component_names[min].component_name;
268 if (component_name == NULL || component_name[0] == '\0') {
269 if (stored_name != NULL) {
270 TTCN_error("Internal error: Trying to register component "
271 "reference %d without any name, but this component "
272 "reference is already registered with name %s.",
273 component_reference, stored_name);
274 }
275 } else {
276 if (stored_name == NULL) {
277 TTCN_error("Internal error: Trying to register component "
278 "reference %d with name %s, but this component "
279 "reference is already registered without name.",
280 component_reference, component_name);
281 } else if (strcmp(component_name, stored_name)) {
282 TTCN_error("Internal error: Trying to register component "
283 "reference %d with name %s, but this component "
284 "reference is already registered with a different "
285 "name (%s).", component_reference, component_name,
286 stored_name);
287 }
288 }
289 return;
290 } else {
291 if (component_names[min].component_reference < component_reference)
292 min++;
293 // the component reference will be inserted before the index "min"
294 component_names =
295 (component_name_struct*)Realloc(component_names,
296 (n_component_names + 1) * sizeof(*component_names));
297 memmove(component_names + min + 1, component_names + min,
298 (n_component_names - min) * sizeof(*component_names));
299 }
300 } else {
301 // this is the first component reference to be registered
302 component_names =
303 (component_name_struct*)Malloc(sizeof(*component_names));
304 }
305 component_names[min].component_reference = component_reference;
306 if (component_name == NULL || component_name[0] == '\0')
307 component_names[min].component_name = NULL;
308 else component_names[min].component_name = mcopystr(component_name);
309 n_component_names++;
310 }
311
312 const char *COMPONENT::get_component_name(component component_reference)
313 {
314 if (self.component_value == component_reference) {
315 // the own name of the PTC is not registered
316 return TTCN_Runtime::get_component_name();
317 } else if (n_component_names > 0) {
318 unsigned int min = 0, max = n_component_names - 1;
319 while (min < max) {
320 unsigned int mid = min + (max - min) / 2;
321 if (component_names[mid].component_reference < component_reference)
322 min = mid + 1;
323 else if (component_names[mid].component_reference ==
324 component_reference)
325 return component_names[mid].component_name;
326 else max = mid;
327 }
328 if (component_names[min].component_reference != component_reference)
329 TTCN_error("Internal error: Trying to get the name of PTC with "
330 "component reference %d, but the name of the component "
331 "is not registered.", component_reference);
332 return component_names[min].component_name;
333 } else {
334 TTCN_error("Internal error: Trying to get the name of PTC with "
335 "component reference %d, but there are no component names "
336 "registered.", component_reference);
337 return NULL;
338 }
339 }
340
341 void COMPONENT::clear_component_names()
342 {
343 for (unsigned int i = 0; i < n_component_names; i++)
344 Free(component_names[i].component_name);
345 Free(component_names);
346 n_component_names = 0;
347 component_names = NULL;
348 }
349
350 void COMPONENT::log_component_reference(component component_reference)
351 {
352 switch (component_reference) {
353 case NULL_COMPREF:
354 TTCN_Logger::log_event_str("null");
355 break;
356 case MTC_COMPREF:
357 TTCN_Logger::log_event_str("mtc");
358 break;
359 case SYSTEM_COMPREF:
360 TTCN_Logger::log_event_str("system");
361 break;
362 default:
363 const char *component_name = get_component_name(component_reference);
364 if (component_name != NULL) TTCN_Logger::log_event("%s(%d)",
365 component_name, component_reference);
366 else TTCN_Logger::log_event("%d", component_reference);
367 break;
368 }
369 }
370
371 // get_component_string is suspiciously similar to log_component_reference.
372 // It would be trivially easy to implement log_... with get_...
373 // but it would involve a runtime penalty, because get_component_string
374 // returns a newly allocated string which must be freed, whereas log_...
375 // uses fixed strings. So the current implementation pays for speed with size.
376 // Perhaps log_component_reference will go away one day.
377 char *COMPONENT::get_component_string(component component_reference)
378 {
379 switch (component_reference) {
380 case NULL_COMPREF:
381 return mcopystr("null");
382 case MTC_COMPREF:
383 return mcopystr("mtc");
384 case SYSTEM_COMPREF:
385 return mcopystr("system");
386 case CONTROL_COMPREF:
387 return mcopystr("control");
388 default:
389 const char *component_name = get_component_name(component_reference);
390 if (component_name != NULL) return mprintf("%s(%d)",
391 component_name, component_reference);
392 else return mprintf("%d", component_reference);
393 }
394 }
395
396 COMPONENT self;
397
398 void COMPONENT_template::clean_up()
399 {
400 if (template_selection == VALUE_LIST
401 ||template_selection == COMPLEMENTED_LIST)
402 delete [] value_list.list_value;
403 template_selection = UNINITIALIZED_TEMPLATE;
404 }
405
406 void COMPONENT_template::copy_template(const COMPONENT_template& other_value)
407 {
408 switch (other_value.template_selection) {
409 case SPECIFIC_VALUE:
410 single_value = other_value.single_value;
411 break;
412 case OMIT_VALUE:
413 case ANY_VALUE:
414 case ANY_OR_OMIT:
415 break;
416 case VALUE_LIST:
417 case COMPLEMENTED_LIST:
418 value_list.n_values = other_value.value_list.n_values;
419 value_list.list_value = new COMPONENT_template[value_list.n_values];
420 for (unsigned int i = 0; i < value_list.n_values; i++)
421 value_list.list_value[i].copy_template(
422 other_value.value_list.list_value[i]);
423 break;
424 default:
425 TTCN_error("Copying an uninitialized/unsupported component reference "
426 "template.");
427 }
428 set_selection(other_value);
429 }
430
431 COMPONENT_template::COMPONENT_template()
432 {
433
434 }
435
436 COMPONENT_template::COMPONENT_template(template_sel other_value)
437 : Base_Template(other_value)
438 {
439 check_single_selection(other_value);
440 }
441
442 COMPONENT_template::COMPONENT_template(component other_value)
443 : Base_Template(SPECIFIC_VALUE)
444 {
445 single_value = other_value;
446 }
447
448 COMPONENT_template::COMPONENT_template(const COMPONENT& other_value)
449 : Base_Template(SPECIFIC_VALUE)
450 {
451 if (other_value.component_value == UNBOUND_COMPREF)
452 TTCN_error("Creating a template from an unbound component reference.");
453 single_value = other_value.component_value;
454 }
455
456 COMPONENT_template::COMPONENT_template(const OPTIONAL<COMPONENT>& other_value)
457 {
458 switch (other_value.get_selection()) {
459 case OPTIONAL_PRESENT:
460 set_selection(SPECIFIC_VALUE);
461 single_value = (component)(const COMPONENT&)other_value;
462 break;
463 case OPTIONAL_OMIT:
464 set_selection(OMIT_VALUE);
465 break;
466 default:
467 TTCN_error("Creating a component reference template from an unbound "
468 "optional field.");
469 }
470 }
471
472 COMPONENT_template::COMPONENT_template(const COMPONENT_template& other_value)
473 : Base_Template()
474 {
475 copy_template(other_value);
476 }
477
478 COMPONENT_template::~COMPONENT_template()
479 {
480 clean_up();
481 }
482
483 COMPONENT_template& COMPONENT_template::operator=(template_sel other_value)
484 {
485 check_single_selection(other_value);
486 clean_up();
487 set_selection(other_value);
488 return *this;
489 }
490
491 COMPONENT_template& COMPONENT_template::operator=(component other_value)
492 {
493 clean_up();
494 set_selection(SPECIFIC_VALUE);
495 single_value = other_value;
496 return *this;
497 }
498
499 COMPONENT_template& COMPONENT_template::operator=(const COMPONENT& other_value)
500 {
501 if (other_value.component_value == UNBOUND_COMPREF)
502 TTCN_error("Assignment of an unbound component reference to a "
503 "template.");
504 return *this = other_value.component_value;
505 }
506
507 COMPONENT_template& COMPONENT_template::operator=
508 (const OPTIONAL<COMPONENT>& other_value)
509 {
510 clean_up();
511 switch (other_value.get_selection()) {
512 case OPTIONAL_PRESENT:
513 set_selection(SPECIFIC_VALUE);
514 single_value = (component)(const COMPONENT&)other_value;
515 break;
516 case OPTIONAL_OMIT:
517 set_selection(OMIT_VALUE);
518 break;
519 default:
520 TTCN_error("Assignment of an unbound optional field to a component "
521 "reference template.");
522 }
523 return *this;
524 }
525
526 COMPONENT_template& COMPONENT_template::operator=
527 (const COMPONENT_template& other_value)
528 {
529 if (&other_value != this) {
530 clean_up();
531 copy_template(other_value);
532 }
533 return *this;
534 }
535
536 boolean COMPONENT_template::match(component other_value,
537 boolean /* legacy */) const
538 {
539 switch (template_selection) {
540 case SPECIFIC_VALUE:
541 return single_value == other_value;
542 case OMIT_VALUE:
543 return FALSE;
544 case ANY_VALUE:
545 case ANY_OR_OMIT:
546 return TRUE;
547 case VALUE_LIST:
548 case COMPLEMENTED_LIST:
549 for (unsigned int i = 0; i < value_list.n_values; i++)
550 if (value_list.list_value[i].match(other_value))
551 return template_selection == VALUE_LIST;
552 return template_selection == COMPLEMENTED_LIST;
553 default:
554 TTCN_error("Matching an uninitialized/unsupported component reference "
555 "template.");
556 }
557 return FALSE;
558 }
559
560 boolean COMPONENT_template::match(const COMPONENT& other_value,
561 boolean /* legacy */) const
562 {
563 if (other_value.component_value == UNBOUND_COMPREF)
564 TTCN_error("Matching an unbound component reference with a template.");
565 return match(other_value.component_value);
566 }
567
568 component COMPONENT_template::valueof() const
569 {
570 if (template_selection != SPECIFIC_VALUE || is_ifpresent)
571 TTCN_error("Performing a valueof or send operation on a non-specific "
572 "component reference template.");
573 return single_value;
574 }
575
576 void COMPONENT_template::set_type(template_sel template_type,
577 unsigned int list_length)
578 {
579 if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
580 TTCN_error("Setting an invalid list type for a component reference "
581 "template.");
582 clean_up();
583 set_selection(template_type);
584 value_list.n_values = list_length;
585 value_list.list_value = new COMPONENT_template[list_length];
586 }
587
588 COMPONENT_template& COMPONENT_template::list_item(unsigned int list_index)
589 {
590 if (template_selection != VALUE_LIST &&
591 template_selection != COMPLEMENTED_LIST)
592 TTCN_error("Accessing a list element of a non-list component "
593 "reference template.");
594 if (list_index >= value_list.n_values)
595 TTCN_error("Index overflow in a component reference value list "
596 "template.");
597 return value_list.list_value[list_index];
598 }
599
600 void COMPONENT_template::log() const
601 {
602 switch (template_selection) {
603 case SPECIFIC_VALUE:
604 switch (single_value) {
605 case NULL_COMPREF:
606 TTCN_Logger::log_event_str("null");
607 break;
608 case MTC_COMPREF:
609 TTCN_Logger::log_event_str("mtc");
610 break;
611 case SYSTEM_COMPREF:
612 TTCN_Logger::log_event_str("system");
613 break;
614 default:
615 TTCN_Logger::log_event("%d", single_value);
616 break;
617 }
618 break;
619 case COMPLEMENTED_LIST:
620 TTCN_Logger::log_event_str("complement ");
621 // no break
622 case VALUE_LIST:
623 TTCN_Logger::log_char('(');
624 for (unsigned int i = 0; i < value_list.n_values; i++) {
625 if (i > 0) TTCN_Logger::log_event_str(", ");
626 value_list.list_value[i].log();
627 }
628 TTCN_Logger::log_char(')');
629 break;
630 default:
631 log_generic();
632 break;
633 }
634 log_ifpresent();
635 }
636
637 void COMPONENT_template::log_match(const COMPONENT& match_value,
638 boolean /* legacy */) const
639 {
640 if (TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()
641 && TTCN_Logger::get_logmatch_buffer_len() != 0) {
642 TTCN_Logger::print_logmatch_buffer();
643 TTCN_Logger::log_event_str(" := ");
644 }
645 match_value.log();
646 TTCN_Logger::log_event_str(" with ");
647 log();
648 if (match(match_value)) TTCN_Logger::log_event_str(" matched");
649 else TTCN_Logger::log_event_str(" unmatched");
650 }
651
652 void COMPONENT_template::set_param(Module_Param& param) {
653 param.basic_check(Module_Param::BC_TEMPLATE, "component reference (integer or null) template");
654 Module_Param_Ptr mp = &param;
655 if (param.get_type() == Module_Param::MP_Reference) {
656 mp = param.get_referenced_param();
657 }
658 switch (mp->get_type()) {
659 case Module_Param::MP_Omit:
660 *this = OMIT_VALUE;
661 break;
662 case Module_Param::MP_Any:
663 *this = ANY_VALUE;
664 break;
665 case Module_Param::MP_AnyOrNone:
666 *this = ANY_OR_OMIT;
667 break;
668 case Module_Param::MP_List_Template:
669 case Module_Param::MP_ComplementList_Template: {
670 COMPONENT_template temp;
671 temp.set_type(mp->get_type() == Module_Param::MP_List_Template ?
672 VALUE_LIST : COMPLEMENTED_LIST, mp->get_size());
673 for (size_t i=0; i<mp->get_size(); i++) {
674 temp.list_item(i).set_param(*mp->get_elem(i));
675 }
676 *this = temp;
677 break; }
678 case Module_Param::MP_Integer:
679 *this = (component)mp->get_integer()->get_val();
680 break;
681 case Module_Param::MP_Ttcn_Null:
682 *this = NULL_COMPREF;
683 break;
684 case Module_Param::MP_Ttcn_mtc:
685 *this = MTC_COMPREF;
686 break;
687 case Module_Param::MP_Ttcn_system:
688 *this = SYSTEM_COMPREF;
689 break;
690 default:
691 param.type_error("component reference (integer or null) template");
692 }
693 is_ifpresent = param.get_ifpresent() || mp->get_ifpresent();
694 }
695
696 Module_Param* COMPONENT_template::get_param(Module_Param_Name& param_name) const
697 {
698 Module_Param* mp = NULL;
699 switch (template_selection) {
700 case UNINITIALIZED_TEMPLATE:
701 mp = new Module_Param_Unbound();
702 break;
703 case OMIT_VALUE:
704 mp = new Module_Param_Omit();
705 break;
706 case ANY_VALUE:
707 mp = new Module_Param_Any();
708 break;
709 case ANY_OR_OMIT:
710 mp = new Module_Param_AnyOrNone();
711 break;
712 case SPECIFIC_VALUE:
713 switch (single_value) {
714 case NULL_COMPREF:
715 mp = new Module_Param_Ttcn_Null();
716 break;
717 case MTC_COMPREF:
718 mp = new Module_Param_Ttcn_mtc();
719 break;
720 case SYSTEM_COMPREF:
721 mp = new Module_Param_Ttcn_system();
722 break;
723 default:
724 mp = new Module_Param_Integer(new int_val_t(single_value));
725 break;
726 }
727 break;
728 case VALUE_LIST:
729 case COMPLEMENTED_LIST: {
730 if (template_selection == VALUE_LIST) {
731 mp = new Module_Param_List_Template();
732 }
733 else {
734 mp = new Module_Param_ComplementList_Template();
735 }
736 for (size_t i = 0; i < value_list.n_values; ++i) {
737 mp->add_elem(value_list.list_value[i].get_param(param_name));
738 }
739 break; }
740 default:
741 break;
742 }
743 if (is_ifpresent) {
744 mp->set_ifpresent();
745 }
746 return mp;
747 }
748
749 void COMPONENT_template::encode_text(Text_Buf& text_buf) const
750 {
751 encode_text_base(text_buf);
752 switch (template_selection) {
753 case OMIT_VALUE:
754 case ANY_VALUE:
755 case ANY_OR_OMIT:
756 break;
757 case SPECIFIC_VALUE:
758 text_buf.push_int(single_value);
759 break;
760 case COMPLEMENTED_LIST:
761 case VALUE_LIST:
762 text_buf.push_int(value_list.n_values);
763 for (unsigned int i = 0; i < value_list.n_values; i++)
764 value_list.list_value[i].encode_text(text_buf);
765 break;
766 default:
767 TTCN_error("Text encoder: Encoding an uninitialized/unsupported "
768 "component reference template.");
769 }
770 }
771
772 void COMPONENT_template::decode_text(Text_Buf& text_buf)
773 {
774 clean_up();
775 decode_text_base(text_buf);
776 switch (template_selection) {
777 case OMIT_VALUE:
778 case ANY_VALUE:
779 case ANY_OR_OMIT:
780 break;
781 case SPECIFIC_VALUE:
782 single_value = (component)text_buf.pull_int().get_val();
783 break;
784 case COMPLEMENTED_LIST:
785 case VALUE_LIST:
786 value_list.n_values = text_buf.pull_int().get_val();
787 value_list.list_value = new COMPONENT_template[value_list.n_values];
788 for (unsigned int i = 0; i < value_list.n_values; i++)
789 value_list.list_value[i].decode_text(text_buf);
790 break;
791 default:
792 TTCN_error("Text decoder: An unknown/unsupported selection was "
793 "received for a component reference template.");
794 }
795 }
796
797 boolean COMPONENT_template::is_present(boolean legacy /* = FALSE */) const
798 {
799 if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
800 return !match_omit(legacy);
801 }
802
803 boolean COMPONENT_template::match_omit(boolean legacy /* = FALSE */) const
804 {
805 if (is_ifpresent) return TRUE;
806 switch (template_selection) {
807 case OMIT_VALUE:
808 case ANY_OR_OMIT:
809 return TRUE;
810 case VALUE_LIST:
811 case COMPLEMENTED_LIST:
812 if (legacy) {
813 // legacy behavior: 'omit' can appear in the value/complement list
814 for (unsigned int i=0; i<value_list.n_values; i++)
815 if (value_list.list_value[i].match_omit())
816 return template_selection==VALUE_LIST;
817 return template_selection==COMPLEMENTED_LIST;
818 }
819 // else fall through
820 default:
821 return FALSE;
822 }
823 return FALSE;
824 }
825
826 #ifndef TITAN_RUNTIME_2
827 void COMPONENT_template::check_restriction(template_res t_res, const char* t_name,
828 boolean legacy /* = FALSE */) const
829 {
830 if (template_selection==UNINITIALIZED_TEMPLATE) return;
831 switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
832 case TR_VALUE:
833 if (!is_ifpresent && template_selection==SPECIFIC_VALUE) return;
834 break;
835 case TR_OMIT:
836 if (!is_ifpresent && (template_selection==OMIT_VALUE ||
837 template_selection==SPECIFIC_VALUE)) return;
838 break;
839 case TR_PRESENT:
840 if (!match_omit(legacy)) return;
841 break;
842 default:
843 return;
844 }
845 TTCN_error("Restriction `%s' on template of type %s violated.",
846 get_res_name(t_res), t_name ? t_name : "component reference");
847 }
848 #endif
849
850 const COMPONENT_template any_compref_value(ANY_VALUE);
851 const COMPONENT_template& any_compref = any_compref_value;
This page took 0.046481 seconds and 5 git commands to generate.