1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8 #include "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 if (param
.get_type()!=Module_Param::MP_Verdict
) param
.type_error("verdict value");
99 const verdicttype verdict
= param
.get_verdict();
100 if (!IS_VALID(verdict
)) param
.error("Internal error: invalid verdict value (%d).", verdict
);
101 verdict_value
= verdict
;
104 void VERDICTTYPE::encode_text(Text_Buf
& text_buf
) const
107 TTCN_error("Text encoder: Encoding an unbound verdict value.");
108 text_buf
.push_int(verdict_value
);
111 void VERDICTTYPE::decode_text(Text_Buf
& text_buf
)
113 int received_value
= text_buf
.pull_int().get_val();
114 if (!IS_VALID(received_value
)) TTCN_error("Text decoder: Invalid verdict "
115 "value (%d) was received.", received_value
);
116 verdict_value
= (verdicttype
)received_value
;
119 void VERDICTTYPE::encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
120 TTCN_EncDec::coding_t p_coding
, ...) const
123 va_start(pvar
, p_coding
);
126 case TTCN_EncDec::CT_BER
: {
127 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
128 unsigned BER_coding
=va_arg(pvar
, unsigned);
129 BER_encode_chk_coding(BER_coding
);
130 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
131 tlv
->put_in_buffer(p_buf
);
132 ASN_BER_TLV_t::destruct(tlv
);
134 case TTCN_EncDec::CT_RAW
: {
135 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
137 TTCN_EncDec_ErrorContext::error_internal
138 ("No RAW descriptor available for type '%s'.", p_td
.name
);
142 RAW_enc_tree
root(TRUE
,NULL
,&rp
,1,p_td
.raw
);
143 RAW_encode(p_td
, root
);
144 root
.put_to_buf(p_buf
);
146 case TTCN_EncDec::CT_TEXT
: {
147 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
149 TTCN_EncDec_ErrorContext::error_internal
150 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
151 TEXT_encode(p_td
,p_buf
);
154 case TTCN_EncDec::CT_XER
: {
155 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
156 unsigned XER_coding
=va_arg(pvar
, unsigned);
157 XER_encode(*p_td
.xer
, p_buf
, XER_coding
, 0, 0);
159 case TTCN_EncDec::CT_JSON
: {
160 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
162 TTCN_EncDec_ErrorContext::error_internal
163 ("No JSON descriptor available for type '%s'.", p_td
.name
);
164 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
165 JSON_encode(p_td
, tok
);
166 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
169 TTCN_error("Unknown coding method requested to encode type '%s'",
175 void VERDICTTYPE::decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
176 TTCN_EncDec::coding_t p_coding
, ...)
179 va_start(pvar
, p_coding
);
182 case TTCN_EncDec::CT_RAW
: {
183 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
185 TTCN_EncDec_ErrorContext::error_internal
186 ("No RAW descriptor available for type '%s'.", p_td
.name
);
188 switch(p_td
.raw
->top_bit_order
){
196 if(RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
)<0)
197 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
198 "Can not decode type '%s', because invalid or incomplete"
199 " message was received"
202 case TTCN_EncDec::CT_TEXT
: {
203 Limit_Token_List limit
;
204 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
206 TTCN_EncDec_ErrorContext::error_internal
207 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
208 const unsigned char *b
=p_buf
.get_data();
209 if(b
[p_buf
.get_len()-1]!='\0'){
210 p_buf
.set_pos(p_buf
.get_len());
211 p_buf
.put_zero(8,ORDER_LSB
);
214 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
215 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
216 "Can not decode type '%s', because invalid or incomplete"
217 " message was received"
221 case TTCN_EncDec::CT_XER
: {
222 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
223 unsigned XER_coding
=va_arg(pvar
, unsigned);
224 XmlReaderWrap
reader(p_buf
);
225 for (int success
= reader
.Read(); success
==1; success
=reader
.Read()) {
226 int type
= reader
.NodeType();
227 if (type
==XML_READER_TYPE_ELEMENT
)
230 XER_decode(*p_td
.xer
, reader
, XER_coding
, 0);
231 size_t bytes
= reader
.ByteConsumed();
232 p_buf
.set_pos(bytes
);
234 case TTCN_EncDec::CT_JSON
: {
235 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
237 TTCN_EncDec_ErrorContext::error_internal
238 ("No JSON descriptor available for type '%s'.", p_td
.name
);
239 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
240 if(JSON_decode(p_td
, tok
, false)<0)
241 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
242 "Can not decode type '%s', because invalid or incomplete"
243 " message was received"
245 p_buf
.set_pos(tok
.get_buf_pos());
248 TTCN_error("Unknown coding method requested to decode type '%s'",
255 int VERDICTTYPE::XER_encode(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
256 unsigned int p_flavor
, int p_indent
, embed_values_enc_struct_t
*) const
258 int encoded_length
=(int)p_buf
.get_len();
259 //const boolean e_xer = is_exer(p_flavor);
260 p_flavor
|= (SIMPLE_TYPE
| BXER_EMPTY_ELEM
);
261 if (begin_xml(p_td
, p_buf
, p_flavor
, p_indent
, false) == -1) --encoded_length
;
262 //if (!e_xer) p_buf.put_c('<');
264 const char * enumval
= verdict_name
[verdict_value
];
265 p_buf
.put_s(strlen(enumval
), (const unsigned char*)enumval
);
267 //if (!e_xer) p_buf.put_s(2, (const unsigned char*)"/>");
268 end_xml(p_td
, p_buf
, p_flavor
, p_indent
, false);
269 return (int)p_buf
.get_len() - encoded_length
;
272 verdicttype
VERDICTTYPE::str_to_verdict(const char *v
, boolean silent
)
274 for (int i
= NONE
; i
<= ERROR
; ++i
) {
275 if (0 == strcmp(v
, verdict_name
[i
])) {
276 return (verdicttype
)i
;
281 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
282 "Invalid value for verdicttype: '%s'", v
);
284 return UNBOUND_VERDICT
;
287 int VERDICTTYPE::XER_decode(const XERdescriptor_t
& p_td
, XmlReaderWrap
& p_reader
,
288 unsigned int p_flavor
, embed_values_dec_struct_t
*)
291 const int e_xer
= is_exer(p_flavor
);
292 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
)))));
293 if (e_xer
&& ((p_td
.xer_bits
& XER_ATTRIBUTE
) || is_exerlist(p_flavor
))) {
294 if ((p_td
.xer_bits
& XER_ATTRIBUTE
)) verify_name(p_reader
, p_td
, e_xer
);
295 const char * value
= (const char *)p_reader
.Value();
297 verdict_value
= str_to_verdict(value
, (p_flavor
& EXIT_ON_ERROR
) ? true : false);
301 if (name_tag
) for (; rd_ok
== 1; rd_ok
= p_reader
.Read()) {
302 type
= p_reader
.NodeType();
303 if (XML_READER_TYPE_ELEMENT
== type
) {
304 rd_ok
= p_reader
.Read();
308 for (; rd_ok
== 1; rd_ok
= p_reader
.Read()) {
309 type
= p_reader
.NodeType();
310 if (!e_xer
&& XML_READER_TYPE_ELEMENT
== type
) break;
311 if (XML_READER_TYPE_TEXT
== type
) break;
313 const char *local_name
= /*e_xer ?*/ (const char *)p_reader
.Value() /*: (const char *)p_reader.Name()*/;
314 if (!local_name
) ; else {
315 for (; '\t'==*local_name
|| '\n'==*local_name
; ++local_name
) ;
316 verdict_value
= str_to_verdict(local_name
, (p_flavor
& EXIT_ON_ERROR
) ? true : false);
319 for (rd_ok
= p_reader
.Read(); rd_ok
== 1; rd_ok
= p_reader
.Read()) {
320 type
= p_reader
.NodeType();
321 if (XML_READER_TYPE_END_ELEMENT
== type
) {
326 else p_reader
.Read();
328 int decoded_length
= 0;
329 return decoded_length
;
332 int VERDICTTYPE::JSON_encode(const TTCN_Typedescriptor_t
&, JSON_Tokenizer
& p_tok
) const
335 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND
,
336 "Encoding an unbound verdicttype value.");
340 char* tmp_str
= mprintf("\"%s\"", verdict_name
[verdict_value
]);
341 int enc_len
= p_tok
.put_next_token(JSON_TOKEN_STRING
, tmp_str
);
346 int VERDICTTYPE::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
& p_tok
, boolean p_silent
)
348 json_token_t token
= JSON_TOKEN_NONE
;
350 size_t value_len
= 0;
352 boolean use_default
= p_td
.json
->default_value
&& 0 == p_tok
.get_buffer_length();
354 // No JSON data in the buffer -> use default value
355 value
= (char*)p_td
.json
->default_value
;
356 value_len
= strlen(value
);
358 dec_len
= p_tok
.get_next_token(&token
, &value
, &value_len
);
360 boolean error
= true;
361 if (JSON_TOKEN_ERROR
== token
) {
362 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_BAD_TOKEN_ERROR
, "");
363 dec_len
= JSON_ERROR_FATAL
;
365 else if (JSON_TOKEN_STRING
== token
|| use_default
) {
366 if (use_default
|| (value
[0] == '\"' && value
[value_len
- 1] == '\"')) {
368 // The default value doesn't have quotes around it
372 for (int i
= NONE
; i
<= ERROR
; ++i
) {
373 if (0 == strncmp(value
, verdict_name
[i
], value_len
)) {
374 verdict_value
= (verdicttype
)i
;
382 verdict_value
= UNBOUND_VERDICT
;
383 dec_len
= JSON_ERROR_INVALID_TOKEN
;
386 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG
, JSON_DEC_FORMAT_ERROR
, "string", "verdicttype");
387 verdict_value
= UNBOUND_VERDICT
;
388 dec_len
= JSON_ERROR_FATAL
;
394 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
396 boolean
operator==(verdicttype par_value
, const VERDICTTYPE
& other_value
)
398 if (!IS_VALID(par_value
)) TTCN_error("The left operand of comparison is "
399 "an invalid verdict value (%d).", par_value
);
400 if (!other_value
.is_bound()) TTCN_error("The right operand of comparison "
401 "is an unbound verdict value.");
402 return par_value
== other_value
.verdict_value
;
405 void VERDICTTYPE_template::clean_up()
407 if (template_selection
== VALUE_LIST
||
408 template_selection
== COMPLEMENTED_LIST
)
409 delete [] value_list
.list_value
;
410 template_selection
= UNINITIALIZED_TEMPLATE
;
413 void VERDICTTYPE_template::copy_value(const VERDICTTYPE
& other_value
)
415 if (!other_value
.is_bound())
416 TTCN_error("Creating a template from an unbound verdict value.");
417 single_value
= other_value
.verdict_value
;
418 set_selection(SPECIFIC_VALUE
);
421 void VERDICTTYPE_template::copy_template
422 (const VERDICTTYPE_template
& other_value
)
424 switch (other_value
.template_selection
) {
426 single_value
= other_value
.single_value
;
433 case COMPLEMENTED_LIST
:
434 value_list
.n_values
= other_value
.value_list
.n_values
;
435 value_list
.list_value
= new VERDICTTYPE_template
[value_list
.n_values
];
436 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
437 value_list
.list_value
[i
].copy_template(
438 other_value
.value_list
.list_value
[i
]);
441 TTCN_error("Copying an uninitialized/unsupported verdict template.");
443 set_selection(other_value
);
446 VERDICTTYPE_template::VERDICTTYPE_template()
450 VERDICTTYPE_template::VERDICTTYPE_template(template_sel other_value
)
451 : Base_Template(other_value
)
453 check_single_selection(other_value
);
456 VERDICTTYPE_template::VERDICTTYPE_template(verdicttype other_value
)
457 : Base_Template(SPECIFIC_VALUE
)
459 if (!IS_VALID(other_value
)) TTCN_error("Creating a template from an "
460 "invalid verdict value (%d).", other_value
);
461 single_value
= other_value
;
464 VERDICTTYPE_template::VERDICTTYPE_template(const VERDICTTYPE
& other_value
)
466 copy_value(other_value
);
469 VERDICTTYPE_template::VERDICTTYPE_template
470 (const OPTIONAL
<VERDICTTYPE
>& other_value
)
472 switch (other_value
.get_selection()) {
473 case OPTIONAL_PRESENT
:
474 copy_value((const VERDICTTYPE
&)other_value
);
477 set_selection(OMIT_VALUE
);
480 TTCN_error("Creating a verdict template from an unbound optional field.");
484 VERDICTTYPE_template::VERDICTTYPE_template
485 (const VERDICTTYPE_template
& other_value
)
488 copy_template(other_value
);
491 VERDICTTYPE_template::~VERDICTTYPE_template()
496 VERDICTTYPE_template
& VERDICTTYPE_template::operator=(template_sel other_value
)
498 check_single_selection(other_value
);
500 set_selection(other_value
);
504 VERDICTTYPE_template
& VERDICTTYPE_template::operator=(verdicttype other_value
)
506 if (!IS_VALID(other_value
)) TTCN_error("Assignment of an invalid verdict "
507 "value (%d) to a template.", other_value
);
509 set_selection(SPECIFIC_VALUE
);
510 single_value
= other_value
;
514 VERDICTTYPE_template
& VERDICTTYPE_template::operator=
515 (const VERDICTTYPE
& other_value
)
518 copy_value(other_value
);
522 VERDICTTYPE_template
& VERDICTTYPE_template::operator=
523 (const OPTIONAL
<VERDICTTYPE
>& other_value
)
526 switch (other_value
.get_selection()) {
527 case OPTIONAL_PRESENT
:
528 copy_value((const VERDICTTYPE
&)other_value
);
531 set_selection(OMIT_VALUE
);
534 TTCN_error("Assignment of an unbound optional field to a verdict "
540 VERDICTTYPE_template
& VERDICTTYPE_template::operator=
541 (const VERDICTTYPE_template
& other_value
)
543 if (&other_value
!= this) {
545 copy_template(other_value
);
550 boolean
VERDICTTYPE_template::match(verdicttype other_value
) const
552 if (!IS_VALID(other_value
)) TTCN_error("Matching a verdict template with "
553 "an invalid value (%d).", other_value
);
554 switch (template_selection
) {
556 return single_value
== other_value
;
563 case COMPLEMENTED_LIST
:
564 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
565 if (value_list
.list_value
[i
].match(other_value
))
566 return template_selection
== VALUE_LIST
;
567 return template_selection
== COMPLEMENTED_LIST
;
569 TTCN_error("Matching with an uninitialized/unsupported verdict template.");
574 boolean
VERDICTTYPE_template::match(const VERDICTTYPE
& other_value
) const
576 if (!other_value
.is_bound()) return FALSE
;
577 return match(other_value
.verdict_value
);
580 verdicttype
VERDICTTYPE_template::valueof() const
582 if (template_selection
!= SPECIFIC_VALUE
|| is_ifpresent
)
583 TTCN_error("Performing a valueof "
584 "or send operation on a non-specific verdict template.");
588 void VERDICTTYPE_template::set_type(template_sel template_type
,
589 unsigned int list_length
)
591 if (template_type
!= VALUE_LIST
&& template_type
!= COMPLEMENTED_LIST
)
592 TTCN_error("Internal error: Setting an invalid list type for a verdict "
595 set_selection(template_type
);
596 value_list
.n_values
= list_length
;
597 value_list
.list_value
= new VERDICTTYPE_template
[list_length
];
600 VERDICTTYPE_template
& VERDICTTYPE_template::list_item(unsigned int list_index
)
602 if (template_selection
!= VALUE_LIST
&&
603 template_selection
!= COMPLEMENTED_LIST
)
604 TTCN_error("Internal error: Accessing a list element of a non-list "
605 "verdict template.");
606 if (list_index
>= value_list
.n_values
)
607 TTCN_error("Internal error: Index overflow in a verdict value list "
609 return value_list
.list_value
[list_index
];
612 void VERDICTTYPE_template::log() const
614 switch (template_selection
) {
616 if (IS_VALID(single_value
))
617 TTCN_Logger::log_event("%s", verdict_name
[single_value
]);
618 else TTCN_Logger::log_event("<unknown verdict value: %d>", single_value
);
620 case COMPLEMENTED_LIST
:
621 TTCN_Logger::log_event_str("complement ");
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();
629 TTCN_Logger::log_char(')');
638 void VERDICTTYPE_template::log_match(const VERDICTTYPE
& match_value
) const
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(" := ");
646 TTCN_Logger::log_event_str(" with ");
648 if (match(match_value
)) TTCN_Logger::log_event_str(" matched");
649 else TTCN_Logger::log_event_str(" unmatched");
652 void VERDICTTYPE_template::set_param(Module_Param
& param
) {
653 param
.basic_check(Module_Param::BC_TEMPLATE
, "verdict template");
654 switch (param
.get_type()) {
655 case Module_Param::MP_Omit
:
658 case Module_Param::MP_Any
:
661 case Module_Param::MP_AnyOrNone
:
664 case Module_Param::MP_List_Template
:
665 case Module_Param::MP_ComplementList_Template
:
666 set_type(param
.get_type()==Module_Param::MP_List_Template
? VALUE_LIST
: COMPLEMENTED_LIST
, param
.get_size());
667 for (size_t i
=0; i
<param
.get_size(); i
++) {
668 list_item(i
).set_param(*param
.get_elem(i
));
671 case Module_Param::MP_Verdict
:
672 *this = param
.get_verdict();
675 param
.type_error("verdict template");
677 is_ifpresent
= param
.get_ifpresent();
680 void VERDICTTYPE_template::encode_text(Text_Buf
& text_buf
) const
682 encode_text_base(text_buf
);
683 switch (template_selection
) {
689 text_buf
.push_int(single_value
);
692 case COMPLEMENTED_LIST
:
693 text_buf
.push_int(value_list
.n_values
);
694 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
695 value_list
.list_value
[i
].encode_text(text_buf
);
698 TTCN_error("Text encoder: Encoding an undefined/unsupported verdict "
703 void VERDICTTYPE_template::decode_text(Text_Buf
& text_buf
)
706 decode_text_base(text_buf
);
707 switch (template_selection
) {
712 case SPECIFIC_VALUE
: {
713 int received_value
= text_buf
.pull_int().get_val();
714 if (!IS_VALID(received_value
)) TTCN_error("Text decoder: Invalid "
715 "verdict value (%d) was received for a template.", received_value
);
716 single_value
= (verdicttype
)received_value
;
719 case COMPLEMENTED_LIST
:
720 value_list
.n_values
= text_buf
.pull_int().get_val();
721 value_list
.list_value
= new VERDICTTYPE_template
[value_list
.n_values
];
722 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
723 value_list
.list_value
[i
].decode_text(text_buf
);
726 TTCN_error("Text decoder: An unknown/unsupported selection was received "
727 "for a verdict template.");
731 boolean
VERDICTTYPE_template::is_present() const
733 if (template_selection
==UNINITIALIZED_TEMPLATE
) return FALSE
;
734 return !match_omit();
737 boolean
VERDICTTYPE_template::match_omit() const
739 if (is_ifpresent
) return TRUE
;
740 switch (template_selection
) {
745 case COMPLEMENTED_LIST
:
746 for (unsigned int i
=0; i
<value_list
.n_values
; i
++)
747 if (value_list
.list_value
[i
].match_omit())
748 return template_selection
==VALUE_LIST
;
749 return template_selection
==COMPLEMENTED_LIST
;
756 #ifndef TITAN_RUNTIME_2
757 void VERDICTTYPE_template::check_restriction(template_res t_res
, const char* t_name
) const
759 if (template_selection
==UNINITIALIZED_TEMPLATE
) return;
760 switch ((t_name
&&(t_res
==TR_VALUE
))?TR_OMIT
:t_res
) {
762 if (!is_ifpresent
&& template_selection
==SPECIFIC_VALUE
) return;
765 if (!is_ifpresent
&& (template_selection
==OMIT_VALUE
||
766 template_selection
==SPECIFIC_VALUE
)) return;
769 if (!match_omit()) return;
774 TTCN_error("Restriction `%s' on template of type %s violated.",
775 get_res_name(t_res
), t_name
? t_name
: "verdict");