Sync with 5.2.0
[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, 0);
109 break;}
110 case TTCN_EncDec::CT_JSON: {
111 TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name);
112 if(!p_td.json)
113 TTCN_EncDec_ErrorContext::error_internal
114 ("No JSON descriptor available for type '%s'.", p_td.name);
115 JSON_Tokenizer tok(va_arg(pvar, int) != 0);
116 JSON_encode(p_td, tok);
117 p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());
118 break;}
119 case TTCN_EncDec::CT_RAW:
120 default:
121 TTCN_error("Unknown coding method requested to encode type '%s'",
122 p_td.name);
123 }
124 va_end(pvar);
125 }
126
127 void ASN_NULL::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
128 TTCN_EncDec::coding_t p_coding, ...)
129 {
130 va_list pvar;
131 va_start(pvar, p_coding);
132 switch(p_coding) {
133 case TTCN_EncDec::CT_BER: {
134 TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name);
135 unsigned L_form=va_arg(pvar, unsigned);
136 ASN_BER_TLV_t tlv;
137 BER_decode_str2TLV(p_buf, tlv, L_form);
138 BER_decode_TLV(p_td, tlv, L_form);
139 if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());
140 break;}
141 case TTCN_EncDec::CT_XER: {
142 TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
143 unsigned XER_coding=va_arg(pvar, unsigned);
144 XmlReaderWrap reader(p_buf);
145 int success = reader.Read();
146 for (; success==1; success=reader.Read()) {
147 int type = reader.NodeType();
148 if (type==XML_READER_TYPE_ELEMENT)
149 break;
150 }
151 XER_decode(*p_td.xer, reader, XER_coding, 0);
152 size_t bytes = reader.ByteConsumed();
153 p_buf.set_pos(bytes);
154 break;}
155 case TTCN_EncDec::CT_JSON: {
156 TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name);
157 if(!p_td.json)
158 TTCN_EncDec_ErrorContext::error_internal
159 ("No JSON descriptor available for type '%s'.", p_td.name);
160 JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());
161 if(JSON_decode(p_td, tok, false)<0)
162 ec.error(TTCN_EncDec::ET_INCOMPL_MSG,
163 "Can not decode type '%s', because invalid or incomplete"
164 " message was received"
165 , p_td.name);
166 p_buf.set_pos(tok.get_buf_pos());
167 break;}
168 case TTCN_EncDec::CT_RAW:
169 default:
170 TTCN_error("Unknown coding method requested to decode type '%s'",
171 p_td.name);
172 }
173 va_end(pvar);
174 }
175
176 ASN_BER_TLV_t*
177 ASN_NULL::BER_encode_TLV(const TTCN_Typedescriptor_t& p_td,
178 unsigned p_coding) const
179 {
180 BER_chk_descr(p_td);
181 ASN_BER_TLV_t *new_tlv=BER_encode_chk_bound(is_bound());
182 if(!new_tlv) {
183 new_tlv=ASN_BER_TLV_t::construct(0, NULL);
184 }
185 new_tlv=ASN_BER_V2TLV(new_tlv, p_td, p_coding);
186 return new_tlv;
187 }
188
189 boolean ASN_NULL::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,
190 const ASN_BER_TLV_t& p_tlv,
191 unsigned L_form)
192 {
193 bound_flag = FALSE;
194 BER_chk_descr(p_td);
195 ASN_BER_TLV_t stripped_tlv;
196 BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv);
197 TTCN_EncDec_ErrorContext ec("While decoding NULL type: ");
198 stripped_tlv.chk_constructed_flag(FALSE);
199 if(!stripped_tlv.V_tlvs_selected && stripped_tlv.V.str.Vlen!=0)
200 ec.error(TTCN_EncDec::ET_INVAL_MSG, "Length of V-part is not 0.");
201 bound_flag=TRUE;
202 return TRUE;
203 }
204
205 int ASN_NULL::XER_encode(const XERdescriptor_t& p_td,
206 TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
207 {
208 int exer = is_exer(flavor);
209 TTCN_EncDec_ErrorContext ec("While XER encoding NULL type: ");
210 if(!is_bound()) {
211 TTCN_EncDec_ErrorContext::error
212 (TTCN_EncDec::ET_UNBOUND, "Encoding an unbound ASN.1 NULL value.");
213 }
214
215 int indenting = !is_canonical(flavor) && !is_record_of(flavor);
216 int encoded_length=(int)p_buf.get_len();
217
218 if (indenting) do_indent(p_buf, indent);
219 p_buf.put_c('<');
220
221 // empty element tag
222 if (exer) write_ns_prefix(p_td, p_buf);
223 p_buf.put_s((size_t)p_td.namelens[exer]-2, (const unsigned char*)p_td.names[exer]);
224
225 p_buf.put_s(2 + indenting , (const unsigned char*)"/>\n");
226 return (int)p_buf.get_len() - encoded_length;
227 }
228
229 int ASN_NULL::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
230 unsigned int flavor, embed_values_dec_struct_t*)
231 {
232 int exer = is_exer(flavor);
233 TTCN_EncDec_ErrorContext ec("While XER decoding NULL type: ");
234 int success = reader.Ok(), depth = -1;
235 for (; success == 1; success = reader.Read()) {
236 int type = reader.NodeType();
237 if (XML_READER_TYPE_ELEMENT == type) {
238 verify_name(reader, p_td, exer);
239 depth = reader.Depth();
240 break;
241 }
242 }
243 bound_flag = TRUE;
244 int gol = reader.IsEmptyElement();
245 if (!gol) { // shouldn't happen
246 for (success = reader.Read(); success == 1; success = reader.Read()) {
247 int type = reader.NodeType();
248 if (XML_READER_TYPE_END_ELEMENT == type) {
249 verify_end(reader, p_td, depth, exer);
250 // FIXME reader.Read() ??
251 break;
252 }
253 } // next
254 } // if gol
255
256 reader.Read();
257 return 1; // decode successful
258 }
259
260 int ASN_NULL::JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok) const
261 {
262 if (!is_bound()) {
263 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,
264 "Encoding an unbound ASN.1 NULL value.");
265 return -1;
266 }
267
268 return p_tok.put_next_token(JSON_TOKEN_LITERAL_NULL);
269 }
270
271 int ASN_NULL::JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok, boolean p_silent)
272 {
273 json_token_t token = JSON_TOKEN_NONE;
274 int dec_len = p_tok.get_next_token(&token, NULL, NULL);
275 if (JSON_TOKEN_ERROR == token) {
276 JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, "");
277 return JSON_ERROR_FATAL;
278 }
279 else if (JSON_TOKEN_LITERAL_NULL != token) {
280 return JSON_ERROR_INVALID_TOKEN;
281 }
282 bound_flag = TRUE;
283 return dec_len;
284 }
285
286 boolean operator==(asn_null_type, const ASN_NULL& other_value)
287 {
288 if (!other_value.is_bound()) TTCN_error("The right operand of comparison "
289 "is an unbound ASN.1 NULL value.");
290 return TRUE;
291 }
292
293 void ASN_NULL_template::clean_up()
294 {
295 if (template_selection == VALUE_LIST ||
296 template_selection == COMPLEMENTED_LIST) delete [] value_list.list_value;
297 template_selection = UNINITIALIZED_TEMPLATE;
298 }
299
300 void ASN_NULL_template::copy_template(const ASN_NULL_template& other_value)
301 {
302 switch (other_value.template_selection) {
303 case SPECIFIC_VALUE:
304 case OMIT_VALUE:
305 case ANY_VALUE:
306 case ANY_OR_OMIT:
307 break;
308 case VALUE_LIST:
309 case COMPLEMENTED_LIST:
310 value_list.n_values = other_value.value_list.n_values;
311 value_list.list_value = new ASN_NULL_template[value_list.n_values];
312 for (unsigned int i = 0; i < value_list.n_values; i++)
313 value_list.list_value[i].copy_template(
314 other_value.value_list.list_value[i]);
315 break;
316 default:
317 TTCN_error("Copying an uninitialized/unsupported template of ASN.1 "
318 "NULL type.");
319 }
320 set_selection(other_value);
321 }
322
323 ASN_NULL_template::ASN_NULL_template()
324 {
325
326 }
327
328 ASN_NULL_template::ASN_NULL_template(template_sel other_value)
329 : Base_Template(other_value)
330 {
331 check_single_selection(other_value);
332 }
333
334 ASN_NULL_template::ASN_NULL_template(asn_null_type)
335 : Base_Template(SPECIFIC_VALUE)
336 {
337
338 }
339
340 ASN_NULL_template::ASN_NULL_template(const ASN_NULL& other_value)
341 : Base_Template(SPECIFIC_VALUE)
342 {
343 if (!other_value.is_bound())
344 TTCN_error("Creating a template from an unbound ASN.1 NULL value.");
345 }
346
347 ASN_NULL_template::ASN_NULL_template(const OPTIONAL<ASN_NULL>& other_value)
348 {
349 switch (other_value.get_selection()) {
350 case OPTIONAL_PRESENT:
351 set_selection(SPECIFIC_VALUE);
352 break;
353 case OPTIONAL_OMIT:
354 set_selection(OMIT_VALUE);
355 break;
356 default:
357 TTCN_error("Creating a template of ASN.1 NULL type from an unbound "
358 "optional field.");
359 }
360 }
361
362 ASN_NULL_template::ASN_NULL_template(const ASN_NULL_template& other_value)
363 : Base_Template()
364 {
365 copy_template(other_value);
366 }
367
368 ASN_NULL_template::~ASN_NULL_template()
369 {
370 clean_up();
371 }
372
373 ASN_NULL_template& ASN_NULL_template::operator=(template_sel other_value)
374 {
375 check_single_selection(other_value);
376 clean_up();
377 set_selection(other_value);
378 return *this;
379 }
380
381 ASN_NULL_template& ASN_NULL_template::operator=(asn_null_type)
382 {
383 clean_up();
384 set_selection(SPECIFIC_VALUE);
385 return *this;
386 }
387
388 ASN_NULL_template& ASN_NULL_template::operator=(const ASN_NULL& other_value)
389 {
390 if (!other_value.is_bound()) TTCN_error("Assignment of an unbound ASN.1 "
391 "NULL value to a template.");
392 clean_up();
393 set_selection(SPECIFIC_VALUE);
394 return *this;
395 }
396
397 ASN_NULL_template& ASN_NULL_template::operator=
398 (const OPTIONAL<ASN_NULL>& other_value)
399 {
400 clean_up();
401 switch (other_value.get_selection()) {
402 case OPTIONAL_PRESENT:
403 set_selection(SPECIFIC_VALUE);
404 break;
405 case OPTIONAL_OMIT:
406 set_selection(OMIT_VALUE);
407 break;
408 default:
409 TTCN_error("Assignment of an unbound optional field to a template of "
410 "ASN.1 NULL type.");
411 }
412 return *this;
413 }
414
415 ASN_NULL_template& ASN_NULL_template::operator=
416 (const ASN_NULL_template& other_value)
417 {
418 if (&other_value != this) {
419 clean_up();
420 copy_template(other_value);
421 }
422 return *this;
423 }
424
425 boolean ASN_NULL_template::match(asn_null_type other_value) const
426 {
427 switch (template_selection) {
428 case OMIT_VALUE:
429 return FALSE;
430 case SPECIFIC_VALUE:
431 case ANY_VALUE:
432 case ANY_OR_OMIT:
433 return TRUE;
434 case VALUE_LIST:
435 case COMPLEMENTED_LIST:
436 for (unsigned int i = 0; i < value_list.n_values; i++)
437 if (value_list.list_value[i].match(other_value))
438 return template_selection == VALUE_LIST;
439 return template_selection == COMPLEMENTED_LIST;
440 default:
441 TTCN_error("Matching with an uninitialized/unsupported template of "
442 "ASN.1 NULL type.");
443 }
444 return FALSE;
445 }
446
447 boolean ASN_NULL_template::match(const ASN_NULL& other_value) const
448 {
449 if (!other_value.is_bound()) return FALSE;
450 return match(ASN_NULL_VALUE);
451 }
452
453 asn_null_type ASN_NULL_template::valueof() const
454 {
455 if (template_selection != SPECIFIC_VALUE || is_ifpresent)
456 TTCN_error("Performing a valueof "
457 "or send operation on a non-specific template of ASN.1 NULL type.");
458 return ASN_NULL_VALUE;
459 }
460
461 void ASN_NULL_template::set_type(template_sel template_type,
462 unsigned int list_length)
463 {
464 if (template_type != VALUE_LIST && template_type != COMPLEMENTED_LIST)
465 TTCN_error("Setting an invalid list type for a template of ASN.1 NULL "
466 "type.");
467 clean_up();
468 set_selection(template_type);
469 value_list.n_values = list_length;
470 value_list.list_value = new ASN_NULL_template[list_length];
471 }
472
473 ASN_NULL_template& ASN_NULL_template::list_item(unsigned int list_index)
474 {
475 if (template_selection != VALUE_LIST &&
476 template_selection != COMPLEMENTED_LIST) TTCN_error("Accessing a list "
477 "element of a non-list template for ASN.1 NULL type.");
478 if (list_index >= value_list.n_values)
479 TTCN_error("Index overflow in a value list template of ASN.1 NULL type.");
480 return value_list.list_value[list_index];
481 }
482
483 void ASN_NULL_template::log() const
484 {
485 switch (template_selection) {
486 case SPECIFIC_VALUE:
487 TTCN_Logger::log_event_str("NULL");
488 break;
489 case COMPLEMENTED_LIST:
490 TTCN_Logger::log_event_str("complement ");
491 case VALUE_LIST:
492 TTCN_Logger::log_char('(');
493 for (unsigned int i = 0; i < value_list.n_values; i++) {
494 if (i > 0) TTCN_Logger::log_event_str(", ");
495 value_list.list_value[i].log();
496 }
497 TTCN_Logger::log_char(')');
498 break;
499 default:
500 log_generic();
501 }
502 log_ifpresent();
503 }
504
505 void ASN_NULL_template::log_match(const ASN_NULL& match_value) const
506 {
507 if(TTCN_Logger::VERBOSITY_COMPACT == TTCN_Logger::get_matching_verbosity()){
508 TTCN_Logger::print_logmatch_buffer();
509 TTCN_Logger::log_event_str(" := ");
510 }
511 match_value.log();
512 TTCN_Logger::log_event_str(" with ");
513 log();
514 if (match(match_value)) TTCN_Logger::log_event_str(" matched");
515 else TTCN_Logger::log_event_str(" unmatched");
516 }
517
518 void ASN_NULL_template::set_param(Module_Param& param) {
519 param.basic_check(Module_Param::BC_TEMPLATE, "NULL template");
520 switch (param.get_type()) {
521 case Module_Param::MP_Omit:
522 *this = OMIT_VALUE;
523 break;
524 case Module_Param::MP_Any:
525 *this = ANY_VALUE;
526 break;
527 case Module_Param::MP_AnyOrNone:
528 *this = ANY_OR_OMIT;
529 break;
530 case Module_Param::MP_List_Template:
531 case Module_Param::MP_ComplementList_Template:
532 set_type(param.get_type()==Module_Param::MP_List_Template ? VALUE_LIST : COMPLEMENTED_LIST, param.get_size());
533 for (size_t i=0; i<param.get_size(); i++) {
534 list_item(i).set_param(*param.get_elem(i));
535 }
536 break;
537 case Module_Param::MP_Asn_Null:
538 *this = ASN_NULL_VALUE;
539 break;
540 default:
541 param.type_error("NULL template");
542 }
543 is_ifpresent = param.get_ifpresent();
544 }
545
546 void ASN_NULL_template::encode_text(Text_Buf& text_buf) const
547 {
548 encode_text_base(text_buf);
549 switch (template_selection) {
550 case SPECIFIC_VALUE:
551 case OMIT_VALUE:
552 case ANY_VALUE:
553 case ANY_OR_OMIT:
554 break;
555 case VALUE_LIST:
556 case COMPLEMENTED_LIST:
557 text_buf.push_int(value_list.n_values);
558 for (unsigned int i = 0; i < value_list.n_values; i++)
559 value_list.list_value[i].encode_text(text_buf);
560 break;
561 default:
562 TTCN_error("Text encoder: Encoding an undefined/unsupported template "
563 "of ASN.1 NULL type.");
564 }
565 }
566
567 void ASN_NULL_template::decode_text(Text_Buf& text_buf)
568 {
569 clean_up();
570 decode_text_base(text_buf);
571 switch (template_selection) {
572 case SPECIFIC_VALUE:
573 case OMIT_VALUE:
574 case ANY_VALUE:
575 case ANY_OR_OMIT:
576 break;
577 case VALUE_LIST:
578 case COMPLEMENTED_LIST:
579 value_list.n_values = text_buf.pull_int().get_val();
580 value_list.list_value = new ASN_NULL_template[value_list.n_values];
581 for (unsigned int i = 0; i < value_list.n_values; i++)
582 value_list.list_value[i].decode_text(text_buf);
583 break;
584 default:
585 TTCN_error("Text decoder: An unknown/unsupported selection was received "
586 "in a template for ASN.1 NULL type.");
587 }
588 }
589
590 boolean ASN_NULL_template::is_present() const
591 {
592 if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
593 return !match_omit();
594 }
595
596 boolean ASN_NULL_template::match_omit() const
597 {
598 if (is_ifpresent) return TRUE;
599 switch (template_selection) {
600 case OMIT_VALUE:
601 case ANY_OR_OMIT:
602 return TRUE;
603 case VALUE_LIST:
604 case COMPLEMENTED_LIST:
605 for (unsigned int i=0; i<value_list.n_values; i++)
606 if (value_list.list_value[i].match_omit())
607 return template_selection==VALUE_LIST;
608 return template_selection==COMPLEMENTED_LIST;
609 default:
610 return FALSE;
611 }
612 return FALSE;
613 }
614
615 #ifndef TITAN_RUNTIME_2
616 void ASN_NULL_template::check_restriction(template_res t_res, const char* t_name) const
617 {
618 if (template_selection==UNINITIALIZED_TEMPLATE) return;
619 switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {
620 case TR_VALUE:
621 if (!is_ifpresent && template_selection==SPECIFIC_VALUE) return;
622 break;
623 case TR_OMIT:
624 if (!is_ifpresent && (template_selection==OMIT_VALUE ||
625 template_selection==SPECIFIC_VALUE)) return;
626 break;
627 case TR_PRESENT:
628 if (!match_omit()) return;
629 break;
630 default:
631 return;
632 }
633 TTCN_error("Restriction `%s' on template of type %s violated.",
634 get_res_name(t_res), t_name ? t_name : "ASN.1 NULL");
635 }
636 #endif
This page took 0.043528 seconds and 5 git commands to generate.