800c533413b601eae1792b828bbb8599f452936c
[deliverable/titan.core.git] / core / ASN_Null.cc
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 <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 if (param.get_type()!=Module_Param::MP_Asn_Null) param.type_error("NULL value");
77 bound_flag = TRUE;
78 }
79
80 void ASN_NULL::encode_text(Text_Buf&) const
81 {
82 if (!bound_flag)
83 TTCN_error("Text encoder: Encoding an unbound ASN.1 NULL value.");
84 }
85
86 void ASN_NULL::decode_text(Text_Buf&)
87 {
88 bound_flag = TRUE;
89 }
90
91 void ASN_NULL::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
92 TTCN_EncDec::coding_t p_coding, ...) const
93 {
94 va_list pvar;
95 va_start(pvar, p_coding);
96 switch(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);
104 break;}
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);
109 break;}
110 case TTCN_EncDec::CT_RAW:
111 default:
112 TTCN_error("Unknown coding method requested to encode type '%s'",
113 p_td.name);
114 }
115 va_end(pvar);
116 }
117
118 void ASN_NULL::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
119 TTCN_EncDec::coding_t p_coding, ...)
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-decoding type '%s': ", p_td.name);
126 unsigned L_form=va_arg(pvar, unsigned);
127 ASN_BER_TLV_t tlv;
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());
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 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)
140 break;
141 }
142 XER_decode(*p_td.xer, reader, XER_coding);
143 size_t bytes = reader.ByteConsumed();
144 p_buf.set_pos(bytes);
145 break;}
146 case TTCN_EncDec::CT_RAW:
147 default:
148 TTCN_error("Unknown coding method requested to decode type '%s'",
149 p_td.name);
150 }
151 va_end(pvar);
152 }
153
154 ASN_BER_TLV_t*
155 ASN_NULL::BER_encode_TLV(const TTCN_Typedescriptor_t& p_td,
156 unsigned p_coding) const
157 {
158 BER_chk_descr(p_td);
159 ASN_BER_TLV_t *new_tlv=BER_encode_chk_bound(is_bound());
160 if(!new_tlv) {
161 new_tlv=ASN_BER_TLV_t::construct(0, NULL);
162 }
163 new_tlv=ASN_BER_V2TLV(new_tlv, p_td, p_coding);
164 return new_tlv;
165 }
166
167 boolean ASN_NULL::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,
168 const ASN_BER_TLV_t& p_tlv,
169 unsigned L_form)
170 {
171 bound_flag = FALSE;
172 BER_chk_descr(p_td);
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.");
179 bound_flag=TRUE;
180 return TRUE;
181 }
182
183 int ASN_NULL::XER_encode(const XERdescriptor_t& p_td,
184 TTCN_Buffer& p_buf, unsigned int flavor, int indent ) const
185 {
186 int exer = is_exer(flavor);
187 TTCN_EncDec_ErrorContext ec("While XER encoding NULL type: ");
188 if(!is_bound()) {
189 TTCN_EncDec_ErrorContext::error
190 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound ASN.1 NULL value.");
191 }
192
193 int indenting = !is_canonical(flavor) && !is_record_of(flavor);
194 int encoded_length=(int)p_buf.get_len();
195
196 if (indenting) do_indent(p_buf, indent);
197 p_buf.put_c('<');
198
199 // empty element tag
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]);
202
203 p_buf.put_s(2 + indenting , (const unsigned char*)"/>\n");
204 return (int)p_buf.get_len() - encoded_length;
205 }
206
207 int ASN_NULL::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
208 unsigned int flavor)
209 {
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();
218 break;
219 }
220 }
221 bound_flag = TRUE;
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() ??
229 break;
230 }
231 } // next
232 } // if gol
233
234 reader.Read();
235 return 1; // decode successful
236 }
237
238 boolean operator==(asn_null_type, const ASN_NULL& other_value)
239 {
240 if (!other_value.is_bound()) TTCN_error("The right operand of comparison "
241 "is an unbound ASN.1 NULL value.");
242 return TRUE;
243 }
244
245 void ASN_NULL_template::clean_up()
246 {
247 if (template_selection == VALUE_LIST ||
248 template_selection == COMPLEMENTED_LIST) delete [] value_list.list_value;
249 template_selection = UNINITIALIZED_TEMPLATE;
250 }
251
252 void ASN_NULL_template::copy_template(const ASN_NULL_template& other_value)
253 {
254 switch (other_value.template_selection) {
255 case SPECIFIC_VALUE:
256 case OMIT_VALUE:
257 case ANY_VALUE:
258 case ANY_OR_OMIT:
259 break;
260 case VALUE_LIST:
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]);
267 break;
268 default:
269 TTCN_error("Copying an uninitialized/unsupported template of ASN.1 "
270 "NULL type.");
271 }
272 set_selection(other_value);
273 }
274
275 ASN_NULL_template::ASN_NULL_template()
276 {
277
278 }
279
280 ASN_NULL_template::ASN_NULL_template(template_sel other_value)
281 : Base_Template(other_value)
282 {
283 check_single_selection(other_value);
284 }
285
286 ASN_NULL_template::ASN_NULL_template(asn_null_type)
287 : Base_Template(SPECIFIC_VALUE)
288 {
289
290 }
291
292 ASN_NULL_template::ASN_NULL_template(const ASN_NULL& other_value)
293 : Base_Template(SPECIFIC_VALUE)
294 {
295 if (!other_value.is_bound())
296 TTCN_error("Creating a template from an unbound ASN.1 NULL value.");
297 }
298
299 ASN_NULL_template::ASN_NULL_template(const OPTIONAL<ASN_NULL>& other_value)
300 {
301 switch (other_value.get_selection()) {
302 case OPTIONAL_PRESENT:
303 set_selection(SPECIFIC_VALUE);
304 break;
305 case OPTIONAL_OMIT:
306 set_selection(OMIT_VALUE);
307 break;
308 default:
309 TTCN_error("Creating a template of ASN.1 NULL type from an unbound "
310 "optional field.");
311 }
312 }
313
314 ASN_NULL_template::ASN_NULL_template(const ASN_NULL_template& other_value)
315 : Base_Template()
316 {
317 copy_template(other_value);
318 }
319
320 ASN_NULL_template::~ASN_NULL_template()
321 {
322 clean_up();
323 }
324
325 ASN_NULL_template& ASN_NULL_template::operator=(template_sel other_value)
326 {
327 check_single_selection(other_value);
328 clean_up();
329 set_selection(other_value);
330 return *this;
331 }
332
333 ASN_NULL_template& ASN_NULL_template::operator=(asn_null_type)
334 {
335 clean_up();
336 set_selection(SPECIFIC_VALUE);
337 return *this;
338 }
339
340 ASN_NULL_template& ASN_NULL_template::operator=(const ASN_NULL& other_value)
341 {
342 if (!other_value.is_bound()) TTCN_error("Assignment of an unbound ASN.1 "
343 "NULL value to a template.");
344 clean_up();
345 set_selection(SPECIFIC_VALUE);
346 return *this;
347 }
348
349 ASN_NULL_template& ASN_NULL_template::operator=
350 (const OPTIONAL<ASN_NULL>& other_value)
351 {
352 clean_up();
353 switch (other_value.get_selection()) {
354 case OPTIONAL_PRESENT:
355 set_selection(SPECIFIC_VALUE);
356 break;
357 case OPTIONAL_OMIT:
358 set_selection(OMIT_VALUE);
359 break;
360 default:
361 TTCN_error("Assignment of an unbound optional field to a template of "
362 "ASN.1 NULL type.");
363 }
364 return *this;
365 }
366
367 ASN_NULL_template& ASN_NULL_template::operator=
368 (const ASN_NULL_template& other_value)
369 {
370 if (&other_value != this) {
371 clean_up();
372 copy_template(other_value);
373 }
374 return *this;
375 }
376
377 boolean ASN_NULL_template::match(asn_null_type other_value) const
378 {
379 switch (template_selection) {
380 case OMIT_VALUE:
381 return FALSE;
382 case SPECIFIC_VALUE:
383 case ANY_VALUE:
384 case ANY_OR_OMIT:
385 return TRUE;
386 case VALUE_LIST:
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;
392 default:
393 TTCN_error("Matching with an uninitialized/unsupported template of "
394 "ASN.1 NULL type.");
395 }
396 return FALSE;
397 }
398
399 boolean ASN_NULL_template::match(const ASN_NULL& other_value) const
400 {
401 if (!other_value.is_bound()) return FALSE;
402 return match(ASN_NULL_VALUE);
403 }
404
405 asn_null_type ASN_NULL_template::valueof() const
406 {
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;
411 }
412
413 void ASN_NULL_template::set_type(template_sel template_type,
414 unsigned int list_length)
415 {
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 "
418 "type.");
419 clean_up();
420 set_selection(template_type);
421 value_list.n_values = list_length;
422 value_list.list_value = new ASN_NULL_template[list_length];
423 }
424
425 ASN_NULL_template& ASN_NULL_template::list_item(unsigned int list_index)
426 {
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];
433 }
434
435 void ASN_NULL_template::log() const
436 {
437 switch (template_selection) {
438 case SPECIFIC_VALUE:
439 TTCN_Logger::log_event_str("NULL");
440 break;
441 case COMPLEMENTED_LIST:
442 TTCN_Logger::log_event_str("complement ");
443 case VALUE_LIST:
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();
448 }
449 TTCN_Logger::log_char(')');
450 break;
451 default:
452 log_generic();
453 }
454 log_ifpresent();
455 }
456
457 void ASN_NULL_template::log_match(const ASN_NULL& match_value) const
458 {
459 if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
460 TTCN_Logger::print_logmatch_buffer();
461 TTCN_Logger::log_event_str(" := ");
462 }
463 match_value.log();
464 TTCN_Logger::log_event_str(" with ");
465 log();
466 if (match(match_value)) TTCN_Logger::log_event_str(" matched");
467 else TTCN_Logger::log_event_str(" unmatched");
468 }
469
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:
474 *this = OMIT_VALUE;
475 break;
476 case Module_Param::MP_Any:
477 *this = ANY_VALUE;
478 break;
479 case Module_Param::MP_AnyOrNone:
480 *this = ANY_OR_OMIT;
481 break;
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));
487 }
488 break;
489 case Module_Param::MP_Asn_Null:
490 *this = ASN_NULL_VALUE;
491 break;
492 default:
493 param.type_error("NULL template");
494 }
495 is_ifpresent = param.get_ifpresent();
496 }
497
498 void ASN_NULL_template::encode_text(Text_Buf& text_buf) const
499 {
500 encode_text_base(text_buf);
501 switch (template_selection) {
502 case SPECIFIC_VALUE:
503 case OMIT_VALUE:
504 case ANY_VALUE:
505 case ANY_OR_OMIT:
506 break;
507 case VALUE_LIST:
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);
512 break;
513 default:
514 TTCN_error("Text encoder: Encoding an undefined/unsupported template "
515 "of ASN.1 NULL type.");
516 }
517 }
518
519 void ASN_NULL_template::decode_text(Text_Buf& text_buf)
520 {
521 clean_up();
522 decode_text_base(text_buf);
523 switch (template_selection) {
524 case SPECIFIC_VALUE:
525 case OMIT_VALUE:
526 case ANY_VALUE:
527 case ANY_OR_OMIT:
528 break;
529 case VALUE_LIST:
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);
535 break;
536 default:
537 TTCN_error("Text decoder: An unknown/unsupported selection was received "
538 "in a template for ASN.1 NULL type.");
539 }
540 }
541
542 boolean ASN_NULL_template::is_present() const
543 {
544 if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
545 return !match_omit();
546 }
547
548 boolean ASN_NULL_template::match_omit() const
549 {
550 if (is_ifpresent) return TRUE;
551 switch (template_selection) {
552 case OMIT_VALUE:
553 case ANY_OR_OMIT:
554 return TRUE;
555 case VALUE_LIST:
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;
561 default:
562 return FALSE;
563 }
564 return FALSE;
565 }
566
567 #ifndef TITAN_RUNTIME_2
568 void ASN_NULL_template::check_restriction(template_res t_res, const char* t_name) const
569 {
570 if (template_selection==UNINITIALIZED_TEMPLATE) return;
571 switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
572 case TR_VALUE:
573 if (!is_ifpresent && template_selection==SPECIFIC_VALUE) return;
574 break;
575 case TR_OMIT:
576 if (!is_ifpresent && (template_selection==OMIT_VALUE ||
577 template_selection==SPECIFIC_VALUE)) return;
578 break;
579 case TR_PRESENT:
580 if (!match_omit()) return;
581 break;
582 default:
583 return;
584 }
585 TTCN_error("Restriction `%s' on template of type %s violated.",
586 get_res_name(t_res), t_name ? t_name : "ASN.1 NULL");
587 }
588 #endif
This page took 0.078527 seconds and 4 git commands to generate.