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