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
19 * Szabo, Janos Zoltan – initial implementation
22 ******************************************************************************/
23 #include "Verdicttype.hh"
25 #include "Param_Types.hh"
30 #include "../common/dbgnew.hh"
32 #define UNBOUND_VERDICT ((verdicttype)(ERROR + 1))
33 #define IS_VALID(verdict_value) (verdict_value >= NONE && verdict_value <= ERROR)
35 const char * const verdict_name
[] = { "none", "pass", "inconc", "fail", "error" };
37 VERDICTTYPE::VERDICTTYPE()
39 verdict_value
= UNBOUND_VERDICT
;
42 VERDICTTYPE::VERDICTTYPE(verdicttype other_value
)
44 if (!IS_VALID(other_value
)) TTCN_error("Initializing a verdict variable "
45 "with an invalid value (%d).", other_value
);
46 verdict_value
= other_value
;
49 VERDICTTYPE::VERDICTTYPE(const VERDICTTYPE
& other_value
)
50 : Base_Type(other_value
)
52 if (!other_value
.is_bound()) TTCN_error("Copying an unbound verdict value.");
53 verdict_value
= other_value
.verdict_value
;
56 VERDICTTYPE
& VERDICTTYPE::operator=(verdicttype other_value
)
58 if (!IS_VALID(other_value
))
59 TTCN_error("Assignment of an invalid verdict value (%d).", other_value
);
60 verdict_value
= other_value
;
64 VERDICTTYPE
& VERDICTTYPE::operator=(const VERDICTTYPE
& other_value
)
66 if (!other_value
.is_bound())
67 TTCN_error("Assignment of an unbound verdict value.");
68 verdict_value
= other_value
.verdict_value
;
72 boolean
VERDICTTYPE::operator==(verdicttype other_value
) const
74 if (!is_bound()) TTCN_error("The left operand of comparison is an unbound "
76 if (!IS_VALID(other_value
)) TTCN_error("The right operand of comparison is "
77 "an invalid verdict value (%d).", other_value
);
78 return verdict_value
== other_value
;
81 boolean
VERDICTTYPE::operator==(const VERDICTTYPE
& other_value
) const
83 if (!is_bound()) TTCN_error("The left operand of comparison is an unbound "
85 if (!other_value
.is_bound()) TTCN_error("The right operand of comparison is "
86 "an unbound verdict value.");
87 return verdict_value
== other_value
.verdict_value
;
90 VERDICTTYPE::operator verdicttype() const
93 TTCN_error("Using the value of an unbound verdict variable.");
97 void VERDICTTYPE::clean_up()
99 verdict_value
= UNBOUND_VERDICT
;
102 void VERDICTTYPE::log() const
104 if (IS_VALID(verdict_value
))
105 TTCN_Logger::log_event_str(verdict_name
[verdict_value
]);
106 else if (verdict_value
== UNBOUND_VERDICT
)
107 TTCN_Logger::log_event_unbound();
108 else TTCN_Logger::log_event("<invalid verdict value: %d>", verdict_value
);
111 void VERDICTTYPE::set_param(Module_Param
& param
) {
112 param
.basic_check(Module_Param::BC_VALUE
, "verdict value");
113 Module_Param_Ptr mp
= ¶m
;
114 if (param
.get_type() == Module_Param::MP_Reference
) {
115 mp
= param
.get_referenced_param();
117 if (mp
->get_type()!=Module_Param::MP_Verdict
) param
.type_error("verdict value");
118 const verdicttype verdict
= mp
->get_verdict();
119 if (!IS_VALID(verdict
)) param
.error("Internal error: invalid verdict value (%d).", verdict
);
120 verdict_value
= verdict
;
123 Module_Param
* VERDICTTYPE::get_param(Module_Param_Name
& /* param_name */) const
126 return new Module_Param_Unbound();
128 return new Module_Param_Verdict(verdict_value
);
131 void VERDICTTYPE::encode_text(Text_Buf
& text_buf
) const
134 TTCN_error("Text encoder: Encoding an unbound verdict value.");
135 text_buf
.push_int(verdict_value
);
138 void VERDICTTYPE::decode_text(Text_Buf
& text_buf
)
140 int received_value
= text_buf
.pull_int().get_val();
141 if (!IS_VALID(received_value
)) TTCN_error("Text decoder: Invalid verdict "
142 "value (%d) was received.", received_value
);
143 verdict_value
= (verdicttype
)received_value
;
146 void VERDICTTYPE::encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
147 TTCN_EncDec::coding_t p_coding
, ...) const
150 va_start(pvar
, p_coding
);
153 case TTCN_EncDec::CT_BER
: {
154 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
155 unsigned BER_coding
=va_arg(pvar
, unsigned);
156 BER_encode_chk_coding(BER_coding
);
157 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
158 tlv
->put_in_buffer(p_buf
);
159 ASN_BER_TLV_t::destruct(tlv
);
161 case TTCN_EncDec::CT_RAW
: {
162 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
164 TTCN_EncDec_ErrorContext::error_internal
165 ("No RAW descriptor available for type '%s'.", p_td
.name
);
169 RAW_enc_tree
root(TRUE
,NULL
,&rp
,1,p_td
.raw
);
170 RAW_encode(p_td
, root
);
171 root
.put_to_buf(p_buf
);
173 case TTCN_EncDec::CT_TEXT
: {
174 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
176 TTCN_EncDec_ErrorContext::error_internal
177 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
178 TEXT_encode(p_td
,p_buf
);
181 case TTCN_EncDec::CT_XER
: {
182 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
183 unsigned XER_coding
=va_arg(pvar
, unsigned);
184 XER_encode(*p_td
.xer
, p_buf
, XER_coding
, 0, 0);
186 case TTCN_EncDec::CT_JSON
: {
187 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
189 TTCN_EncDec_ErrorContext::error_internal
190 ("No JSON descriptor available for type '%s'.", p_td
.name
);
191 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
192 JSON_encode(p_td
, tok
);
193 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
196 TTCN_error("Unknown coding method requested to encode type '%s'",
202 void VERDICTTYPE::decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
203 TTCN_EncDec::coding_t p_coding
, ...)
206 va_start(pvar
, p_coding
);
209 case TTCN_EncDec::CT_RAW
: {
210 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
212 TTCN_EncDec_ErrorContext::error_internal
213 ("No RAW descriptor available for type '%s'.", p_td
.name
);
215 switch(p_td
.raw
->top_bit_order
){
223 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
224 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
225 "Can not decode type '%s', because invalid or incomplete"
226 " message was received"
229 case TTCN_EncDec::CT_TEXT
: {
230 Limit_Token_List limit
;
231 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
233 TTCN_EncDec_ErrorContext::error_internal
234 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
235 const unsigned char *b
=p_buf
.get_data();
236 if(b
[p_buf
.get_len()-1]!='\0'){
237 p_buf
.set_pos(p_buf
.get_len());
238 p_buf
.put_zero(8,ORDER_LSB
);
241 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
242 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
243 "Can not decode type '%s', because invalid or incomplete"
244 " message was received"
248 case TTCN_EncDec::CT_XER
: {
249 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
250 unsigned XER_coding
=va_arg(pvar
, unsigned);
251 XmlReaderWrap
reader(p_buf
);
252 for (int success
= reader
.Read(); success
==1; success
=reader
.Read()) {
253 int type
= reader
.NodeType();
254 if (type
==XML_READER_TYPE_ELEMENT
)
257 XER_decode(*p_td
.xer
, reader
, XER_coding
, XER_NONE
, 0);
258 size_t bytes
= reader
.ByteConsumed();
259 p_buf
.set_pos(bytes
);
261 case TTCN_EncDec::CT_JSON
: {
262 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
264 TTCN_EncDec_ErrorContext::error_internal
265 ("No JSON descriptor available for type '%s'.", p_td
.name
);
266 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
267 if(JSON_decode(p_td
, tok
, false)<0)
268 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
269 "Can not decode type '%s', because invalid or incomplete"
270 " message was received"
272 p_buf
.set_pos(tok
.get_buf_pos());
275 TTCN_error("Unknown coding method requested to decode type '%s'",
282 int VERDICTTYPE::XER_encode(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
283 unsigned int p_flavor
, int p_indent
, embed_values_enc_struct_t
*) const
285 int encoded_length
=(int)p_buf
.get_len();
286 //const boolean e_xer = is_exer(p_flavor);
287 p_flavor
|= (SIMPLE_TYPE
| BXER_EMPTY_ELEM
);
288 if (begin_xml(p_td
, p_buf
, p_flavor
, p_indent
, false) == -1) --encoded_length
;
289 //if (!e_xer) p_buf.put_c('<');
291 const char * enumval
= verdict_name
[verdict_value
];
292 p_buf
.put_s(strlen(enumval
), (const unsigned char*)enumval
);
294 //if (!e_xer) p_buf.put_s(2, (const unsigned char*)"/>");
295 end_xml(p_td
, p_buf
, p_flavor
, p_indent
, false);
296 return (int)p_buf
.get_len() - encoded_length
;
299 verdicttype
VERDICTTYPE::str_to_verdict(const char *v
, boolean silent
)
301 for (int i
= NONE
; i
<= ERROR
; ++i
) {
302 if (0 == strcmp(v
, verdict_name
[i
])) {
303 return (verdicttype
)i
;
308 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
309 "Invalid value for verdicttype: '%s'", v
);
311 return UNBOUND_VERDICT
;
314 int VERDICTTYPE::XER_decode(const XERdescriptor_t
& p_td
, XmlReaderWrap
& p_reader
,
315 unsigned int p_flavor
, unsigned int /*flavor2*/, embed_values_dec_struct_t
*)
318 const int e_xer
= is_exer(p_flavor
);
319 const boolean name_tag
= !((!e_xer
&& is_record_of(p_flavor
)) || (e_xer
&& ((p_td
.xer_bits
& UNTAGGED
) ||(is_record_of(p_flavor
) && is_exerlist(p_flavor
)))));
320 if (e_xer
&& ((p_td
.xer_bits
& XER_ATTRIBUTE
) || is_exerlist(p_flavor
))) {
321 if ((p_td
.xer_bits
& XER_ATTRIBUTE
)) verify_name(p_reader
, p_td
, e_xer
);
322 const char * value
= (const char *)p_reader
.Value();
324 verdict_value
= str_to_verdict(value
, (p_flavor
& EXIT_ON_ERROR
) ? true : false);
328 if (name_tag
) for (; rd_ok
== 1; rd_ok
= p_reader
.Read()) {
329 type
= p_reader
.NodeType();
330 if (XML_READER_TYPE_ELEMENT
== type
) {
331 rd_ok
= p_reader
.Read();
335 for (; rd_ok
== 1; rd_ok
= p_reader
.Read()) {
336 type
= p_reader
.NodeType();
337 if (!e_xer
&& XML_READER_TYPE_ELEMENT
== type
) break;
338 if (XML_READER_TYPE_TEXT
== type
) break;
340 const char *local_name
= /*e_xer ?*/ (const char *)p_reader
.Value() /*: (const char *)p_reader.Name()*/;
341 if (!local_name
) ; else {
342 for (; '\t'==*local_name
|| '\n'==*local_name
; ++local_name
) ;
343 verdict_value
= str_to_verdict(local_name
, (p_flavor
& EXIT_ON_ERROR
) ? true : false);
346 for (rd_ok
= p_reader
.Read(); rd_ok
== 1; rd_ok
= p_reader
.Read()) {
347 type
= p_reader
.NodeType();
348 if (XML_READER_TYPE_END_ELEMENT
== type
) {
353 else p_reader
.Read();
355 int decoded_length
= 0;
356 return decoded_length
;
359 int VERDICTTYPE::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
362 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
363 "Encoding an unbound verdicttype value.");
367 char* tmp_str
= mprintf("\"%s\"", verdict_name
[verdict_value
]);
368 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_STRING
, tmp_str
);
373 int VERDICTTYPE::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
375 json_token_t token
= JSON_TOKEN_NONE
;
377 size_t value_len
= 0;
379 boolean use_default
= p_td
.json
->default_value
&& 0 == p_tok
.get_buffer_length();
381 // No JSON data in the buffer -> use default value
382 value
= (char*)p_td
.json
->default_value
;
383 value_len
= strlen(value
);
385 dec_len
= p_tok
.get_next_token(&token
, &value
, &value_len
);
387 boolean error
= true;
388 if (JSON_TOKEN_ERROR
== token
) {
389 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
390 dec_len
= JSON_ERROR_FATAL
;
392 else if (JSON_TOKEN_STRING
== token
|| use_default
) {
393 if (use_default
|| (value
[0] == '\"' && value
[value_len
- 1] == '\"')) {
395 // The default value doesn't have quotes around it
399 for (int i
= NONE
; i
<= ERROR
; ++i
) {
400 if (0 == strncmp(value
, verdict_name
[i
], value_len
)) {
401 verdict_value
= (verdicttype
)i
;
409 verdict_value
= UNBOUND_VERDICT
;
410 dec_len
= JSON_ERROR_INVALID_TOKEN
;
413 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FORMAT_ERROR
, "string", "verdicttype");
414 verdict_value
= UNBOUND_VERDICT
;
415 dec_len
= JSON_ERROR_FATAL
;
421 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
423 boolean
operator==(verdicttype par_value
, const VERDICTTYPE
& other_value
)
425 if (!IS_VALID(par_value
)) TTCN_error("The left operand of comparison is "
426 "an invalid verdict value (%d).", par_value
);
427 if (!other_value
.is_bound()) TTCN_error("The right operand of comparison "
428 "is an unbound verdict value.");
429 return par_value
== other_value
.verdict_value
;
432 void VERDICTTYPE_template::clean_up()
434 if (template_selection
== VALUE_LIST
||
435 template_selection
== COMPLEMENTED_LIST
)
436 delete [] value_list
.list_value
;
437 template_selection
= UNINITIALIZED_TEMPLATE
;
440 void VERDICTTYPE_template::copy_value(const VERDICTTYPE
& other_value
)
442 if (!other_value
.is_bound())
443 TTCN_error("Creating a template from an unbound verdict value.");
444 single_value
= other_value
.verdict_value
;
445 set_selection(SPECIFIC_VALUE
);
448 void VERDICTTYPE_template::copy_template
449 (const VERDICTTYPE_template
& other_value
)
451 switch (other_value
.template_selection
) {
453 single_value
= other_value
.single_value
;
460 case COMPLEMENTED_LIST
:
461 value_list
.n_values
= other_value
.value_list
.n_values
;
462 value_list
.list_value
= new VERDICTTYPE_template
[value_list
.n_values
];
463 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
464 value_list
.list_value
[i
].copy_template(
465 other_value
.value_list
.list_value
[i
]);
468 TTCN_error("Copying an uninitialized/unsupported verdict template.");
470 set_selection(other_value
);
473 VERDICTTYPE_template::VERDICTTYPE_template()
477 VERDICTTYPE_template::VERDICTTYPE_template(template_sel other_value
)
478 : Base_Template(other_value
)
480 check_single_selection(other_value
);
483 VERDICTTYPE_template::VERDICTTYPE_template(verdicttype other_value
)
484 : Base_Template(SPECIFIC_VALUE
)
486 if (!IS_VALID(other_value
)) TTCN_error("Creating a template from an "
487 "invalid verdict value (%d).", other_value
);
488 single_value
= other_value
;
491 VERDICTTYPE_template::VERDICTTYPE_template(const VERDICTTYPE
& other_value
)
493 copy_value(other_value
);
496 VERDICTTYPE_template::VERDICTTYPE_template
497 (const OPTIONAL
<VERDICTTYPE
>& other_value
)
499 switch (other_value
.get_selection()) {
500 case OPTIONAL_PRESENT
:
501 copy_value((const VERDICTTYPE
&)other_value
);
504 set_selection(OMIT_VALUE
);
507 TTCN_error("Creating a verdict template from an unbound optional field.");
511 VERDICTTYPE_template::VERDICTTYPE_template
512 (const VERDICTTYPE_template
& other_value
)
515 copy_template(other_value
);
518 VERDICTTYPE_template::~VERDICTTYPE_template()
523 VERDICTTYPE_template
& VERDICTTYPE_template::operator=(template_sel other_value
)
525 check_single_selection(other_value
);
527 set_selection(other_value
);
531 VERDICTTYPE_template
& VERDICTTYPE_template::operator=(verdicttype other_value
)
533 if (!IS_VALID(other_value
)) TTCN_error("Assignment of an invalid verdict "
534 "value (%d) to a template.", other_value
);
536 set_selection(SPECIFIC_VALUE
);
537 single_value
= other_value
;
541 VERDICTTYPE_template
& VERDICTTYPE_template::operator=
542 (const VERDICTTYPE
& other_value
)
545 copy_value(other_value
);
549 VERDICTTYPE_template
& VERDICTTYPE_template::operator=
550 (const OPTIONAL
<VERDICTTYPE
>& other_value
)
553 switch (other_value
.get_selection()) {
554 case OPTIONAL_PRESENT
:
555 copy_value((const VERDICTTYPE
&)other_value
);
558 set_selection(OMIT_VALUE
);
561 TTCN_error("Assignment of an unbound optional field to a verdict "
567 VERDICTTYPE_template
& VERDICTTYPE_template::operator=
568 (const VERDICTTYPE_template
& other_value
)
570 if (&other_value
!= this) {
572 copy_template(other_value
);
577 boolean
VERDICTTYPE_template::match(verdicttype other_value
,
578 boolean
/* legacy */) const
580 if (!IS_VALID(other_value
)) TTCN_error("Matching a verdict template with "
581 "an invalid value (%d).", other_value
);
582 switch (template_selection
) {
584 return single_value
== other_value
;
591 case COMPLEMENTED_LIST
:
592 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
593 if (value_list
.list_value
[i
].match(other_value
))
594 return template_selection
== VALUE_LIST
;
595 return template_selection
== COMPLEMENTED_LIST
;
597 TTCN_error("Matching with an uninitialized/unsupported verdict template.");
602 boolean
VERDICTTYPE_template::match(const VERDICTTYPE
& other_value
,
603 boolean
/* legacy */) const
605 if (!other_value
.is_bound()) return FALSE
;
606 return match(other_value
.verdict_value
);
609 verdicttype
VERDICTTYPE_template::valueof() const
611 if (template_selection
!= SPECIFIC_VALUE
|| is_ifpresent
)
612 TTCN_error("Performing a valueof "
613 "or send operation on a non-specific verdict template.");
617 void VERDICTTYPE_template::set_type(template_sel template_type
,
618 unsigned int list_length
)
620 if (template_type
!= VALUE_LIST
&& template_type
!= COMPLEMENTED_LIST
)
621 TTCN_error("Internal error: Setting an invalid list type for a verdict "
624 set_selection(template_type
);
625 value_list
.n_values
= list_length
;
626 value_list
.list_value
= new VERDICTTYPE_template
[list_length
];
629 VERDICTTYPE_template
& VERDICTTYPE_template::list_item(unsigned int list_index
)
631 if (template_selection
!= VALUE_LIST
&&
632 template_selection
!= COMPLEMENTED_LIST
)
633 TTCN_error("Internal error: Accessing a list element of a non-list "
634 "verdict template.");
635 if (list_index
>= value_list
.n_values
)
636 TTCN_error("Internal error: Index overflow in a verdict value list "
638 return value_list
.list_value
[list_index
];
641 void VERDICTTYPE_template::log() const
643 switch (template_selection
) {
645 if (IS_VALID(single_value
))
646 TTCN_Logger::log_event("%s", verdict_name
[single_value
]);
647 else TTCN_Logger::log_event("<unknown verdict value: %d>", single_value
);
649 case COMPLEMENTED_LIST
:
650 TTCN_Logger::log_event_str("complement ");
653 TTCN_Logger::log_char('(');
654 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++) {
655 if (i
> 0) TTCN_Logger::log_event_str(", ");
656 value_list
.list_value
[i
].log();
658 TTCN_Logger::log_char(')');
667 void VERDICTTYPE_template::log_match(const VERDICTTYPE
& match_value
,
668 boolean
/* legacy */) const
670 if (TTCN_Logger::VERBOSITY_COMPACT
== TTCN_Logger::get_matching_verbosity()
671 && TTCN_Logger::get_logmatch_buffer_len() != 0) {
672 TTCN_Logger::print_logmatch_buffer();
673 TTCN_Logger::log_event_str(" := ");
676 TTCN_Logger::log_event_str(" with ");
678 if (match(match_value
)) TTCN_Logger::log_event_str(" matched");
679 else TTCN_Logger::log_event_str(" unmatched");
682 void VERDICTTYPE_template::set_param(Module_Param
& param
) {
683 param
.basic_check(Module_Param::BC_TEMPLATE
, "verdict template");
684 Module_Param_Ptr mp
= ¶m
;
685 if (param
.get_type() == Module_Param::MP_Reference
) {
686 mp
= param
.get_referenced_param();
688 switch (mp
->get_type()) {
689 case Module_Param::MP_Omit
:
692 case Module_Param::MP_Any
:
695 case Module_Param::MP_AnyOrNone
:
698 case Module_Param::MP_List_Template
:
699 case Module_Param::MP_ComplementList_Template
: {
700 VERDICTTYPE_template temp
;
701 temp
.set_type(mp
->get_type() == Module_Param::MP_List_Template
?
702 VALUE_LIST
: COMPLEMENTED_LIST
, mp
->get_size());
703 for (size_t i
=0; i
<mp
->get_size(); i
++) {
704 temp
.list_item(i
).set_param(*mp
->get_elem(i
));
708 case Module_Param::MP_Verdict
:
709 *this = mp
->get_verdict();
712 param
.type_error("verdict template");
714 is_ifpresent
= param
.get_ifpresent() || mp
->get_ifpresent();
717 Module_Param
* VERDICTTYPE_template::get_param(Module_Param_Name
& param_name
) const
719 Module_Param
* mp
= NULL
;
720 switch (template_selection
) {
721 case UNINITIALIZED_TEMPLATE
:
722 mp
= new Module_Param_Unbound();
725 mp
= new Module_Param_Omit();
728 mp
= new Module_Param_Any();
731 mp
= new Module_Param_AnyOrNone();
734 mp
= new Module_Param_Verdict(single_value
);
737 case COMPLEMENTED_LIST
: {
738 if (template_selection
== VALUE_LIST
) {
739 mp
= new Module_Param_List_Template();
742 mp
= new Module_Param_ComplementList_Template();
744 for (size_t i
= 0; i
< value_list
.n_values
; ++i
) {
745 mp
->add_elem(value_list
.list_value
[i
].get_param(param_name
));
757 void VERDICTTYPE_template::encode_text(Text_Buf
& text_buf
) const
759 encode_text_base(text_buf
);
760 switch (template_selection
) {
766 text_buf
.push_int(single_value
);
769 case COMPLEMENTED_LIST
:
770 text_buf
.push_int(value_list
.n_values
);
771 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
772 value_list
.list_value
[i
].encode_text(text_buf
);
775 TTCN_error("Text encoder: Encoding an undefined/unsupported verdict "
780 void VERDICTTYPE_template::decode_text(Text_Buf
& text_buf
)
783 decode_text_base(text_buf
);
784 switch (template_selection
) {
789 case SPECIFIC_VALUE
: {
790 int received_value
= text_buf
.pull_int().get_val();
791 if (!IS_VALID(received_value
)) TTCN_error("Text decoder: Invalid "
792 "verdict value (%d) was received for a template.", received_value
);
793 single_value
= (verdicttype
)received_value
;
796 case COMPLEMENTED_LIST
:
797 value_list
.n_values
= text_buf
.pull_int().get_val();
798 value_list
.list_value
= new VERDICTTYPE_template
[value_list
.n_values
];
799 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
800 value_list
.list_value
[i
].decode_text(text_buf
);
803 TTCN_error("Text decoder: An unknown/unsupported selection was received "
804 "for a verdict template.");
808 boolean
VERDICTTYPE_template::is_present(boolean legacy
/* = FALSE */) const
810 if (template_selection
==UNINITIALIZED_TEMPLATE
) return FALSE
;
811 return !match_omit(legacy
);
814 boolean
VERDICTTYPE_template::match_omit(boolean legacy
/* = FALSE */) const
816 if (is_ifpresent
) return TRUE
;
817 switch (template_selection
) {
822 case COMPLEMENTED_LIST
:
824 // legacy behavior: 'omit' can appear in the value/complement list
825 for (unsigned int i
=0; i
<value_list
.n_values
; i
++)
826 if (value_list
.list_value
[i
].match_omit())
827 return template_selection
==VALUE_LIST
;
828 return template_selection
==COMPLEMENTED_LIST
;
837 #ifndef TITAN_RUNTIME_2
838 void VERDICTTYPE_template::check_restriction(template_res t_res
, const char* t_name
,
839 boolean legacy
/* = FALSE */) const
841 if (template_selection
==UNINITIALIZED_TEMPLATE
) return;
842 switch ((t_name
&&(t_res
==TR_VALUE
))?TR_OMIT
:t_res
) {
844 if (!is_ifpresent
&& template_selection
==SPECIFIC_VALUE
) return;
847 if (!is_ifpresent
&& (template_selection
==OMIT_VALUE
||
848 template_selection
==SPECIFIC_VALUE
)) return;
851 if (!match_omit(legacy
)) return;
856 TTCN_error("Restriction `%s' on template of type %s violated.",
857 get_res_name(t_res
), t_name
? t_name
: "verdict");