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 ///////////////////////////////////////////////////////////////////////////////
9 #include "../common/memory.h"
17 #include "XmlReader.hh"
18 #include "Module_list.hh"
19 #include "Universal_charstring.hh"
21 #include <openssl/bn.h>
26 // Note: RT2-only classes (Record_Type, Record_Of_Type) and Base_Type methods
27 // are in core2/Basetype2.cc
29 boolean
Base_Type::ispresent() const
31 TTCN_error("Base_Type::ispresent(): calling ispresent() on a non-optional field.");
35 void Base_Type::log() const
37 TTCN_Logger::log_event_str("<logging of this type is not implemented>");
40 void Base_Type::encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
41 TTCN_EncDec::coding_t p_coding
, ...) const
44 va_start(pvar
, p_coding
);
46 case TTCN_EncDec::CT_BER
: {
47 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
48 unsigned BER_coding
=va_arg(pvar
, unsigned);
49 BER_encode_chk_coding(BER_coding
);
50 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
51 tlv
->put_in_buffer(p_buf
);
52 ASN_BER_TLV_t::destruct(tlv
);
54 case TTCN_EncDec::CT_RAW
: {
55 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
57 TTCN_EncDec_ErrorContext::error_internal
58 ("No RAW descriptor available for type '%s'.", p_td
.name
);
62 RAW_enc_tree
root(TRUE
, NULL
, &rp
, 1, p_td
.raw
);
63 RAW_encode(p_td
, root
);
64 root
.put_to_buf(p_buf
);
66 case TTCN_EncDec::CT_TEXT
: {
67 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
69 TTCN_EncDec_ErrorContext::error_internal
70 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
71 TEXT_encode(p_td
,p_buf
);
73 case TTCN_EncDec::CT_XER
: {
74 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
75 if(!p_td
.xer
) TTCN_EncDec_ErrorContext::error_internal(
76 "No XER descriptor available for type '%s'.", p_td
.name
);
77 unsigned XER_coding
=va_arg(pvar
, unsigned);
78 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
81 case TTCN_EncDec::CT_JSON
: {
82 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
84 TTCN_EncDec_ErrorContext::error_internal
85 ("No JSON descriptor available for type '%s'.", p_td
.name
);
86 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
87 JSON_encode(p_td
, tok
);
88 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
91 TTCN_error("Unknown coding method requested to encode type '%s'",
97 void Base_Type::decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
98 TTCN_EncDec::coding_t p_coding
, ...)
101 va_start(pvar
, p_coding
);
103 case TTCN_EncDec::CT_BER
: {
104 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
105 unsigned L_form
=va_arg(pvar
, unsigned);
107 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
108 BER_decode_TLV(p_td
, tlv
, L_form
);
109 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
111 case TTCN_EncDec::CT_RAW
: {
112 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
114 TTCN_EncDec_ErrorContext::error_internal
115 ("No RAW descriptor available for type '%s'.", p_td
.name
);
117 switch(p_td
.raw
->top_bit_order
) {
125 RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
);
127 case TTCN_EncDec::CT_TEXT
: {
128 Limit_Token_List limit
;
129 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
131 TTCN_EncDec_ErrorContext::error_internal
132 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
133 const unsigned char *b
=p_buf
.get_data();
134 if(b
[p_buf
.get_len()-1]!='\0'){
135 p_buf
.set_pos(p_buf
.get_len());
136 p_buf
.put_zero(8,ORDER_LSB
);
139 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
140 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
141 "Can not decode type '%s', because invalid or incomplete"
142 " message was received"
145 case TTCN_EncDec::CT_XER
: {
146 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
147 unsigned XER_coding
=va_arg(pvar
, unsigned);
148 XmlReaderWrap
reader(p_buf
);
149 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
150 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
152 XER_decode(*(p_td
.xer
), reader
, XER_coding
, 0);
153 size_t bytes
= reader
.ByteConsumed();
154 p_buf
.set_pos(bytes
);
156 case TTCN_EncDec::CT_JSON
: {
157 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
159 TTCN_EncDec_ErrorContext::error_internal
160 ("No JSON descriptor available for type '%s'.", p_td
.name
);
161 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
162 if(JSON_decode(p_td
, tok
, false)<0)
163 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
164 "Can not decode type '%s', because invalid or incomplete"
165 " message was received"
167 p_buf
.set_pos(tok
.get_buf_pos());
170 TTCN_error("Unknown coding method requested to decode type '%s'",
176 void Base_Type::BER_chk_descr(const TTCN_Typedescriptor_t
& p_td
)
179 TTCN_EncDec_ErrorContext::error_internal
180 ("No BER descriptor available for type '%s'.", p_td
.name
);
183 void Base_Type::BER_encode_chk_coding(unsigned& p_coding
)
190 TTCN_warning("Unknown BER encoding requested; using DER.");
191 p_coding
=BER_ENCODE_DER
;
196 void Base_Type::XER_encode_chk_coding(unsigned& p_coding
,
197 const TTCN_Typedescriptor_t
& p_td
)
200 TTCN_EncDec_ErrorContext::error_internal
201 ("No XER descriptor available for type '%s'.", p_td
.name
);
207 case XER_EXTENDED
| XER_CANONICAL
:
210 TTCN_warning("Unknown XER encoding requested; using Basic XER.");
211 p_coding
= XER_BASIC
;
216 static const cbyte empty_tag_end
[4] = "/>\n";
218 int Base_Type::begin_xml(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
219 unsigned int& flavor
, int indent
, bool empty
,
220 collector_fn collector
, const char *type_atr
) const
222 const int indenting
= !is_canonical(flavor
);
223 const int exer
= is_exer(flavor
);
224 int omit_tag
= (indent
!= 0) // can never omit the tag at the toplevel
225 && ( ((flavor
& XER_RECOF
) // can remove the tag even if not EXER
226 && !(exer
&& (flavor
& BXER_EMPTY_ELEM
))) // except 26.6, 26.7
228 && ( (p_td
.xer_bits
& (UNTAGGED
|ANY_ATTRIBUTES
|ANY_ELEMENT
))
229 || (flavor
& (EMBED_VALUES
|XER_LIST
|ANY_ATTRIBUTES
|USE_NIL
|USE_TYPE_ATTR
)))));
231 // If a default namespace is in effect (uri but no prefix) and the type
232 // is unqualified, the default namespace must be canceled; otherwise
233 // an XML tag without a ns prefix looks like it belongs to the def.namespace
234 const boolean empty_ns_hack
= exer
&& !omit_tag
&& (indent
> 0)
235 && (p_td
.xer_bits
& FORM_UNQUALIFIED
)
236 && (flavor
& DEF_NS_PRESENT
);
238 if (exer
&& (p_td
.xer_bits
& XER_ATTRIBUTE
)) {
239 begin_attribute(p_td
, p_buf
);
241 else if (!omit_tag
) { // full tag
242 if (indenting
) do_indent(p_buf
, indent
);
244 if (exer
) write_ns_prefix(p_td
, p_buf
);
246 const namespace_t
*ns_info
= NULL
;
247 bool namespaces_needed
= false;
249 if (p_td
.my_module
!= NULL
&& p_td
.ns_index
!= -1) {
250 ns_info
= p_td
.my_module
->get_ns(p_td
.ns_index
);
253 namespaces_needed
= exer
&& //!(p_td.xer_bits & FORM_UNQUALIFIED) &&
254 (indent
==0 // top-level type
255 || (ns_info
&& *ns_info
->px
== '\0' // own ns is prefixless
256 && (flavor
& DEF_NS_SQUASHED
))
260 size_t num_collected
= 0;
261 char **collected_ns
= NULL
;
263 if (namespaces_needed
) {
264 collected_ns
= (this->*collector
)(p_td
, num_collected
, def_ns
);
267 p_buf
.put_s((size_t)p_td
.namelens
[exer
] - 2, (cbyte
*)p_td
.names
[exer
]);
269 if (namespaces_needed
) {
270 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
271 p_buf
.put_s(strlen(collected_ns
[cur_coll
]), (cbyte
*)collected_ns
[cur_coll
]);
272 Free(collected_ns
[cur_coll
]); // job done
278 p_buf
.put_s(9, (cbyte
*)" xmlns=''");
279 flavor
&= ~DEF_NS_PRESENT
;
280 flavor
|= DEF_NS_SQUASHED
;
283 flavor
&= ~DEF_NS_SQUASHED
;
284 flavor
|= DEF_NS_PRESENT
;
288 p_buf
.put_s(mstrlen(const_cast<char*>(type_atr
)), (cbyte
*)type_atr
);
292 p_buf
.put_s(2 + indenting
, empty_tag_end
);
297 && !(flavor
& SIMPLE_TYPE
)
298 && !(exer
&& (p_td
.xer_bits
& (XER_LIST
|USE_TYPE_ATTR
)))),
302 else { // tag is omitted
303 // If the outer XML element optimistically wrote a newline after its start tag,
305 size_t buf_used
= p_buf
.get_len();
306 if (exer
&& (flavor
& USE_NIL
) && (buf_used
-- > 0) && // sequence point!
307 (p_buf
.get_data()[buf_used
] == '\n')) {
308 p_buf
.increase_length((size_t)-1); // back up over the newline
309 omit_tag
= -1; // to help fix HO85831
313 Free(const_cast<char*>(type_atr
));
318 void Base_Type::end_xml (const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
319 unsigned int flavor
, int indent
, bool empty
) const
321 int exer
= is_exer(flavor
);
322 int indenting
= !is_canonical(flavor
);
323 bool omit_tag
= (indent
!= 0) // can never omit the tag at the toplevel
324 && ( ((flavor
& XER_RECOF
) // can remove the tag even if not EXER
325 && !(exer
&& (flavor
& BXER_EMPTY_ELEM
))) // except 26.6, 26.7
327 && ( (p_td
.xer_bits
& (UNTAGGED
|ANY_ATTRIBUTES
|ANY_ELEMENT
))
328 || (flavor
& (EMBED_VALUES
|XER_LIST
|ANY_ATTRIBUTES
|USE_NIL
|USE_TYPE_ATTR
)))));
330 if (exer
&& (p_td
.xer_bits
& XER_ATTRIBUTE
)) {
333 else if (!empty
&& !omit_tag
) {
335 if (indenting
&& !(flavor
& SIMPLE_TYPE
)) do_indent(p_buf
, indent
);
336 p_buf
.put_s(2, (cbyte
*)"</");
337 if (exer
) write_ns_prefix(p_td
, p_buf
);
338 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-1+indenting
, (cbyte
*)p_td
.names
[exer
]);
344 ASN_BER_TLV_t
* Base_Type::BER_encode_chk_bound(boolean p_isbound
)
347 TTCN_EncDec_ErrorContext::error
348 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
349 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(0, NULL
);
359 // Called only from the two places in BER_encode_TLV_OCTETSTRING, below.
360 void Base_Type::BER_encode_putoctets_OCTETSTRING
361 (unsigned char *target
,
362 unsigned int octetnum_start
, unsigned int octet_count
,
363 int p_nof_octets
, const unsigned char *p_octets_ptr
)
365 if( octetnum_start
> static_cast<unsigned int>(p_nof_octets
)
366 || octetnum_start
+octet_count
> static_cast<unsigned int>(p_nof_octets
))
367 TTCN_EncDec_ErrorContext::error_internal
368 ("In Base_Type::BER_encode_putoctets_OCTETSTRING(): Index overflow.");
369 memcpy(target
, &p_octets_ptr
[octetnum_start
], octet_count
);
372 ASN_BER_TLV_t
* Base_Type::BER_encode_TLV_OCTETSTRING
374 int p_nof_octets
, const unsigned char *p_octets_ptr
)
376 unsigned char *V_ptr
;
378 unsigned int nof_fragments
=0;
380 if(p_coding
==BER_ENCODE_CER
) {
381 nof_fragments
=(p_nof_octets
+999)/1000;
382 if(!nof_fragments
) nof_fragments
=1;
384 else /*if(coding==BER_ENCODE_DER)*/ {
388 ASN_BER_TLV_t
*new_tlv
=NULL
;
389 boolean is_constructed
=nof_fragments
>1;
390 if(!is_constructed
) {
392 V_ptr
=(unsigned char*)Malloc(V_len
);
393 BER_encode_putoctets_OCTETSTRING(V_ptr
, 0, p_nof_octets
,
394 p_nof_octets
, p_octets_ptr
);
395 new_tlv
=ASN_BER_TLV_t::construct(V_len
, V_ptr
);
397 else { // is constructed
398 ASN_BER_TLV_t
*tmp_tlv
=NULL
;
399 new_tlv
=ASN_BER_TLV_t::construct(NULL
);
400 unsigned int rest_octets
=p_nof_octets
-(nof_fragments
-1)*1000;
402 for(unsigned int i
=0; i
<nof_fragments
; i
++) {
403 if(i
==nof_fragments
-1) V_len
=rest_octets
;
404 V_ptr
=(unsigned char*)Malloc(V_len
);
405 BER_encode_putoctets_OCTETSTRING(V_ptr
, i
*1000, V_len
,
406 p_nof_octets
, p_octets_ptr
);
407 tmp_tlv
=ASN_BER_TLV_t::construct(V_len
, V_ptr
);
408 tmp_tlv
=ASN_BER_V2TLV(tmp_tlv
, OCTETSTRING_descr_
, p_coding
);
409 new_tlv
->add_TLV(tmp_tlv
);
416 // for debugging purposes
417 static std::string bignum_as_bin(const BIGNUM* const BN) {
418 int bytes = BN_num_bytes(BN);
419 unsigned char* bn_as_bin = (unsigned char*) Malloc(bytes);
420 BN_bn2bin(BN, bn_as_bin);
423 for (int i = 0; i < bytes; ++i) {
424 result.append(char_as_bin(bn_as_bin[i]));
431 static std::string int_as_bin(int myInt) {
433 for (int i = sizeof(myInt) - 1; i >= 0; --i) {
434 char current = (myInt >> (i * 8)) & 0xFF;
435 result.append(char_as_bin(current));
440 static std::string char_as_bin(unsigned char ch) {
442 for (int i = 0; i < 8; ++i) {
443 result.append((ch & 0x80) == 0x80 ? "1" : "0");
449 static std::string chars_as_bin(const unsigned char* const chars, int len) {
451 for (int i = 0; i < len; ++i) {
452 result.append(char_as_bin(chars[i]));
461 ASN_BER_TLV_t
*Base_Type::BER_encode_TLV_INTEGER(unsigned,
462 const int_val_t
& p_int_val
)
464 if(p_int_val
.is_native()){
465 RInt p_int_val_int
=p_int_val
.get_val();
466 // Determine the number of octets to be used in the encoding.
467 unsigned long ulong_val
=p_int_val_int
>= 0
468 ?static_cast<unsigned long>(p_int_val_int
):
469 ~static_cast<unsigned long>(p_int_val_int
);
476 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(V_len
,NULL
);
477 // Already in 2's complement encoding.
478 ulong_val
=static_cast<unsigned long>(p_int_val_int
);
479 for(size_t i
=V_len
;i
>0;i
--){
480 new_tlv
->V
.str
.Vstr
[i
-1]=ulong_val
&0xFF;
488 const BIGNUM
* const D
= p_int_val
.get_val_openssl();
490 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(1,NULL
);
491 new_tlv
->V
.str
.Vstr
[0] = 0;
495 size_t num_bytes
= BN_num_bytes(D
);
496 unsigned char* bn_as_bin
= (unsigned char*) Malloc(num_bytes
);
497 BN_bn2bin(D
, bn_as_bin
);
500 if (BN_is_negative(D
)) {
501 for(size_t i
= 0; i
< num_bytes
; ++i
){
502 bn_as_bin
[i
] = ~bn_as_bin
[i
];
507 for (int i
= num_bytes
- 1; i
>= 0 && !stop
; --i
) {
508 for (int j
= 0; j
< 8 && !stop
; ++j
) {
509 unsigned char mask
= (0x1 << j
);
510 if (!(bn_as_bin
[i
] & mask
)) {
511 bn_as_bin
[i
] |= mask
;
514 bn_as_bin
[i
] ^= mask
;
518 pad
= !(bn_as_bin
[0] & 0x80);
520 pad
= bn_as_bin
[0] & 0x80;
523 ASN_BER_TLV_t
* new_tlv
= ASN_BER_TLV_t::construct(num_bytes
+ pad
, NULL
);
525 new_tlv
->V
.str
.Vstr
[0] = BN_is_negative(D
) ? 0xFF : 0x0;
528 memcpy(new_tlv
->V
.str
.Vstr
+ pad
, bn_as_bin
, num_bytes
);
534 ASN_BER_TLV_t
*Base_Type::BER_encode_TLV_INTEGER(unsigned p_coding
,
535 const int& p_int_val
)
537 int_val_t
p_int_val_val(p_int_val
);
538 return BER_encode_TLV_INTEGER(p_coding
, p_int_val_val
);
541 void Base_Type::BER_encode_chk_enum_valid(const TTCN_Typedescriptor_t
& p_td
,
542 boolean p_isvalid
, int p_value
)
545 TTCN_EncDec_ErrorContext::error
546 (TTCN_EncDec::ET_ENC_ENUM
,
547 "Encoding unknown value '%d' for enumerated type '%s'.",
552 void Base_Type::BER_decode_str2TLV(TTCN_Buffer
& p_buf
, ASN_BER_TLV_t
& p_tlv
,
555 if(!ASN_BER_str2TLV(p_buf
.get_read_len(), p_buf
.get_read_data(),
557 TTCN_EncDec_ErrorContext::error
558 (TTCN_EncDec::ET_INCOMPL_MSG
, "TLV is not complete.");
561 boolean
Base_Type::BER_decode_constdTLV_next(const ASN_BER_TLV_t
& p_tlv
,
564 ASN_BER_TLV_t
& p_target_tlv
)
566 if(p_tlv
.V
.str
.Vlen
<=V_pos
) {
567 if(!p_tlv
.isLenDefinite
)
568 TTCN_EncDec_ErrorContext::error
569 (TTCN_EncDec::ET_INCOMPL_MSG
,
570 "Missing end-of-contents octet in the indefinite length"
571 " constructed TLV.");
574 if(!ASN_BER_str2TLV(p_tlv
.V
.str
.Vlen
-V_pos
,
575 p_tlv
.V
.str
.Vstr
+V_pos
, p_target_tlv
, L_form
)) {
576 TTCN_EncDec_ErrorContext::error
577 (TTCN_EncDec::ET_INCOMPL_MSG
,
578 "Incomplete TLV in the constructed TLV.");
580 if(!p_tlv
.isLenDefinite
&& p_target_tlv
.tagnumber
==0
581 && p_target_tlv
.tagclass
==ASN_TAG_UNIV
)
583 V_pos
+=p_target_tlv
.get_len();
587 void Base_Type::BER_decode_constdTLV_end(const ASN_BER_TLV_t
& p_tlv
,
590 ASN_BER_TLV_t
& p_target_tlv
,
594 || BER_decode_constdTLV_next(p_tlv
, V_pos
, L_form
, p_target_tlv
)) {
595 TTCN_EncDec_ErrorContext::error
596 (TTCN_EncDec::ET_SUPERFL
,
597 "Superfluous TLV(s) at the end of constructed TLV.");
601 static void BER_decode_chk_tag(const ASN_Tag_t
& tag
,
602 const ASN_BER_TLV_t
& tlv
)
604 if (tlv
.isTagComplete
&&
605 (tag
.tagclass
!= tlv
.tagclass
|| tag
.tagnumber
!= tlv
.tagnumber
)) {
607 rcvdtag
.tagclass
=tlv
.tagclass
;
608 rcvdtag
.tagnumber
=tlv
.tagnumber
;
609 char *rcvdstr
=rcvdtag
.print();
611 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG
,
612 "Tag mismatch: Received: %s.", rcvdstr
);
621 void Base_Type::BER_decode_strip_tags(const ASN_BERdescriptor_t
& p_ber
,
622 const ASN_BER_TLV_t
& p_tlv
,
624 ASN_BER_TLV_t
& stripped_tlv
)
626 size_t i
=p_ber
.n_tags
;
631 char *expectedstr
=p_ber
.print_tags();
632 TTCN_EncDec_ErrorContext
ec("While checking tags (expecting %s): ",
636 BER_decode_chk_tag(p_ber
.tags
[0], p_tlv
);
640 ASN_BER_TLV_t curr_tlv
=p_tlv
;
644 TTCN_EncDec_ErrorContext
ec2("At pos #%lu: ",
645 (unsigned long) (p_ber
.n_tags
- i
));
646 BER_decode_chk_tag(p_ber
.tags
[i
], curr_tlv
);
647 if(i
!=0) { // not the innermost tag
648 if(!curr_tlv
.isConstructed
) {
649 ec2
.error(TTCN_EncDec::ET_TAG
,
650 "The other (innermost %lu) tag(s) are missing.", (unsigned long) i
);
652 stripped_tlv
=curr_tlv
;
654 else { // O.K., is constructed
656 BER_decode_constdTLV_next(curr_tlv
, V_pos
, L_form
, stripped_tlv
);
657 // if superfluous...?
658 ASN_BER_TLV_t endchecker_tlv
;
659 BER_decode_constdTLV_end(curr_tlv
, V_pos
, L_form
, endchecker_tlv
,
661 curr_tlv
=stripped_tlv
;
664 } // not the innermost
665 else { // innermost tag
671 void Base_Type::BER_decode_getoctets_OCTETSTRING
672 (const unsigned char *source
, size_t s_len
,
673 unsigned int& octetnum_start
,
674 int& p_nof_octets
, unsigned char *p_octets_ptr
)
676 p_nof_octets
=octetnum_start
+s_len
;
677 memcpy(&p_octets_ptr
[octetnum_start
], source
, s_len
);
678 octetnum_start
+=s_len
;
681 void Base_Type::BER_decode_TLV_OCTETSTRING
682 (const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
,
683 unsigned int& octetnum_start
,
684 int& p_nof_octets
, unsigned char *p_octets_ptr
)
686 if(!p_tlv
.isConstructed
) {
687 BER_decode_getoctets_OCTETSTRING
688 (p_tlv
.V
.str
.Vstr
, p_tlv
.V
.str
.Vlen
, octetnum_start
,
689 p_nof_octets
, p_octets_ptr
);
691 else { // is constructed
696 if(!ASN_BER_str2TLV(p_tlv
.V
.str
.Vlen
-V_pos
, p_tlv
.V
.str
.Vstr
+V_pos
,
698 TTCN_EncDec_ErrorContext::error
699 (TTCN_EncDec::ET_INCOMPL_MSG
,
700 "Incomplete TLV in a constructed OCTETSTRING TLV.");
703 if(!p_tlv
.isLenDefinite
&& tlv2
.tagnumber
==0
704 && tlv2
.tagclass
==ASN_TAG_UNIV
)
705 doit
=FALSE
; // End-of-contents
707 ASN_BER_TLV_t stripped_tlv
;
708 BER_decode_strip_tags(OCTETSTRING_ber_
, tlv2
, L_form
, stripped_tlv
);
709 BER_decode_TLV_OCTETSTRING(tlv2
, L_form
, octetnum_start
,
710 p_nof_octets
, p_octets_ptr
);
711 V_pos
+=tlv2
.get_len();
712 if(V_pos
>=p_tlv
.V
.str
.Vlen
) doit
=FALSE
;
715 } // else / is constructed
720 boolean
Base_Type::BER_decode_TLV_INTEGER(const ASN_BER_TLV_t
& p_tlv
,
721 unsigned, int_val_t
& p_int_val
)
723 p_tlv
.chk_constructed_flag(FALSE
);
724 if (!p_tlv
.isComplete
) return FALSE
;
725 if (!p_tlv
.V_tlvs_selected
&& p_tlv
.V
.str
.Vlen
== 0) {
726 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
727 "Length of V-part is 0.");
731 const size_t Vlen
= p_tlv
.V
.str
.Vlen
;
733 if (Vlen
> sizeof(RInt
)) { // Bignum
735 const bool negative
= p_tlv
.V
.str
.Vstr
[0] & 0x80;
736 BIGNUM
*D
= BN_new();
739 unsigned char* const Vstr
= (unsigned char*) Malloc(Vlen
);
740 memcpy(Vstr
, p_tlv
.V
.str
.Vstr
, Vlen
);
743 for (int i
= Vlen
- 1; i
>= 0 && !stop
; --i
) {
744 for(int j
= 0; j
< 8 && !stop
; ++j
) {
745 unsigned char mask
= (0x1 << j
);
746 if (Vstr
[i
] & mask
) {
755 for (size_t i
= 0; i
< Vlen
; ++i
) {
759 BN_bin2bn(Vstr
, Vlen
, D
);
761 } else { // positive case
762 BN_bin2bn(p_tlv
.V
.str
.Vstr
, Vlen
, D
);
765 BN_set_negative(D
, negative
);
766 p_int_val
= int_val_t(D
);
770 // Native int Vlen <= sizeof(RInt)
771 const unsigned char* const Vstr
= p_tlv
.V
.str
.Vstr
;
773 if (Vstr
[0] & 0x80) { // negative
774 // the first bytes should be 1-s
775 // e.g. -1 encoded on 32 bits: 11111111111111111111111111111111
776 // e.g. -1 encoded on 8 bits: 11111111
777 // [(sizeof(RInt)-Vlen)*8 ][Vlen*8]
778 // [ sizeof(RInt)*8 ]
780 for (size_t i
= 0; i
< sizeof(RInt
) - Vlen
; ++i
) {
786 int_val
|= p_tlv
.V
.str
.Vstr
[0];
787 for (size_t i
= 1; i
< Vlen
; ++i
) {
789 int_val
|= p_tlv
.V
.str
.Vstr
[i
];
792 p_int_val
= int_val_t(int_val
);
796 boolean
Base_Type::BER_decode_TLV_INTEGER(const ASN_BER_TLV_t
& p_tlv
,
797 unsigned L_form
, int& p_int_val
)
799 int_val_t
p_int_val_val(p_int_val
);
800 boolean ret_val
= BER_decode_TLV_INTEGER(p_tlv
, L_form
, p_int_val_val
);
801 if (p_int_val_val
.is_native()) {
802 p_int_val
= p_int_val_val
.get_val();
804 TTCN_warning("Large integer value was decoded and it can't be returned "
805 "as a native `int'");
812 // Actually, this is not used, but when we ever need a
813 // type-independent integer decoding, then we can move this to
814 // Basetype.hh. It is so beautiful and wonderful, I did not wanted
815 // this to get lost. :)
817 template<typename int_type>
818 void Base_Type::BER_decode_TLV_INTEGER
819 (const ASN_BER_TLV_t& p_tlv, unsigned L_form, int_type& p_intval)
821 boolean overflow_flag=FALSE;
822 p_tlv.chk_constructed_flag(FALSE);
823 if(!p_tlv.V_tlvs_selected && p_tlv.V.str.Vlen==0) {
824 TTCN_EncDec_ErrorContext::error
825 (TTCN_EncDec::ET_INVAL_MSG, "Length of V-part is 0.");
826 p_intval=static_cast<int_type>(0);
829 int_type tmp_int=static_cast<int_type>(p_tlv.V.str.Vstr[0] & 0x7F);
830 for(size_t i=1; i<p_tlv.V.str.Vlen; i++) {
832 tmp_int=static_cast<int_type>(256*tmp_int);
833 if(tmp_int<p_intval) overflow_flag=TRUE;
834 tmp_int=static_cast<int_type>(tmp_int+p_tlv.V.str.Vstr[i]);
836 if(p_tlv.V.str.Vstr[0] & 0x80) { // negative
837 int_type highbit=static_cast<int_type>(1);
838 for(size_t i=0; i<p_tlv.V.str.Vlen*8-1; i++) {
839 int_type backup=highbit;
840 highbit=static_cast<int_type>(2*highbit);
841 if(highbit/2!=backup) overflow_flag=TRUE;
843 p_intval=static_cast<int_type>(tmp_int-highbit);
849 TTCN_EncDec_ErrorContext::error
850 (TTCN_EncDec::ET_REPR,
851 "Value is too big (%lu octets).", p_tlv.V.str.Vlen);
856 boolean
Base_Type::BER_decode_TLV_CHOICE(const ASN_BERdescriptor_t
& p_ber
,
857 const ASN_BER_TLV_t
& p_tlv
,
859 ASN_BER_TLV_t
& p_target_tlv
)
863 p_tlv
.chk_constructed_flag(TRUE
);
864 if(!BER_decode_constdTLV_next(p_tlv
, V_pos
, L_form
, p_target_tlv
))
867 else p_target_tlv
=p_tlv
;
871 boolean
Base_Type::BER_decode_CHOICE_selection(boolean select_result
,
872 const ASN_BER_TLV_t
& p_tlv
)
874 if(select_result
) return TRUE
;
876 rcvd_tag
.tagclass
=p_tlv
.tagclass
;
877 rcvd_tag
.tagnumber
=p_tlv
.tagnumber
;
878 char *rcvd_str
=rcvd_tag
.print();
880 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG
,
881 "Invalid tag or unknown alternative: %s.", rcvd_str
);
890 void Base_Type::BER_decode_chk_enum_valid(const TTCN_Typedescriptor_t
& p_td
,
891 boolean p_isvalid
, int p_value
)
893 /** \todo If extensible ENUMERATED is supported (for example, in the
894 * typedescriptor there is something...), then give different error
895 * message depending on that flag. */
897 TTCN_EncDec_ErrorContext::error
898 (TTCN_EncDec::ET_DEC_ENUM
,
899 "Unknown value '%d' received for enumerated type '%s'.",
904 Base_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
908 ASN_BER_TLV_t
*tlv
=BER_encode_chk_bound(TRUE
);
910 TTCN_EncDec_ErrorContext::error_internal
911 ("BER_encode_V() not implemented for type '%s'.", p_td
.name
);
915 boolean
Base_Type::BER_decode_isMyMsg(const TTCN_Typedescriptor_t
& p_td
,
916 const ASN_BER_TLV_t
& p_tlv
)
918 if(p_td
.ber
->n_tags
==0 || !p_tlv
.isTagComplete
) return TRUE
;
919 const ASN_Tag_t
& tag
=p_td
.ber
->tags
[p_td
.ber
->n_tags
-1];
920 return (tag
.tagclass
==p_tlv
.tagclass
&& tag
.tagnumber
==p_tlv
.tagnumber
);
923 boolean
Base_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
924 const ASN_BER_TLV_t
& p_tlv
,
928 ASN_BER_TLV_t stripped_tlv
;
929 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
930 TTCN_EncDec_ErrorContext ec
;
932 ("BER_decode_V() not implemented for type '%s'.", p_td
.name
);
936 int Base_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
939 TTCN_error("RAW encoding requested for type '%s'"
940 " which has no RAW encoding method.", p_td
.name
);
944 int Base_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
,
947 TTCN_error("TEXT encoding requested for type '%s'"
948 " which has no TEXT encoding method.", p_td
.name
);
952 int Base_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
,
953 TTCN_Buffer
&, Limit_Token_List
&, boolean
, boolean
)
955 TTCN_error("TEXT decoding requested for type '%s'"
956 " which has no TEXT decoding method.", p_td
.name
);
960 int Base_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
,
961 TTCN_Buffer
&, int /* limit */, raw_order_t
/* top_bit_ord */,
962 boolean
/* no_error */, int /* sel_field */, boolean
/* first_call */ )
964 TTCN_error("RAW decoding requested for type '%s'"
965 " which has no RAW decoding method.",p_td
.name
);
969 int Base_Type::XER_encode(const XERdescriptor_t
& p_td
,
970 TTCN_Buffer
&, unsigned int, int, embed_values_enc_struct_t
*) const
972 TTCN_error("XER encoding requested for type '%-.*s' which has no"
973 " XER encoding method.", p_td
.namelens
[0]-2, p_td
.names
[0]);
977 int Base_Type::XER_decode(const XERdescriptor_t
& p_td
, XmlReaderWrap
&,
978 unsigned int, embed_values_dec_struct_t
*) {
979 TTCN_error("XER decoding requested for type '%-.*s' which has no"
980 " XER decoding method.", p_td
.namelens
[0]-2, p_td
.names
[0]);
984 int Base_Type::JSON_encode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
&) const
986 TTCN_error("JSON encoding requested for type '%s' which has no"
987 " JSON encoding method.", p_td
.name
);
991 int Base_Type::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
&, boolean
)
993 TTCN_error("JSON decoding requested for type '%s' which has no"
994 " JSON decoding method.", p_td
.name
);
998 boolean
Base_Type::can_start(const char *name
, const char *uri
,
999 XERdescriptor_t
const& xd
, unsigned int flavor
)
1001 boolean e_xer
= is_exer(flavor
);
1002 // Check the name. If EXER, check the namespace too.
1003 return check_name(name
, xd
, e_xer
) && (!e_xer
|| check_namespace(uri
, xd
));
1006 char ** Base_Type::collect_ns(const XERdescriptor_t
& p_td
, size_t& num
, bool& def_ns
) const
1010 if (p_td
.my_module
!= 0 && p_td
.ns_index
!= -1
1011 && !(p_td
.xer_bits
& FORM_UNQUALIFIED
)) {
1012 const namespace_t
*my_ns
= p_td
.my_module
->get_ns(p_td
.ns_index
);
1013 if (!*my_ns
->px
) def_ns
= true;
1014 tmp
= mprintf(" xmlns%s%s='%s'",
1015 ((*my_ns
->px
) ? ":" : ""), my_ns
->px
,
1019 // The above may throw, but then nothing was allocated.
1022 char **retval
= (char**)Malloc(sizeof(char*));
1032 void Base_Type::merge_ns(char **&collected_ns
, size_t& num_collected
,
1033 char **new_namespaces
, size_t num_new
)
1036 for (size_t cur_ns
= 0; cur_ns
< num_new
; ++cur_ns
) {
1037 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
1038 if (!strcmp(new_namespaces
[cur_ns
], collected_ns
[cur_coll
])) {
1040 Free(new_namespaces
[cur_ns
]);
1041 new_namespaces
[cur_ns
] = NULL
;
1046 if (new_namespaces
[cur_ns
]) { // still there
1047 collected_ns
= (char**)Realloc(collected_ns
, sizeof(char*) * ++num_collected
);
1048 collected_ns
[num_collected
-1] = new_namespaces
[cur_ns
];
1051 Free(new_namespaces
);
1055 /////////////////////////////////////////////////////////////
1057 TTCN_Type_list::~TTCN_Type_list()
1062 void TTCN_Type_list::push(const Base_Type
*p_type
)
1064 types
=(const Base_Type
**)Realloc(types
, ++n_types
*sizeof(*types
));
1065 types
[n_types
-1]=p_type
;
1068 const Base_Type
* TTCN_Type_list::pop()
1071 TTCN_EncDec_ErrorContext::error_internal
1072 ("TTCN_Type_list::pop(): List is empty.");
1075 types
=(const Base_Type
**)Realloc(types
, n_types
*sizeof(*types
));
1079 const Base_Type
* TTCN_Type_list::get_nth(size_t pos
) const
1081 if(pos
==0) return types
[0];
1083 TTCN_EncDec_ErrorContext::error_internal
1084 ("TTCN_Type_list::get_nth(%lu): Out of range.", (unsigned long) pos
);
1085 return types
[n_types
-pos
];
1088 const TTCN_Typedescriptor_t BOOLEAN_descr_
={"BOOLEAN", &BOOLEAN_ber_
,
1089 &BOOLEAN_raw_
, &BOOLEAN_text_
, &BOOLEAN_xer_
, &BOOLEAN_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1091 const TTCN_Typedescriptor_t INTEGER_descr_
={"INTEGER", &INTEGER_ber_
,
1092 &INTEGER_raw_
, &INTEGER_text_
, &INTEGER_xer_
, &INTEGER_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1094 const TTCN_Typedescriptor_t FLOAT_descr_
={"REAL", &FLOAT_ber_
, &FLOAT_raw_
,
1095 NULL
, &FLOAT_xer_
, &FLOAT_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1097 const TTCN_Typedescriptor_t VERDICTTYPE_descr_
={"verdicttype", NULL
, NULL
,
1098 NULL
, &VERDICTTYPE_xer_
, &VERDICTTYPE_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1100 const TTCN_Typedescriptor_t OBJID_descr_
={"OBJECT IDENTIFIER", &OBJID_ber_
,
1101 NULL
, NULL
, &OBJID_xer_
, &OBJID_json_
, TTCN_Typedescriptor_t::OBJID
};
1103 const TTCN_Typedescriptor_t BITSTRING_descr_
={"BIT STRING", &BITSTRING_ber_
,
1104 &BITSTRING_raw_
, NULL
, &BITSTRING_xer_
, &BITSTRING_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1106 const TTCN_Typedescriptor_t HEXSTRING_descr_
={"hexstring", NULL
,
1107 &HEXSTRING_raw_
, NULL
, &HEXSTRING_xer_
, &HEXSTRING_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1109 const TTCN_Typedescriptor_t OCTETSTRING_descr_
={"OCTET STRING",
1110 &OCTETSTRING_ber_
, &OCTETSTRING_raw_
, &OCTETSTRING_text_
, &OCTETSTRING_xer_
, &OCTETSTRING_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1112 const TTCN_Typedescriptor_t CHARSTRING_descr_
={"charstring", NULL
,
1113 &CHARSTRING_raw_
, &CHARSTRING_text_
, &CHARSTRING_xer_
, &CHARSTRING_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1115 const TTCN_Typedescriptor_t UNIVERSAL_CHARSTRING_descr_
={"universal charstring",
1116 NULL
, NULL
, NULL
, &UNIVERSAL_CHARSTRING_xer_
, &UNIVERSAL_CHARSTRING_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1118 const TTCN_Typedescriptor_t COMPONENT_descr_
={"component", NULL
, NULL
, NULL
,
1119 NULL
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1121 const TTCN_Typedescriptor_t DEFAULT_descr_
={"default", NULL
, NULL
, NULL
,
1122 NULL
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1124 const TTCN_Typedescriptor_t ASN_NULL_descr_
={"NULL", &ASN_NULL_ber_
, NULL
,
1125 NULL
, &ASN_NULL_xer_
, &ASN_NULL_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1127 const TTCN_Typedescriptor_t ASN_ANY_descr_
={"ANY", &ASN_ANY_ber_
, NULL
,
1128 NULL
, NULL
, &ASN_ANY_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1130 const TTCN_Typedescriptor_t EXTERNAL_descr_
={"EXTERNAL", &EXTERNAL_ber_
, NULL
,
1131 NULL
, &EXTERNAL_xer_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1133 const TTCN_Typedescriptor_t EMBEDDED_PDV_descr_
={"EMBEDDED PDV",
1134 &EMBEDDED_PDV_ber_
, NULL
, NULL
, &EMBEDDED_PDV_xer_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1136 const TTCN_Typedescriptor_t CHARACTER_STRING_descr_
={"CHARACTER STRING",
1137 &CHARACTER_STRING_ber_
, NULL
, NULL
, &CHARACTER_STRING_xer_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1139 const TTCN_Typedescriptor_t ObjectDescriptor_descr_
={"ObjectDescriptor",
1140 &ObjectDescriptor_ber_
, NULL
, NULL
, NULL
, NULL
, TTCN_Typedescriptor_t::GRAPHICSTRING
};
1142 const TTCN_Typedescriptor_t UTF8String_descr_
={"UTF8String", &UTF8String_ber_
,
1143 NULL
, NULL
, &UTF8String_xer_
, NULL
, TTCN_Typedescriptor_t::UTF8STRING
};
1145 const TTCN_Typedescriptor_t ASN_ROID_descr_
={"RELATIVE-OID", &ASN_ROID_ber_
,
1146 NULL
, NULL
, &ASN_ROID_xer_
, &ASN_ROID_json_
, TTCN_Typedescriptor_t::ROID
};
1148 const TTCN_Typedescriptor_t NumericString_descr_
={"NumericString",
1149 &NumericString_ber_
, NULL
, NULL
, &NumericString_xer_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1151 const TTCN_Typedescriptor_t PrintableString_descr_
={"PrintableString",
1152 &PrintableString_ber_
, NULL
, NULL
, &PrintableString_xer_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1154 const TTCN_Typedescriptor_t TeletexString_descr_
={"TeletexString",
1155 &TeletexString_ber_
, NULL
, NULL
, &TeletexString_xer_
, NULL
, TTCN_Typedescriptor_t::TELETEXSTRING
};
1156 const TTCN_Typedescriptor_t
& T61String_descr_
=TeletexString_descr_
;
1158 const TTCN_Typedescriptor_t VideotexString_descr_
={"VideotexString",
1159 &VideotexString_ber_
, NULL
, NULL
, &VideotexString_xer_
, NULL
, TTCN_Typedescriptor_t::VIDEOTEXSTRING
};
1161 const TTCN_Typedescriptor_t IA5String_descr_
={"IA5String", &IA5String_ber_
,
1162 NULL
, NULL
, &IA5String_xer_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1164 const TTCN_Typedescriptor_t ASN_GeneralizedTime_descr_
={"GeneralizedTime",
1165 &ASN_GeneralizedTime_ber_
, NULL
, NULL
, NULL
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1167 const TTCN_Typedescriptor_t ASN_UTCTime_descr_
={"UTCTime", &ASN_UTCTime_ber_
,
1168 NULL
, NULL
, NULL
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1170 const TTCN_Typedescriptor_t GraphicString_descr_
={"GraphicString",
1171 &GraphicString_ber_
, NULL
, NULL
, &GraphicString_xer_
, NULL
, TTCN_Typedescriptor_t::GRAPHICSTRING
};
1173 const TTCN_Typedescriptor_t VisibleString_descr_
={"VisibleString",
1174 &VisibleString_ber_
, NULL
, NULL
, &VisibleString_xer_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1175 const TTCN_Typedescriptor_t
& ISO646String_descr_
=VisibleString_descr_
;
1177 const TTCN_Typedescriptor_t GeneralString_descr_
={"GeneralString",
1178 &GeneralString_ber_
, NULL
, NULL
, &GeneralString_xer_
, NULL
, TTCN_Typedescriptor_t::GENERALSTRING
};
1180 const TTCN_Typedescriptor_t UniversalString_descr_
={"UniversalString",
1181 &UniversalString_ber_
, NULL
, NULL
, &UniversalString_xer_
, NULL
, TTCN_Typedescriptor_t::UNIVERSALSTRING
};
1183 const TTCN_Typedescriptor_t BMPString_descr_
={"BMPString", &BMPString_ber_
,
1184 NULL
, NULL
, &BMPString_xer_
, NULL
, TTCN_Typedescriptor_t::BMPSTRING
};