Sync with 5.2.0
[deliverable/titan.core.git] / core / Verdicttype.cc
CommitLineData
970ed795
EL
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"
9
10#include "Param_Types.hh"
11#include "Error.hh"
12#include "Logger.hh"
13#include "Textbuf.hh"
14
15#include "../common/dbgnew.hh"
16
17#define UNBOUND_VERDICT ((verdicttype)(ERROR + 1))
18#define IS_VALID(verdict_value) (verdict_value >= NONE && verdict_value <= ERROR)
19
20const char * const verdict_name[] = { "none", "pass", "inconc", "fail", "error" };
21
22VERDICTTYPE::VERDICTTYPE()
23{
24 verdict_value = UNBOUND_VERDICT;
25}
26
27VERDICTTYPE::VERDICTTYPE(verdicttype other_value)
28{
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;
32}
33
34VERDICTTYPE::VERDICTTYPE(const VERDICTTYPE& other_value)
35: Base_Type(other_value)
36{
37 if (!other_value.is_bound()) TTCN_error("Copying an unbound verdict value.");
38 verdict_value = other_value.verdict_value;
39}
40
41VERDICTTYPE& VERDICTTYPE::operator=(verdicttype other_value)
42{
43 if (!IS_VALID(other_value))
44 TTCN_error("Assignment of an invalid verdict value (%d).", other_value);
45 verdict_value = other_value;
46 return *this;
47}
48
49VERDICTTYPE& VERDICTTYPE::operator=(const VERDICTTYPE& other_value)
50{
51 if (!other_value.is_bound())
52 TTCN_error("Assignment of an unbound verdict value.");
53 verdict_value = other_value.verdict_value;
54 return *this;
55}
56
57boolean VERDICTTYPE::operator==(verdicttype other_value) const
58{
59 if (!is_bound()) TTCN_error("The left operand of comparison is an unbound "
60 "verdict value.");
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;
64}
65
66boolean VERDICTTYPE::operator==(const VERDICTTYPE& other_value) const
67{
68 if (!is_bound()) TTCN_error("The left operand of comparison is an unbound "
69 "verdict value.");
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;
73}
74
75VERDICTTYPE::operator verdicttype() const
76{
77 if (!is_bound())
78 TTCN_error("Using the value of an unbound verdict variable.");
79 return verdict_value;
80}
81
82void VERDICTTYPE::clean_up()
83{
84 verdict_value = UNBOUND_VERDICT;
85}
86
87void VERDICTTYPE::log() const
88{
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);
94}
95
96void 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;
102}
103
104void VERDICTTYPE::encode_text(Text_Buf& text_buf) const
105{
106 if (!is_bound())
107 TTCN_error("Text encoder: Encoding an unbound verdict value.");
108 text_buf.push_int(verdict_value);
109}
110
111void VERDICTTYPE::decode_text(Text_Buf& text_buf)
112{
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;
117}
118
119void VERDICTTYPE::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
120 TTCN_EncDec::coding_t p_coding, ...) const
121{
122 va_list pvar;
123 va_start(pvar, p_coding);
124 switch(p_coding) {
125#if 0
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);
133 break;}
134 case TTCN_EncDec::CT_RAW: {
135 TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name);
136 if(!p_td.raw)
137 TTCN_EncDec_ErrorContext::error_internal
138 ("No RAW descriptor available for type '%s'.", p_td.name);
139 RAW_enc_tr_pos rp;
140 rp.level=0;
141 rp.pos=NULL;
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);
145 break;}
146 case TTCN_EncDec::CT_TEXT: {
147 TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name);
148 if(!p_td.text)
149 TTCN_EncDec_ErrorContext::error_internal
150 ("No TEXT descriptor available for type '%s'.", p_td.name);
151 TEXT_encode(p_td,p_buf);
152 break;}
153#endif
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);
af710487 157 XER_encode(*p_td.xer, p_buf, XER_coding, 0, 0);
970ed795
EL
158 break;}
159 case TTCN_EncDec::CT_JSON: {
160 TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
161 if(!p_td.json)
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());
167 break;}
168 default:
169 TTCN_error("Unknown coding method requested to encode type '%s'",
170 p_td.name);
171 }
172 va_end(pvar);
173}
174
175void VERDICTTYPE::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
176 TTCN_EncDec::coding_t p_coding, ...)
177{
178 va_list pvar;
179 va_start(pvar, p_coding);
180 switch(p_coding) {
181#if 0
182 case TTCN_EncDec::CT_RAW: {
183 TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name);
184 if(!p_td.raw)
185 TTCN_EncDec_ErrorContext::error_internal
186 ("No RAW descriptor available for type '%s'.", p_td.name);
187 raw_order_t order;
188 switch(p_td.raw->top_bit_order){
189 case TOP_BIT_LEFT:
190 order=ORDER_LSB;
191 break;
192 case TOP_BIT_RIGHT:
193 default:
194 order=ORDER_MSB;
195 }
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"
200 , p_td.name);
201 break;}
202 case TTCN_EncDec::CT_TEXT: {
203 Limit_Token_List limit;
204 TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name);
205 if(!p_td.text)
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);
212 p_buf.rewind();
213 }
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"
218 , p_td.name);
219 break;}
220#endif
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)
228 break;
229 }
af710487 230 XER_decode(*p_td.xer, reader, XER_coding, 0);
970ed795
EL
231 size_t bytes = reader.ByteConsumed();
232 p_buf.set_pos(bytes);
233 break;}
234 case TTCN_EncDec::CT_JSON: {
235 TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
236 if(!p_td.json)
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"
244 , p_td.name);
245 p_buf.set_pos(tok.get_buf_pos());
246 break;}
247 default:
248 TTCN_error("Unknown coding method requested to decode type '%s'",
249 p_td.name);
250 }
251 va_end(pvar);
252}
253
254
255int VERDICTTYPE::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf,
af710487 256 unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const
970ed795
EL
257{
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('<');
263 {
264 const char * enumval = verdict_name[verdict_value];
265 p_buf.put_s(strlen(enumval), (const unsigned char*)enumval);
266 }
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;
270}
271
272verdicttype VERDICTTYPE::str_to_verdict(const char *v, boolean silent)
273{
274 for (int i = NONE; i <= ERROR; ++i) {
275 if (0 == strcmp(v, verdict_name[i])) {
276 return (verdicttype)i;
277 }
278 }
279
280 if (!silent) {
281 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
282 "Invalid value for verdicttype: '%s'", v);
283 }
284 return UNBOUND_VERDICT;
285}
286
287int VERDICTTYPE::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader,
af710487 288 unsigned int p_flavor, embed_values_dec_struct_t*)
970ed795
EL
289{
290 int rd_ok = 1, type;
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();
296 if (value) {
297 verdict_value = str_to_verdict(value, (p_flavor & EXIT_ON_ERROR) ? true : false);
298 }
299 }
300 else {
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();
305 break;
306 }
307 }
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;
312 }
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);
317 }
318 if (name_tag)
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) {
322 p_reader.Read();
323 break;
324 }
325 }
326 else p_reader.Read();
327 }
328 int decoded_length = 0;
329 return decoded_length;
330}
331
332int VERDICTTYPE::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const
333{
334 if (!is_bound()) {
335 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
336 "Encoding an unbound verdicttype value.");
337 return -1;
338 }
339
340 char* tmp_str = mprintf("\"%s\"", verdict_name[verdict_value]);
341 int enc_len = p_tok.put_next_token(JSON_TOKEN_STRING, tmp_str);
342 Free(tmp_str);
343 return enc_len;
344}
345
346int VERDICTTYPE::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok, boolean p_silent)
347{
348 json_token_t token = JSON_TOKEN_NONE;
349 char* value = 0;
350 size_t value_len = 0;
351 int dec_len = 0;
352 boolean use_default = p_td.json->default_value && 0 == p_tok.get_buffer_length();
353 if (use_default) {
354 // No JSON data in the buffer -> use default value
355 value = (char*)p_td.json->default_value;
356 value_len = strlen(value);
357 } else {
358 dec_len = p_tok.get_next_token(&token, &value, &value_len);
359 }
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;
364 }
365 else if (JSON_TOKEN_STRING == token || use_default) {
366 if (use_default || (value[0] == '\"' && value[value_len - 1] == '\"')) {
367 if (!use_default) {
368 // The default value doesn't have quotes around it
369 value_len -= 2;
370 ++value;
371 }
372 for (int i = NONE; i <= ERROR; ++i) {
373 if (0 == strncmp(value, verdict_name[i], value_len)) {
374 verdict_value = (verdicttype)i;
375 error = false;
376 break;
377 }
378 }
379 }
380 } else {
381 error = false;
382 verdict_value = UNBOUND_VERDICT;
383 dec_len = JSON_ERROR_INVALID_TOKEN;
384 }
385 if (error) {
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;
389 }
390 return dec_len;
391}
392
393
394// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
395
396boolean operator==(verdicttype par_value, const VERDICTTYPE& other_value)
397{
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;
403}
404
405void VERDICTTYPE_template::clean_up()
406{
407 if (template_selection == VALUE_LIST ||
408 template_selection == COMPLEMENTED_LIST)
409 delete [] value_list.list_value;
410 template_selection = UNINITIALIZED_TEMPLATE;
411}
412
413void VERDICTTYPE_template::copy_value(const VERDICTTYPE& other_value)
414{
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);
419}
420
421void VERDICTTYPE_template::copy_template
422 (const VERDICTTYPE_template& other_value)
423{
424 switch (other_value.template_selection) {
425 case SPECIFIC_VALUE:
426 single_value = other_value.single_value;
427 break;
428 case OMIT_VALUE:
429 case ANY_VALUE:
430 case ANY_OR_OMIT:
431 break;
432 case VALUE_LIST:
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]);
439 break;
440 default:
441 TTCN_error("Copying an uninitialized/unsupported verdict template.");
442 }
443 set_selection(other_value);
444}
445
446VERDICTTYPE_template::VERDICTTYPE_template()
447{
448}
449
450VERDICTTYPE_template::VERDICTTYPE_template(template_sel other_value)
451 : Base_Template(other_value)
452{
453 check_single_selection(other_value);
454}
455
456VERDICTTYPE_template::VERDICTTYPE_template(verdicttype other_value)
457 : Base_Template(SPECIFIC_VALUE)
458{
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;
462}
463
464VERDICTTYPE_template::VERDICTTYPE_template(const VERDICTTYPE& other_value)
465{
466 copy_value(other_value);
467}
468
469VERDICTTYPE_template::VERDICTTYPE_template
470 (const OPTIONAL<VERDICTTYPE>& other_value)
471{
472 switch (other_value.get_selection()) {
473 case OPTIONAL_PRESENT:
474 copy_value((const VERDICTTYPE&)other_value);
475 break;
476 case OPTIONAL_OMIT:
477 set_selection(OMIT_VALUE);
478 break;
479 default:
480 TTCN_error("Creating a verdict template from an unbound optional field.");
481 }
482}
483
484VERDICTTYPE_template::VERDICTTYPE_template
485 (const VERDICTTYPE_template& other_value)
486: Base_Template()
487{
488 copy_template(other_value);
489}
490
491VERDICTTYPE_template::~VERDICTTYPE_template()
492{
493 clean_up();
494}
495
496VERDICTTYPE_template& VERDICTTYPE_template::operator=(template_sel other_value)
497{
498 check_single_selection(other_value);
499 clean_up();
500 set_selection(other_value);
501 return *this;
502}
503
504VERDICTTYPE_template& VERDICTTYPE_template::operator=(verdicttype other_value)
505{
506 if (!IS_VALID(other_value)) TTCN_error("Assignment of an invalid verdict "
507 "value (%d) to a template.", other_value);
508 clean_up();
509 set_selection(SPECIFIC_VALUE);
510 single_value = other_value;
511 return *this;
512}
513
514VERDICTTYPE_template& VERDICTTYPE_template::operator=
515 (const VERDICTTYPE& other_value)
516{
517 clean_up();
518 copy_value(other_value);
519 return *this;
520}
521
522VERDICTTYPE_template& VERDICTTYPE_template::operator=
523 (const OPTIONAL<VERDICTTYPE>& other_value)
524{
525 clean_up();
526 switch (other_value.get_selection()) {
527 case OPTIONAL_PRESENT:
528 copy_value((const VERDICTTYPE&)other_value);
529 break;
530 case OPTIONAL_OMIT:
531 set_selection(OMIT_VALUE);
532 break;
533 default:
534 TTCN_error("Assignment of an unbound optional field to a verdict "
535 "template.");
536 }
537 return *this;
538}
539
540VERDICTTYPE_template& VERDICTTYPE_template::operator=
541 (const VERDICTTYPE_template& other_value)
542{
543 if (&other_value != this) {
544 clean_up();
545 copy_template(other_value);
546 }
547 return *this;
548}
549
550boolean VERDICTTYPE_template::match(verdicttype other_value) const
551{
552 if (!IS_VALID(other_value)) TTCN_error("Matching a verdict template with "
553 "an invalid value (%d).", other_value);
554 switch (template_selection) {
555 case SPECIFIC_VALUE:
556 return single_value == other_value;
557 case OMIT_VALUE:
558 return FALSE;
559 case ANY_VALUE:
560 case ANY_OR_OMIT:
561 return TRUE;
562 case VALUE_LIST:
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;
568 default:
569 TTCN_error("Matching with an uninitialized/unsupported verdict template.");
570 }
571 return FALSE;
572}
573
574boolean VERDICTTYPE_template::match(const VERDICTTYPE& other_value) const
575{
576 if (!other_value.is_bound()) return FALSE;
577 return match(other_value.verdict_value);
578}
579
580verdicttype VERDICTTYPE_template::valueof() const
581{
582 if (template_selection != SPECIFIC_VALUE || is_ifpresent)
583 TTCN_error("Performing a valueof "
584 "or send operation on a non-specific verdict template.");
585 return single_value;
586}
587
588void VERDICTTYPE_template::set_type(template_sel template_type,
589 unsigned int list_length)
590{
591 if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
592 TTCN_error("Internal error: Setting an invalid list type for a verdict "
593 "template.");
594 clean_up();
595 set_selection(template_type);
596 value_list.n_values = list_length;
597 value_list.list_value = new VERDICTTYPE_template[list_length];
598}
599
600VERDICTTYPE_template& VERDICTTYPE_template::list_item(unsigned int list_index)
601{
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 "
608 "template.");
609 return value_list.list_value[list_index];
610}
611
612void VERDICTTYPE_template::log() const
613{
614 switch (template_selection) {
615 case SPECIFIC_VALUE:
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);
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
638void VERDICTTYPE_template::log_match(const VERDICTTYPE& match_value) const
639{
640 if (TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()
641 && TTCN_Logger::get_logmatch_buffer_len() != 0) {
642 TTCN_Logger::print_logmatch_buffer();
643 TTCN_Logger::log_event_str(" := ");
644 }
645 match_value.log();
646 TTCN_Logger::log_event_str(" with ");
647 log();
648 if (match(match_value)) TTCN_Logger::log_event_str(" matched");
649 else TTCN_Logger::log_event_str(" unmatched");
650}
651
652void 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:
656 *this = OMIT_VALUE;
657 break;
658 case Module_Param::MP_Any:
659 *this = ANY_VALUE;
660 break;
661 case Module_Param::MP_AnyOrNone:
662 *this = ANY_OR_OMIT;
663 break;
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));
669 }
670 break;
671 case Module_Param::MP_Verdict:
672 *this = param.get_verdict();
673 break;
674 default:
675 param.type_error("verdict template");
676 }
677 is_ifpresent = param.get_ifpresent();
678}
679
680void VERDICTTYPE_template::encode_text(Text_Buf& text_buf) const
681{
682 encode_text_base(text_buf);
683 switch (template_selection) {
684 case OMIT_VALUE:
685 case ANY_VALUE:
686 case ANY_OR_OMIT:
687 break;
688 case SPECIFIC_VALUE:
689 text_buf.push_int(single_value);
690 break;
691 case VALUE_LIST:
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);
696 break;
697 default:
698 TTCN_error("Text encoder: Encoding an undefined/unsupported verdict "
699 "template.");
700 }
701}
702
703void VERDICTTYPE_template::decode_text(Text_Buf& text_buf)
704{
705 clean_up();
706 decode_text_base(text_buf);
707 switch (template_selection) {
708 case OMIT_VALUE:
709 case ANY_VALUE:
710 case ANY_OR_OMIT:
711 break;
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;
717 break; }
718 case VALUE_LIST:
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);
724 break;
725 default:
726 TTCN_error("Text decoder: An unknown/unsupported selection was received "
727 "for a verdict template.");
728 }
729}
730
731boolean VERDICTTYPE_template::is_present() const
732{
733 if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
734 return !match_omit();
735}
736
737boolean VERDICTTYPE_template::match_omit() const
738{
739 if (is_ifpresent) return TRUE;
740 switch (template_selection) {
741 case OMIT_VALUE:
742 case ANY_OR_OMIT:
743 return TRUE;
744 case VALUE_LIST:
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;
750 default:
751 return FALSE;
752 }
753 return FALSE;
754}
755
756#ifndef TITAN_RUNTIME_2
757void VERDICTTYPE_template::check_restriction(template_res t_res, const char* t_name) const
758{
759 if (template_selection==UNINITIALIZED_TEMPLATE) return;
760 switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
761 case TR_VALUE:
762 if (!is_ifpresent && template_selection==SPECIFIC_VALUE) return;
763 break;
764 case TR_OMIT:
765 if (!is_ifpresent && (template_selection==OMIT_VALUE ||
766 template_selection==SPECIFIC_VALUE)) return;
767 break;
768 case TR_PRESENT:
769 if (!match_omit()) return;
770 break;
771 default:
772 return;
773 }
774 TTCN_error("Restriction `%s' on template of type %s violated.",
775 get_res_name(t_res), t_name ? t_name : "verdict");
776}
777#endif
This page took 0.073132 seconds and 5 git commands to generate.