1 /******************************************************************************
2 * Copyright (c) 2000-2016 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
19 * Szabo, Janos Zoltan – initial implementation
22 ******************************************************************************/
23 #include "Basetype.hh"
24 #include "../common/memory.h"
32 #include "XmlReader.hh"
33 #include "Module_list.hh"
34 #include "Universal_charstring.hh"
36 #include <openssl/bn.h>
41 // Note: RT2-only classes (Record_Type, Record_Of_Type) and Base_Type methods
42 // are in core2/Basetype2.cc
44 boolean
Base_Type::ispresent() const
46 TTCN_error("Base_Type::ispresent(): calling ispresent() on a non-optional field.");
50 void Base_Type::log() const
52 TTCN_Logger::log_event_str("<logging of this type is not implemented>");
55 void Base_Type::encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
56 TTCN_EncDec::coding_t p_coding
, ...) const
59 va_start(pvar
, p_coding
);
61 case TTCN_EncDec::CT_BER
: {
62 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
63 unsigned BER_coding
=va_arg(pvar
, unsigned);
64 BER_encode_chk_coding(BER_coding
);
65 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
66 tlv
->put_in_buffer(p_buf
);
67 ASN_BER_TLV_t::destruct(tlv
);
69 case TTCN_EncDec::CT_RAW
: {
70 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
72 TTCN_EncDec_ErrorContext::error_internal
73 ("No RAW descriptor available for type '%s'.", p_td
.name
);
77 RAW_enc_tree
root(TRUE
, NULL
, &rp
, 1, p_td
.raw
);
78 RAW_encode(p_td
, root
);
79 root
.put_to_buf(p_buf
);
81 case TTCN_EncDec::CT_TEXT
: {
82 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
84 TTCN_EncDec_ErrorContext::error_internal
85 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
86 TEXT_encode(p_td
,p_buf
);
88 case TTCN_EncDec::CT_XER
: {
89 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
90 if(!p_td
.xer
) TTCN_EncDec_ErrorContext::error_internal(
91 "No XER descriptor available for type '%s'.", p_td
.name
);
92 unsigned XER_coding
=va_arg(pvar
, unsigned);
93 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0, 0);
96 case TTCN_EncDec::CT_JSON
: {
97 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
99 TTCN_EncDec_ErrorContext::error_internal
100 ("No JSON descriptor available for type '%s'.", p_td
.name
);
101 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
102 JSON_encode(p_td
, tok
);
103 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
106 TTCN_error("Unknown coding method requested to encode type '%s'",
112 void Base_Type::decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
113 TTCN_EncDec::coding_t p_coding
, ...)
116 va_start(pvar
, p_coding
);
118 case TTCN_EncDec::CT_BER
: {
119 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
120 unsigned L_form
=va_arg(pvar
, unsigned);
122 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
123 BER_decode_TLV(p_td
, tlv
, L_form
);
124 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
126 case TTCN_EncDec::CT_RAW
: {
127 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
129 TTCN_EncDec_ErrorContext::error_internal
130 ("No RAW descriptor available for type '%s'.", p_td
.name
);
132 switch(p_td
.raw
->top_bit_order
) {
140 RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
);
142 case TTCN_EncDec::CT_TEXT
: {
143 Limit_Token_List limit
;
144 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
146 TTCN_EncDec_ErrorContext::error_internal
147 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
148 const unsigned char *b
=p_buf
.get_data();
149 if(b
[p_buf
.get_len()-1]!='\0'){
150 p_buf
.set_pos(p_buf
.get_len());
151 p_buf
.put_zero(8,ORDER_LSB
);
154 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
155 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
156 "Can not decode type '%s', because invalid or incomplete"
157 " message was received"
160 case TTCN_EncDec::CT_XER
: {
161 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
162 unsigned XER_coding
=va_arg(pvar
, unsigned);
163 XmlReaderWrap
reader(p_buf
);
164 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
165 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
167 XER_decode(*(p_td
.xer
), reader
, XER_coding
, XER_NONE
, 0);
168 size_t bytes
= reader
.ByteConsumed();
169 p_buf
.set_pos(bytes
);
171 case TTCN_EncDec::CT_JSON
: {
172 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
174 TTCN_EncDec_ErrorContext::error_internal
175 ("No JSON descriptor available for type '%s'.", p_td
.name
);
176 JSON_Tokenizer
tok((const char*)p_buf
.get_data(), p_buf
.get_len());
177 if(JSON_decode(p_td
, tok
, false)<0)
178 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
179 "Can not decode type '%s', because invalid or incomplete"
180 " message was received"
182 p_buf
.set_pos(tok
.get_buf_pos());
185 TTCN_error("Unknown coding method requested to decode type '%s'",
191 void Base_Type::BER_chk_descr(const TTCN_Typedescriptor_t
& p_td
)
194 TTCN_EncDec_ErrorContext::error_internal
195 ("No BER descriptor available for type '%s'.", p_td
.name
);
198 void Base_Type::BER_encode_chk_coding(unsigned& p_coding
)
205 TTCN_warning("Unknown BER encoding requested; using DER.");
206 p_coding
=BER_ENCODE_DER
;
211 void Base_Type::XER_encode_chk_coding(unsigned& p_coding
,
212 const TTCN_Typedescriptor_t
& p_td
)
215 TTCN_EncDec_ErrorContext::error_internal
216 ("No XER descriptor available for type '%s'.", p_td
.name
);
222 case XER_EXTENDED
| XER_CANONICAL
:
225 TTCN_warning("Unknown XER encoding requested; using Basic XER.");
226 p_coding
= XER_BASIC
;
231 static const cbyte empty_tag_end
[4] = "/>\n";
233 int Base_Type::begin_xml(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
234 unsigned int& flavor
, int indent
, bool empty
,
235 collector_fn collector
, const char *type_atr
) const
237 const int indenting
= !is_canonical(flavor
);
238 const int exer
= is_exer(flavor
);
239 int omit_tag
= (indent
!= 0) // can never omit the tag at the toplevel
240 && ( ((flavor
& XER_RECOF
) // can remove the tag even if not EXER
241 && !(exer
&& (flavor
& BXER_EMPTY_ELEM
))) // except 26.6, 26.7
243 && ( (p_td
.xer_bits
& (UNTAGGED
|ANY_ATTRIBUTES
|ANY_ELEMENT
))
244 || (flavor
& (EMBED_VALUES
|XER_LIST
|ANY_ATTRIBUTES
|USE_NIL
|USE_TYPE_ATTR
)))));
246 // If a default namespace is in effect (uri but no prefix) and the type
247 // is unqualified, the default namespace must be canceled; otherwise
248 // an XML tag without a ns prefix looks like it belongs to the def.namespace
249 const boolean empty_ns_hack
= exer
&& !omit_tag
&& (indent
> 0)
250 && (p_td
.xer_bits
& FORM_UNQUALIFIED
)
251 && (flavor
& DEF_NS_PRESENT
);
253 if (exer
&& (p_td
.xer_bits
& XER_ATTRIBUTE
)) {
254 begin_attribute(p_td
, p_buf
);
256 else if (!omit_tag
) { // full tag
257 if (indenting
) do_indent(p_buf
, indent
);
259 if (exer
) write_ns_prefix(p_td
, p_buf
);
261 const namespace_t
*ns_info
= NULL
;
262 bool namespaces_needed
= false;
264 if (p_td
.my_module
!= NULL
&& p_td
.ns_index
!= -1) {
265 ns_info
= p_td
.my_module
->get_ns(p_td
.ns_index
);
268 namespaces_needed
= exer
&& //!(p_td.xer_bits & FORM_UNQUALIFIED) &&
269 (indent
==0 // top-level type
270 || (ns_info
&& *ns_info
->px
== '\0' // own ns is prefixless
271 && (flavor
& DEF_NS_SQUASHED
))
275 size_t num_collected
= 0;
276 char **collected_ns
= NULL
;
278 if (namespaces_needed
) {
279 collected_ns
= (this->*collector
)(p_td
, num_collected
, def_ns
);
282 p_buf
.put_s((size_t)p_td
.namelens
[exer
] - 2, (cbyte
*)p_td
.names
[exer
]);
284 if (namespaces_needed
) {
285 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
286 p_buf
.put_s(strlen(collected_ns
[cur_coll
]), (cbyte
*)collected_ns
[cur_coll
]);
287 Free(collected_ns
[cur_coll
]); // job done
293 p_buf
.put_s(9, (cbyte
*)" xmlns=''");
294 flavor
&= ~DEF_NS_PRESENT
;
295 flavor
|= DEF_NS_SQUASHED
;
298 flavor
&= ~DEF_NS_SQUASHED
;
299 flavor
|= DEF_NS_PRESENT
;
303 p_buf
.put_s(mstrlen(const_cast<char*>(type_atr
)), (cbyte
*)type_atr
);
307 p_buf
.put_s(2 + indenting
, empty_tag_end
);
312 && !(flavor
& SIMPLE_TYPE
)
313 && !(exer
&& (p_td
.xer_bits
& (XER_LIST
|USE_TYPE_ATTR
)))),
317 else { // tag is omitted
318 // If the outer XML element optimistically wrote a newline after its start tag,
320 size_t buf_used
= p_buf
.get_len();
321 if (exer
&& (flavor
& USE_NIL
) && (buf_used
-- > 0) && // sequence point!
322 (p_buf
.get_data()[buf_used
] == '\n')) {
323 p_buf
.increase_length((size_t)-1); // back up over the newline
324 omit_tag
= -1; // to help fix HO85831
328 Free(const_cast<char*>(type_atr
));
333 void Base_Type::end_xml (const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
334 unsigned int flavor
, int indent
, bool empty
) const
336 int exer
= is_exer(flavor
);
337 int indenting
= !is_canonical(flavor
);
338 bool omit_tag
= (indent
!= 0) // can never omit the tag at the toplevel
339 && ( ((flavor
& XER_RECOF
) // can remove the tag even if not EXER
340 && !(exer
&& (flavor
& BXER_EMPTY_ELEM
))) // except 26.6, 26.7
342 && ( (p_td
.xer_bits
& (UNTAGGED
|ANY_ATTRIBUTES
|ANY_ELEMENT
))
343 || (flavor
& (EMBED_VALUES
|XER_LIST
|ANY_ATTRIBUTES
|USE_NIL
|USE_TYPE_ATTR
)))));
345 if (exer
&& (p_td
.xer_bits
& XER_ATTRIBUTE
)) {
348 else if (!empty
&& !omit_tag
) {
350 if (indenting
&& !(flavor
& SIMPLE_TYPE
)) do_indent(p_buf
, indent
);
351 p_buf
.put_s(2, (cbyte
*)"</");
352 if (exer
) write_ns_prefix(p_td
, p_buf
);
353 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-1+indenting
, (cbyte
*)p_td
.names
[exer
]);
359 ASN_BER_TLV_t
* Base_Type::BER_encode_chk_bound(boolean p_isbound
)
362 TTCN_EncDec_ErrorContext::error
363 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
364 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(0, NULL
);
374 // Called only from the two places in BER_encode_TLV_OCTETSTRING, below.
375 void Base_Type::BER_encode_putoctets_OCTETSTRING
376 (unsigned char *target
,
377 unsigned int octetnum_start
, unsigned int octet_count
,
378 int p_nof_octets
, const unsigned char *p_octets_ptr
)
380 if( octetnum_start
> static_cast<unsigned int>(p_nof_octets
)
381 || octetnum_start
+octet_count
> static_cast<unsigned int>(p_nof_octets
))
382 TTCN_EncDec_ErrorContext::error_internal
383 ("In Base_Type::BER_encode_putoctets_OCTETSTRING(): Index overflow.");
384 memcpy(target
, &p_octets_ptr
[octetnum_start
], octet_count
);
387 ASN_BER_TLV_t
* Base_Type::BER_encode_TLV_OCTETSTRING
389 int p_nof_octets
, const unsigned char *p_octets_ptr
)
391 unsigned char *V_ptr
;
393 unsigned int nof_fragments
=0;
395 if(p_coding
==BER_ENCODE_CER
) {
396 nof_fragments
=(p_nof_octets
+999)/1000;
397 if(!nof_fragments
) nof_fragments
=1;
399 else /*if(coding==BER_ENCODE_DER)*/ {
403 ASN_BER_TLV_t
*new_tlv
=NULL
;
404 boolean is_constructed
=nof_fragments
>1;
405 if(!is_constructed
) {
407 V_ptr
=(unsigned char*)Malloc(V_len
);
408 BER_encode_putoctets_OCTETSTRING(V_ptr
, 0, p_nof_octets
,
409 p_nof_octets
, p_octets_ptr
);
410 new_tlv
=ASN_BER_TLV_t::construct(V_len
, V_ptr
);
412 else { // is constructed
413 ASN_BER_TLV_t
*tmp_tlv
=NULL
;
414 new_tlv
=ASN_BER_TLV_t::construct(NULL
);
415 unsigned int rest_octets
=p_nof_octets
-(nof_fragments
-1)*1000;
417 for(unsigned int i
=0; i
<nof_fragments
; i
++) {
418 if(i
==nof_fragments
-1) V_len
=rest_octets
;
419 V_ptr
=(unsigned char*)Malloc(V_len
);
420 BER_encode_putoctets_OCTETSTRING(V_ptr
, i
*1000, V_len
,
421 p_nof_octets
, p_octets_ptr
);
422 tmp_tlv
=ASN_BER_TLV_t::construct(V_len
, V_ptr
);
423 tmp_tlv
=ASN_BER_V2TLV(tmp_tlv
, OCTETSTRING_descr_
, p_coding
);
424 new_tlv
->add_TLV(tmp_tlv
);
431 // for debugging purposes
432 static std::string bignum_as_bin(const BIGNUM* const BN) {
433 int bytes = BN_num_bytes(BN);
434 unsigned char* bn_as_bin = (unsigned char*) Malloc(bytes);
435 BN_bn2bin(BN, bn_as_bin);
438 for (int i = 0; i < bytes; ++i) {
439 result.append(char_as_bin(bn_as_bin[i]));
446 static std::string int_as_bin(int myInt) {
448 for (int i = sizeof(myInt) - 1; i >= 0; --i) {
449 char current = (myInt >> (i * 8)) & 0xFF;
450 result.append(char_as_bin(current));
455 static std::string char_as_bin(unsigned char ch) {
457 for (int i = 0; i < 8; ++i) {
458 result.append((ch & 0x80) == 0x80 ? "1" : "0");
464 static std::string chars_as_bin(const unsigned char* const chars, int len) {
466 for (int i = 0; i < len; ++i) {
467 result.append(char_as_bin(chars[i]));
476 ASN_BER_TLV_t
*Base_Type::BER_encode_TLV_INTEGER(unsigned,
477 const int_val_t
& p_int_val
)
479 if(p_int_val
.is_native()){
480 RInt p_int_val_int
=p_int_val
.get_val();
481 // Determine the number of octets to be used in the encoding.
482 unsigned long ulong_val
=p_int_val_int
>= 0
483 ?static_cast<unsigned long>(p_int_val_int
):
484 ~static_cast<unsigned long>(p_int_val_int
);
491 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(V_len
,NULL
);
492 // Already in 2's complement encoding.
493 ulong_val
=static_cast<unsigned long>(p_int_val_int
);
494 for(size_t i
=V_len
;i
>0;i
--){
495 new_tlv
->V
.str
.Vstr
[i
-1]=ulong_val
&0xFF;
503 const BIGNUM
* const D
= p_int_val
.get_val_openssl();
505 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(1,NULL
);
506 new_tlv
->V
.str
.Vstr
[0] = 0;
510 size_t num_bytes
= BN_num_bytes(D
);
511 unsigned char* bn_as_bin
= (unsigned char*) Malloc(num_bytes
);
512 BN_bn2bin(D
, bn_as_bin
);
515 if (BN_is_negative(D
)) {
516 for(size_t i
= 0; i
< num_bytes
; ++i
){
517 bn_as_bin
[i
] = ~bn_as_bin
[i
];
522 for (int i
= num_bytes
- 1; i
>= 0 && !stop
; --i
) {
523 for (int j
= 0; j
< 8 && !stop
; ++j
) {
524 unsigned char mask
= (0x1 << j
);
525 if (!(bn_as_bin
[i
] & mask
)) {
526 bn_as_bin
[i
] |= mask
;
529 bn_as_bin
[i
] ^= mask
;
533 pad
= !(bn_as_bin
[0] & 0x80);
535 pad
= bn_as_bin
[0] & 0x80;
538 ASN_BER_TLV_t
* new_tlv
= ASN_BER_TLV_t::construct(num_bytes
+ pad
, NULL
);
540 new_tlv
->V
.str
.Vstr
[0] = BN_is_negative(D
) ? 0xFF : 0x0;
543 memcpy(new_tlv
->V
.str
.Vstr
+ pad
, bn_as_bin
, num_bytes
);
549 ASN_BER_TLV_t
*Base_Type::BER_encode_TLV_INTEGER(unsigned p_coding
,
550 const int& p_int_val
)
552 int_val_t
p_int_val_val(p_int_val
);
553 return BER_encode_TLV_INTEGER(p_coding
, p_int_val_val
);
556 void Base_Type::BER_encode_chk_enum_valid(const TTCN_Typedescriptor_t
& p_td
,
557 boolean p_isvalid
, int p_value
)
560 TTCN_EncDec_ErrorContext::error
561 (TTCN_EncDec::ET_ENC_ENUM
,
562 "Encoding unknown value '%d' for enumerated type '%s'.",
567 void Base_Type::BER_decode_str2TLV(TTCN_Buffer
& p_buf
, ASN_BER_TLV_t
& p_tlv
,
570 if(!ASN_BER_str2TLV(p_buf
.get_read_len(), p_buf
.get_read_data(),
572 TTCN_EncDec_ErrorContext::error
573 (TTCN_EncDec::ET_INCOMPL_MSG
, "TLV is not complete.");
576 boolean
Base_Type::BER_decode_constdTLV_next(const ASN_BER_TLV_t
& p_tlv
,
579 ASN_BER_TLV_t
& p_target_tlv
)
581 if(p_tlv
.V
.str
.Vlen
<=V_pos
) {
582 if(!p_tlv
.isLenDefinite
)
583 TTCN_EncDec_ErrorContext::error
584 (TTCN_EncDec::ET_INCOMPL_MSG
,
585 "Missing end-of-contents octet in the indefinite length"
586 " constructed TLV.");
589 if(!ASN_BER_str2TLV(p_tlv
.V
.str
.Vlen
-V_pos
,
590 p_tlv
.V
.str
.Vstr
+V_pos
, p_target_tlv
, L_form
)) {
591 TTCN_EncDec_ErrorContext::error
592 (TTCN_EncDec::ET_INCOMPL_MSG
,
593 "Incomplete TLV in the constructed TLV.");
595 if(!p_tlv
.isLenDefinite
&& p_target_tlv
.tagnumber
==0
596 && p_target_tlv
.tagclass
==ASN_TAG_UNIV
)
598 V_pos
+=p_target_tlv
.get_len();
602 void Base_Type::BER_decode_constdTLV_end(const ASN_BER_TLV_t
& p_tlv
,
605 ASN_BER_TLV_t
& p_target_tlv
,
609 || BER_decode_constdTLV_next(p_tlv
, V_pos
, L_form
, p_target_tlv
)) {
610 TTCN_EncDec_ErrorContext::error
611 (TTCN_EncDec::ET_SUPERFL
,
612 "Superfluous TLV(s) at the end of constructed TLV.");
616 static void BER_decode_chk_tag(const ASN_Tag_t
& tag
,
617 const ASN_BER_TLV_t
& tlv
)
619 if (tlv
.isTagComplete
&&
620 (tag
.tagclass
!= tlv
.tagclass
|| tag
.tagnumber
!= tlv
.tagnumber
)) {
622 rcvdtag
.tagclass
=tlv
.tagclass
;
623 rcvdtag
.tagnumber
=tlv
.tagnumber
;
624 char *rcvdstr
=rcvdtag
.print();
626 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG
,
627 "Tag mismatch: Received: %s.", rcvdstr
);
636 void Base_Type::BER_decode_strip_tags(const ASN_BERdescriptor_t
& p_ber
,
637 const ASN_BER_TLV_t
& p_tlv
,
639 ASN_BER_TLV_t
& stripped_tlv
)
641 size_t i
=p_ber
.n_tags
;
646 char *expectedstr
=p_ber
.print_tags();
647 TTCN_EncDec_ErrorContext
ec("While checking tags (expecting %s): ",
651 BER_decode_chk_tag(p_ber
.tags
[0], p_tlv
);
655 ASN_BER_TLV_t curr_tlv
=p_tlv
;
659 TTCN_EncDec_ErrorContext
ec2("At pos #%lu: ",
660 (unsigned long) (p_ber
.n_tags
- i
));
661 BER_decode_chk_tag(p_ber
.tags
[i
], curr_tlv
);
662 if(i
!=0) { // not the innermost tag
663 if(!curr_tlv
.isConstructed
) {
664 ec2
.error(TTCN_EncDec::ET_TAG
,
665 "The other (innermost %lu) tag(s) are missing.", (unsigned long) i
);
667 stripped_tlv
=curr_tlv
;
669 else { // O.K., is constructed
671 BER_decode_constdTLV_next(curr_tlv
, V_pos
, L_form
, stripped_tlv
);
672 // if superfluous...?
673 ASN_BER_TLV_t endchecker_tlv
;
674 BER_decode_constdTLV_end(curr_tlv
, V_pos
, L_form
, endchecker_tlv
,
676 curr_tlv
=stripped_tlv
;
679 } // not the innermost
680 else { // innermost tag
686 void Base_Type::BER_decode_getoctets_OCTETSTRING
687 (const unsigned char *source
, size_t s_len
,
688 unsigned int& octetnum_start
,
689 int& p_nof_octets
, unsigned char *p_octets_ptr
)
691 p_nof_octets
=octetnum_start
+s_len
;
692 memcpy(&p_octets_ptr
[octetnum_start
], source
, s_len
);
693 octetnum_start
+=s_len
;
696 void Base_Type::BER_decode_TLV_OCTETSTRING
697 (const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
,
698 unsigned int& octetnum_start
,
699 int& p_nof_octets
, unsigned char *p_octets_ptr
)
701 if(!p_tlv
.isConstructed
) {
702 BER_decode_getoctets_OCTETSTRING
703 (p_tlv
.V
.str
.Vstr
, p_tlv
.V
.str
.Vlen
, octetnum_start
,
704 p_nof_octets
, p_octets_ptr
);
706 else { // is constructed
711 if(!ASN_BER_str2TLV(p_tlv
.V
.str
.Vlen
-V_pos
, p_tlv
.V
.str
.Vstr
+V_pos
,
713 TTCN_EncDec_ErrorContext::error
714 (TTCN_EncDec::ET_INCOMPL_MSG
,
715 "Incomplete TLV in a constructed OCTETSTRING TLV.");
718 if(!p_tlv
.isLenDefinite
&& tlv2
.tagnumber
==0
719 && tlv2
.tagclass
==ASN_TAG_UNIV
)
720 doit
=FALSE
; // End-of-contents
722 ASN_BER_TLV_t stripped_tlv
;
723 BER_decode_strip_tags(OCTETSTRING_ber_
, tlv2
, L_form
, stripped_tlv
);
724 BER_decode_TLV_OCTETSTRING(tlv2
, L_form
, octetnum_start
,
725 p_nof_octets
, p_octets_ptr
);
726 V_pos
+=tlv2
.get_len();
727 if(V_pos
>=p_tlv
.V
.str
.Vlen
) doit
=FALSE
;
730 } // else / is constructed
735 boolean
Base_Type::BER_decode_TLV_INTEGER(const ASN_BER_TLV_t
& p_tlv
,
736 unsigned, int_val_t
& p_int_val
)
738 p_tlv
.chk_constructed_flag(FALSE
);
739 if (!p_tlv
.isComplete
) return FALSE
;
740 if (!p_tlv
.V_tlvs_selected
&& p_tlv
.V
.str
.Vlen
== 0) {
741 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
742 "Length of V-part is 0.");
746 const size_t Vlen
= p_tlv
.V
.str
.Vlen
;
748 if (Vlen
> sizeof(RInt
)) { // Bignum
750 const bool negative
= p_tlv
.V
.str
.Vstr
[0] & 0x80;
751 BIGNUM
*D
= BN_new();
754 unsigned char* const Vstr
= (unsigned char*) Malloc(Vlen
);
755 memcpy(Vstr
, p_tlv
.V
.str
.Vstr
, Vlen
);
758 for (int i
= Vlen
- 1; i
>= 0 && !stop
; --i
) {
759 for(int j
= 0; j
< 8 && !stop
; ++j
) {
760 unsigned char mask
= (0x1 << j
);
761 if (Vstr
[i
] & mask
) {
770 for (size_t i
= 0; i
< Vlen
; ++i
) {
774 BN_bin2bn(Vstr
, Vlen
, D
);
776 } else { // positive case
777 BN_bin2bn(p_tlv
.V
.str
.Vstr
, Vlen
, D
);
780 BN_set_negative(D
, negative
);
781 p_int_val
= int_val_t(D
);
785 // Native int Vlen <= sizeof(RInt)
786 const unsigned char* const Vstr
= p_tlv
.V
.str
.Vstr
;
788 if (Vstr
[0] & 0x80) { // negative
789 // the first bytes should be 1-s
790 // e.g. -1 encoded on 32 bits: 11111111111111111111111111111111
791 // e.g. -1 encoded on 8 bits: 11111111
792 // [(sizeof(RInt)-Vlen)*8 ][Vlen*8]
793 // [ sizeof(RInt)*8 ]
795 for (size_t i
= 0; i
< sizeof(RInt
) - Vlen
; ++i
) {
801 int_val
|= p_tlv
.V
.str
.Vstr
[0];
802 for (size_t i
= 1; i
< Vlen
; ++i
) {
804 int_val
|= p_tlv
.V
.str
.Vstr
[i
];
807 p_int_val
= int_val_t(int_val
);
811 boolean
Base_Type::BER_decode_TLV_INTEGER(const ASN_BER_TLV_t
& p_tlv
,
812 unsigned L_form
, int& p_int_val
)
814 int_val_t
p_int_val_val(p_int_val
);
815 boolean ret_val
= BER_decode_TLV_INTEGER(p_tlv
, L_form
, p_int_val_val
);
816 if (p_int_val_val
.is_native()) {
817 p_int_val
= p_int_val_val
.get_val();
819 TTCN_warning("Large integer value was decoded and it can't be returned "
820 "as a native `int'");
827 // Actually, this is not used, but when we ever need a
828 // type-independent integer decoding, then we can move this to
829 // Basetype.hh. It is so beautiful and wonderful, I did not wanted
830 // this to get lost. :)
832 template<typename int_type>
833 void Base_Type::BER_decode_TLV_INTEGER
834 (const ASN_BER_TLV_t& p_tlv, unsigned L_form, int_type& p_intval)
836 boolean overflow_flag=FALSE;
837 p_tlv.chk_constructed_flag(FALSE);
838 if(!p_tlv.V_tlvs_selected && p_tlv.V.str.Vlen==0) {
839 TTCN_EncDec_ErrorContext::error
840 (TTCN_EncDec::ET_INVAL_MSG, "Length of V-part is 0.");
841 p_intval=static_cast<int_type>(0);
844 int_type tmp_int=static_cast<int_type>(p_tlv.V.str.Vstr[0] & 0x7F);
845 for(size_t i=1; i<p_tlv.V.str.Vlen; i++) {
847 tmp_int=static_cast<int_type>(256*tmp_int);
848 if(tmp_int<p_intval) overflow_flag=TRUE;
849 tmp_int=static_cast<int_type>(tmp_int+p_tlv.V.str.Vstr[i]);
851 if(p_tlv.V.str.Vstr[0] & 0x80) { // negative
852 int_type highbit=static_cast<int_type>(1);
853 for(size_t i=0; i<p_tlv.V.str.Vlen*8-1; i++) {
854 int_type backup=highbit;
855 highbit=static_cast<int_type>(2*highbit);
856 if(highbit/2!=backup) overflow_flag=TRUE;
858 p_intval=static_cast<int_type>(tmp_int-highbit);
864 TTCN_EncDec_ErrorContext::error
865 (TTCN_EncDec::ET_REPR,
866 "Value is too big (%lu octets).", p_tlv.V.str.Vlen);
871 boolean
Base_Type::BER_decode_TLV_CHOICE(const ASN_BERdescriptor_t
& p_ber
,
872 const ASN_BER_TLV_t
& p_tlv
,
874 ASN_BER_TLV_t
& p_target_tlv
)
878 p_tlv
.chk_constructed_flag(TRUE
);
879 if(!BER_decode_constdTLV_next(p_tlv
, V_pos
, L_form
, p_target_tlv
))
882 else p_target_tlv
=p_tlv
;
886 boolean
Base_Type::BER_decode_CHOICE_selection(boolean select_result
,
887 const ASN_BER_TLV_t
& p_tlv
)
889 if(select_result
) return TRUE
;
891 rcvd_tag
.tagclass
=p_tlv
.tagclass
;
892 rcvd_tag
.tagnumber
=p_tlv
.tagnumber
;
893 char *rcvd_str
=rcvd_tag
.print();
895 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG
,
896 "Invalid tag or unknown alternative: %s.", rcvd_str
);
905 void Base_Type::BER_decode_chk_enum_valid(const TTCN_Typedescriptor_t
& p_td
,
906 boolean p_isvalid
, int p_value
)
908 /** \todo If extensible ENUMERATED is supported (for example, in the
909 * typedescriptor there is something...), then give different error
910 * message depending on that flag. */
912 TTCN_EncDec_ErrorContext::error
913 (TTCN_EncDec::ET_DEC_ENUM
,
914 "Unknown value '%d' received for enumerated type '%s'.",
919 Base_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
923 ASN_BER_TLV_t
*tlv
=BER_encode_chk_bound(TRUE
);
925 TTCN_EncDec_ErrorContext::error_internal
926 ("BER_encode_V() not implemented for type '%s'.", p_td
.name
);
930 boolean
Base_Type::BER_decode_isMyMsg(const TTCN_Typedescriptor_t
& p_td
,
931 const ASN_BER_TLV_t
& p_tlv
)
933 if(p_td
.ber
->n_tags
==0 || !p_tlv
.isTagComplete
) return TRUE
;
934 const ASN_Tag_t
& tag
=p_td
.ber
->tags
[p_td
.ber
->n_tags
-1];
935 return (tag
.tagclass
==p_tlv
.tagclass
&& tag
.tagnumber
==p_tlv
.tagnumber
);
938 boolean
Base_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
939 const ASN_BER_TLV_t
& p_tlv
,
943 ASN_BER_TLV_t stripped_tlv
;
944 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
945 TTCN_EncDec_ErrorContext ec
;
947 ("BER_decode_V() not implemented for type '%s'.", p_td
.name
);
951 int Base_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
954 TTCN_error("RAW encoding requested for type '%s'"
955 " which has no RAW encoding method.", p_td
.name
);
959 int Base_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
,
962 TTCN_error("TEXT encoding requested for type '%s'"
963 " which has no TEXT encoding method.", p_td
.name
);
967 int Base_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
,
968 TTCN_Buffer
&, Limit_Token_List
&, boolean
, boolean
)
970 TTCN_error("TEXT decoding requested for type '%s'"
971 " which has no TEXT decoding method.", p_td
.name
);
975 int Base_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
,
976 TTCN_Buffer
&, int /* limit */, raw_order_t
/* top_bit_ord */,
977 boolean
/* no_error */, int /* sel_field */, boolean
/* first_call */ )
979 TTCN_error("RAW decoding requested for type '%s'"
980 " which has no RAW decoding method.",p_td
.name
);
984 int Base_Type::XER_encode(const XERdescriptor_t
& p_td
,
985 TTCN_Buffer
&, unsigned int, int, embed_values_enc_struct_t
*) const
987 TTCN_error("XER encoding requested for type '%-.*s' which has no"
988 " XER encoding method.", p_td
.namelens
[0]-2, p_td
.names
[0]);
992 int Base_Type::XER_decode(const XERdescriptor_t
& p_td
, XmlReaderWrap
&,
993 unsigned int, unsigned int, embed_values_dec_struct_t
*) {
994 TTCN_error("XER decoding requested for type '%-.*s' which has no"
995 " XER decoding method.", p_td
.namelens
[0]-2, p_td
.names
[0]);
999 int Base_Type::JSON_encode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
&) const
1001 TTCN_error("JSON encoding requested for type '%s' which has no"
1002 " JSON encoding method.", p_td
.name
);
1006 int Base_Type::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
&, boolean
)
1008 TTCN_error("JSON decoding requested for type '%s' which has no"
1009 " JSON decoding method.", p_td
.name
);
1013 boolean
Base_Type::can_start(const char *name
, const char *uri
,
1014 XERdescriptor_t
const& xd
, unsigned int flavor
)
1016 boolean e_xer
= is_exer(flavor
);
1017 // Check the name. If EXER, check the namespace too.
1018 return check_name(name
, xd
, e_xer
) && (!e_xer
|| check_namespace(uri
, xd
));
1021 char ** Base_Type::collect_ns(const XERdescriptor_t
& p_td
, size_t& num
, bool& def_ns
) const
1025 if (p_td
.my_module
!= 0 && p_td
.ns_index
!= -1
1026 && !(p_td
.xer_bits
& FORM_UNQUALIFIED
)) {
1027 const namespace_t
*my_ns
= p_td
.my_module
->get_ns(p_td
.ns_index
);
1028 if (!*my_ns
->px
) def_ns
= true;
1029 tmp
= mprintf(" xmlns%s%s='%s'",
1030 ((*my_ns
->px
) ? ":" : ""), my_ns
->px
,
1034 // The above may throw, but then nothing was allocated.
1037 char **retval
= (char**)Malloc(sizeof(char*));
1047 void Base_Type::merge_ns(char **&collected_ns
, size_t& num_collected
,
1048 char **new_namespaces
, size_t num_new
)
1051 for (size_t cur_ns
= 0; cur_ns
< num_new
; ++cur_ns
) {
1052 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
1053 if (!strcmp(new_namespaces
[cur_ns
], collected_ns
[cur_coll
])) {
1055 Free(new_namespaces
[cur_ns
]);
1056 new_namespaces
[cur_ns
] = NULL
;
1061 if (new_namespaces
[cur_ns
]) { // still there
1062 collected_ns
= (char**)Realloc(collected_ns
, sizeof(char*) * ++num_collected
);
1063 collected_ns
[num_collected
-1] = new_namespaces
[cur_ns
];
1066 Free(new_namespaces
);
1070 /////////////////////////////////////////////////////////////
1072 TTCN_Type_list::~TTCN_Type_list()
1077 void TTCN_Type_list::push(const Base_Type
*p_type
)
1079 types
=(const Base_Type
**)Realloc(types
, ++n_types
*sizeof(*types
));
1080 types
[n_types
-1]=p_type
;
1083 const Base_Type
* TTCN_Type_list::pop()
1086 TTCN_EncDec_ErrorContext::error_internal
1087 ("TTCN_Type_list::pop(): List is empty.");
1090 types
=(const Base_Type
**)Realloc(types
, n_types
*sizeof(*types
));
1094 const Base_Type
* TTCN_Type_list::get_nth(size_t pos
) const
1096 if(pos
==0) return types
[0];
1098 TTCN_EncDec_ErrorContext::error_internal
1099 ("TTCN_Type_list::get_nth(%lu): Out of range.", (unsigned long) pos
);
1100 return types
[n_types
-pos
];
1103 const TTCN_Typedescriptor_t BOOLEAN_descr_
={"BOOLEAN", &BOOLEAN_ber_
,
1104 &BOOLEAN_raw_
, &BOOLEAN_text_
, &BOOLEAN_xer_
, &BOOLEAN_json_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1106 const TTCN_Typedescriptor_t INTEGER_descr_
={"INTEGER", &INTEGER_ber_
,
1107 &INTEGER_raw_
, &INTEGER_text_
, &INTEGER_xer_
, &INTEGER_json_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1109 const TTCN_Typedescriptor_t FLOAT_descr_
={"REAL", &FLOAT_ber_
, &FLOAT_raw_
,
1110 NULL
, &FLOAT_xer_
, &FLOAT_json_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1112 const TTCN_Typedescriptor_t VERDICTTYPE_descr_
={"verdicttype", NULL
, NULL
,
1113 NULL
, &VERDICTTYPE_xer_
, &VERDICTTYPE_json_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1115 const TTCN_Typedescriptor_t OBJID_descr_
={"OBJECT IDENTIFIER", &OBJID_ber_
,
1116 NULL
, NULL
, &OBJID_xer_
, &OBJID_json_
, NULL
, TTCN_Typedescriptor_t::OBJID
};
1118 const TTCN_Typedescriptor_t BITSTRING_descr_
={"BIT STRING", &BITSTRING_ber_
,
1119 &BITSTRING_raw_
, NULL
, &BITSTRING_xer_
, &BITSTRING_json_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1121 const TTCN_Typedescriptor_t HEXSTRING_descr_
={"hexstring", NULL
,
1122 &HEXSTRING_raw_
, NULL
, &HEXSTRING_xer_
, &HEXSTRING_json_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1124 const TTCN_Typedescriptor_t OCTETSTRING_descr_
={"OCTET STRING",
1125 &OCTETSTRING_ber_
, &OCTETSTRING_raw_
, &OCTETSTRING_text_
, &OCTETSTRING_xer_
, &OCTETSTRING_json_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1127 const TTCN_Typedescriptor_t CHARSTRING_descr_
={"charstring", NULL
,
1128 &CHARSTRING_raw_
, &CHARSTRING_text_
, &CHARSTRING_xer_
, &CHARSTRING_json_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1130 const TTCN_Typedescriptor_t UNIVERSAL_CHARSTRING_descr_
={"universal charstring",
1131 NULL
, &UNIVERSAL_CHARSTRING_raw_
, &UNIVERSAL_CHARSTRING_text_
, &UNIVERSAL_CHARSTRING_xer_
, &UNIVERSAL_CHARSTRING_json_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1133 const TTCN_Typedescriptor_t COMPONENT_descr_
={"component", NULL
, NULL
, NULL
,
1134 NULL
, NULL
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1136 const TTCN_Typedescriptor_t DEFAULT_descr_
={"default", NULL
, NULL
, NULL
,
1137 NULL
, NULL
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1139 const TTCN_Typedescriptor_t ASN_NULL_descr_
={"NULL", &ASN_NULL_ber_
, NULL
,
1140 NULL
, &ASN_NULL_xer_
, &ASN_NULL_json_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1142 const TTCN_Typedescriptor_t ASN_ANY_descr_
={"ANY", &ASN_ANY_ber_
, NULL
,
1143 NULL
, NULL
, &ASN_ANY_json_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1145 const TTCN_Typedescriptor_t EXTERNAL_descr_
={"EXTERNAL", &EXTERNAL_ber_
, NULL
,
1146 NULL
, &EXTERNAL_xer_
, NULL
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1148 const TTCN_Typedescriptor_t EMBEDDED_PDV_descr_
={"EMBEDDED PDV",
1149 &EMBEDDED_PDV_ber_
, NULL
, NULL
, &EMBEDDED_PDV_xer_
, NULL
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1151 const TTCN_Typedescriptor_t CHARACTER_STRING_descr_
={"CHARACTER STRING",
1152 &CHARACTER_STRING_ber_
, NULL
, NULL
, &CHARACTER_STRING_xer_
, NULL
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1154 const TTCN_Typedescriptor_t ObjectDescriptor_descr_
={"ObjectDescriptor",
1155 &ObjectDescriptor_ber_
, NULL
, NULL
, NULL
, NULL
, NULL
, TTCN_Typedescriptor_t::GRAPHICSTRING
};
1157 const TTCN_Typedescriptor_t UTF8String_descr_
={"UTF8String", &UTF8String_ber_
,
1158 NULL
, NULL
, &UTF8String_xer_
, &UTF8String_json_
, NULL
, TTCN_Typedescriptor_t::UTF8STRING
};
1160 const TTCN_Typedescriptor_t ASN_ROID_descr_
={"RELATIVE-OID", &ASN_ROID_ber_
,
1161 NULL
, NULL
, &ASN_ROID_xer_
, &ASN_ROID_json_
, NULL
, TTCN_Typedescriptor_t::ROID
};
1163 const TTCN_Typedescriptor_t NumericString_descr_
={"NumericString",
1164 &NumericString_ber_
, NULL
, NULL
, &NumericString_xer_
, &NumericString_json_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1166 const TTCN_Typedescriptor_t PrintableString_descr_
={"PrintableString",
1167 &PrintableString_ber_
, NULL
, NULL
, &PrintableString_xer_
, &PrintableString_json_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1169 const TTCN_Typedescriptor_t TeletexString_descr_
={"TeletexString",
1170 &TeletexString_ber_
, NULL
, NULL
, &TeletexString_xer_
, &TeletexString_json_
, NULL
, TTCN_Typedescriptor_t::TELETEXSTRING
};
1171 const TTCN_Typedescriptor_t
& T61String_descr_
=TeletexString_descr_
;
1173 const TTCN_Typedescriptor_t VideotexString_descr_
={"VideotexString",
1174 &VideotexString_ber_
, NULL
, NULL
, &VideotexString_xer_
, &VideotexString_json_
, NULL
, TTCN_Typedescriptor_t::VIDEOTEXSTRING
};
1176 const TTCN_Typedescriptor_t IA5String_descr_
={"IA5String", &IA5String_ber_
,
1177 NULL
, NULL
, &IA5String_xer_
, &IA5String_json_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1179 const TTCN_Typedescriptor_t ASN_GeneralizedTime_descr_
={"GeneralizedTime",
1180 &ASN_GeneralizedTime_ber_
, NULL
, NULL
, NULL
, NULL
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1182 const TTCN_Typedescriptor_t ASN_UTCTime_descr_
={"UTCTime", &ASN_UTCTime_ber_
,
1183 NULL
, NULL
, NULL
, NULL
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1185 const TTCN_Typedescriptor_t GraphicString_descr_
={"GraphicString",
1186 &GraphicString_ber_
, NULL
, NULL
, &GraphicString_xer_
, &GraphicString_json_
, NULL
, TTCN_Typedescriptor_t::GRAPHICSTRING
};
1188 const TTCN_Typedescriptor_t VisibleString_descr_
={"VisibleString",
1189 &VisibleString_ber_
, NULL
, NULL
, &VisibleString_xer_
, &VisibleString_json_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1190 const TTCN_Typedescriptor_t
& ISO646String_descr_
=VisibleString_descr_
;
1192 const TTCN_Typedescriptor_t GeneralString_descr_
={"GeneralString",
1193 &GeneralString_ber_
, NULL
, NULL
, &GeneralString_xer_
, &GeneralString_json_
, NULL
, TTCN_Typedescriptor_t::GENERALSTRING
};
1195 const TTCN_Typedescriptor_t UniversalString_descr_
={"UniversalString",
1196 &UniversalString_ber_
, NULL
, NULL
, &UniversalString_xer_
, &UniversalString_json_
, NULL
, TTCN_Typedescriptor_t::UNIVERSALSTRING
};
1198 const TTCN_Typedescriptor_t BMPString_descr_
={"BMPString", &BMPString_ber_
,
1199 NULL
, NULL
, &BMPString_xer_
, &BMPString_json_
, NULL
, TTCN_Typedescriptor_t::BMPSTRING
};