Merge "implemented decmatch (artf724241)"
[deliverable/titan.core.git] / core / ASN_Null.cc
CommitLineData
d44e3c4f 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 ******************************************************************************/
970ed795
EL
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
35ASN_NULL::ASN_NULL()
36{
37 bound_flag = FALSE;
38}
39
40ASN_NULL::ASN_NULL(asn_null_type)
41{
42 bound_flag = TRUE;
43}
44
45ASN_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
53ASN_NULL& ASN_NULL::operator=(asn_null_type)
54{
55 bound_flag = TRUE;
56 return *this;
57}
58
59ASN_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
67boolean 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
74boolean 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
83void ASN_NULL::log() const
84{
85 if (bound_flag) TTCN_Logger::log_event_str("NULL");
86 else TTCN_Logger::log_event_unbound();
87}
88
89void ASN_NULL::set_param(Module_Param& param) {
90 param.basic_check(Module_Param::BC_VALUE, "NULL value");
3abe9331 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");
970ed795
EL
96 bound_flag = TRUE;
97}
98
3abe9331 99Module_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
970ed795
EL
107void 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
113void ASN_NULL::decode_text(Text_Buf&)
114{
115 bound_flag = TRUE;
116}
117
118void 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);
af710487 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());
970ed795
EL
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
154void 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: {
af710487 169 TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
970ed795
EL
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 }
feade998 178 XER_decode(*p_td.xer, reader, XER_coding, XER_NONE, 0);
970ed795
EL
179 size_t bytes = reader.ByteConsumed();
180 p_buf.set_pos(bytes);
181 break;}
af710487 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;}
970ed795
EL
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
203ASN_BER_TLV_t*
204ASN_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
216boolean 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
232int ASN_NULL::XER_encode(const XERdescriptor_t& p_td,
af710487 233 TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
970ed795
EL
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
256int ASN_NULL::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
feade998 257 unsigned int flavor, unsigned int /*flavor2*/, embed_values_dec_struct_t*)
970ed795
EL
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
af710487 287int 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
298int 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
970ed795
EL
313boolean 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
320void 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
327void 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
350ASN_NULL_template::ASN_NULL_template()
351{
352
353}
354
355ASN_NULL_template::ASN_NULL_template(template_sel other_value)
356 : Base_Template(other_value)
357{
358 check_single_selection(other_value);
359}
360
361ASN_NULL_template::ASN_NULL_template(asn_null_type)
362 : Base_Template(SPECIFIC_VALUE)
363{
364
365}
366
367ASN_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
374ASN_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
389ASN_NULL_template::ASN_NULL_template(const ASN_NULL_template& other_value)
390: Base_Template()
391{
392 copy_template(other_value);
393}
394
395ASN_NULL_template::~ASN_NULL_template()
396{
397 clean_up();
398}
399
400ASN_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
408ASN_NULL_template& ASN_NULL_template::operator=(asn_null_type)
409{
410 clean_up();
411 set_selection(SPECIFIC_VALUE);
412 return *this;
413}
414
415ASN_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
424ASN_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
442ASN_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
3abe9331 452boolean ASN_NULL_template::match(asn_null_type other_value,
453 boolean /* legacy */) const
970ed795
EL
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
3abe9331 475boolean ASN_NULL_template::match(const ASN_NULL& other_value,
476 boolean /* legacy */) const
970ed795
EL
477{
478 if (!other_value.is_bound()) return FALSE;
479 return match(ASN_NULL_VALUE);
480}
481
482asn_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
490void 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
502ASN_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
512void 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
3abe9331 534void ASN_NULL_template::log_match(const ASN_NULL& match_value,
535 boolean /* legacy */) const
970ed795
EL
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
548void ASN_NULL_template::set_param(Module_Param& param) {
549 param.basic_check(Module_Param::BC_TEMPLATE, "NULL template");
3abe9331 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()) {
970ed795
EL
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:
3abe9331 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));
970ed795 571 }
3abe9331 572 *this = temp;
573 break; }
970ed795
EL
574 case Module_Param::MP_Asn_Null:
575 *this = ASN_NULL_VALUE;
576 break;
577 default:
578 param.type_error("NULL template");
579 }
3abe9331 580 is_ifpresent = param.get_ifpresent() || mp->get_ifpresent();
581}
582
583Module_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;
970ed795
EL
621}
622
623void 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
644void 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
3abe9331 667boolean ASN_NULL_template::is_present(boolean legacy /* = FALSE */) const
970ed795
EL
668{
669 if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
3abe9331 670 return !match_omit(legacy);
970ed795
EL
671}
672
3abe9331 673boolean ASN_NULL_template::match_omit(boolean legacy /* = FALSE */) const
970ed795
EL
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:
3abe9331 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
970ed795
EL
690 default:
691 return FALSE;
692 }
693 return FALSE;
694}
695
696#ifndef TITAN_RUNTIME_2
3abe9331 697void ASN_NULL_template::check_restriction(template_res t_res, const char* t_name,
698 boolean legacy /* = FALSE */) const
970ed795
EL
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:
3abe9331 710 if (!match_omit(legacy)) return;
970ed795
EL
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.050115 seconds and 5 git commands to generate.