Commit | Line | Data |
---|---|---|
d44e3c4f | 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 | |
7 | * | |
8 | * Contributors: | |
9 | * Balasko, Jeno | |
10 | * Baranyi, Botond | |
11 | * Forstner, Matyas | |
12 | * Szabados, Kristof | |
13 | * Szabo, Janos Zoltan – initial implementation | |
14 | * Szalai, Gabor | |
15 | * | |
16 | ******************************************************************************/ | |
970ed795 EL |
17 | #include "ASN_Any.hh" |
18 | #include "String_struct.hh" | |
19 | #include <string.h> | |
20 | #include "../common/memory.h" | |
21 | ||
22 | void ASN_ANY::encode(const TTCN_Typedescriptor_t& p_td, | |
23 | TTCN_Buffer& p_buf, | |
24 | TTCN_EncDec::coding_t p_coding, ...) const | |
25 | { | |
26 | va_list pvar; | |
27 | va_start(pvar, p_coding); | |
28 | switch(p_coding) { | |
29 | case TTCN_EncDec::CT_BER: { | |
30 | TTCN_EncDec_ErrorContext ec("While BER-encoding type '%s': ", p_td.name); | |
31 | unsigned BER_coding=va_arg(pvar, unsigned); | |
32 | BER_encode_chk_coding(BER_coding); | |
33 | ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding); | |
34 | tlv->put_in_buffer(p_buf); | |
35 | ASN_BER_TLV_t::destruct(tlv); | |
36 | break;} | |
af710487 | 37 | case TTCN_EncDec::CT_JSON: { |
38 | TTCN_EncDec_ErrorContext ec("While JSON-encoding type '%s': ", p_td.name); | |
39 | if(!p_td.json) | |
40 | TTCN_EncDec_ErrorContext::error_internal | |
41 | ("No JSON descriptor available for type '%s'.", p_td.name); | |
42 | JSON_Tokenizer tok(va_arg(pvar, int) != 0); | |
43 | JSON_encode(p_td, tok); | |
44 | p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer()); | |
45 | break;} | |
970ed795 EL |
46 | case TTCN_EncDec::CT_RAW: |
47 | default: | |
48 | TTCN_error("Unknown coding method requested to encode type '%s'", | |
49 | p_td.name); | |
50 | } | |
51 | va_end(pvar); | |
52 | } | |
53 | ||
54 | void ASN_ANY::decode(const TTCN_Typedescriptor_t& p_td, | |
55 | TTCN_Buffer& p_buf, | |
56 | TTCN_EncDec::coding_t p_coding, ...) | |
57 | { | |
58 | va_list pvar; | |
59 | va_start(pvar, p_coding); | |
60 | switch(p_coding) { | |
61 | case TTCN_EncDec::CT_BER: { | |
62 | TTCN_EncDec_ErrorContext ec("While BER-decoding type '%s': ", p_td.name); | |
63 | unsigned L_form=va_arg(pvar, unsigned); | |
64 | ASN_BER_TLV_t tlv; | |
65 | BER_decode_str2TLV(p_buf, tlv, L_form); | |
66 | BER_decode_TLV(p_td, tlv, L_form); | |
67 | if(tlv.isComplete) p_buf.increase_pos(tlv.get_len()); | |
68 | break;} | |
af710487 | 69 | case TTCN_EncDec::CT_JSON: { |
70 | TTCN_EncDec_ErrorContext ec("While JSON-decoding type '%s': ", p_td.name); | |
71 | if(!p_td.json) | |
72 | TTCN_EncDec_ErrorContext::error_internal | |
73 | ("No JSON descriptor available for type '%s'.", p_td.name); | |
74 | JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len()); | |
75 | if(JSON_decode(p_td, tok, false)<0) | |
76 | ec.error(TTCN_EncDec::ET_INCOMPL_MSG, | |
77 | "Can not decode type '%s', because invalid or incomplete" | |
78 | " message was received" | |
79 | , p_td.name); | |
80 | p_buf.set_pos(tok.get_buf_pos()); | |
81 | break;} | |
970ed795 EL |
82 | case TTCN_EncDec::CT_RAW: |
83 | default: | |
84 | TTCN_error("Unknown coding method requested to decode type '%s'", | |
85 | p_td.name); | |
86 | } | |
87 | va_end(pvar); | |
88 | } | |
89 | ||
90 | ASN_BER_TLV_t* | |
91 | ASN_ANY::BER_encode_TLV(const TTCN_Typedescriptor_t& p_td, | |
92 | unsigned p_coding) const | |
93 | { | |
94 | BER_chk_descr(p_td); | |
95 | ASN_BER_TLV_t *new_tlv=BER_encode_chk_bound(is_bound()); | |
96 | if(new_tlv) return new_tlv; | |
97 | ASN_BER_TLV_t *tmp_tlv=ASN_BER_TLV_t::construct(0, NULL); | |
98 | { | |
99 | TTCN_EncDec_ErrorContext ec("While checking ANY value: "); | |
100 | if(!ASN_BER_str2TLV(val_ptr->n_octets, val_ptr->octets_ptr, | |
101 | *tmp_tlv, BER_ACCEPT_ALL) | |
102 | || tmp_tlv->get_len()!=static_cast<size_t>(val_ptr->n_octets)) | |
103 | TTCN_EncDec_ErrorContext::error | |
104 | (TTCN_EncDec::ET_INCOMPL_ANY, | |
105 | "The content of an ASN ANY value must be a valid, complete TLV."); | |
106 | } | |
107 | new_tlv=ASN_BER_TLV_t::construct(0, NULL); | |
108 | *new_tlv=*tmp_tlv; | |
109 | new_tlv->Tstr=(unsigned char*)Malloc(new_tlv->Tlen); | |
110 | new_tlv->Lstr=(unsigned char*)Malloc(new_tlv->Llen); | |
111 | new_tlv->V.str.Vstr=(unsigned char*)Malloc(new_tlv->V.str.Vlen); | |
112 | memcpy(new_tlv->Tstr, tmp_tlv->Tstr, new_tlv->Tlen); | |
113 | memcpy(new_tlv->Lstr, tmp_tlv->Lstr, new_tlv->Llen); | |
114 | memcpy(new_tlv->V.str.Vstr, tmp_tlv->V.str.Vstr, new_tlv->V.str.Vlen); | |
115 | Free(tmp_tlv); | |
116 | new_tlv=ASN_BER_V2TLV(new_tlv, p_td, p_coding); | |
117 | return new_tlv; | |
118 | } | |
119 | ||
120 | boolean ASN_ANY::BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, | |
121 | const ASN_BER_TLV_t& p_tlv, | |
122 | unsigned L_form) | |
123 | { | |
124 | clean_up(); | |
125 | BER_chk_descr(p_td); | |
126 | ASN_BER_TLV_t stripped_tlv; | |
127 | BER_decode_strip_tags(*p_td.ber, p_tlv, L_form, stripped_tlv); | |
128 | TTCN_EncDec_ErrorContext ec("While decoding ASN ANY type: "); | |
129 | if(stripped_tlv.V_tlvs_selected) | |
130 | TTCN_EncDec_ErrorContext::error_internal | |
131 | ("In ASN_ANY::BER_decode_TLV()."); | |
132 | size_t pos=0; | |
133 | if(p_td.ber->n_tags>0) { | |
134 | stripped_tlv.Tlen=0; | |
135 | stripped_tlv.Llen=0; | |
136 | } | |
137 | init_struct(stripped_tlv.get_len()); | |
138 | memcpy(val_ptr->octets_ptr+pos, stripped_tlv.Tstr, stripped_tlv.Tlen); | |
139 | pos+=stripped_tlv.Tlen; | |
140 | memcpy(val_ptr->octets_ptr+pos, stripped_tlv.Lstr, stripped_tlv.Llen); | |
141 | pos+=stripped_tlv.Llen; | |
142 | memcpy(val_ptr->octets_ptr+pos, | |
143 | stripped_tlv.V.str.Vstr, stripped_tlv.V.str.Vlen); | |
144 | return TRUE; | |
145 | } |