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"
20 #include <openssl/bn.h>
25 // Note: RT2-only classes (Record_Type, Record_Of_Type) and Base_Type methods
26 // are in core2/Basetype2.cc
28 boolean
Base_Type::ispresent() const
30 TTCN_error("Base_Type::ispresent(): calling ispresent() on a non-optional field.");
34 void Base_Type::log() const
36 TTCN_Logger::log_event_str("<logging of this type is not implemented>");
39 void Base_Type::encode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
40 TTCN_EncDec::coding_t p_coding
, ...) const
43 va_start(pvar
, p_coding
);
45 case TTCN_EncDec::CT_BER
: {
46 TTCN_EncDec_ErrorContext
ec("While BER-encoding type '%s': ", p_td
.name
);
47 unsigned BER_coding
=va_arg(pvar
, unsigned);
48 BER_encode_chk_coding(BER_coding
);
49 ASN_BER_TLV_t
*tlv
=BER_encode_TLV(p_td
, BER_coding
);
50 tlv
->put_in_buffer(p_buf
);
51 ASN_BER_TLV_t::destruct(tlv
);
53 case TTCN_EncDec::CT_RAW
: {
54 TTCN_EncDec_ErrorContext
ec("While RAW-encoding type '%s': ", p_td
.name
);
56 TTCN_EncDec_ErrorContext::error_internal
57 ("No RAW descriptor available for type '%s'.", p_td
.name
);
61 RAW_enc_tree
root(TRUE
, NULL
, &rp
, 1, p_td
.raw
);
62 RAW_encode(p_td
, root
);
63 root
.put_to_buf(p_buf
);
65 case TTCN_EncDec::CT_TEXT
: {
66 TTCN_EncDec_ErrorContext
ec("While TEXT-encoding type '%s': ", p_td
.name
);
68 TTCN_EncDec_ErrorContext::error_internal
69 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
70 TEXT_encode(p_td
,p_buf
);
72 case TTCN_EncDec::CT_XER
: {
73 TTCN_EncDec_ErrorContext
ec("While XER-encoding type '%s': ", p_td
.name
);
74 if(!p_td
.xer
) TTCN_EncDec_ErrorContext::error_internal(
75 "No XER descriptor available for type '%s'.", p_td
.name
);
76 unsigned XER_coding
=va_arg(pvar
, unsigned);
77 XER_encode(*(p_td
.xer
),p_buf
, XER_coding
, 0);
80 case TTCN_EncDec::CT_JSON
: {
81 TTCN_EncDec_ErrorContext
ec("While JSON-encoding type '%s': ", p_td
.name
);
83 TTCN_EncDec_ErrorContext::error_internal
84 ("No JSON descriptor available for type '%s'.", p_td
.name
);
85 JSON_Tokenizer
tok(va_arg(pvar
, int) != 0);
86 JSON_encode(p_td
, tok
);
87 p_buf
.put_s(tok
.get_buffer_length(), (const unsigned char*)tok
.get_buffer());
90 TTCN_error("Unknown coding method requested to encode type '%s'",
96 void Base_Type::decode(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
97 TTCN_EncDec::coding_t p_coding
, ...)
100 va_start(pvar
, p_coding
);
102 case TTCN_EncDec::CT_BER
: {
103 TTCN_EncDec_ErrorContext
ec("While BER-decoding type '%s': ", p_td
.name
);
104 unsigned L_form
=va_arg(pvar
, unsigned);
106 BER_decode_str2TLV(p_buf
, tlv
, L_form
);
107 BER_decode_TLV(p_td
, tlv
, L_form
);
108 if(tlv
.isComplete
) p_buf
.increase_pos(tlv
.get_len());
110 case TTCN_EncDec::CT_RAW
: {
111 TTCN_EncDec_ErrorContext
ec("While RAW-decoding type '%s': ", p_td
.name
);
113 TTCN_EncDec_ErrorContext::error_internal
114 ("No RAW descriptor available for type '%s'.", p_td
.name
);
116 switch(p_td
.raw
->top_bit_order
) {
124 RAW_decode(p_td
, p_buf
, p_buf
.get_len()*8, order
);
126 case TTCN_EncDec::CT_TEXT
: {
127 Limit_Token_List limit
;
128 TTCN_EncDec_ErrorContext
ec("While TEXT-decoding type '%s': ", p_td
.name
);
130 TTCN_EncDec_ErrorContext::error_internal
131 ("No TEXT descriptor available for type '%s'.", p_td
.name
);
132 const unsigned char *b
=p_buf
.get_data();
133 if(b
[p_buf
.get_len()-1]!='\0'){
134 p_buf
.set_pos(p_buf
.get_len());
135 p_buf
.put_zero(8,ORDER_LSB
);
138 if(TEXT_decode(p_td
,p_buf
,limit
)<0)
139 ec
.error(TTCN_EncDec::ET_INCOMPL_MSG
,
140 "Can not decode type '%s', because invalid or incomplete"
141 " message was received"
144 case TTCN_EncDec::CT_XER
: {
145 TTCN_EncDec_ErrorContext
ec("While XER-decoding type '%s': ", p_td
.name
);
146 unsigned XER_coding
=va_arg(pvar
, unsigned);
147 XmlReaderWrap
reader(p_buf
);
148 for (int success
=reader
.Read(); success
==1; success
=reader
.Read()) {
149 if (reader
.NodeType() == XML_READER_TYPE_ELEMENT
) break;
151 XER_decode(*(p_td
.xer
), reader
, XER_coding
);
152 size_t bytes
= reader
.ByteConsumed();
153 p_buf
.set_pos(bytes
);
155 case TTCN_EncDec::CT_JSON
: {
156 TTCN_EncDec_ErrorContext
ec("While JSON-decoding type '%s': ", p_td
.name
);
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"
166 p_buf
.set_pos(tok
.get_buf_pos());
169 TTCN_error("Unknown coding method requested to decode type '%s'",
175 void Base_Type::BER_chk_descr(const TTCN_Typedescriptor_t
& p_td
)
178 TTCN_EncDec_ErrorContext::error_internal
179 ("No BER descriptor available for type '%s'.", p_td
.name
);
182 void Base_Type::BER_encode_chk_coding(unsigned& p_coding
)
189 TTCN_warning("Unknown BER encoding requested; using DER.");
190 p_coding
=BER_ENCODE_DER
;
195 void Base_Type::XER_encode_chk_coding(unsigned& p_coding
,
196 const TTCN_Typedescriptor_t
& p_td
)
199 TTCN_EncDec_ErrorContext::error_internal
200 ("No XER descriptor available for type '%s'.", p_td
.name
);
206 case XER_EXTENDED
| XER_CANONICAL
:
209 TTCN_warning("Unknown XER encoding requested; using Basic XER.");
210 p_coding
= XER_BASIC
;
215 static const cbyte empty_tag_end
[4] = "/>\n";
217 int Base_Type::begin_xml(const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
218 unsigned int& flavor
, int indent
, bool empty
,
219 collector_fn collector
, const char *type_atr
) const
221 const int indenting
= !is_canonical(flavor
);
222 const int exer
= is_exer(flavor
);
223 int omit_tag
= (indent
!= 0) // can never omit the tag at the toplevel
224 && ( ((flavor
& XER_RECOF
) // can remove the tag even if not EXER
225 && !(exer
&& (flavor
& BXER_EMPTY_ELEM
))) // except 26.6, 26.7
227 && ( (p_td
.xer_bits
& (UNTAGGED
|ANY_ATTRIBUTES
|ANY_ELEMENT
))
228 || (flavor
& (EMBED_VALUES
|XER_LIST
|ANY_ATTRIBUTES
|USE_NIL
|USE_TYPE_ATTR
)))));
230 // If a default namespace is in effect (uri but no prefix) and the type
231 // is unqualified, the default namespace must be canceled; otherwise
232 // an XML tag without a ns prefix looks like it belongs to the def.namespace
233 const boolean empty_ns_hack
= exer
&& !omit_tag
&& (indent
> 0)
234 && (p_td
.xer_bits
& FORM_UNQUALIFIED
)
235 && (flavor
& DEF_NS_PRESENT
);
237 if (exer
&& (p_td
.xer_bits
& XER_ATTRIBUTE
)) {
238 begin_attribute(p_td
, p_buf
);
240 else if (!omit_tag
) { // full tag
241 if (indenting
) do_indent(p_buf
, indent
);
243 if (exer
) write_ns_prefix(p_td
, p_buf
);
245 const namespace_t
*ns_info
= NULL
;
246 bool namespaces_needed
= false;
248 if (p_td
.my_module
!= NULL
&& p_td
.ns_index
!= -1) {
249 ns_info
= p_td
.my_module
->get_ns(p_td
.ns_index
);
252 namespaces_needed
= exer
&& //!(p_td.xer_bits & FORM_UNQUALIFIED) &&
253 (indent
==0 // top-level type
254 || (ns_info
&& *ns_info
->px
== '\0' // own ns is prefixless
255 && (flavor
& DEF_NS_SQUASHED
))
259 size_t num_collected
= 0;
260 char **collected_ns
= NULL
;
262 if (namespaces_needed
) {
263 collected_ns
= (this->*collector
)(p_td
, num_collected
, def_ns
);
266 p_buf
.put_s((size_t)p_td
.namelens
[exer
] - 2, (cbyte
*)p_td
.names
[exer
]);
268 if (namespaces_needed
) {
269 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
270 p_buf
.put_s(strlen(collected_ns
[cur_coll
]), (cbyte
*)collected_ns
[cur_coll
]);
271 Free(collected_ns
[cur_coll
]); // job done
277 p_buf
.put_s(9, (cbyte
*)" xmlns=''");
278 flavor
&= ~DEF_NS_PRESENT
;
279 flavor
|= DEF_NS_SQUASHED
;
282 flavor
&= ~DEF_NS_SQUASHED
;
283 flavor
|= DEF_NS_PRESENT
;
287 p_buf
.put_s(mstrlen(const_cast<char*>(type_atr
)), (cbyte
*)type_atr
);
291 p_buf
.put_s(2 + indenting
, empty_tag_end
);
296 && !(flavor
& SIMPLE_TYPE
)
297 && !(exer
&& (p_td
.xer_bits
& (XER_LIST
|USE_TYPE_ATTR
)))),
301 else { // tag is omitted
302 // If the outer XML element optimistically wrote a newline after its start tag,
304 size_t buf_used
= p_buf
.get_len();
305 if (exer
&& (flavor
& USE_NIL
) && (buf_used
-- > 0) && // sequence point!
306 (p_buf
.get_data()[buf_used
] == '\n')) {
307 p_buf
.increase_length((size_t)-1); // back up over the newline
308 omit_tag
= -1; // to help fix HO85831
312 Free(const_cast<char*>(type_atr
));
317 void Base_Type::end_xml (const XERdescriptor_t
& p_td
, TTCN_Buffer
& p_buf
,
318 unsigned int flavor
, int indent
, bool empty
) const
320 int exer
= is_exer(flavor
);
321 int indenting
= !is_canonical(flavor
);
322 bool omit_tag
= (indent
!= 0) // can never omit the tag at the toplevel
323 && ( ((flavor
& XER_RECOF
) // can remove the tag even if not EXER
324 && !(exer
&& (flavor
& BXER_EMPTY_ELEM
))) // except 26.6, 26.7
326 && ( (p_td
.xer_bits
& (UNTAGGED
|ANY_ATTRIBUTES
|ANY_ELEMENT
))
327 || (flavor
& (EMBED_VALUES
|XER_LIST
|ANY_ATTRIBUTES
|USE_NIL
|USE_TYPE_ATTR
)))));
329 if (exer
&& (p_td
.xer_bits
& XER_ATTRIBUTE
)) {
332 else if (!empty
&& !omit_tag
) {
334 if (indenting
&& !(flavor
& SIMPLE_TYPE
)) do_indent(p_buf
, indent
);
335 p_buf
.put_s(2, (cbyte
*)"</");
336 if (exer
) write_ns_prefix(p_td
, p_buf
);
337 p_buf
.put_s((size_t)p_td
.namelens
[exer
]-1+indenting
, (cbyte
*)p_td
.names
[exer
]);
343 ASN_BER_TLV_t
* Base_Type::BER_encode_chk_bound(boolean p_isbound
)
346 TTCN_EncDec_ErrorContext::error
347 (TTCN_EncDec::ET_UNBOUND
, "Encoding an unbound value.");
348 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(0, NULL
);
358 // Called only from the two places in BER_encode_TLV_OCTETSTRING, below.
359 void Base_Type::BER_encode_putoctets_OCTETSTRING
360 (unsigned char *target
,
361 unsigned int octetnum_start
, unsigned int octet_count
,
362 int p_nof_octets
, const unsigned char *p_octets_ptr
)
364 if( octetnum_start
> static_cast<unsigned int>(p_nof_octets
)
365 || octetnum_start
+octet_count
> static_cast<unsigned int>(p_nof_octets
))
366 TTCN_EncDec_ErrorContext::error_internal
367 ("In Base_Type::BER_encode_putoctets_OCTETSTRING(): Index overflow.");
368 memcpy(target
, &p_octets_ptr
[octetnum_start
], octet_count
);
371 ASN_BER_TLV_t
* Base_Type::BER_encode_TLV_OCTETSTRING
373 int p_nof_octets
, const unsigned char *p_octets_ptr
)
375 unsigned char *V_ptr
;
377 unsigned int nof_fragments
=0;
379 if(p_coding
==BER_ENCODE_CER
) {
380 nof_fragments
=(p_nof_octets
+999)/1000;
381 if(!nof_fragments
) nof_fragments
=1;
383 else /*if(coding==BER_ENCODE_DER)*/ {
387 ASN_BER_TLV_t
*new_tlv
=NULL
;
388 boolean is_constructed
=nof_fragments
>1;
389 if(!is_constructed
) {
391 V_ptr
=(unsigned char*)Malloc(V_len
);
392 BER_encode_putoctets_OCTETSTRING(V_ptr
, 0, p_nof_octets
,
393 p_nof_octets
, p_octets_ptr
);
394 new_tlv
=ASN_BER_TLV_t::construct(V_len
, V_ptr
);
396 else { // is constructed
397 ASN_BER_TLV_t
*tmp_tlv
=NULL
;
398 new_tlv
=ASN_BER_TLV_t::construct(NULL
);
399 unsigned int rest_octets
=p_nof_octets
-(nof_fragments
-1)*1000;
401 for(unsigned int i
=0; i
<nof_fragments
; i
++) {
402 if(i
==nof_fragments
-1) V_len
=rest_octets
;
403 V_ptr
=(unsigned char*)Malloc(V_len
);
404 BER_encode_putoctets_OCTETSTRING(V_ptr
, i
*1000, V_len
,
405 p_nof_octets
, p_octets_ptr
);
406 tmp_tlv
=ASN_BER_TLV_t::construct(V_len
, V_ptr
);
407 tmp_tlv
=ASN_BER_V2TLV(tmp_tlv
, OCTETSTRING_descr_
, p_coding
);
408 new_tlv
->add_TLV(tmp_tlv
);
415 // for debugging purposes
416 static std::string bignum_as_bin(const BIGNUM* const BN) {
417 int bytes = BN_num_bytes(BN);
418 unsigned char* bn_as_bin = (unsigned char*) Malloc(bytes);
419 BN_bn2bin(BN, bn_as_bin);
422 for (int i = 0; i < bytes; ++i) {
423 result.append(char_as_bin(bn_as_bin[i]));
430 static std::string int_as_bin(int myInt) {
432 for (int i = sizeof(myInt) - 1; i >= 0; --i) {
433 char current = (myInt >> (i * 8)) & 0xFF;
434 result.append(char_as_bin(current));
439 static std::string char_as_bin(unsigned char ch) {
441 for (int i = 0; i < 8; ++i) {
442 result.append((ch & 0x80) == 0x80 ? "1" : "0");
448 static std::string chars_as_bin(const unsigned char* const chars, int len) {
450 for (int i = 0; i < len; ++i) {
451 result.append(char_as_bin(chars[i]));
460 ASN_BER_TLV_t
*Base_Type::BER_encode_TLV_INTEGER(unsigned,
461 const int_val_t
& p_int_val
)
463 if(p_int_val
.is_native()){
464 RInt p_int_val_int
=p_int_val
.get_val();
465 // Determine the number of octets to be used in the encoding.
466 unsigned long ulong_val
=p_int_val_int
>= 0
467 ?static_cast<unsigned long>(p_int_val_int
):
468 ~static_cast<unsigned long>(p_int_val_int
);
475 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(V_len
,NULL
);
476 // Already in 2's complement encoding.
477 ulong_val
=static_cast<unsigned long>(p_int_val_int
);
478 for(size_t i
=V_len
;i
>0;i
--){
479 new_tlv
->V
.str
.Vstr
[i
-1]=ulong_val
&0xFF;
487 const BIGNUM
* const D
= p_int_val
.get_val_openssl();
489 ASN_BER_TLV_t
*new_tlv
=ASN_BER_TLV_t::construct(1,NULL
);
490 new_tlv
->V
.str
.Vstr
[0] = 0;
494 size_t num_bytes
= BN_num_bytes(D
);
495 unsigned char* bn_as_bin
= (unsigned char*) Malloc(num_bytes
);
496 BN_bn2bin(D
, bn_as_bin
);
499 if (BN_is_negative(D
)) {
500 for(size_t i
= 0; i
< num_bytes
; ++i
){
501 bn_as_bin
[i
] = ~bn_as_bin
[i
];
506 for (int i
= num_bytes
- 1; i
>= 0 && !stop
; --i
) {
507 for (int j
= 0; j
< 8 && !stop
; ++j
) {
508 unsigned char mask
= (0x1 << j
);
509 if (!(bn_as_bin
[i
] & mask
)) {
510 bn_as_bin
[i
] |= mask
;
513 bn_as_bin
[i
] ^= mask
;
517 pad
= !(bn_as_bin
[0] & 0x80);
519 pad
= bn_as_bin
[0] & 0x80;
522 ASN_BER_TLV_t
* new_tlv
= ASN_BER_TLV_t::construct(num_bytes
+ pad
, NULL
);
524 new_tlv
->V
.str
.Vstr
[0] = BN_is_negative(D
) ? 0xFF : 0x0;
527 memcpy(new_tlv
->V
.str
.Vstr
+ pad
, bn_as_bin
, num_bytes
);
533 ASN_BER_TLV_t
*Base_Type::BER_encode_TLV_INTEGER(unsigned p_coding
,
534 const int& p_int_val
)
536 int_val_t
p_int_val_val(p_int_val
);
537 return BER_encode_TLV_INTEGER(p_coding
, p_int_val_val
);
540 void Base_Type::BER_encode_chk_enum_valid(const TTCN_Typedescriptor_t
& p_td
,
541 boolean p_isvalid
, int p_value
)
544 TTCN_EncDec_ErrorContext::error
545 (TTCN_EncDec::ET_ENC_ENUM
,
546 "Encoding unknown value '%d' for enumerated type '%s'.",
551 void Base_Type::BER_decode_str2TLV(TTCN_Buffer
& p_buf
, ASN_BER_TLV_t
& p_tlv
,
554 if(!ASN_BER_str2TLV(p_buf
.get_read_len(), p_buf
.get_read_data(),
556 TTCN_EncDec_ErrorContext::error
557 (TTCN_EncDec::ET_INCOMPL_MSG
, "TLV is not complete.");
560 boolean
Base_Type::BER_decode_constdTLV_next(const ASN_BER_TLV_t
& p_tlv
,
563 ASN_BER_TLV_t
& p_target_tlv
)
565 if(p_tlv
.V
.str
.Vlen
<=V_pos
) {
566 if(!p_tlv
.isLenDefinite
)
567 TTCN_EncDec_ErrorContext::error
568 (TTCN_EncDec::ET_INCOMPL_MSG
,
569 "Missing end-of-contents octet in the indefinite length"
570 " constructed TLV.");
573 if(!ASN_BER_str2TLV(p_tlv
.V
.str
.Vlen
-V_pos
,
574 p_tlv
.V
.str
.Vstr
+V_pos
, p_target_tlv
, L_form
)) {
575 TTCN_EncDec_ErrorContext::error
576 (TTCN_EncDec::ET_INCOMPL_MSG
,
577 "Incomplete TLV in the constructed TLV.");
579 if(!p_tlv
.isLenDefinite
&& p_target_tlv
.tagnumber
==0
580 && p_target_tlv
.tagclass
==ASN_TAG_UNIV
)
582 V_pos
+=p_target_tlv
.get_len();
586 void Base_Type::BER_decode_constdTLV_end(const ASN_BER_TLV_t
& p_tlv
,
589 ASN_BER_TLV_t
& p_target_tlv
,
593 || BER_decode_constdTLV_next(p_tlv
, V_pos
, L_form
, p_target_tlv
)) {
594 TTCN_EncDec_ErrorContext::error
595 (TTCN_EncDec::ET_SUPERFL
,
596 "Superfluous TLV(s) at the end of constructed TLV.");
600 static void BER_decode_chk_tag(const ASN_Tag_t
& tag
,
601 const ASN_BER_TLV_t
& tlv
)
603 if (tlv
.isTagComplete
&&
604 (tag
.tagclass
!= tlv
.tagclass
|| tag
.tagnumber
!= tlv
.tagnumber
)) {
606 rcvdtag
.tagclass
=tlv
.tagclass
;
607 rcvdtag
.tagnumber
=tlv
.tagnumber
;
608 char *rcvdstr
=rcvdtag
.print();
610 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG
,
611 "Tag mismatch: Received: %s.", rcvdstr
);
620 void Base_Type::BER_decode_strip_tags(const ASN_BERdescriptor_t
& p_ber
,
621 const ASN_BER_TLV_t
& p_tlv
,
623 ASN_BER_TLV_t
& stripped_tlv
)
625 size_t i
=p_ber
.n_tags
;
630 char *expectedstr
=p_ber
.print_tags();
631 TTCN_EncDec_ErrorContext
ec("While checking tags (expecting %s): ",
635 BER_decode_chk_tag(p_ber
.tags
[0], p_tlv
);
639 ASN_BER_TLV_t curr_tlv
=p_tlv
;
643 TTCN_EncDec_ErrorContext
ec2("At pos #%lu: ",
644 (unsigned long) (p_ber
.n_tags
- i
));
645 BER_decode_chk_tag(p_ber
.tags
[i
], curr_tlv
);
646 if(i
!=0) { // not the innermost tag
647 if(!curr_tlv
.isConstructed
) {
648 ec2
.error(TTCN_EncDec::ET_TAG
,
649 "The other (innermost %lu) tag(s) are missing.", (unsigned long) i
);
651 stripped_tlv
=curr_tlv
;
653 else { // O.K., is constructed
655 BER_decode_constdTLV_next(curr_tlv
, V_pos
, L_form
, stripped_tlv
);
656 // if superfluous...?
657 ASN_BER_TLV_t endchecker_tlv
;
658 BER_decode_constdTLV_end(curr_tlv
, V_pos
, L_form
, endchecker_tlv
,
660 curr_tlv
=stripped_tlv
;
663 } // not the innermost
664 else { // innermost tag
670 void Base_Type::BER_decode_getoctets_OCTETSTRING
671 (const unsigned char *source
, size_t s_len
,
672 unsigned int& octetnum_start
,
673 int& p_nof_octets
, unsigned char *p_octets_ptr
)
675 p_nof_octets
=octetnum_start
+s_len
;
676 memcpy(&p_octets_ptr
[octetnum_start
], source
, s_len
);
677 octetnum_start
+=s_len
;
680 void Base_Type::BER_decode_TLV_OCTETSTRING
681 (const ASN_BER_TLV_t
& p_tlv
, unsigned L_form
,
682 unsigned int& octetnum_start
,
683 int& p_nof_octets
, unsigned char *p_octets_ptr
)
685 if(!p_tlv
.isConstructed
) {
686 BER_decode_getoctets_OCTETSTRING
687 (p_tlv
.V
.str
.Vstr
, p_tlv
.V
.str
.Vlen
, octetnum_start
,
688 p_nof_octets
, p_octets_ptr
);
690 else { // is constructed
695 if(!ASN_BER_str2TLV(p_tlv
.V
.str
.Vlen
-V_pos
, p_tlv
.V
.str
.Vstr
+V_pos
,
697 TTCN_EncDec_ErrorContext::error
698 (TTCN_EncDec::ET_INCOMPL_MSG
,
699 "Incomplete TLV in a constructed OCTETSTRING TLV.");
702 if(!p_tlv
.isLenDefinite
&& tlv2
.tagnumber
==0
703 && tlv2
.tagclass
==ASN_TAG_UNIV
)
704 doit
=FALSE
; // End-of-contents
706 ASN_BER_TLV_t stripped_tlv
;
707 BER_decode_strip_tags(OCTETSTRING_ber_
, tlv2
, L_form
, stripped_tlv
);
708 BER_decode_TLV_OCTETSTRING(tlv2
, L_form
, octetnum_start
,
709 p_nof_octets
, p_octets_ptr
);
710 V_pos
+=tlv2
.get_len();
711 if(V_pos
>=p_tlv
.V
.str
.Vlen
) doit
=FALSE
;
714 } // else / is constructed
719 boolean
Base_Type::BER_decode_TLV_INTEGER(const ASN_BER_TLV_t
& p_tlv
,
720 unsigned, int_val_t
& p_int_val
)
722 p_tlv
.chk_constructed_flag(FALSE
);
723 if (!p_tlv
.isComplete
) return FALSE
;
724 if (!p_tlv
.V_tlvs_selected
&& p_tlv
.V
.str
.Vlen
== 0) {
725 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG
,
726 "Length of V-part is 0.");
730 const size_t Vlen
= p_tlv
.V
.str
.Vlen
;
732 if (Vlen
> sizeof(RInt
)) { // Bignum
734 const bool negative
= p_tlv
.V
.str
.Vstr
[0] & 0x80;
735 BIGNUM
*D
= BN_new();
738 unsigned char* const Vstr
= (unsigned char*) Malloc(Vlen
);
739 memcpy(Vstr
, p_tlv
.V
.str
.Vstr
, Vlen
);
742 for (int i
= Vlen
- 1; i
>= 0 && !stop
; --i
) {
743 for(int j
= 0; j
< 8 && !stop
; ++j
) {
744 unsigned char mask
= (0x1 << j
);
745 if (Vstr
[i
] & mask
) {
754 for (size_t i
= 0; i
< Vlen
; ++i
) {
758 BN_bin2bn(Vstr
, Vlen
, D
);
760 } else { // positive case
761 BN_bin2bn(p_tlv
.V
.str
.Vstr
, Vlen
, D
);
764 BN_set_negative(D
, negative
);
765 p_int_val
= int_val_t(D
);
769 // Native int Vlen <= sizeof(RInt)
770 const unsigned char* const Vstr
= p_tlv
.V
.str
.Vstr
;
772 if (Vstr
[0] & 0x80) { // negative
773 // the first bytes should be 1-s
774 // e.g. -1 encoded on 32 bits: 11111111111111111111111111111111
775 // e.g. -1 encoded on 8 bits: 11111111
776 // [(sizeof(RInt)-Vlen)*8 ][Vlen*8]
777 // [ sizeof(RInt)*8 ]
779 for (size_t i
= 0; i
< sizeof(RInt
) - Vlen
; ++i
) {
785 int_val
|= p_tlv
.V
.str
.Vstr
[0];
786 for (size_t i
= 1; i
< Vlen
; ++i
) {
788 int_val
|= p_tlv
.V
.str
.Vstr
[i
];
791 p_int_val
= int_val_t(int_val
);
795 boolean
Base_Type::BER_decode_TLV_INTEGER(const ASN_BER_TLV_t
& p_tlv
,
796 unsigned L_form
, int& p_int_val
)
798 int_val_t
p_int_val_val(p_int_val
);
799 boolean ret_val
= BER_decode_TLV_INTEGER(p_tlv
, L_form
, p_int_val_val
);
800 if (p_int_val_val
.is_native()) {
801 p_int_val
= p_int_val_val
.get_val();
803 TTCN_warning("Large integer value was decoded and it can't be returned "
804 "as a native `int'");
811 // Actually, this is not used, but when we ever need a
812 // type-independent integer decoding, then we can move this to
813 // Basetype.hh. It is so beautiful and wonderful, I did not wanted
814 // this to get lost. :)
816 template<typename int_type>
817 void Base_Type::BER_decode_TLV_INTEGER
818 (const ASN_BER_TLV_t& p_tlv, unsigned L_form, int_type& p_intval)
820 boolean overflow_flag=FALSE;
821 p_tlv.chk_constructed_flag(FALSE);
822 if(!p_tlv.V_tlvs_selected && p_tlv.V.str.Vlen==0) {
823 TTCN_EncDec_ErrorContext::error
824 (TTCN_EncDec::ET_INVAL_MSG, "Length of V-part is 0.");
825 p_intval=static_cast<int_type>(0);
828 int_type tmp_int=static_cast<int_type>(p_tlv.V.str.Vstr[0] & 0x7F);
829 for(size_t i=1; i<p_tlv.V.str.Vlen; i++) {
831 tmp_int=static_cast<int_type>(256*tmp_int);
832 if(tmp_int<p_intval) overflow_flag=TRUE;
833 tmp_int=static_cast<int_type>(tmp_int+p_tlv.V.str.Vstr[i]);
835 if(p_tlv.V.str.Vstr[0] & 0x80) { // negative
836 int_type highbit=static_cast<int_type>(1);
837 for(size_t i=0; i<p_tlv.V.str.Vlen*8-1; i++) {
838 int_type backup=highbit;
839 highbit=static_cast<int_type>(2*highbit);
840 if(highbit/2!=backup) overflow_flag=TRUE;
842 p_intval=static_cast<int_type>(tmp_int-highbit);
848 TTCN_EncDec_ErrorContext::error
849 (TTCN_EncDec::ET_REPR,
850 "Value is too big (%lu octets).", p_tlv.V.str.Vlen);
855 boolean
Base_Type::BER_decode_TLV_CHOICE(const ASN_BERdescriptor_t
& p_ber
,
856 const ASN_BER_TLV_t
& p_tlv
,
858 ASN_BER_TLV_t
& p_target_tlv
)
862 p_tlv
.chk_constructed_flag(TRUE
);
863 if(!BER_decode_constdTLV_next(p_tlv
, V_pos
, L_form
, p_target_tlv
))
866 else p_target_tlv
=p_tlv
;
870 boolean
Base_Type::BER_decode_CHOICE_selection(boolean select_result
,
871 const ASN_BER_TLV_t
& p_tlv
)
873 if(select_result
) return TRUE
;
875 rcvd_tag
.tagclass
=p_tlv
.tagclass
;
876 rcvd_tag
.tagnumber
=p_tlv
.tagnumber
;
877 char *rcvd_str
=rcvd_tag
.print();
879 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG
,
880 "Invalid tag or unknown alternative: %s.", rcvd_str
);
889 void Base_Type::BER_decode_chk_enum_valid(const TTCN_Typedescriptor_t
& p_td
,
890 boolean p_isvalid
, int p_value
)
892 /** \todo If extensible ENUMERATED is supported (for example, in the
893 * typedescriptor there is something...), then give different error
894 * message depending on that flag. */
896 TTCN_EncDec_ErrorContext::error
897 (TTCN_EncDec::ET_DEC_ENUM
,
898 "Unknown value '%d' received for enumerated type '%s'.",
903 Base_Type::BER_encode_TLV(const TTCN_Typedescriptor_t
& p_td
,
907 ASN_BER_TLV_t
*tlv
=BER_encode_chk_bound(TRUE
);
909 TTCN_EncDec_ErrorContext::error_internal
910 ("BER_encode_V() not implemented for type '%s'.", p_td
.name
);
914 boolean
Base_Type::BER_decode_isMyMsg(const TTCN_Typedescriptor_t
& p_td
,
915 const ASN_BER_TLV_t
& p_tlv
)
917 if(p_td
.ber
->n_tags
==0 || !p_tlv
.isTagComplete
) return TRUE
;
918 const ASN_Tag_t
& tag
=p_td
.ber
->tags
[p_td
.ber
->n_tags
-1];
919 return (tag
.tagclass
==p_tlv
.tagclass
&& tag
.tagnumber
==p_tlv
.tagnumber
);
922 boolean
Base_Type::BER_decode_TLV(const TTCN_Typedescriptor_t
& p_td
,
923 const ASN_BER_TLV_t
& p_tlv
,
927 ASN_BER_TLV_t stripped_tlv
;
928 BER_decode_strip_tags(*p_td
.ber
, p_tlv
, L_form
, stripped_tlv
);
929 TTCN_EncDec_ErrorContext ec
;
931 ("BER_decode_V() not implemented for type '%s'.", p_td
.name
);
935 int Base_Type::RAW_encode(const TTCN_Typedescriptor_t
& p_td
,
938 TTCN_error("RAW encoding requested for type '%s'"
939 " which has no RAW encoding method.", p_td
.name
);
943 int Base_Type::TEXT_encode(const TTCN_Typedescriptor_t
& p_td
,
946 TTCN_error("TEXT encoding requested for type '%s'"
947 " which has no TEXT encoding method.", p_td
.name
);
951 int Base_Type::TEXT_decode(const TTCN_Typedescriptor_t
& p_td
,
952 TTCN_Buffer
&, Limit_Token_List
&, boolean
, boolean
)
954 TTCN_error("TEXT decoding requested for type '%s'"
955 " which has no TEXT decoding method.", p_td
.name
);
959 int Base_Type::RAW_decode(const TTCN_Typedescriptor_t
& p_td
,
960 TTCN_Buffer
&, int /* limit */, raw_order_t
/* top_bit_ord */,
961 boolean
/* no_error */, int /* sel_field */, boolean
/* first_call */ )
963 TTCN_error("RAW decoding requested for type '%s'"
964 " which has no RAW decoding method.",p_td
.name
);
968 int Base_Type::XER_encode(const XERdescriptor_t
& p_td
,
969 TTCN_Buffer
&, unsigned int, int) const
971 TTCN_error("XER encoding requested for type '%-.*s' which has no"
972 " XER encoding method.", p_td
.namelens
[0]-2, p_td
.names
[0]);
976 int Base_Type::XER_decode(const XERdescriptor_t
& p_td
, XmlReaderWrap
&, unsigned int) {
977 TTCN_error("XER decoding requested for type '%-.*s' which has no"
978 " XER decoding method.", p_td
.namelens
[0]-2, p_td
.names
[0]);
982 int Base_Type::JSON_encode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
&) const
984 TTCN_error("JSON encoding requested for type '%s' which has no"
985 " JSON encoding method.", p_td
.name
);
989 int Base_Type::JSON_decode(const TTCN_Typedescriptor_t
& p_td
, JSON_Tokenizer
&, boolean
)
991 TTCN_error("JSON decoding requested for type '%s' which has no"
992 " JSON decoding method.", p_td
.name
);
996 boolean
Base_Type::can_start(const char *name
, const char *uri
,
997 XERdescriptor_t
const& xd
, unsigned int flavor
)
999 boolean e_xer
= is_exer(flavor
);
1000 // Check the name. If EXER, check the namespace too.
1001 return check_name(name
, xd
, e_xer
) && (!e_xer
|| check_namespace(uri
, xd
));
1004 char ** Base_Type::collect_ns(const XERdescriptor_t
& p_td
, size_t& num
, bool& def_ns
) const
1008 if (p_td
.my_module
!= 0 && p_td
.ns_index
!= -1
1009 && !(p_td
.xer_bits
& FORM_UNQUALIFIED
)) {
1010 const namespace_t
*my_ns
= p_td
.my_module
->get_ns(p_td
.ns_index
);
1011 if (!*my_ns
->px
) def_ns
= true;
1012 tmp
= mprintf(" xmlns%s%s='%s'",
1013 ((*my_ns
->px
) ? ":" : ""), my_ns
->px
,
1017 // The above may throw, but then nothing was allocated.
1020 char **retval
= (char**)Malloc(sizeof(char*));
1030 void Base_Type::merge_ns(char **&collected_ns
, size_t& num_collected
,
1031 char **new_namespaces
, size_t num_new
)
1034 for (size_t cur_ns
= 0; cur_ns
< num_new
; ++cur_ns
) {
1035 for (size_t cur_coll
= 0; cur_coll
< num_collected
; ++cur_coll
) {
1036 if (!strcmp(new_namespaces
[cur_ns
], collected_ns
[cur_coll
])) {
1038 Free(new_namespaces
[cur_ns
]);
1039 new_namespaces
[cur_ns
] = NULL
;
1044 if (new_namespaces
[cur_ns
]) { // still there
1045 collected_ns
= (char**)Realloc(collected_ns
, sizeof(char*) * ++num_collected
);
1046 collected_ns
[num_collected
-1] = new_namespaces
[cur_ns
];
1049 Free(new_namespaces
);
1053 /////////////////////////////////////////////////////////////
1055 TTCN_Type_list::~TTCN_Type_list()
1060 void TTCN_Type_list::push(const Base_Type
*p_type
)
1062 types
=(const Base_Type
**)Realloc(types
, ++n_types
*sizeof(*types
));
1063 types
[n_types
-1]=p_type
;
1066 const Base_Type
* TTCN_Type_list::pop()
1069 TTCN_EncDec_ErrorContext::error_internal
1070 ("TTCN_Type_list::pop(): List is empty.");
1073 types
=(const Base_Type
**)Realloc(types
, n_types
*sizeof(*types
));
1077 const Base_Type
* TTCN_Type_list::get_nth(size_t pos
) const
1079 if(pos
==0) return types
[0];
1081 TTCN_EncDec_ErrorContext::error_internal
1082 ("TTCN_Type_list::get_nth(%lu): Out of range.", (unsigned long) pos
);
1083 return types
[n_types
-pos
];
1086 const TTCN_Typedescriptor_t BOOLEAN_descr_
={"BOOLEAN", &BOOLEAN_ber_
,
1087 &BOOLEAN_raw_
, &BOOLEAN_text_
, &BOOLEAN_xer_
, &BOOLEAN_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1089 const TTCN_Typedescriptor_t INTEGER_descr_
={"INTEGER", &INTEGER_ber_
,
1090 &INTEGER_raw_
, &INTEGER_text_
, &INTEGER_xer_
, &INTEGER_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1092 const TTCN_Typedescriptor_t FLOAT_descr_
={"REAL", &FLOAT_ber_
, &FLOAT_raw_
,
1093 NULL
, &FLOAT_xer_
, &FLOAT_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1095 const TTCN_Typedescriptor_t VERDICTTYPE_descr_
={"verdicttype", NULL
, NULL
,
1096 NULL
, &VERDICTTYPE_xer_
, &VERDICTTYPE_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1098 const TTCN_Typedescriptor_t OBJID_descr_
={"OBJECT IDENTIFIER", &OBJID_ber_
,
1099 NULL
, NULL
, &OBJID_xer_
, NULL
, TTCN_Typedescriptor_t::OBJID
};
1101 const TTCN_Typedescriptor_t BITSTRING_descr_
={"BIT STRING", &BITSTRING_ber_
,
1102 &BITSTRING_raw_
, NULL
, &BITSTRING_xer_
, &BITSTRING_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1104 const TTCN_Typedescriptor_t HEXSTRING_descr_
={"hexstring", NULL
,
1105 &HEXSTRING_raw_
, NULL
, &HEXSTRING_xer_
, &HEXSTRING_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1107 const TTCN_Typedescriptor_t OCTETSTRING_descr_
={"OCTET STRING",
1108 &OCTETSTRING_ber_
, &OCTETSTRING_raw_
, &OCTETSTRING_text_
, &OCTETSTRING_xer_
, &OCTETSTRING_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1110 const TTCN_Typedescriptor_t CHARSTRING_descr_
={"charstring", NULL
,
1111 &CHARSTRING_raw_
, &CHARSTRING_text_
, &CHARSTRING_xer_
, &CHARSTRING_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1113 const TTCN_Typedescriptor_t UNIVERSAL_CHARSTRING_descr_
={"universal charstring",
1114 NULL
, NULL
, NULL
, &UNIVERSAL_CHARSTRING_xer_
, &UNIVERSAL_CHARSTRING_json_
, TTCN_Typedescriptor_t::DONTCARE
};
1116 const TTCN_Typedescriptor_t COMPONENT_descr_
={"component", NULL
, NULL
, NULL
,
1117 NULL
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1119 const TTCN_Typedescriptor_t DEFAULT_descr_
={"default", NULL
, NULL
, NULL
,
1120 NULL
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1122 const TTCN_Typedescriptor_t ASN_NULL_descr_
={"NULL", &ASN_NULL_ber_
, NULL
,
1123 NULL
, &ASN_NULL_xer_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1125 const TTCN_Typedescriptor_t ASN_ANY_descr_
={"ANY", &ASN_ANY_ber_
, NULL
,
1126 NULL
, NULL
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1128 const TTCN_Typedescriptor_t EXTERNAL_descr_
={"EXTERNAL", &EXTERNAL_ber_
, NULL
,
1129 NULL
, &EXTERNAL_xer_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1131 const TTCN_Typedescriptor_t EMBEDDED_PDV_descr_
={"EMBEDDED PDV",
1132 &EMBEDDED_PDV_ber_
, NULL
, NULL
, &EMBEDDED_PDV_xer_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1134 const TTCN_Typedescriptor_t CHARACTER_STRING_descr_
={"CHARACTER STRING",
1135 &CHARACTER_STRING_ber_
, NULL
, NULL
, &CHARACTER_STRING_xer_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1137 const TTCN_Typedescriptor_t ObjectDescriptor_descr_
={"ObjectDescriptor",
1138 &ObjectDescriptor_ber_
, NULL
, NULL
, NULL
, NULL
, TTCN_Typedescriptor_t::GRAPHICSTRING
};
1140 const TTCN_Typedescriptor_t UTF8String_descr_
={"UTF8String", &UTF8String_ber_
,
1141 NULL
, NULL
, &UTF8String_xer_
, NULL
, TTCN_Typedescriptor_t::UTF8STRING
};
1143 const TTCN_Typedescriptor_t ASN_ROID_descr_
={"RELATIVE-OID", &ASN_ROID_ber_
,
1144 NULL
, NULL
, &ASN_ROID_xer_
, NULL
, TTCN_Typedescriptor_t::ROID
};
1146 const TTCN_Typedescriptor_t NumericString_descr_
={"NumericString",
1147 &NumericString_ber_
, NULL
, NULL
, &NumericString_xer_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1149 const TTCN_Typedescriptor_t PrintableString_descr_
={"PrintableString",
1150 &PrintableString_ber_
, NULL
, NULL
, &PrintableString_xer_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1152 const TTCN_Typedescriptor_t TeletexString_descr_
={"TeletexString",
1153 &TeletexString_ber_
, NULL
, NULL
, &TeletexString_xer_
, NULL
, TTCN_Typedescriptor_t::TELETEXSTRING
};
1154 const TTCN_Typedescriptor_t
& T61String_descr_
=TeletexString_descr_
;
1156 const TTCN_Typedescriptor_t VideotexString_descr_
={"VideotexString",
1157 &VideotexString_ber_
, NULL
, NULL
, &VideotexString_xer_
, NULL
, TTCN_Typedescriptor_t::VIDEOTEXSTRING
};
1159 const TTCN_Typedescriptor_t IA5String_descr_
={"IA5String", &IA5String_ber_
,
1160 NULL
, NULL
, &IA5String_xer_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1162 const TTCN_Typedescriptor_t ASN_GeneralizedTime_descr_
={"GeneralizedTime",
1163 &ASN_GeneralizedTime_ber_
, NULL
, NULL
, NULL
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1165 const TTCN_Typedescriptor_t ASN_UTCTime_descr_
={"UTCTime", &ASN_UTCTime_ber_
,
1166 NULL
, NULL
, NULL
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1168 const TTCN_Typedescriptor_t GraphicString_descr_
={"GraphicString",
1169 &GraphicString_ber_
, NULL
, NULL
, &GraphicString_xer_
, NULL
, TTCN_Typedescriptor_t::GRAPHICSTRING
};
1171 const TTCN_Typedescriptor_t VisibleString_descr_
={"VisibleString",
1172 &VisibleString_ber_
, NULL
, NULL
, &VisibleString_xer_
, NULL
, TTCN_Typedescriptor_t::DONTCARE
};
1173 const TTCN_Typedescriptor_t
& ISO646String_descr_
=VisibleString_descr_
;
1175 const TTCN_Typedescriptor_t GeneralString_descr_
={"GeneralString",
1176 &GeneralString_ber_
, NULL
, NULL
, &GeneralString_xer_
, NULL
, TTCN_Typedescriptor_t::GENERALSTRING
};
1178 const TTCN_Typedescriptor_t UniversalString_descr_
={"UniversalString",
1179 &UniversalString_ber_
, NULL
, NULL
, &UniversalString_xer_
, NULL
, TTCN_Typedescriptor_t::UNIVERSALSTRING
};
1181 const TTCN_Typedescriptor_t BMPString_descr_
={"BMPString", &BMPString_ber_
,
1182 NULL
, NULL
, &BMPString_xer_
, NULL
, TTCN_Typedescriptor_t::BMPSTRING
};