Sync with 5.2.0
[deliverable/titan.core.git] / core / ASN_Null.cc
CommitLineData
970ed795
EL
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
20ASN_NULL::ASN_NULL()
21{
22 bound_flag = FALSE;
23}
24
25ASN_NULL::ASN_NULL(asn_null_type)
26{
27 bound_flag = TRUE;
28}
29
30ASN_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
38ASN_NULL& ASN_NULL::operator=(asn_null_type)
39{
40 bound_flag = TRUE;
41 return *this;
42}
43
44ASN_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
52boolean 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
59boolean 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
68void ASN_NULL::log() const
69{
70 if (bound_flag) TTCN_Logger::log_event_str("NULL");
71 else TTCN_Logger::log_event_unbound();
72}
73
74void 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
80void 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
86void ASN_NULL::decode_text(Text_Buf&)
87{
88 bound_flag = TRUE;
89}
90
91void 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);
af710487 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());
970ed795
EL
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
127void 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: {
af710487 142 TTCN_EncDec_ErrorContext ec("While XER-decoding type '%s': ", p_td.name);
970ed795
EL
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 }
af710487 151 XER_decode(*p_td.xer, reader, XER_coding, 0);
970ed795
EL
152 size_t bytes = reader.ByteConsumed();
153 p_buf.set_pos(bytes);
154 break;}
af710487 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;}
970ed795
EL
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
176ASN_BER_TLV_t*
177ASN_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
189boolean 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
205int ASN_NULL::XER_encode(const XERdescriptor_t& p_td,
af710487 206 TTCN_Buffer& p_buf, unsigned int flavor, int indent, embed_values_enc_struct_t*) const
970ed795
EL
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
229int ASN_NULL::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& reader,
af710487 230 unsigned int flavor, embed_values_dec_struct_t*)
970ed795
EL
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
af710487 260int 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
271int 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
970ed795
EL
286boolean 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
293void 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
300void 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
323ASN_NULL_template::ASN_NULL_template()
324{
325
326}
327
328ASN_NULL_template::ASN_NULL_template(template_sel other_value)
329 : Base_Template(other_value)
330{
331 check_single_selection(other_value);
332}
333
334ASN_NULL_template::ASN_NULL_template(asn_null_type)
335 : Base_Template(SPECIFIC_VALUE)
336{
337
338}
339
340ASN_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
347ASN_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
362ASN_NULL_template::ASN_NULL_template(const ASN_NULL_template& other_value)
363: Base_Template()
364{
365 copy_template(other_value);
366}
367
368ASN_NULL_template::~ASN_NULL_template()
369{
370 clean_up();
371}
372
373ASN_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
381ASN_NULL_template& ASN_NULL_template::operator=(asn_null_type)
382{
383 clean_up();
384 set_selection(SPECIFIC_VALUE);
385 return *this;
386}
387
388ASN_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
397ASN_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
415ASN_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
425boolean 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
447boolean 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
453asn_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
461void 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
473ASN_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
483void 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
505void 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
518void 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
546void 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
567void 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
590boolean ASN_NULL_template::is_present() const
591{
592 if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;
593 return !match_omit();
594}
595
596boolean 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
616void 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.087366 seconds and 5 git commands to generate.