1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8 #include "Verdicttype.hh"
10 #include "Param_Types.hh"
15 #include "../common/dbgnew.hh"
17 #define UNBOUND_VERDICT ((verdicttype)(ERROR + 1))
18 #define IS_VALID(verdict_value) (verdict_value >= NONE && verdict_value <= ERROR)
20 const char * const verdict_name
[] = { "none", "pass", "inconc", "fail", "error" };
22 VERDICTTYPE::VERDICTTYPE()
24 verdict_value
= UNBOUND_VERDICT
;
27 VERDICTTYPE::VERDICTTYPE(verdicttype other_value
)
29 if (!IS_VALID(other_value
)) TTCN_error("Initializing a verdict variable "
30 "with an invalid value (%d).", other_value
);
31 verdict_value
= other_value
;
34 VERDICTTYPE::VERDICTTYPE(const VERDICTTYPE
& other_value
)
35 : Base_Type(other_value
)
37 if (!other_value
.is_bound()) TTCN_error("Copying an unbound verdict value.");
38 verdict_value
= other_value
.verdict_value
;
41 VERDICTTYPE
& VERDICTTYPE::operator=(verdicttype other_value
)
43 if (!IS_VALID(other_value
))
44 TTCN_error("Assignment of an invalid verdict value (%d).", other_value
);
45 verdict_value
= other_value
;
49 VERDICTTYPE
& VERDICTTYPE::operator=(const VERDICTTYPE
& other_value
)
51 if (!other_value
.is_bound())
52 TTCN_error("Assignment of an unbound verdict value.");
53 verdict_value
= other_value
.verdict_value
;
57 boolean
VERDICTTYPE::operator==(verdicttype other_value
) const
59 if (!is_bound()) TTCN_error("The left operand of comparison is an unbound "
61 if (!IS_VALID(other_value
)) TTCN_error("The right operand of comparison is "
62 "an invalid verdict value (%d).", other_value
);
63 return verdict_value
== other_value
;
66 boolean
VERDICTTYPE::operator==(const VERDICTTYPE
& other_value
) const
68 if (!is_bound()) TTCN_error("The left operand of comparison is an unbound "
70 if (!other_value
.is_bound()) TTCN_error("The right operand of comparison is "
71 "an unbound verdict value.");
72 return verdict_value
== other_value
.verdict_value
;
75 VERDICTTYPE::operator verdicttype() const
78 TTCN_error("Using the value of an unbound verdict variable.");
82 void VERDICTTYPE::clean_up()
84 verdict_value
= UNBOUND_VERDICT
;
87 void VERDICTTYPE::log() const
89 if (IS_VALID(verdict_value
))
90 TTCN_Logger::log_event_str(verdict_name
[verdict_value
]);
91 else if (verdict_value
== UNBOUND_VERDICT
)
92 TTCN_Logger::log_event_unbound();
93 else TTCN_Logger::log_event("<invalid verdict value: %d>", verdict_value
);
96 void VERDICTTYPE::set_param(Module_Param
& param
) {
97 param
.basic_check(Module_Param::BC_VALUE
, "verdict value");
98 Module_Param_Ptr mp
= ¶m
;
99 if (param
.get_type() == Module_Param::MP_Reference
) {
100 mp
= param
.get_referenced_param();
102 if (mp
->get_type()!=Module_Param::MP_Verdict
) param
.type_error("verdict value");
103 const verdicttype verdict
= mp
->get_verdict();
104 if (!IS_VALID(verdict
)) param
.error("Internal error: invalid verdict value (%d).", verdict
);
105 verdict_value
= verdict
;
108 Module_Param
* VERDICTTYPE::get_param(Module_Param_Name
& /* param_name */) const
111 return new Module_Param_Unbound();
113 return new Module_Param_Verdict(verdict_value
);
116 void VERDICTTYPE::encode_text(Text_Buf
& text_buf
) const
119 TTCN_error("Text encoder: Encoding an unbound verdict value.");
120 text_buf
.push_int(verdict_value
);
123 void VERDICTTYPE::decode_text(Text_Buf
& text_buf
)
125 int received_value
= text_buf
.pull_int().get_val();
126 if (!IS_VALID(received_value
)) TTCN_error("Text decoder: Invalid verdict "
127 "value (%d) was received.", received_value
);
128 verdict_value
= (verdicttype
)received_value
;
131 void VERDICTTYPE::encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
132 TTCN_EncDec::coding_t p_coding
, ...) const
135 va_start(pvar
, p_coding
);
138 case TTCN_EncDec::CT_BER
: {
139 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
140 unsigned BER_coding
=va_arg(pvar
, unsigned);
141 BER_encode_chk_coding(BER_coding
);
142 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
143 tlv
->put_in_buffer(p_buf
);
144 ASN_BER_TLV_t::destruct(tlv
);
146 case TTCN_EncDec::CT_RAW
: {
147 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
149 TTCN_EncDec_ErrorContext::error_internal
150 ("No RAW descriptor available for type '%s'.", p_td
.name
);
154 RAW_enc_tree
root(TRUE
,NULL
,&rp
,1,p_td
.raw
);
155 RAW_encode(p_td
, root
);
156 root
.put_to_buf(p_buf
);
158 case TTCN_EncDec::CT_TEXT
: {
159 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
161 TTCN_EncDec_ErrorContext::error_internal
162 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
163 TEXT_encode(p_td
,p_buf
);
166 case TTCN_EncDec::CT_XER
: {
167 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
168 unsigned XER_coding
=va_arg(pvar
, unsigned);
169 XER_encode(*p_td
.xer
, p_buf
, XER_coding
, 0, 0);
171 case TTCN_EncDec::CT_JSON
: {
172 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
174 TTCN_EncDec_ErrorContext::error_internal
175 ("No JSON descriptor available for type '%s'.", p_td
.name
);
176 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
177 JSON_encode(p_td
, tok
);
178 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
181 TTCN_error("Unknown coding method requested to encode type '%s'",
187 void VERDICTTYPE::decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
188 TTCN_EncDec::coding_t p_coding
, ...)
191 va_start(pvar
, p_coding
);
194 case TTCN_EncDec::CT_RAW
: {
195 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
197 TTCN_EncDec_ErrorContext::error_internal
198 ("No RAW descriptor available for type '%s'.", p_td
.name
);
200 switch(p_td
.raw
->top_bit_order
){
208 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
209 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
210 "Can not decode type '%s', because invalid or incomplete"
211 " message was received"
214 case TTCN_EncDec::CT_TEXT
: {
215 Limit_Token_List limit
;
216 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
218 TTCN_EncDec_ErrorContext::error_internal
219 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
220 const unsigned char *b
=p_buf
.get_data();
221 if(b
[p_buf
.get_len()-1]!='\0'){
222 p_buf
.set_pos(p_buf
.get_len());
223 p_buf
.put_zero(8,ORDER_LSB
);
226 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
227 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
228 "Can not decode type '%s', because invalid or incomplete"
229 " message was received"
233 case TTCN_EncDec::CT_XER
: {
234 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
235 unsigned XER_coding
=va_arg(pvar
, unsigned);
236 XmlReaderWrap
reader(p_buf
);
237 for (int success
= reader
.Read(); success
==1; success
=reader
.Read()) {
238 int type
= reader
.NodeType();
239 if (type
==XML_READER_TYPE_ELEMENT
)
242 XER_decode(*p_td
.xer
, reader
, XER_coding
, XER_NONE
, 0);
243 size_t bytes
= reader
.ByteConsumed();
244 p_buf
.set_pos(bytes
);
246 case TTCN_EncDec::CT_JSON
: {
247 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
249 TTCN_EncDec_ErrorContext::error_internal
250 ("No JSON descriptor available for type '%s'.", p_td
.name
);
251 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
252 if(JSON_decode(p_td
, tok
, false)<0)
253 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
254 "Can not decode type '%s', because invalid or incomplete"
255 " message was received"
257 p_buf
.set_pos(tok
.get_buf_pos());
260 TTCN_error("Unknown coding method requested to decode type '%s'",
267 int VERDICTTYPE::XER_encode(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
268 unsigned int p_flavor
, int p_indent
, embed_values_enc_struct_t
*) const
270 int encoded_length
=(int)p_buf
.get_len();
271 //const boolean e_xer = is_exer(p_flavor);
272 p_flavor
|= (SIMPLE_TYPE
| BXER_EMPTY_ELEM
);
273 if (begin_xml(p_td
, p_buf
, p_flavor
, p_indent
, false) == -1) --encoded_length
;
274 //if (!e_xer) p_buf.put_c('<');
276 const char * enumval
= verdict_name
[verdict_value
];
277 p_buf
.put_s(strlen(enumval
), (const unsigned char*)enumval
);
279 //if (!e_xer) p_buf.put_s(2, (const unsigned char*)"/>");
280 end_xml(p_td
, p_buf
, p_flavor
, p_indent
, false);
281 return (int)p_buf
.get_len() - encoded_length
;
284 verdicttype
VERDICTTYPE::str_to_verdict(const char *v
, boolean silent
)
286 for (int i
= NONE
; i
<= ERROR
; ++i
) {
287 if (0 == strcmp(v
, verdict_name
[i
])) {
288 return (verdicttype
)i
;
293 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
294 "Invalid value for verdicttype: '%s'", v
);
296 return UNBOUND_VERDICT
;
299 int VERDICTTYPE::XER_decode(const XERdescriptor_t
& p_td
, XmlReaderWrap
& p_reader
,
300 unsigned int p_flavor
, unsigned int /*flavor2*/, embed_values_dec_struct_t
*)
303 const int e_xer
= is_exer(p_flavor
);
304 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
)))));
305 if (e_xer
&& ((p_td
.xer_bits
& XER_ATTRIBUTE
) || is_exerlist(p_flavor
))) {
306 if ((p_td
.xer_bits
& XER_ATTRIBUTE
)) verify_name(p_reader
, p_td
, e_xer
);
307 const char * value
= (const char *)p_reader
.Value();
309 verdict_value
= str_to_verdict(value
, (p_flavor
& EXIT_ON_ERROR
) ? true : false);
313 if (name_tag
) for (; rd_ok
== 1; rd_ok
= p_reader
.Read()) {
314 type
= p_reader
.NodeType();
315 if (XML_READER_TYPE_ELEMENT
== type
) {
316 rd_ok
= p_reader
.Read();
320 for (; rd_ok
== 1; rd_ok
= p_reader
.Read()) {
321 type
= p_reader
.NodeType();
322 if (!e_xer
&& XML_READER_TYPE_ELEMENT
== type
) break;
323 if (XML_READER_TYPE_TEXT
== type
) break;
325 const char *local_name
= /*e_xer ?*/ (const char *)p_reader
.Value() /*: (const char *)p_reader.Name()*/;
326 if (!local_name
) ; else {
327 for (; '\t'==*local_name
|| '\n'==*local_name
; ++local_name
) ;
328 verdict_value
= str_to_verdict(local_name
, (p_flavor
& EXIT_ON_ERROR
) ? true : false);
331 for (rd_ok
= p_reader
.Read(); rd_ok
== 1; rd_ok
= p_reader
.Read()) {
332 type
= p_reader
.NodeType();
333 if (XML_READER_TYPE_END_ELEMENT
== type
) {
338 else p_reader
.Read();
340 int decoded_length
= 0;
341 return decoded_length
;
344 int VERDICTTYPE::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
347 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
348 "Encoding an unbound verdicttype value.");
352 char* tmp_str
= mprintf("\"%s\"", verdict_name
[verdict_value
]);
353 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_STRING
, tmp_str
);
358 int VERDICTTYPE::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
360 json_token_t token
= JSON_TOKEN_NONE
;
362 size_t value_len
= 0;
364 boolean use_default
= p_td
.json
->default_value
&& 0 == p_tok
.get_buffer_length();
366 // No JSON data in the buffer -> use default value
367 value
= (char*)p_td
.json
->default_value
;
368 value_len
= strlen(value
);
370 dec_len
= p_tok
.get_next_token(&token
, &value
, &value_len
);
372 boolean error
= true;
373 if (JSON_TOKEN_ERROR
== token
) {
374 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
375 dec_len
= JSON_ERROR_FATAL
;
377 else if (JSON_TOKEN_STRING
== token
|| use_default
) {
378 if (use_default
|| (value
[0] == '\"' && value
[value_len
- 1] == '\"')) {
380 // The default value doesn't have quotes around it
384 for (int i
= NONE
; i
<= ERROR
; ++i
) {
385 if (0 == strncmp(value
, verdict_name
[i
], value_len
)) {
386 verdict_value
= (verdicttype
)i
;
394 verdict_value
= UNBOUND_VERDICT
;
395 dec_len
= JSON_ERROR_INVALID_TOKEN
;
398 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FORMAT_ERROR
, "string", "verdicttype");
399 verdict_value
= UNBOUND_VERDICT
;
400 dec_len
= JSON_ERROR_FATAL
;
406 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
408 boolean
operator==(verdicttype par_value
, const VERDICTTYPE
& other_value
)
410 if (!IS_VALID(par_value
)) TTCN_error("The left operand of comparison is "
411 "an invalid verdict value (%d).", par_value
);
412 if (!other_value
.is_bound()) TTCN_error("The right operand of comparison "
413 "is an unbound verdict value.");
414 return par_value
== other_value
.verdict_value
;
417 void VERDICTTYPE_template::clean_up()
419 if (template_selection
== VALUE_LIST
||
420 template_selection
== COMPLEMENTED_LIST
)
421 delete [] value_list
.list_value
;
422 template_selection
= UNINITIALIZED_TEMPLATE
;
425 void VERDICTTYPE_template::copy_value(const VERDICTTYPE
& other_value
)
427 if (!other_value
.is_bound())
428 TTCN_error("Creating a template from an unbound verdict value.");
429 single_value
= other_value
.verdict_value
;
430 set_selection(SPECIFIC_VALUE
);
433 void VERDICTTYPE_template::copy_template
434 (const VERDICTTYPE_template
& other_value
)
436 switch (other_value
.template_selection
) {
438 single_value
= other_value
.single_value
;
445 case COMPLEMENTED_LIST
:
446 value_list
.n_values
= other_value
.value_list
.n_values
;
447 value_list
.list_value
= new VERDICTTYPE_template
[value_list
.n_values
];
448 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
449 value_list
.list_value
[i
].copy_template(
450 other_value
.value_list
.list_value
[i
]);
453 TTCN_error("Copying an uninitialized/unsupported verdict template.");
455 set_selection(other_value
);
458 VERDICTTYPE_template::VERDICTTYPE_template()
462 VERDICTTYPE_template::VERDICTTYPE_template(template_sel other_value
)
463 : Base_Template(other_value
)
465 check_single_selection(other_value
);
468 VERDICTTYPE_template::VERDICTTYPE_template(verdicttype other_value
)
469 : Base_Template(SPECIFIC_VALUE
)
471 if (!IS_VALID(other_value
)) TTCN_error("Creating a template from an "
472 "invalid verdict value (%d).", other_value
);
473 single_value
= other_value
;
476 VERDICTTYPE_template::VERDICTTYPE_template(const VERDICTTYPE
& other_value
)
478 copy_value(other_value
);
481 VERDICTTYPE_template::VERDICTTYPE_template
482 (const OPTIONAL
<VERDICTTYPE
>& other_value
)
484 switch (other_value
.get_selection()) {
485 case OPTIONAL_PRESENT
:
486 copy_value((const VERDICTTYPE
&)other_value
);
489 set_selection(OMIT_VALUE
);
492 TTCN_error("Creating a verdict template from an unbound optional field.");
496 VERDICTTYPE_template::VERDICTTYPE_template
497 (const VERDICTTYPE_template
& other_value
)
500 copy_template(other_value
);
503 VERDICTTYPE_template::~VERDICTTYPE_template()
508 VERDICTTYPE_template
& VERDICTTYPE_template::operator=(template_sel other_value
)
510 check_single_selection(other_value
);
512 set_selection(other_value
);
516 VERDICTTYPE_template
& VERDICTTYPE_template::operator=(verdicttype other_value
)
518 if (!IS_VALID(other_value
)) TTCN_error("Assignment of an invalid verdict "
519 "value (%d) to a template.", other_value
);
521 set_selection(SPECIFIC_VALUE
);
522 single_value
= other_value
;
526 VERDICTTYPE_template
& VERDICTTYPE_template::operator=
527 (const VERDICTTYPE
& other_value
)
530 copy_value(other_value
);
534 VERDICTTYPE_template
& VERDICTTYPE_template::operator=
535 (const OPTIONAL
<VERDICTTYPE
>& other_value
)
538 switch (other_value
.get_selection()) {
539 case OPTIONAL_PRESENT
:
540 copy_value((const VERDICTTYPE
&)other_value
);
543 set_selection(OMIT_VALUE
);
546 TTCN_error("Assignment of an unbound optional field to a verdict "
552 VERDICTTYPE_template
& VERDICTTYPE_template::operator=
553 (const VERDICTTYPE_template
& other_value
)
555 if (&other_value
!= this) {
557 copy_template(other_value
);
562 boolean
VERDICTTYPE_template::match(verdicttype other_value
,
563 boolean
/* legacy */) const
565 if (!IS_VALID(other_value
)) TTCN_error("Matching a verdict template with "
566 "an invalid value (%d).", other_value
);
567 switch (template_selection
) {
569 return single_value
== other_value
;
576 case COMPLEMENTED_LIST
:
577 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
578 if (value_list
.list_value
[i
].match(other_value
))
579 return template_selection
== VALUE_LIST
;
580 return template_selection
== COMPLEMENTED_LIST
;
582 TTCN_error("Matching with an uninitialized/unsupported verdict template.");
587 boolean
VERDICTTYPE_template::match(const VERDICTTYPE
& other_value
,
588 boolean
/* legacy */) const
590 if (!other_value
.is_bound()) return FALSE
;
591 return match(other_value
.verdict_value
);
594 verdicttype
VERDICTTYPE_template::valueof() const
596 if (template_selection
!= SPECIFIC_VALUE
|| is_ifpresent
)
597 TTCN_error("Performing a valueof "
598 "or send operation on a non-specific verdict template.");
602 void VERDICTTYPE_template::set_type(template_sel template_type
,
603 unsigned int list_length
)
605 if (template_type
!= VALUE_LIST
&& template_type
!= COMPLEMENTED_LIST
)
606 TTCN_error("Internal error: Setting an invalid list type for a verdict "
609 set_selection(template_type
);
610 value_list
.n_values
= list_length
;
611 value_list
.list_value
= new VERDICTTYPE_template
[list_length
];
614 VERDICTTYPE_template
& VERDICTTYPE_template::list_item(unsigned int list_index
)
616 if (template_selection
!= VALUE_LIST
&&
617 template_selection
!= COMPLEMENTED_LIST
)
618 TTCN_error("Internal error: Accessing a list element of a non-list "
619 "verdict template.");
620 if (list_index
>= value_list
.n_values
)
621 TTCN_error("Internal error: Index overflow in a verdict value list "
623 return value_list
.list_value
[list_index
];
626 void VERDICTTYPE_template::log() const
628 switch (template_selection
) {
630 if (IS_VALID(single_value
))
631 TTCN_Logger::log_event("%s", verdict_name
[single_value
]);
632 else TTCN_Logger::log_event("<unknown verdict value: %d>", single_value
);
634 case COMPLEMENTED_LIST
:
635 TTCN_Logger::log_event_str("complement ");
638 TTCN_Logger::log_char('(');
639 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++) {
640 if (i
> 0) TTCN_Logger::log_event_str(", ");
641 value_list
.list_value
[i
].log();
643 TTCN_Logger::log_char(')');
652 void VERDICTTYPE_template::log_match(const VERDICTTYPE
& match_value
,
653 boolean
/* legacy */) const
655 if (TTCN_Logger::VERBOSITY_COMPACT
== TTCN_Logger::get_matching_verbosity()
656 && TTCN_Logger::get_logmatch_buffer_len() != 0) {
657 TTCN_Logger::print_logmatch_buffer();
658 TTCN_Logger::log_event_str(" := ");
661 TTCN_Logger::log_event_str(" with ");
663 if (match(match_value
)) TTCN_Logger::log_event_str(" matched");
664 else TTCN_Logger::log_event_str(" unmatched");
667 void VERDICTTYPE_template::set_param(Module_Param
& param
) {
668 param
.basic_check(Module_Param::BC_TEMPLATE
, "verdict template");
669 Module_Param_Ptr mp
= ¶m
;
670 if (param
.get_type() == Module_Param::MP_Reference
) {
671 mp
= param
.get_referenced_param();
673 switch (mp
->get_type()) {
674 case Module_Param::MP_Omit
:
677 case Module_Param::MP_Any
:
680 case Module_Param::MP_AnyOrNone
:
683 case Module_Param::MP_List_Template
:
684 case Module_Param::MP_ComplementList_Template
: {
685 VERDICTTYPE_template temp
;
686 temp
.set_type(mp
->get_type() == Module_Param::MP_List_Template
?
687 VALUE_LIST
: COMPLEMENTED_LIST
, mp
->get_size());
688 for (size_t i
=0; i
<mp
->get_size(); i
++) {
689 temp
.list_item(i
).set_param(*mp
->get_elem(i
));
693 case Module_Param::MP_Verdict
:
694 *this = mp
->get_verdict();
697 param
.type_error("verdict template");
699 is_ifpresent
= param
.get_ifpresent() || mp
->get_ifpresent();
702 Module_Param
* VERDICTTYPE_template::get_param(Module_Param_Name
& param_name
) const
704 Module_Param
* mp
= NULL
;
705 switch (template_selection
) {
706 case UNINITIALIZED_TEMPLATE
:
707 mp
= new Module_Param_Unbound();
710 mp
= new Module_Param_Omit();
713 mp
= new Module_Param_Any();
716 mp
= new Module_Param_AnyOrNone();
719 mp
= new Module_Param_Verdict(single_value
);
722 case COMPLEMENTED_LIST
: {
723 if (template_selection
== VALUE_LIST
) {
724 mp
= new Module_Param_List_Template();
727 mp
= new Module_Param_ComplementList_Template();
729 for (size_t i
= 0; i
< value_list
.n_values
; ++i
) {
730 mp
->add_elem(value_list
.list_value
[i
].get_param(param_name
));
742 void VERDICTTYPE_template::encode_text(Text_Buf
& text_buf
) const
744 encode_text_base(text_buf
);
745 switch (template_selection
) {
751 text_buf
.push_int(single_value
);
754 case COMPLEMENTED_LIST
:
755 text_buf
.push_int(value_list
.n_values
);
756 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
757 value_list
.list_value
[i
].encode_text(text_buf
);
760 TTCN_error("Text encoder: Encoding an undefined/unsupported verdict "
765 void VERDICTTYPE_template::decode_text(Text_Buf
& text_buf
)
768 decode_text_base(text_buf
);
769 switch (template_selection
) {
774 case SPECIFIC_VALUE
: {
775 int received_value
= text_buf
.pull_int().get_val();
776 if (!IS_VALID(received_value
)) TTCN_error("Text decoder: Invalid "
777 "verdict value (%d) was received for a template.", received_value
);
778 single_value
= (verdicttype
)received_value
;
781 case COMPLEMENTED_LIST
:
782 value_list
.n_values
= text_buf
.pull_int().get_val();
783 value_list
.list_value
= new VERDICTTYPE_template
[value_list
.n_values
];
784 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
785 value_list
.list_value
[i
].decode_text(text_buf
);
788 TTCN_error("Text decoder: An unknown/unsupported selection was received "
789 "for a verdict template.");
793 boolean
VERDICTTYPE_template::is_present(boolean legacy
/* = FALSE */) const
795 if (template_selection
==UNINITIALIZED_TEMPLATE
) return FALSE
;
796 return !match_omit(legacy
);
799 boolean
VERDICTTYPE_template::match_omit(boolean legacy
/* = FALSE */) const
801 if (is_ifpresent
) return TRUE
;
802 switch (template_selection
) {
807 case COMPLEMENTED_LIST
:
809 // legacy behavior: 'omit' can appear in the value/complement list
810 for (unsigned int i
=0; i
<value_list
.n_values
; i
++)
811 if (value_list
.list_value
[i
].match_omit())
812 return template_selection
==VALUE_LIST
;
813 return template_selection
==COMPLEMENTED_LIST
;
822 #ifndef TITAN_RUNTIME_2
823 void VERDICTTYPE_template::check_restriction(template_res t_res
, const char* t_name
,
824 boolean legacy
/* = FALSE */) const
826 if (template_selection
==UNINITIALIZED_TEMPLATE
) return;
827 switch ((t_name
&&(t_res
==TR_VALUE
))?TR_OMIT
:t_res
) {
829 if (!is_ifpresent
&& template_selection
==SPECIFIC_VALUE
) return;
832 if (!is_ifpresent
&& (template_selection
==OMIT_VALUE
||
833 template_selection
==SPECIFIC_VALUE
)) return;
836 if (!match_omit(legacy
)) return;
841 TTCN_error("Restriction `%s' on template of type %s violated.",
842 get_res_name(t_res
), t_name
? t_name
: "verdict");