Use LTTngUSTLogger logger plugin in logtest regression test
[deliverable/titan.core.git] / core / ASN_Null.cc
1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Balasko, Jeno
10 * Baranyi, Botond
11 * Beres, Szabolcs
12 * Delic, Adam
13 * Forstner, Matyas
14 * Kovacs, Ferenc
15 * Raduly, Csaba
16 * Szabados, Kristof
17 * Szabo, Bence Janos
18 * Szabo, Janos Zoltan – initial implementation
19 * Szalai, Gabor
20 * Tatarka, Gabor
21 *
22 ******************************************************************************/
23 #include <stdarg.h>
24
25 #include "ASN_Null.hh"
26 #include "Parameters.h"
27 #include "Param_Types.hh"
28 #include "Error.hh"
29 #include "Logger.hh"
30 #include "Encdec.hh"
31 #include "BER.hh"
32
33 #include "../common/dbgnew.hh"
34
35 ASN_NULL::ASN_NULL()
36 {
37 bound_flag = FALSE;
38 }
39
40 ASN_NULL::ASN_NULL(asn_null_type)
41 {
42 bound_flag = TRUE;
43 }
44
45 ASN_NULL::ASN_NULL(const ASN_NULL& other_value)
46 : Base_Type(other_value)
47 {
48 if (!other_value.bound_flag)
49 TTCN_error("Copying an unbound ASN.1 NULL value.");
50 bound_flag = TRUE;
51 }
52
53 ASN_NULL& ASN_NULL::operator=(asn_null_type)
54 {
55 bound_flag = TRUE;
56 return *this;
57 }
58
59 ASN_NULL& ASN_NULL::operator=(const ASN_NULL& other_value)
60 {
61 if (!other_value.bound_flag)
62 TTCN_error("Assignment of an unbound ASN.1 NULL value.");
63 bound_flag = TRUE;
64 return *this;
65 }
66
67 boolean ASN_NULL::operator==(asn_null_type) const
68 {
69 if (!bound_flag) TTCN_error("The left operand of comparison is an unbound "
70 "ASN.1 NULL value.");
71 return TRUE;
72 }
73
74 boolean ASN_NULL::operator==(const ASN_NULL& other_value) const
75 {
76 if (!bound_flag) TTCN_error("The left operand of comparison is an unbound "
77 "ASN.1 NULL value.");
78 if (!other_value.bound_flag) TTCN_error("The right operand of comparison "
79 "is an unbound ASN.1 NULL value.");
80 return TRUE;
81 }
82
83 void ASN_NULL::log() const
84 {
85 if (bound_flag) TTCN_Logger::log_event_str("NULL");
86 else TTCN_Logger::log_event_unbound();
87 }
88
89 void ASN_NULL::set_param(Module_Param& param) {
90 param.basic_check(Module_Param::BC_VALUE, "NULL value");
91 Module_Param_Ptr mp = &param;
92 if (param.get_type() == Module_Param::MP_Reference) {
93 mp = param.get_referenced_param();
94 }
95 if (mp->get_type()!=Module_Param::MP_Asn_Null) param.type_error("NULL value");
96 bound_flag = TRUE;
97 }
98
99 Module_Param* ASN_NULL::get_param(Module_Param_Name& /* param_name */) const
100 {
101 if (!is_bound()) {
102 return new Module_Param_Unbound();
103 }
104 return new Module_Param_Asn_Null();
105 }
106
107 void ASN_NULL::encode_text(Text_Buf&) const
108 {
109 if (!bound_flag)
110 TTCN_error("Text encoder: Encoding an unbound ASN.1 NULL value.");
111 }
112
113 void ASN_NULL::decode_text(Text_Buf&)
114 {
115 bound_flag = TRUE;
116 }
117
118 void ASN_NULL::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
119 TTCN_EncDec::coding_t p_coding, ...) const
120 {
121 va_list pvar;
122 va_start(pvar, p_coding);
123 switch(p_coding) {
124 case TTCN_EncDec::CT_BER: {
125 TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name);
126 unsigned BER_coding=va_arg(pvar, unsigned);
127 BER_encode_chk_coding(BER_coding);
128 ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);
129 tlv->put_in_buffer(p_buf);
130 ASN_BER_TLV_t::destruct(tlv);
131 break;}
132 case TTCN_EncDec::CT_XER: {
133 TTCN_EncDec_ErrorContext ec("While XER-encoding type '%s': ", p_td.name);
134 unsigned XER_coding=va_arg(pvar, unsigned);
135 XER_encode(*p_td.xer, p_buf, XER_coding, 0, 0);
136 break;}
137 case TTCN_EncDec::CT_JSON: {
138 TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
139 if(!p_td.json)
140 TTCN_EncDec_ErrorContext::error_internal
141 ("No JSON descriptor available for type '%s'.", p_td.name);
142 JSON_Tokenizer tok(va_arg(pvar, int) != 0);
143 JSON_encode(p_td, tok);
144 p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
145 break;}
146 case TTCN_EncDec::CT_RAW:
147 default:
148 TTCN_error("Unknown coding method requested to encode type '%s'",
149 p_td.name);
150 }
151 va_end(pvar);
152 }
153
154 void ASN_NULL::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
155 TTCN_EncDec::coding_t p_coding, ...)
156 {
157 va_list pvar;
158 va_start(pvar, p_coding);
159 switch(p_coding) {
160 case TTCN_EncDec::CT_BER: {
161 TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
162 unsigned L_form=va_arg(pvar, unsigned);
163 ASN_BER_TLV_t tlv;
164 BER_decode_str2TLV(p_buf, tlv, L_form);
165 BER_decode_TLV(p_td, tlv, L_form);
166 if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
167 break;}
168 case TTCN_EncDec::CT_XER: {
169 TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
170 unsigned XER_coding=va_arg(pvar, unsigned);
171 XmlReaderWrap reader(p_buf);
172 int success = reader.Read();
173 for (; success==1; success=reader.Read()) {
174 int type = reader.NodeType();
175 if (type==XML_READER_TYPE_ELEMENT)
176 break;
177 }
178 XER_decode(*p_td.xer, reader, XER_coding, XER_NONE, 0);
179 size_t bytes = reader.ByteConsumed();
180 p_buf.set_pos(bytes);
181 break;}
182 case TTCN_EncDec::CT_JSON: {
183 TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
184 if(!p_td.json)
185 TTCN_EncDec_ErrorContext::error_internal
186 ("No JSON descriptor available for type '%s'.", p_td.name);
187 JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
188 if(JSON_decode(p_td, tok, false)<0)
189 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
190 "Can not decode type '%s', because invalid or incomplete"
191 " message was received"
192 , p_td.name);
193 p_buf.set_pos(tok.get_buf_pos());
194 break;}
195 case TTCN_EncDec::CT_RAW:
196 default:
197 TTCN_error("Unknown coding method requested to decode type '%s'",
198 p_td.name);
199 }
200 va_end(pvar);
201 }
202
203 ASN_BER_TLV_t*
204 ASN_NULL::BER_encode_TLV(const TTCN_Typedescriptor_t& p_td,
205 unsigned p_coding) const
206 {
207 BER_chk_descr(p_td);
208 ASN_BER_TLV_t *new_tlv=BER_encode_chk_bound(is_bound());
209 if(!new_tlv) {
210 new_tlv=ASN_BER_TLV_t::construct(0, NULL);
211 }
212 new_tlv=ASN_BER_V2TLV(new_tlv, p_td, p_coding);
213 return new_tlv;
214 }
215
216 boolean ASN_NULL::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,
217 const ASN_BER_TLV_t& p_tlv,
218 unsigned L_form)
219 {
220 bound_flag = FALSE;
221 BER_chk_descr(p_td);
222 ASN_BER_TLV_t stripped_tlv;
223 BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv);
224 TTCN_EncDec_ErrorContext ec("While decoding NULL type: ");
225 stripped_tlv.chk_constructed_flag(FALSE);
226 if(!stripped_tlv.V_tlvs_selected && stripped_tlv.V.str.Vlen!=0)
227 ec.error(TTCN_EncDec::ET_INVAL_MSG, "Length of V-part is not 0.");
228 bound_flag=TRUE;
229 return TRUE;
230 }
231
232 int ASN_NULL::XER_encode(const XERdescriptor_t& p_td,
233 TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
234 {
235 int exer = is_exer(flavor);
236 TTCN_EncDec_ErrorContext ec("While XER encoding NULL type: ");
237 if(!is_bound()) {
238 TTCN_EncDec_ErrorContext::error
239 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound ASN.1 NULL value.");
240 }
241
242 int indenting = !is_canonical(flavor) && !is_record_of(flavor);
243 int encoded_length=(int)p_buf.get_len();
244
245 if (indenting) do_indent(p_buf, indent);
246 p_buf.put_c('<');
247
248 // empty element tag
249 if (exer) write_ns_prefix(p_td, p_buf);
250 p_buf.put_s((size_t)p_td.namelens[exer]-2, (const unsigned char*)p_td.names[exer]);
251
252 p_buf.put_s(2 + indenting , (const unsigned char*)"/>\n");
253 return (int)p_buf.get_len() - encoded_length;
254 }
255
256 int ASN_NULL::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
257 unsigned int flavor, unsigned int /*flavor2*/, embed_values_dec_struct_t*)
258 {
259 int exer = is_exer(flavor);
260 TTCN_EncDec_ErrorContext ec("While XER decoding NULL type: ");
261 int success = reader.Ok(), depth = -1;
262 for (; success == 1; success = reader.Read()) {
263 int type = reader.NodeType();
264 if (XML_READER_TYPE_ELEMENT == type) {
265 verify_name(reader, p_td, exer);
266 depth = reader.Depth();
267 break;
268 }
269 }
270 bound_flag = TRUE;
271 int gol = reader.IsEmptyElement();
272 if (!gol) { // shouldn't happen
273 for (success = reader.Read(); success == 1; success = reader.Read()) {
274 int type = reader.NodeType();
275 if (XML_READER_TYPE_END_ELEMENT == type) {
276 verify_end(reader, p_td, depth, exer);
277 // FIXME reader.Read() ??
278 break;
279 }
280 } // next
281 } // if gol
282
283 reader.Read();
284 return 1; // decode successful
285 }
286
287 int ASN_NULL::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const
288 {
289 if (!is_bound()) {
290 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
291 "Encoding an unbound ASN.1 NULL value.");
292 return -1;
293 }
294
295 return p_tok.put_next_token(JSON_TOKEN_LITERAL_NULL);
296 }
297
298 int ASN_NULL::JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok, boolean p_silent)
299 {
300 json_token_t token = JSON_TOKEN_NONE;
301 int dec_len = p_tok.get_next_token(&token, NULL, NULL);
302 if (JSON_TOKEN_ERROR == token) {
303 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, "");
304 return JSON_ERROR_FATAL;
305 }
306 else if (JSON_TOKEN_LITERAL_NULL != token) {
307 return JSON_ERROR_INVALID_TOKEN;
308 }
309 bound_flag = TRUE;
310 return dec_len;
311 }
312
313 boolean operator==(asn_null_type, const ASN_NULL& other_value)
314 {
315 if (!other_value.is_bound()) TTCN_error("The right operand of comparison "
316 "is an unbound ASN.1 NULL value.");
317 return TRUE;
318 }
319
320 void ASN_NULL_template::clean_up()
321 {
322 if (template_selection == VALUE_LIST ||
323 template_selection == COMPLEMENTED_LIST) delete [] value_list.list_value;
324 template_selection = UNINITIALIZED_TEMPLATE;
325 }
326
327 void ASN_NULL_template::copy_template(const ASN_NULL_template& other_value)
328 {
329 switch (other_value.template_selection) {
330 case SPECIFIC_VALUE:
331 case OMIT_VALUE:
332 case ANY_VALUE:
333 case ANY_OR_OMIT:
334 break;
335 case VALUE_LIST:
336 case COMPLEMENTED_LIST:
337 value_list.n_values = other_value.value_list.n_values;
338 value_list.list_value = new ASN_NULL_template[value_list.n_values];
339 for (unsigned int i = 0; i < value_list.n_values; i++)
340 value_list.list_value[i].copy_template(
341 other_value.value_list.list_value[i]);
342 break;
343 default:
344 TTCN_error("Copying an uninitialized/unsupported template of ASN.1 "
345 "NULL type.");
346 }
347 set_selection(other_value);
348 }
349
350 ASN_NULL_template::ASN_NULL_template()
351 {
352
353 }
354
355 ASN_NULL_template::ASN_NULL_template(template_sel other_value)
356 : Base_Template(other_value)
357 {
358 check_single_selection(other_value);
359 }
360
361 ASN_NULL_template::ASN_NULL_template(asn_null_type)
362 : Base_Template(SPECIFIC_VALUE)
363 {
364
365 }
366
367 ASN_NULL_template::ASN_NULL_template(const ASN_NULL& other_value)
368 : Base_Template(SPECIFIC_VALUE)
369 {
370 if (!other_value.is_bound())
371 TTCN_error("Creating a template from an unbound ASN.1 NULL value.");
372 }
373
374 ASN_NULL_template::ASN_NULL_template(const OPTIONAL<ASN_NULL>& other_value)
375 {
376 switch (other_value.get_selection()) {
377 case OPTIONAL_PRESENT:
378 set_selection(SPECIFIC_VALUE);
379 break;
380 case OPTIONAL_OMIT:
381 set_selection(OMIT_VALUE);
382 break;
383 default:
384 TTCN_error("Creating a template of ASN.1 NULL type from an unbound "
385 "optional field.");
386 }
387 }
388
389 ASN_NULL_template::ASN_NULL_template(const ASN_NULL_template& other_value)
390 : Base_Template()
391 {
392 copy_template(other_value);
393 }
394
395 ASN_NULL_template::~ASN_NULL_template()
396 {
397 clean_up();
398 }
399
400 ASN_NULL_template& ASN_NULL_template::operator=(template_sel other_value)
401 {
402 check_single_selection(other_value);
403 clean_up();
404 set_selection(other_value);
405 return *this;
406 }
407
408 ASN_NULL_template& ASN_NULL_template::operator=(asn_null_type)
409 {
410 clean_up();
411 set_selection(SPECIFIC_VALUE);
412 return *this;
413 }
414
415 ASN_NULL_template& ASN_NULL_template::operator=(const ASN_NULL& other_value)
416 {
417 if (!other_value.is_bound()) TTCN_error("Assignment of an unbound ASN.1 "
418 "NULL value to a template.");
419 clean_up();
420 set_selection(SPECIFIC_VALUE);
421 return *this;
422 }
423
424 ASN_NULL_template& ASN_NULL_template::operator=
425 (const OPTIONAL<ASN_NULL>& other_value)
426 {
427 clean_up();
428 switch (other_value.get_selection()) {
429 case OPTIONAL_PRESENT:
430 set_selection(SPECIFIC_VALUE);
431 break;
432 case OPTIONAL_OMIT:
433 set_selection(OMIT_VALUE);
434 break;
435 default:
436 TTCN_error("Assignment of an unbound optional field to a template of "
437 "ASN.1 NULL type.");
438 }
439 return *this;
440 }
441
442 ASN_NULL_template& ASN_NULL_template::operator=
443 (const ASN_NULL_template& other_value)
444 {
445 if (&other_value != this) {
446 clean_up();
447 copy_template(other_value);
448 }
449 return *this;
450 }
451
452 boolean ASN_NULL_template::match(asn_null_type other_value,
453 boolean /* legacy */) const
454 {
455 switch (template_selection) {
456 case OMIT_VALUE:
457 return FALSE;
458 case SPECIFIC_VALUE:
459 case ANY_VALUE:
460 case ANY_OR_OMIT:
461 return TRUE;
462 case VALUE_LIST:
463 case COMPLEMENTED_LIST:
464 for (unsigned int i = 0; i < value_list.n_values; i++)
465 if (value_list.list_value[i].match(other_value))
466 return template_selection == VALUE_LIST;
467 return template_selection == COMPLEMENTED_LIST;
468 default:
469 TTCN_error("Matching with an uninitialized/unsupported template of "
470 "ASN.1 NULL type.");
471 }
472 return FALSE;
473 }
474
475 boolean ASN_NULL_template::match(const ASN_NULL& other_value,
476 boolean /* legacy */) const
477 {
478 if (!other_value.is_bound()) return FALSE;
479 return match(ASN_NULL_VALUE);
480 }
481
482 asn_null_type ASN_NULL_template::valueof() const
483 {
484 if (template_selection != SPECIFIC_VALUE || is_ifpresent)
485 TTCN_error("Performing a valueof "
486 "or send operation on a non-specific template of ASN.1 NULL type.");
487 return ASN_NULL_VALUE;
488 }
489
490 void ASN_NULL_template::set_type(template_sel template_type,
491 unsigned int list_length)
492 {
493 if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
494 TTCN_error("Setting an invalid list type for a template of ASN.1 NULL "
495 "type.");
496 clean_up();
497 set_selection(template_type);
498 value_list.n_values = list_length;
499 value_list.list_value = new ASN_NULL_template[list_length];
500 }
501
502 ASN_NULL_template& ASN_NULL_template::list_item(unsigned int list_index)
503 {
504 if (template_selection != VALUE_LIST &&
505 template_selection != COMPLEMENTED_LIST) TTCN_error("Accessing a list "
506 "element of a non-list template for ASN.1 NULL type.");
507 if (list_index >= value_list.n_values)
508 TTCN_error("Index overflow in a value list template of ASN.1 NULL type.");
509 return value_list.list_value[list_index];
510 }
511
512 void ASN_NULL_template::log() const
513 {
514 switch (template_selection) {
515 case SPECIFIC_VALUE:
516 TTCN_Logger::log_event_str("NULL");
517 break;
518 case COMPLEMENTED_LIST:
519 TTCN_Logger::log_event_str("complement ");
520 case VALUE_LIST:
521 TTCN_Logger::log_char('(');
522 for (unsigned int i = 0; i < value_list.n_values; i++) {
523 if (i > 0) TTCN_Logger::log_event_str(", ");
524 value_list.list_value[i].log();
525 }
526 TTCN_Logger::log_char(')');
527 break;
528 default:
529 log_generic();
530 }
531 log_ifpresent();
532 }
533
534 void ASN_NULL_template::log_match(const ASN_NULL& match_value,
535 boolean /* legacy */) const
536 {
537 if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
538 TTCN_Logger::print_logmatch_buffer();
539 TTCN_Logger::log_event_str(" := ");
540 }
541 match_value.log();
542 TTCN_Logger::log_event_str(" with ");
543 log();
544 if (match(match_value)) TTCN_Logger::log_event_str(" matched");
545 else TTCN_Logger::log_event_str(" unmatched");
546 }
547
548 void ASN_NULL_template::set_param(Module_Param& param) {
549 param.basic_check(Module_Param::BC_TEMPLATE, "NULL template");
550 Module_Param_Ptr mp = &param;
551 if (param.get_type() == Module_Param::MP_Reference) {
552 mp = param.get_referenced_param();
553 }
554 switch (mp->get_type()) {
555 case Module_Param::MP_Omit:
556 *this = OMIT_VALUE;
557 break;
558 case Module_Param::MP_Any:
559 *this = ANY_VALUE;
560 break;
561 case Module_Param::MP_AnyOrNone:
562 *this = ANY_OR_OMIT;
563 break;
564 case Module_Param::MP_List_Template:
565 case Module_Param::MP_ComplementList_Template: {
566 ASN_NULL_template temp;
567 temp.set_type(mp->get_type() == Module_Param::MP_List_Template ?
568 VALUE_LIST : COMPLEMENTED_LIST, mp->get_size());
569 for (size_t i=0; i<mp->get_size(); i++) {
570 temp.list_item(i).set_param(*mp->get_elem(i));
571 }
572 *this = temp;
573 break; }
574 case Module_Param::MP_Asn_Null:
575 *this = ASN_NULL_VALUE;
576 break;
577 default:
578 param.type_error("NULL template");
579 }
580 is_ifpresent = param.get_ifpresent() || mp->get_ifpresent();
581 }
582
583 Module_Param* ASN_NULL_template::get_param(Module_Param_Name& param_name) const
584 {
585 Module_Param* mp = NULL;
586 switch (template_selection) {
587 case UNINITIALIZED_TEMPLATE:
588 mp = new Module_Param_Unbound();
589 break;
590 case OMIT_VALUE:
591 mp = new Module_Param_Omit();
592 break;
593 case ANY_VALUE:
594 mp = new Module_Param_Any();
595 break;
596 case ANY_OR_OMIT:
597 mp = new Module_Param_AnyOrNone();
598 break;
599 case SPECIFIC_VALUE:
600 mp = new Module_Param_Asn_Null();
601 break;
602 case VALUE_LIST:
603 case COMPLEMENTED_LIST: {
604 if (template_selection == VALUE_LIST) {
605 mp = new Module_Param_List_Template();
606 }
607 else {
608 mp = new Module_Param_ComplementList_Template();
609 }
610 for (size_t i = 0; i < value_list.n_values; ++i) {
611 mp->add_elem(value_list.list_value[i].get_param(param_name));
612 }
613 break; }
614 default:
615 break;
616 }
617 if (is_ifpresent) {
618 mp->set_ifpresent();
619 }
620 return mp;
621 }
622
623 void ASN_NULL_template::encode_text(Text_Buf& text_buf) const
624 {
625 encode_text_base(text_buf);
626 switch (template_selection) {
627 case SPECIFIC_VALUE:
628 case OMIT_VALUE:
629 case ANY_VALUE:
630 case ANY_OR_OMIT:
631 break;
632 case VALUE_LIST:
633 case COMPLEMENTED_LIST:
634 text_buf.push_int(value_list.n_values);
635 for (unsigned int i = 0; i < value_list.n_values; i++)
636 value_list.list_value[i].encode_text(text_buf);
637 break;
638 default:
639 TTCN_error("Text encoder: Encoding an undefined/unsupported template "
640 "of ASN.1 NULL type.");
641 }
642 }
643
644 void ASN_NULL_template::decode_text(Text_Buf& text_buf)
645 {
646 clean_up();
647 decode_text_base(text_buf);
648 switch (template_selection) {
649 case SPECIFIC_VALUE:
650 case OMIT_VALUE:
651 case ANY_VALUE:
652 case ANY_OR_OMIT:
653 break;
654 case VALUE_LIST:
655 case COMPLEMENTED_LIST:
656 value_list.n_values = text_buf.pull_int().get_val();
657 value_list.list_value = new ASN_NULL_template[value_list.n_values];
658 for (unsigned int i = 0; i < value_list.n_values; i++)
659 value_list.list_value[i].decode_text(text_buf);
660 break;
661 default:
662 TTCN_error("Text decoder: An unknown/unsupported selection was received "
663 "in a template for ASN.1 NULL type.");
664 }
665 }
666
667 boolean ASN_NULL_template::is_present(boolean legacy /* = FALSE */) const
668 {
669 if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
670 return !match_omit(legacy);
671 }
672
673 boolean ASN_NULL_template::match_omit(boolean legacy /* = FALSE */) const
674 {
675 if (is_ifpresent) return TRUE;
676 switch (template_selection) {
677 case OMIT_VALUE:
678 case ANY_OR_OMIT:
679 return TRUE;
680 case VALUE_LIST:
681 case COMPLEMENTED_LIST:
682 if (legacy) {
683 // legacy behavior: 'omit' can appear in the value/complement list
684 for (unsigned int i=0; i<value_list.n_values; i++)
685 if (value_list.list_value[i].match_omit())
686 return template_selection==VALUE_LIST;
687 return template_selection==COMPLEMENTED_LIST;
688 }
689 // else fall through
690 default:
691 return FALSE;
692 }
693 return FALSE;
694 }
695
696 #ifndef TITAN_RUNTIME_2
697 void ASN_NULL_template::check_restriction(template_res t_res, const char* t_name,
698 boolean legacy /* = FALSE */) const
699 {
700 if (template_selection==UNINITIALIZED_TEMPLATE) return;
701 switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
702 case TR_VALUE:
703 if (!is_ifpresent && template_selection==SPECIFIC_VALUE) return;
704 break;
705 case TR_OMIT:
706 if (!is_ifpresent && (template_selection==OMIT_VALUE ||
707 template_selection==SPECIFIC_VALUE)) return;
708 break;
709 case TR_PRESENT:
710 if (!match_omit(legacy)) return;
711 break;
712 default:
713 return;
714 }
715 TTCN_error("Restriction `%s' on template of type %s violated.",
716 get_res_name(t_res), t_name ? t_name : "ASN.1 NULL");
717 }
718 #endif
This page took 0.051047 seconds and 5 git commands to generate.