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