Commit | Line | Data |
---|---|---|
970ed795 EL |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Copyright (c) 2000-2014 Ericsson Telecom AB | |
3 | // All rights reserved. This program and the accompanying materials | |
4 | // are made available under the terms of the Eclipse Public License v1.0 | |
5 | // which accompanies this distribution, and is available at | |
6 | // http://www.eclipse.org/legal/epl-v10.html | |
7 | /////////////////////////////////////////////////////////////////////////////// | |
8 | #include "Basetype.hh" | |
9 | #include "../common/memory.h" | |
10 | #include "Logger.hh" | |
11 | #include "Error.hh" | |
12 | #include "BER.hh" | |
13 | #include "RAW.hh" | |
14 | #include "TEXT.hh" | |
15 | #include "XER.hh" | |
16 | #include "JSON.hh" | |
17 | #include "XmlReader.hh" | |
18 | #include "Module_list.hh" | |
19 | ||
20 | #include <openssl/bn.h> | |
21 | ||
22 | #include <stdarg.h> | |
23 | #include <string.h> | |
24 | #include <limits.h> | |
25 | // Note: RT2-only classes (Record_Type, Record_Of_Type) and Base_Type methods | |
26 | // are in core2/Basetype2.cc | |
27 | ||
28 | boolean Base_Type::ispresent() const | |
29 | { | |
30 | TTCN_error("Base_Type::ispresent(): calling ispresent() on a non-optional field."); | |
31 | return TRUE; | |
32 | } | |
33 | ||
34 | void Base_Type::log() const | |
35 | { | |
36 | TTCN_Logger::log_event_str("<logging of this type is not implemented>"); | |
37 | } | |
38 | ||
39 | void Base_Type::encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, | |
40 | TTCN_EncDec::coding_t p_coding, ...) const | |
41 | { | |
42 | va_list pvar; | |
43 | va_start(pvar, p_coding); | |
44 | switch(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); | |
52 | break;} | |
53 | case TTCN_EncDec::CT_RAW: { | |
54 | TTCN_EncDec_ErrorContext ec("While RAW-encoding type '%s': ", p_td.name); | |
55 | if(!p_td.raw) | |
56 | TTCN_EncDec_ErrorContext::error_internal | |
57 | ("No RAW descriptor available for type '%s'.", p_td.name); | |
58 | RAW_enc_tr_pos rp; | |
59 | rp.level=0; | |
60 | rp.pos=NULL; | |
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); | |
64 | break;} | |
65 | case TTCN_EncDec::CT_TEXT: { | |
66 | TTCN_EncDec_ErrorContext ec("While TEXT-encoding type '%s': ", p_td.name); | |
67 | if(!p_td.text) | |
68 | TTCN_EncDec_ErrorContext::error_internal | |
69 | ("No TEXT descriptor available for type '%s'.", p_td.name); | |
70 | TEXT_encode(p_td,p_buf); | |
71 | break;} | |
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); | |
78 | p_buf.put_c('\n'); | |
79 | break;} | |
80 | case TTCN_EncDec::CT_JSON: { | |
81 | TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name); | |
82 | if(!p_td.json) | |
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()); | |
88 | break;} | |
89 | default: | |
90 | TTCN_error("Unknown coding method requested to encode type '%s'", | |
91 | p_td.name); | |
92 | } | |
93 | va_end(pvar); | |
94 | } | |
95 | ||
96 | void Base_Type::decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf, | |
97 | TTCN_EncDec::coding_t p_coding, ...) | |
98 | { | |
99 | va_list pvar; | |
100 | va_start(pvar, p_coding); | |
101 | switch(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); | |
105 | ASN_BER_TLV_t tlv; | |
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()); | |
109 | break;} | |
110 | case TTCN_EncDec::CT_RAW: { | |
111 | TTCN_EncDec_ErrorContext ec("While RAW-decoding type '%s': ", p_td.name); | |
112 | if(!p_td.raw) | |
113 | TTCN_EncDec_ErrorContext::error_internal | |
114 | ("No RAW descriptor available for type '%s'.", p_td.name); | |
115 | raw_order_t order; | |
116 | switch(p_td.raw->top_bit_order) { | |
117 | case TOP_BIT_LEFT: | |
118 | order=ORDER_LSB; | |
119 | break; | |
120 | case TOP_BIT_RIGHT: | |
121 | default: | |
122 | order=ORDER_MSB; | |
123 | } | |
124 | RAW_decode(p_td, p_buf, p_buf.get_len()*8, order); | |
125 | break;} | |
126 | case TTCN_EncDec::CT_TEXT: { | |
127 | Limit_Token_List limit; | |
128 | TTCN_EncDec_ErrorContext ec("While TEXT-decoding type '%s': ", p_td.name); | |
129 | if(!p_td.text) | |
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); | |
136 | p_buf.rewind(); | |
137 | } | |
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" | |
142 | , p_td.name); | |
143 | break;} | |
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; | |
150 | } | |
151 | XER_decode(*(p_td.xer), reader, XER_coding); | |
152 | size_t bytes = reader.ByteConsumed(); | |
153 | p_buf.set_pos(bytes); | |
154 | break;} | |
155 | case TTCN_EncDec::CT_JSON: { | |
156 | TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name); | |
157 | if(!p_td.json) | |
158 | TTCN_EncDec_ErrorContext::error_internal | |
159 | ("No JSON descriptor available for type '%s'.", p_td.name); | |
160 | JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len()); | |
161 | if(JSON_decode(p_td, tok, false)<0) | |
162 | ec.error(TTCN_EncDec::ET_INCOMPL_MSG, | |
163 | "Can not decode type '%s', because invalid or incomplete" | |
164 | " message was received" | |
165 | , p_td.name); | |
166 | p_buf.set_pos(tok.get_buf_pos()); | |
167 | break;} | |
168 | default: | |
169 | TTCN_error("Unknown coding method requested to decode type '%s'", | |
170 | p_td.name); | |
171 | } | |
172 | va_end(pvar); | |
173 | } | |
174 | ||
175 | void Base_Type::BER_chk_descr(const TTCN_Typedescriptor_t& p_td) | |
176 | { | |
177 | if(!p_td.ber) | |
178 | TTCN_EncDec_ErrorContext::error_internal | |
179 | ("No BER descriptor available for type '%s'.", p_td.name); | |
180 | } | |
181 | ||
182 | void Base_Type::BER_encode_chk_coding(unsigned& p_coding) | |
183 | { | |
184 | switch(p_coding) { | |
185 | case BER_ENCODE_CER: | |
186 | case BER_ENCODE_DER: | |
187 | break; | |
188 | default: | |
189 | TTCN_warning("Unknown BER encoding requested; using DER."); | |
190 | p_coding=BER_ENCODE_DER; | |
191 | break; | |
192 | } | |
193 | } | |
194 | ||
195 | void Base_Type::XER_encode_chk_coding(unsigned& p_coding, | |
196 | const TTCN_Typedescriptor_t& p_td) | |
197 | { | |
198 | if (!p_td.xer) { | |
199 | TTCN_EncDec_ErrorContext::error_internal | |
200 | ("No XER descriptor available for type '%s'.", p_td.name); | |
201 | } | |
202 | switch (p_coding) { | |
203 | case XER_BASIC: | |
204 | case XER_CANONICAL: | |
205 | case XER_EXTENDED: | |
206 | case XER_EXTENDED | XER_CANONICAL: | |
207 | break; | |
208 | default: | |
209 | TTCN_warning("Unknown XER encoding requested; using Basic XER."); | |
210 | p_coding = XER_BASIC; | |
211 | break; | |
212 | } | |
213 | } | |
214 | ||
215 | static const cbyte empty_tag_end[4] = "/>\n"; | |
216 | ||
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 | |
220 | { | |
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 | |
226 | || (exer /*&& */ | |
227 | && ( (p_td.xer_bits & (UNTAGGED|ANY_ATTRIBUTES|ANY_ELEMENT)) | |
228 | || (flavor & (EMBED_VALUES|XER_LIST|ANY_ATTRIBUTES|USE_NIL|USE_TYPE_ATTR))))); | |
229 | ||
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); | |
236 | ||
237 | if (exer && (p_td.xer_bits & XER_ATTRIBUTE)) { | |
238 | begin_attribute(p_td, p_buf); | |
239 | } | |
240 | else if (!omit_tag) { // full tag | |
241 | if (indenting) do_indent(p_buf, indent); | |
242 | p_buf.put_c('<'); | |
243 | if (exer) write_ns_prefix(p_td, p_buf); | |
244 | ||
245 | const namespace_t *ns_info = NULL; | |
246 | bool namespaces_needed = false; | |
247 | if (exer) { | |
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); | |
250 | } | |
251 | ||
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)) | |
256 | ); | |
257 | } | |
258 | ||
259 | size_t num_collected = 0; | |
260 | char **collected_ns = NULL; | |
261 | bool def_ns = false; | |
262 | if (namespaces_needed) { | |
263 | collected_ns = (this->*collector)(p_td, num_collected, def_ns); | |
264 | } | |
265 | ||
266 | p_buf.put_s((size_t)p_td.namelens[exer] - 2, (cbyte*)p_td.names[exer]); | |
267 | ||
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 | |
272 | } | |
273 | Free(collected_ns); | |
274 | } | |
275 | ||
276 | if (empty_ns_hack) { | |
277 | p_buf.put_s(9, (cbyte*)" xmlns=''"); | |
278 | flavor &= ~DEF_NS_PRESENT; | |
279 | flavor |= DEF_NS_SQUASHED; | |
280 | } | |
281 | else if (def_ns) { | |
282 | flavor &= ~DEF_NS_SQUASHED; | |
283 | flavor |= DEF_NS_PRESENT; | |
284 | } | |
285 | ||
286 | if (type_atr) { | |
287 | p_buf.put_s(mstrlen(const_cast<char*>(type_atr)), (cbyte*)type_atr); | |
288 | } | |
289 | // now close the tag | |
290 | if (empty) { | |
291 | p_buf.put_s(2 + indenting, empty_tag_end); | |
292 | } | |
293 | else { | |
294 | p_buf.put_s( | |
295 | 1 + (indenting | |
296 | && !(flavor & SIMPLE_TYPE) | |
297 | && !(exer && (p_td.xer_bits & (XER_LIST|USE_TYPE_ATTR)))), | |
298 | empty_tag_end+1); | |
299 | } | |
300 | } | |
301 | else { // tag is omitted | |
302 | // If the outer XML element optimistically wrote a newline after its start tag, | |
303 | // back up over it. | |
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 | |
309 | } | |
310 | } | |
311 | ||
312 | Free(const_cast<char*>(type_atr)); | |
313 | ||
314 | return omit_tag; | |
315 | } | |
316 | ||
317 | void Base_Type::end_xml (const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, | |
318 | unsigned int flavor, int indent, bool empty) const | |
319 | { | |
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 | |
325 | || (exer /*&& */ | |
326 | && ( (p_td.xer_bits & (UNTAGGED|ANY_ATTRIBUTES|ANY_ELEMENT)) | |
327 | || (flavor & (EMBED_VALUES|XER_LIST|ANY_ATTRIBUTES|USE_NIL|USE_TYPE_ATTR))))); | |
328 | ||
329 | if (exer && (p_td.xer_bits & XER_ATTRIBUTE)) { | |
330 | p_buf.put_c('\''); | |
331 | } | |
332 | else if (!empty && !omit_tag) { | |
333 | // now close the 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]); | |
338 | } | |
339 | ||
340 | } | |
341 | ||
342 | ||
343 | ASN_BER_TLV_t* Base_Type::BER_encode_chk_bound(boolean p_isbound) | |
344 | { | |
345 | if(!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); | |
349 | new_tlv->Tlen=0; | |
350 | new_tlv->Tstr=NULL; | |
351 | new_tlv->Llen=0; | |
352 | new_tlv->Lstr=NULL; | |
353 | return new_tlv; | |
354 | } | |
355 | else return NULL; | |
356 | } | |
357 | ||
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) | |
363 | { | |
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); | |
369 | } | |
370 | ||
371 | ASN_BER_TLV_t* Base_Type::BER_encode_TLV_OCTETSTRING | |
372 | (unsigned p_coding, | |
373 | int p_nof_octets, const unsigned char *p_octets_ptr) | |
374 | { | |
375 | unsigned char *V_ptr; | |
376 | size_t V_len; | |
377 | unsigned int nof_fragments=0; | |
378 | ||
379 | if(p_coding==BER_ENCODE_CER) { | |
380 | nof_fragments=(p_nof_octets+999)/1000; | |
381 | if(!nof_fragments) nof_fragments=1; | |
382 | } | |
383 | else /*if(coding==BER_ENCODE_DER)*/ { | |
384 | nof_fragments=1; | |
385 | } | |
386 | ||
387 | ASN_BER_TLV_t *new_tlv=NULL; | |
388 | boolean is_constructed=nof_fragments>1; | |
389 | if(!is_constructed) { | |
390 | V_len=p_nof_octets; | |
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); | |
395 | } | |
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; | |
400 | V_len=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); | |
409 | } | |
410 | } | |
411 | return new_tlv; | |
412 | } | |
413 | ||
414 | /* | |
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); | |
420 | ||
421 | std::string result; | |
422 | for (int i = 0; i < bytes; ++i) { | |
423 | result.append(char_as_bin(bn_as_bin[i])); | |
424 | result.append(" "); | |
425 | } | |
426 | Free(bn_as_bin); | |
427 | return result; | |
428 | } | |
429 | ||
430 | static std::string int_as_bin(int myInt) { | |
431 | std::string result; | |
432 | for (int i = sizeof(myInt) - 1; i >= 0; --i) { | |
433 | char current = (myInt >> (i * 8)) & 0xFF; | |
434 | result.append(char_as_bin(current)); | |
435 | } | |
436 | return result; | |
437 | } | |
438 | ||
439 | static std::string char_as_bin(unsigned char ch) { | |
440 | std::string result; | |
441 | for (int i = 0; i < 8; ++i) { | |
442 | result.append((ch & 0x80) == 0x80 ? "1" : "0"); | |
443 | ch <<= 1; | |
444 | } | |
445 | return result; | |
446 | } | |
447 | ||
448 | static std::string chars_as_bin(const unsigned char* const chars, int len) { | |
449 | std::string result; | |
450 | for (int i = 0; i < len; ++i) { | |
451 | result.append(char_as_bin(chars[i])); | |
452 | if (i != len - 1) { | |
453 | result.append(" "); | |
454 | } | |
455 | } | |
456 | return result; | |
457 | } | |
458 | */ | |
459 | ||
460 | ASN_BER_TLV_t *Base_Type::BER_encode_TLV_INTEGER(unsigned, | |
461 | const int_val_t& p_int_val) | |
462 | { | |
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); | |
469 | size_t V_len=1; | |
470 | ulong_val>>=7; | |
471 | while(ulong_val!=0){ | |
472 | V_len++; | |
473 | ulong_val>>=8; | |
474 | } | |
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; | |
480 | ulong_val>>=8; | |
481 | } | |
482 | return new_tlv; | |
483 | } | |
484 | ||
485 | // bignum | |
486 | ||
487 | const BIGNUM* const D = p_int_val.get_val_openssl(); | |
488 | if (BN_is_zero(D)) { | |
489 | ASN_BER_TLV_t *new_tlv=ASN_BER_TLV_t::construct(1,NULL); | |
490 | new_tlv->V.str.Vstr[0] = 0; | |
491 | return new_tlv; | |
492 | } | |
493 | ||
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); | |
497 | ||
498 | bool pad = false; | |
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]; | |
502 | } | |
503 | ||
504 | // add one | |
505 | bool stop = false; | |
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; | |
511 | stop = true; | |
512 | } else { | |
513 | bn_as_bin[i] ^= mask; | |
514 | } | |
515 | } | |
516 | } | |
517 | pad = !(bn_as_bin[0] & 0x80); | |
518 | } else { | |
519 | pad = bn_as_bin[0] & 0x80; | |
520 | } | |
521 | ||
522 | ASN_BER_TLV_t* new_tlv = ASN_BER_TLV_t::construct(num_bytes + pad, NULL); | |
523 | if (pad) { | |
524 | new_tlv->V.str.Vstr[0] = BN_is_negative(D) ? 0xFF : 0x0; | |
525 | } | |
526 | ||
527 | memcpy(new_tlv->V.str.Vstr + pad, bn_as_bin, num_bytes); | |
528 | ||
529 | Free(bn_as_bin); | |
530 | return new_tlv; | |
531 | } | |
532 | ||
533 | ASN_BER_TLV_t *Base_Type::BER_encode_TLV_INTEGER(unsigned p_coding, | |
534 | const int& p_int_val) | |
535 | { | |
536 | int_val_t p_int_val_val(p_int_val); | |
537 | return BER_encode_TLV_INTEGER(p_coding, p_int_val_val); | |
538 | } | |
539 | ||
540 | void Base_Type::BER_encode_chk_enum_valid(const TTCN_Typedescriptor_t& p_td, | |
541 | boolean p_isvalid, int p_value) | |
542 | { | |
543 | if(!p_isvalid) | |
544 | TTCN_EncDec_ErrorContext::error | |
545 | (TTCN_EncDec::ET_ENC_ENUM, | |
546 | "Encoding unknown value '%d' for enumerated type '%s'.", | |
547 | p_value, p_td.name); | |
548 | ||
549 | } | |
550 | ||
551 | void Base_Type::BER_decode_str2TLV(TTCN_Buffer& p_buf, ASN_BER_TLV_t& p_tlv, | |
552 | unsigned L_form) | |
553 | { | |
554 | if(!ASN_BER_str2TLV(p_buf.get_read_len(), p_buf.get_read_data(), | |
555 | p_tlv, L_form)) | |
556 | TTCN_EncDec_ErrorContext::error | |
557 | (TTCN_EncDec::ET_INCOMPL_MSG, "TLV is not complete."); | |
558 | } | |
559 | ||
560 | boolean Base_Type::BER_decode_constdTLV_next(const ASN_BER_TLV_t& p_tlv, | |
561 | size_t& V_pos, | |
562 | unsigned L_form, | |
563 | ASN_BER_TLV_t& p_target_tlv) | |
564 | { | |
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."); | |
571 | return FALSE; | |
572 | } | |
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."); | |
578 | } | |
579 | if(!p_tlv.isLenDefinite && p_target_tlv.tagnumber==0 | |
580 | && p_target_tlv.tagclass==ASN_TAG_UNIV) | |
581 | return FALSE; | |
582 | V_pos+=p_target_tlv.get_len(); | |
583 | return TRUE; | |
584 | } | |
585 | ||
586 | void Base_Type::BER_decode_constdTLV_end(const ASN_BER_TLV_t& p_tlv, | |
587 | size_t& V_pos, | |
588 | unsigned L_form, | |
589 | ASN_BER_TLV_t& p_target_tlv, | |
590 | boolean tlv_present) | |
591 | { | |
592 | if(tlv_present | |
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."); | |
597 | } | |
598 | } | |
599 | ||
600 | static void BER_decode_chk_tag(const ASN_Tag_t& tag, | |
601 | const ASN_BER_TLV_t& tlv) | |
602 | { | |
603 | if (tlv.isTagComplete && | |
604 | (tag.tagclass != tlv.tagclass || tag.tagnumber != tlv.tagnumber)) { | |
605 | ASN_Tag_t rcvdtag; | |
606 | rcvdtag.tagclass=tlv.tagclass; | |
607 | rcvdtag.tagnumber=tlv.tagnumber; | |
608 | char *rcvdstr=rcvdtag.print(); | |
609 | try { | |
610 | TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG, | |
611 | "Tag mismatch: Received: %s.", rcvdstr); | |
612 | } catch (...) { | |
613 | Free(rcvdstr); | |
614 | throw; | |
615 | } | |
616 | Free(rcvdstr); | |
617 | } | |
618 | } | |
619 | ||
620 | void Base_Type::BER_decode_strip_tags(const ASN_BERdescriptor_t& p_ber, | |
621 | const ASN_BER_TLV_t& p_tlv, | |
622 | unsigned L_form, | |
623 | ASN_BER_TLV_t& stripped_tlv) | |
624 | { | |
625 | size_t i=p_ber.n_tags; | |
626 | if(i==0) { | |
627 | stripped_tlv=p_tlv; | |
628 | return; | |
629 | } | |
630 | char *expectedstr=p_ber.print_tags(); | |
631 | TTCN_EncDec_ErrorContext ec("While checking tags (expecting %s): ", | |
632 | expectedstr); | |
633 | Free(expectedstr); | |
634 | if(i==1) { | |
635 | BER_decode_chk_tag(p_ber.tags[0], p_tlv); | |
636 | stripped_tlv=p_tlv; | |
637 | return; | |
638 | } | |
639 | ASN_BER_TLV_t curr_tlv=p_tlv; | |
640 | boolean doit=TRUE; | |
641 | i--; | |
642 | while(doit) { | |
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); | |
650 | doit=FALSE; | |
651 | stripped_tlv=curr_tlv; | |
652 | } | |
653 | else { // O.K., is constructed | |
654 | size_t V_pos=0; | |
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, | |
659 | FALSE); | |
660 | curr_tlv=stripped_tlv; | |
661 | i--; | |
662 | } // is constructed | |
663 | } // not the innermost | |
664 | else { // innermost tag | |
665 | doit=FALSE; | |
666 | } | |
667 | } // while doit | |
668 | } | |
669 | ||
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) | |
674 | { | |
675 | p_nof_octets=octetnum_start+s_len; | |
676 | memcpy(&p_octets_ptr[octetnum_start], source, s_len); | |
677 | octetnum_start+=s_len; | |
678 | } | |
679 | ||
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) | |
684 | { | |
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); | |
689 | } | |
690 | else { // is constructed | |
691 | ASN_BER_TLV_t tlv2; | |
692 | size_t V_pos=0; | |
693 | boolean doit=TRUE; | |
694 | while(doit) { | |
695 | if(!ASN_BER_str2TLV(p_tlv.V.str.Vlen-V_pos, p_tlv.V.str.Vstr+V_pos, | |
696 | tlv2, L_form)) { | |
697 | TTCN_EncDec_ErrorContext::error | |
698 | (TTCN_EncDec::ET_INCOMPL_MSG, | |
699 | "Incomplete TLV in a constructed OCTETSTRING TLV."); | |
700 | return; | |
701 | } | |
702 | if(!p_tlv.isLenDefinite && tlv2.tagnumber==0 | |
703 | && tlv2.tagclass==ASN_TAG_UNIV) | |
704 | doit=FALSE; // End-of-contents | |
705 | if(doit) { | |
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; | |
712 | } | |
713 | } // while(doit) | |
714 | } // else / is constructed | |
715 | } | |
716 | ||
717 | ||
718 | ||
719 | boolean Base_Type::BER_decode_TLV_INTEGER(const ASN_BER_TLV_t& p_tlv, | |
720 | unsigned, int_val_t& p_int_val) | |
721 | { | |
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."); | |
727 | return FALSE; | |
728 | } | |
729 | ||
730 | const size_t Vlen = p_tlv.V.str.Vlen; | |
731 | ||
732 | if (Vlen > sizeof(RInt)) { // Bignum | |
733 | ||
734 | const bool negative = p_tlv.V.str.Vstr[0] & 0x80; | |
735 | BIGNUM *D = BN_new(); | |
736 | ||
737 | if (negative) { | |
738 | unsigned char* const Vstr = (unsigned char*) Malloc(Vlen); | |
739 | memcpy(Vstr, p_tlv.V.str.Vstr, Vlen); | |
740 | // -1 | |
741 | bool stop = false; | |
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) { | |
746 | Vstr[i] ^= mask; | |
747 | stop = true; | |
748 | } else { | |
749 | Vstr[i] |= mask; | |
750 | } | |
751 | } | |
752 | } | |
753 | ||
754 | for (size_t i = 0; i < Vlen; ++i) { | |
755 | Vstr[i] = ~Vstr[i]; | |
756 | } | |
757 | ||
758 | BN_bin2bn(Vstr, Vlen, D); | |
759 | Free(Vstr); | |
760 | } else { // positive case | |
761 | BN_bin2bn(p_tlv.V.str.Vstr, Vlen, D); | |
762 | } | |
763 | ||
764 | BN_set_negative(D, negative); | |
765 | p_int_val = int_val_t(D); | |
766 | return TRUE; | |
767 | } // bignum | |
768 | ||
769 | // Native int Vlen <= sizeof(RInt) | |
770 | const unsigned char* const Vstr = p_tlv.V.str.Vstr; | |
771 | RInt int_val = 0; | |
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 ] | |
778 | ||
779 | for (size_t i = 0; i < sizeof(RInt) - Vlen; ++i) { | |
780 | int_val |= 0xFF; | |
781 | int_val <<= 8; | |
782 | } | |
783 | } | |
784 | ||
785 | int_val |= p_tlv.V.str.Vstr[0]; | |
786 | for (size_t i = 1; i < Vlen; ++i) { | |
787 | int_val <<= 8; | |
788 | int_val |= p_tlv.V.str.Vstr[i]; | |
789 | } | |
790 | ||
791 | p_int_val = int_val_t(int_val); | |
792 | return TRUE; | |
793 | } | |
794 | ||
795 | boolean Base_Type::BER_decode_TLV_INTEGER(const ASN_BER_TLV_t& p_tlv, | |
796 | unsigned L_form, int& p_int_val) | |
797 | { | |
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(); | |
802 | } else { | |
803 | TTCN_warning("Large integer value was decoded and it can't be returned " | |
804 | "as a native `int'"); | |
805 | } | |
806 | return ret_val; | |
807 | } | |
808 | ||
809 | /* | |
810 | ||
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. :) | |
815 | ||
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) | |
819 | { | |
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); | |
826 | return; | |
827 | } | |
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++) { | |
830 | p_intval=tmp_int; | |
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]); | |
834 | } | |
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; | |
841 | } | |
842 | p_intval=static_cast<int_type>(tmp_int-highbit); | |
843 | } | |
844 | else { // positive | |
845 | p_intval=tmp_int; | |
846 | } | |
847 | if(overflow_flag) | |
848 | TTCN_EncDec_ErrorContext::error | |
849 | (TTCN_EncDec::ET_REPR, | |
850 | "Value is too big (%lu octets).", p_tlv.V.str.Vlen); | |
851 | } | |
852 | ||
853 | */ | |
854 | ||
855 | boolean Base_Type::BER_decode_TLV_CHOICE(const ASN_BERdescriptor_t& p_ber, | |
856 | const ASN_BER_TLV_t& p_tlv, | |
857 | unsigned L_form, | |
858 | ASN_BER_TLV_t& p_target_tlv) | |
859 | { | |
860 | if(p_ber.n_tags>0) { | |
861 | size_t V_pos=0; | |
862 | p_tlv.chk_constructed_flag(TRUE); | |
863 | if(!BER_decode_constdTLV_next(p_tlv, V_pos, L_form, p_target_tlv)) | |
864 | return FALSE; | |
865 | } | |
866 | else p_target_tlv=p_tlv; | |
867 | return TRUE; | |
868 | } | |
869 | ||
870 | boolean Base_Type::BER_decode_CHOICE_selection(boolean select_result, | |
871 | const ASN_BER_TLV_t& p_tlv) | |
872 | { | |
873 | if(select_result) return TRUE; | |
874 | ASN_Tag_t rcvd_tag; | |
875 | rcvd_tag.tagclass=p_tlv.tagclass; | |
876 | rcvd_tag.tagnumber=p_tlv.tagnumber; | |
877 | char *rcvd_str=rcvd_tag.print(); | |
878 | try { | |
879 | TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG, | |
880 | "Invalid tag or unknown alternative: %s.", rcvd_str); | |
881 | } catch (...) { | |
882 | Free(rcvd_str); | |
883 | throw; | |
884 | } | |
885 | Free(rcvd_str); | |
886 | return FALSE; | |
887 | } | |
888 | ||
889 | void Base_Type::BER_decode_chk_enum_valid(const TTCN_Typedescriptor_t& p_td, | |
890 | boolean p_isvalid, int p_value) | |
891 | { | |
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. */ | |
895 | if(!p_isvalid) | |
896 | TTCN_EncDec_ErrorContext::error | |
897 | (TTCN_EncDec::ET_DEC_ENUM, | |
898 | "Unknown value '%d' received for enumerated type '%s'.", | |
899 | p_value, p_td.name); | |
900 | } | |
901 | ||
902 | ASN_BER_TLV_t* | |
903 | Base_Type::BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, | |
904 | unsigned) const | |
905 | { | |
906 | BER_chk_descr(p_td); | |
907 | ASN_BER_TLV_t *tlv=BER_encode_chk_bound(TRUE); | |
908 | if(tlv) return tlv; | |
909 | TTCN_EncDec_ErrorContext::error_internal | |
910 | ("BER_encode_V() not implemented for type '%s'.", p_td.name); | |
911 | return NULL; | |
912 | } | |
913 | ||
914 | boolean Base_Type::BER_decode_isMyMsg(const TTCN_Typedescriptor_t& p_td, | |
915 | const ASN_BER_TLV_t& p_tlv) | |
916 | { | |
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); | |
920 | } | |
921 | ||
922 | boolean Base_Type::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, | |
923 | const ASN_BER_TLV_t& p_tlv, | |
924 | unsigned L_form) | |
925 | { | |
926 | BER_chk_descr(p_td); | |
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; | |
930 | ec.error_internal | |
931 | ("BER_decode_V() not implemented for type '%s'.", p_td.name); | |
932 | return FALSE; | |
933 | } | |
934 | ||
935 | int Base_Type::RAW_encode(const TTCN_Typedescriptor_t& p_td, | |
936 | RAW_enc_tree&) const | |
937 | { | |
938 | TTCN_error("RAW encoding requested for type '%s'" | |
939 | " which has no RAW encoding method.", p_td.name); | |
940 | return 0; | |
941 | } | |
942 | ||
943 | int Base_Type::TEXT_encode(const TTCN_Typedescriptor_t& p_td, | |
944 | TTCN_Buffer&) const | |
945 | { | |
946 | TTCN_error("TEXT encoding requested for type '%s'" | |
947 | " which has no TEXT encoding method.", p_td.name); | |
948 | return 0; | |
949 | } | |
950 | ||
951 | int Base_Type::TEXT_decode(const TTCN_Typedescriptor_t& p_td, | |
952 | TTCN_Buffer&, Limit_Token_List&, boolean, boolean) | |
953 | { | |
954 | TTCN_error("TEXT decoding requested for type '%s'" | |
955 | " which has no TEXT decoding method.", p_td.name); | |
956 | return 0; | |
957 | } | |
958 | ||
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 */ ) | |
962 | { | |
963 | TTCN_error("RAW decoding requested for type '%s'" | |
964 | " which has no RAW decoding method.",p_td.name); | |
965 | return 0; | |
966 | } | |
967 | ||
968 | int Base_Type::XER_encode(const XERdescriptor_t& p_td, | |
969 | TTCN_Buffer&, unsigned int, int) const | |
970 | { | |
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]); | |
973 | return 0; | |
974 | } | |
975 | ||
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]); | |
979 | return 0; | |
980 | } | |
981 | ||
982 | int Base_Type::JSON_encode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer&) const | |
983 | { | |
984 | TTCN_error("JSON encoding requested for type '%s' which has no" | |
985 | " JSON encoding method.", p_td.name); | |
986 | return 0; | |
987 | } | |
988 | ||
989 | int Base_Type::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer&, boolean) | |
990 | { | |
991 | TTCN_error("JSON decoding requested for type '%s' which has no" | |
992 | " JSON decoding method.", p_td.name); | |
993 | return 0; | |
994 | } | |
995 | ||
996 | boolean Base_Type::can_start(const char *name, const char *uri, | |
997 | XERdescriptor_t const& xd, unsigned int flavor) | |
998 | { | |
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)); | |
1002 | } | |
1003 | ||
1004 | char ** Base_Type::collect_ns(const XERdescriptor_t& p_td, size_t& num, bool& def_ns) const | |
1005 | { | |
1006 | def_ns = false; | |
1007 | char *tmp = NULL; | |
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, | |
1014 | my_ns->ns | |
1015 | ); | |
1016 | } | |
1017 | // The above may throw, but then nothing was allocated. | |
1018 | if (tmp != NULL) { | |
1019 | num = 1; | |
1020 | char **retval = (char**)Malloc(sizeof(char*)); | |
1021 | *retval = tmp; | |
1022 | return retval; | |
1023 | } | |
1024 | else { | |
1025 | num = 0; | |
1026 | return NULL; | |
1027 | } | |
1028 | } | |
1029 | ||
1030 | void Base_Type::merge_ns(char **&collected_ns, size_t& num_collected, | |
1031 | char **new_namespaces, size_t num_new) | |
1032 | { | |
1033 | ||
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])) { | |
1037 | // same, drop it | |
1038 | Free(new_namespaces[cur_ns]); | |
1039 | new_namespaces[cur_ns] = NULL; | |
1040 | break; | |
1041 | } | |
1042 | } | |
1043 | ||
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]; | |
1047 | } | |
1048 | } | |
1049 | Free(new_namespaces); | |
1050 | new_namespaces = 0; | |
1051 | } | |
1052 | ||
1053 | ///////////////////////////////////////////////////////////// | |
1054 | ||
1055 | TTCN_Type_list::~TTCN_Type_list() | |
1056 | { | |
1057 | Free(types); | |
1058 | } | |
1059 | ||
1060 | void TTCN_Type_list::push(const Base_Type *p_type) | |
1061 | { | |
1062 | types=(const Base_Type**)Realloc(types, ++n_types*sizeof(*types)); | |
1063 | types[n_types-1]=p_type; | |
1064 | } | |
1065 | ||
1066 | const Base_Type* TTCN_Type_list::pop() | |
1067 | { | |
1068 | if(!n_types) | |
1069 | TTCN_EncDec_ErrorContext::error_internal | |
1070 | ("TTCN_Type_list::pop(): List is empty."); | |
1071 | const Base_Type *t; | |
1072 | t=types[--n_types]; | |
1073 | types=(const Base_Type**)Realloc(types, n_types*sizeof(*types)); | |
1074 | return t; | |
1075 | } | |
1076 | ||
1077 | const Base_Type* TTCN_Type_list::get_nth(size_t pos) const | |
1078 | { | |
1079 | if(pos==0) return types[0]; | |
1080 | if(pos>n_types) | |
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]; | |
1084 | } | |
1085 | ||
1086 | const TTCN_Typedescriptor_t BOOLEAN_descr_={"BOOLEAN", &BOOLEAN_ber_, | |
1087 | &BOOLEAN_raw_, &BOOLEAN_text_, &BOOLEAN_xer_, &BOOLEAN_json_, TTCN_Typedescriptor_t::DONTCARE}; | |
1088 | ||
1089 | const TTCN_Typedescriptor_t INTEGER_descr_={"INTEGER", &INTEGER_ber_, | |
1090 | &INTEGER_raw_, &INTEGER_text_, &INTEGER_xer_, &INTEGER_json_, TTCN_Typedescriptor_t::DONTCARE}; | |
1091 | ||
1092 | const TTCN_Typedescriptor_t FLOAT_descr_={"REAL", &FLOAT_ber_, &FLOAT_raw_, | |
1093 | NULL, &FLOAT_xer_, &FLOAT_json_, TTCN_Typedescriptor_t::DONTCARE}; | |
1094 | ||
1095 | const TTCN_Typedescriptor_t VERDICTTYPE_descr_={"verdicttype", NULL, NULL, | |
1096 | NULL, &VERDICTTYPE_xer_, &VERDICTTYPE_json_, TTCN_Typedescriptor_t::DONTCARE}; | |
1097 | ||
1098 | const TTCN_Typedescriptor_t OBJID_descr_={"OBJECT IDENTIFIER", &OBJID_ber_, | |
1099 | NULL, NULL, &OBJID_xer_, NULL, TTCN_Typedescriptor_t::OBJID}; | |
1100 | ||
1101 | const TTCN_Typedescriptor_t BITSTRING_descr_={"BIT STRING", &BITSTRING_ber_, | |
1102 | &BITSTRING_raw_, NULL, &BITSTRING_xer_, &BITSTRING_json_, TTCN_Typedescriptor_t::DONTCARE}; | |
1103 | ||
1104 | const TTCN_Typedescriptor_t HEXSTRING_descr_={"hexstring", NULL, | |
1105 | &HEXSTRING_raw_, NULL, &HEXSTRING_xer_, &HEXSTRING_json_, TTCN_Typedescriptor_t::DONTCARE}; | |
1106 | ||
1107 | const TTCN_Typedescriptor_t OCTETSTRING_descr_={"OCTET STRING", | |
1108 | &OCTETSTRING_ber_, &OCTETSTRING_raw_, &OCTETSTRING_text_, &OCTETSTRING_xer_, &OCTETSTRING_json_, TTCN_Typedescriptor_t::DONTCARE}; | |
1109 | ||
1110 | const TTCN_Typedescriptor_t CHARSTRING_descr_={"charstring", NULL, | |
1111 | &CHARSTRING_raw_, &CHARSTRING_text_, &CHARSTRING_xer_, &CHARSTRING_json_, TTCN_Typedescriptor_t::DONTCARE}; | |
1112 | ||
1113 | const TTCN_Typedescriptor_t UNIVERSAL_CHARSTRING_descr_={"universal charstring", | |
1114 | NULL, NULL, NULL, &UNIVERSAL_CHARSTRING_xer_, &UNIVERSAL_CHARSTRING_json_, TTCN_Typedescriptor_t::DONTCARE}; | |
1115 | ||
1116 | const TTCN_Typedescriptor_t COMPONENT_descr_={"component", NULL, NULL, NULL, | |
1117 | NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; | |
1118 | ||
1119 | const TTCN_Typedescriptor_t DEFAULT_descr_={"default", NULL, NULL, NULL, | |
1120 | NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; | |
1121 | ||
1122 | const TTCN_Typedescriptor_t ASN_NULL_descr_={"NULL", &ASN_NULL_ber_, NULL, | |
1123 | NULL, &ASN_NULL_xer_, NULL, TTCN_Typedescriptor_t::DONTCARE}; | |
1124 | ||
1125 | const TTCN_Typedescriptor_t ASN_ANY_descr_={"ANY", &ASN_ANY_ber_, NULL, | |
1126 | NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; | |
1127 | ||
1128 | const TTCN_Typedescriptor_t EXTERNAL_descr_={"EXTERNAL", &EXTERNAL_ber_, NULL, | |
1129 | NULL, &EXTERNAL_xer_, NULL, TTCN_Typedescriptor_t::DONTCARE}; | |
1130 | ||
1131 | const TTCN_Typedescriptor_t EMBEDDED_PDV_descr_={"EMBEDDED PDV", | |
1132 | &EMBEDDED_PDV_ber_, NULL, NULL, &EMBEDDED_PDV_xer_, NULL, TTCN_Typedescriptor_t::DONTCARE}; | |
1133 | ||
1134 | const TTCN_Typedescriptor_t CHARACTER_STRING_descr_={"CHARACTER STRING", | |
1135 | &CHARACTER_STRING_ber_, NULL, NULL, &CHARACTER_STRING_xer_, NULL, TTCN_Typedescriptor_t::DONTCARE}; | |
1136 | ||
1137 | const TTCN_Typedescriptor_t ObjectDescriptor_descr_={"ObjectDescriptor", | |
1138 | &ObjectDescriptor_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::GRAPHICSTRING}; | |
1139 | ||
1140 | const TTCN_Typedescriptor_t UTF8String_descr_={"UTF8String", &UTF8String_ber_, | |
1141 | NULL, NULL, &UTF8String_xer_, NULL, TTCN_Typedescriptor_t::UTF8STRING}; | |
1142 | ||
1143 | const TTCN_Typedescriptor_t ASN_ROID_descr_={"RELATIVE-OID", &ASN_ROID_ber_, | |
1144 | NULL, NULL, &ASN_ROID_xer_, NULL, TTCN_Typedescriptor_t::ROID}; | |
1145 | ||
1146 | const TTCN_Typedescriptor_t NumericString_descr_={"NumericString", | |
1147 | &NumericString_ber_, NULL, NULL, &NumericString_xer_, NULL, TTCN_Typedescriptor_t::DONTCARE}; | |
1148 | ||
1149 | const TTCN_Typedescriptor_t PrintableString_descr_={"PrintableString", | |
1150 | &PrintableString_ber_, NULL, NULL, &PrintableString_xer_, NULL, TTCN_Typedescriptor_t::DONTCARE}; | |
1151 | ||
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_; | |
1155 | ||
1156 | const TTCN_Typedescriptor_t VideotexString_descr_={"VideotexString", | |
1157 | &VideotexString_ber_, NULL, NULL, &VideotexString_xer_, NULL, TTCN_Typedescriptor_t::VIDEOTEXSTRING}; | |
1158 | ||
1159 | const TTCN_Typedescriptor_t IA5String_descr_={"IA5String", &IA5String_ber_, | |
1160 | NULL, NULL, &IA5String_xer_, NULL, TTCN_Typedescriptor_t::DONTCARE}; | |
1161 | ||
1162 | const TTCN_Typedescriptor_t ASN_GeneralizedTime_descr_={"GeneralizedTime", | |
1163 | &ASN_GeneralizedTime_ber_, NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; | |
1164 | ||
1165 | const TTCN_Typedescriptor_t ASN_UTCTime_descr_={"UTCTime", &ASN_UTCTime_ber_, | |
1166 | NULL, NULL, NULL, NULL, TTCN_Typedescriptor_t::DONTCARE}; | |
1167 | ||
1168 | const TTCN_Typedescriptor_t GraphicString_descr_={"GraphicString", | |
1169 | &GraphicString_ber_, NULL, NULL, &GraphicString_xer_, NULL, TTCN_Typedescriptor_t::GRAPHICSTRING}; | |
1170 | ||
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_; | |
1174 | ||
1175 | const TTCN_Typedescriptor_t GeneralString_descr_={"GeneralString", | |
1176 | &GeneralString_ber_, NULL, NULL, &GeneralString_xer_, NULL, TTCN_Typedescriptor_t::GENERALSTRING}; | |
1177 | ||
1178 | const TTCN_Typedescriptor_t UniversalString_descr_={"UniversalString", | |
1179 | &UniversalString_ber_, NULL, NULL, &UniversalString_xer_, NULL, TTCN_Typedescriptor_t::UNIVERSALSTRING}; | |
1180 | ||
1181 | const TTCN_Typedescriptor_t BMPString_descr_={"BMPString", &BMPString_ber_, | |
1182 | NULL, NULL, &BMPString_xer_, NULL, TTCN_Typedescriptor_t::BMPSTRING}; | |
1183 | ||
1184 |