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 ///////////////////////////////////////////////////////////////////////////////
10 #include "ASN_Null.hh"
11 #include "Parameters.h"
12 #include "Param_Types.hh"
18 #include "../common/dbgnew.hh"
25 ASN_NULL::ASN_NULL(asn_null_type
)
30 ASN_NULL::ASN_NULL(const ASN_NULL
& other_value
)
31 : Base_Type(other_value
)
33 if (!other_value
.bound_flag
)
34 TTCN_error("Copying an unbound ASN.1 NULL value.");
38 ASN_NULL
& ASN_NULL::operator=(asn_null_type
)
44 ASN_NULL
& ASN_NULL::operator=(const ASN_NULL
& other_value
)
46 if (!other_value
.bound_flag
)
47 TTCN_error("Assignment of an unbound ASN.1 NULL value.");
52 boolean
ASN_NULL::operator==(asn_null_type
) const
54 if (!bound_flag
) TTCN_error("The left operand of comparison is an unbound "
59 boolean
ASN_NULL::operator==(const ASN_NULL
& other_value
) const
61 if (!bound_flag
) TTCN_error("The left operand of comparison is an unbound "
63 if (!other_value
.bound_flag
) TTCN_error("The right operand of comparison "
64 "is an unbound ASN.1 NULL value.");
68 void ASN_NULL::log() const
70 if (bound_flag
) TTCN_Logger::log_event_str("NULL");
71 else TTCN_Logger::log_event_unbound();
74 void ASN_NULL::set_param(Module_Param
& param
) {
75 param
.basic_check(Module_Param::BC_VALUE
, "NULL value");
76 if (param
.get_type()!=Module_Param::MP_Asn_Null
) param
.type_error("NULL value");
80 void ASN_NULL::encode_text(Text_Buf
&) const
83 TTCN_error("Text encoder: Encoding an unbound ASN.1 NULL value.");
86 void ASN_NULL::decode_text(Text_Buf
&)
91 void ASN_NULL::encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
92 TTCN_EncDec::coding_t p_coding
, ...) const
95 va_start(pvar
, p_coding
);
97 case TTCN_EncDec::CT_BER
: {
98 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
99 unsigned BER_coding
=va_arg(pvar
, unsigned);
100 BER_encode_chk_coding(BER_coding
);
101 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
102 tlv
->put_in_buffer(p_buf
);
103 ASN_BER_TLV_t::destruct(tlv
);
105 case TTCN_EncDec::CT_XER
: {
106 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
107 unsigned XER_coding
=va_arg(pvar
, unsigned);
108 XER_encode(*p_td
.xer
, p_buf
, XER_coding
, 0);
110 case TTCN_EncDec::CT_RAW
:
112 TTCN_error("Unknown coding method requested to encode type '%s'",
118 void ASN_NULL::decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
119 TTCN_EncDec::coding_t p_coding
, ...)
122 va_start(pvar
, p_coding
);
124 case TTCN_EncDec::CT_BER
: {
125 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
126 unsigned L_form
=va_arg(pvar
, unsigned);
128 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
129 BER_decode_TLV(p_td
, tlv
, L_form
);
130 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
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 XmlReaderWrap
reader(p_buf
);
136 int success
= reader
.Read();
137 for (; success
==1; success
=reader
.Read()) {
138 int type
= reader
.NodeType();
139 if (type
==XML_READER_TYPE_ELEMENT
)
142 XER_decode(*p_td
.xer
, reader
, XER_coding
);
143 size_t bytes
= reader
.ByteConsumed();
144 p_buf
.set_pos(bytes
);
146 case TTCN_EncDec::CT_RAW
:
148 TTCN_error("Unknown coding method requested to decode type '%s'",
155 ASN_NULL::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
156 unsigned p_coding
) const
159 ASN_BER_TLV_t
*new_tlv
=BER_encode_chk_bound(is_bound());
161 new_tlv
=ASN_BER_TLV_t::construct(0, NULL
);
163 new_tlv
=ASN_BER_V2TLV(new_tlv
, p_td
, p_coding
);
167 boolean
ASN_NULL::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
168 const ASN_BER_TLV_t
& p_tlv
,
173 ASN_BER_TLV_t stripped_tlv
;
174 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
175 TTCN_EncDec_ErrorContext
ec("While decoding NULL type: ");
176 stripped_tlv
.chk_constructed_flag(FALSE
);
177 if(!stripped_tlv
.V_tlvs_selected
&& stripped_tlv
.V
.str
.Vlen
!=0)
178 ec
.error(TTCN_EncDec::ET_INVAL_MSG
, "Length of V-part is not 0.");
183 int ASN_NULL::XER_encode(const XERdescriptor_t
& p_td
,
184 TTCN_Buffer
& p_buf
, unsigned int flavor
, int indent
) const
186 int exer
= is_exer(flavor
);
187 TTCN_EncDec_ErrorContext
ec("While XER encoding NULL type: ");
189 TTCN_EncDec_ErrorContext::error
190 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound ASN.1 NULL value.");
193 int indenting
= !is_canonical(flavor
) && !is_record_of(flavor
);
194 int encoded_length
=(int)p_buf
.get_len();
196 if (indenting
) do_indent(p_buf
, indent
);
200 if (exer
) write_ns_prefix(p_td
, p_buf
);
201 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-2, (const unsigned char*)p_td
.names
[exer
]);
203 p_buf
.put_s(2 + indenting
, (const unsigned char*)"/>\n");
204 return (int)p_buf
.get_len() - encoded_length
;
207 int ASN_NULL::XER_decode(const XERdescriptor_t
& p_td
, XmlReaderWrap
& reader
,
210 int exer
= is_exer(flavor
);
211 TTCN_EncDec_ErrorContext
ec("While XER decoding NULL type: ");
212 int success
= reader
.Ok(), depth
= -1;
213 for (; success
== 1; success
= reader
.Read()) {
214 int type
= reader
.NodeType();
215 if (XML_READER_TYPE_ELEMENT
== type
) {
216 verify_name(reader
, p_td
, exer
);
217 depth
= reader
.Depth();
222 int gol
= reader
.IsEmptyElement();
223 if (!gol
) { // shouldn't happen
224 for (success
= reader
.Read(); success
== 1; success
= reader
.Read()) {
225 int type
= reader
.NodeType();
226 if (XML_READER_TYPE_END_ELEMENT
== type
) {
227 verify_end(reader
, p_td
, depth
, exer
);
228 // FIXME reader.Read() ??
235 return 1; // decode successful
238 boolean
operator==(asn_null_type
, const ASN_NULL
& other_value
)
240 if (!other_value
.is_bound()) TTCN_error("The right operand of comparison "
241 "is an unbound ASN.1 NULL value.");
245 void ASN_NULL_template::clean_up()
247 if (template_selection
== VALUE_LIST
||
248 template_selection
== COMPLEMENTED_LIST
) delete [] value_list
.list_value
;
249 template_selection
= UNINITIALIZED_TEMPLATE
;
252 void ASN_NULL_template::copy_template(const ASN_NULL_template
& other_value
)
254 switch (other_value
.template_selection
) {
261 case COMPLEMENTED_LIST
:
262 value_list
.n_values
= other_value
.value_list
.n_values
;
263 value_list
.list_value
= new ASN_NULL_template
[value_list
.n_values
];
264 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
265 value_list
.list_value
[i
].copy_template(
266 other_value
.value_list
.list_value
[i
]);
269 TTCN_error("Copying an uninitialized/unsupported template of ASN.1 "
272 set_selection(other_value
);
275 ASN_NULL_template::ASN_NULL_template()
280 ASN_NULL_template::ASN_NULL_template(template_sel other_value
)
281 : Base_Template(other_value
)
283 check_single_selection(other_value
);
286 ASN_NULL_template::ASN_NULL_template(asn_null_type
)
287 : Base_Template(SPECIFIC_VALUE
)
292 ASN_NULL_template::ASN_NULL_template(const ASN_NULL
& other_value
)
293 : Base_Template(SPECIFIC_VALUE
)
295 if (!other_value
.is_bound())
296 TTCN_error("Creating a template from an unbound ASN.1 NULL value.");
299 ASN_NULL_template::ASN_NULL_template(const OPTIONAL
<ASN_NULL
>& other_value
)
301 switch (other_value
.get_selection()) {
302 case OPTIONAL_PRESENT
:
303 set_selection(SPECIFIC_VALUE
);
306 set_selection(OMIT_VALUE
);
309 TTCN_error("Creating a template of ASN.1 NULL type from an unbound "
314 ASN_NULL_template::ASN_NULL_template(const ASN_NULL_template
& other_value
)
317 copy_template(other_value
);
320 ASN_NULL_template::~ASN_NULL_template()
325 ASN_NULL_template
& ASN_NULL_template::operator=(template_sel other_value
)
327 check_single_selection(other_value
);
329 set_selection(other_value
);
333 ASN_NULL_template
& ASN_NULL_template::operator=(asn_null_type
)
336 set_selection(SPECIFIC_VALUE
);
340 ASN_NULL_template
& ASN_NULL_template::operator=(const ASN_NULL
& other_value
)
342 if (!other_value
.is_bound()) TTCN_error("Assignment of an unbound ASN.1 "
343 "NULL value to a template.");
345 set_selection(SPECIFIC_VALUE
);
349 ASN_NULL_template
& ASN_NULL_template::operator=
350 (const OPTIONAL
<ASN_NULL
>& other_value
)
353 switch (other_value
.get_selection()) {
354 case OPTIONAL_PRESENT
:
355 set_selection(SPECIFIC_VALUE
);
358 set_selection(OMIT_VALUE
);
361 TTCN_error("Assignment of an unbound optional field to a template of "
367 ASN_NULL_template
& ASN_NULL_template::operator=
368 (const ASN_NULL_template
& other_value
)
370 if (&other_value
!= this) {
372 copy_template(other_value
);
377 boolean
ASN_NULL_template::match(asn_null_type other_value
) const
379 switch (template_selection
) {
387 case COMPLEMENTED_LIST
:
388 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
389 if (value_list
.list_value
[i
].match(other_value
))
390 return template_selection
== VALUE_LIST
;
391 return template_selection
== COMPLEMENTED_LIST
;
393 TTCN_error("Matching with an uninitialized/unsupported template of "
399 boolean
ASN_NULL_template::match(const ASN_NULL
& other_value
) const
401 if (!other_value
.is_bound()) return FALSE
;
402 return match(ASN_NULL_VALUE
);
405 asn_null_type
ASN_NULL_template::valueof() const
407 if (template_selection
!= SPECIFIC_VALUE
|| is_ifpresent
)
408 TTCN_error("Performing a valueof "
409 "or send operation on a non-specific template of ASN.1 NULL type.");
410 return ASN_NULL_VALUE
;
413 void ASN_NULL_template::set_type(template_sel template_type
,
414 unsigned int list_length
)
416 if (template_type
!= VALUE_LIST
&& template_type
!= COMPLEMENTED_LIST
)
417 TTCN_error("Setting an invalid list type for a template of ASN.1 NULL "
420 set_selection(template_type
);
421 value_list
.n_values
= list_length
;
422 value_list
.list_value
= new ASN_NULL_template
[list_length
];
425 ASN_NULL_template
& ASN_NULL_template::list_item(unsigned int list_index
)
427 if (template_selection
!= VALUE_LIST
&&
428 template_selection
!= COMPLEMENTED_LIST
) TTCN_error("Accessing a list "
429 "element of a non-list template for ASN.1 NULL type.");
430 if (list_index
>= value_list
.n_values
)
431 TTCN_error("Index overflow in a value list template of ASN.1 NULL type.");
432 return value_list
.list_value
[list_index
];
435 void ASN_NULL_template::log() const
437 switch (template_selection
) {
439 TTCN_Logger::log_event_str("NULL");
441 case COMPLEMENTED_LIST
:
442 TTCN_Logger::log_event_str("complement ");
444 TTCN_Logger::log_char('(');
445 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++) {
446 if (i
> 0) TTCN_Logger::log_event_str(", ");
447 value_list
.list_value
[i
].log();
449 TTCN_Logger::log_char(')');
457 void ASN_NULL_template::log_match(const ASN_NULL
& match_value
) const
459 if(TTCN_Logger::VERBOSITY_COMPACT
== TTCN_Logger::get_matching_verbosity()){
460 TTCN_Logger::print_logmatch_buffer();
461 TTCN_Logger::log_event_str(" := ");
464 TTCN_Logger::log_event_str(" with ");
466 if (match(match_value
)) TTCN_Logger::log_event_str(" matched");
467 else TTCN_Logger::log_event_str(" unmatched");
470 void ASN_NULL_template::set_param(Module_Param
& param
) {
471 param
.basic_check(Module_Param::BC_TEMPLATE
, "NULL template");
472 switch (param
.get_type()) {
473 case Module_Param::MP_Omit
:
476 case Module_Param::MP_Any
:
479 case Module_Param::MP_AnyOrNone
:
482 case Module_Param::MP_List_Template
:
483 case Module_Param::MP_ComplementList_Template
:
484 set_type(param
.get_type()==Module_Param::MP_List_Template
? VALUE_LIST
: COMPLEMENTED_LIST
, param
.get_size());
485 for (size_t i
=0; i
<param
.get_size(); i
++) {
486 list_item(i
).set_param(*param
.get_elem(i
));
489 case Module_Param::MP_Asn_Null
:
490 *this = ASN_NULL_VALUE
;
493 param
.type_error("NULL template");
495 is_ifpresent
= param
.get_ifpresent();
498 void ASN_NULL_template::encode_text(Text_Buf
& text_buf
) const
500 encode_text_base(text_buf
);
501 switch (template_selection
) {
508 case COMPLEMENTED_LIST
:
509 text_buf
.push_int(value_list
.n_values
);
510 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
511 value_list
.list_value
[i
].encode_text(text_buf
);
514 TTCN_error("Text encoder: Encoding an undefined/unsupported template "
515 "of ASN.1 NULL type.");
519 void ASN_NULL_template::decode_text(Text_Buf
& text_buf
)
522 decode_text_base(text_buf
);
523 switch (template_selection
) {
530 case COMPLEMENTED_LIST
:
531 value_list
.n_values
= text_buf
.pull_int().get_val();
532 value_list
.list_value
= new ASN_NULL_template
[value_list
.n_values
];
533 for (unsigned int i
= 0; i
< value_list
.n_values
; i
++)
534 value_list
.list_value
[i
].decode_text(text_buf
);
537 TTCN_error("Text decoder: An unknown/unsupported selection was received "
538 "in a template for ASN.1 NULL type.");
542 boolean
ASN_NULL_template::is_present() const
544 if (template_selection
==UNINITIALIZED_TEMPLATE
) return FALSE
;
545 return !match_omit();
548 boolean
ASN_NULL_template::match_omit() const
550 if (is_ifpresent
) return TRUE
;
551 switch (template_selection
) {
556 case COMPLEMENTED_LIST
:
557 for (unsigned int i
=0; i
<value_list
.n_values
; i
++)
558 if (value_list
.list_value
[i
].match_omit())
559 return template_selection
==VALUE_LIST
;
560 return template_selection
==COMPLEMENTED_LIST
;
567 #ifndef TITAN_RUNTIME_2
568 void ASN_NULL_template::check_restriction(template_res t_res
, const char* t_name
) const
570 if (template_selection
==UNINITIALIZED_TEMPLATE
) return;
571 switch ((t_name
&&(t_res
==TR_VALUE
))?TR_OMIT
:t_res
) {
573 if (!is_ifpresent
&& template_selection
==SPECIFIC_VALUE
) return;
576 if (!is_ifpresent
&& (template_selection
==OMIT_VALUE
||
577 template_selection
==SPECIFIC_VALUE
)) return;
580 if (!match_omit()) return;
585 TTCN_error("Restriction `%s' on template of type %s violated.",
586 get_res_name(t_res
), t_name
? t_name
: "ASN.1 NULL");