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