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
18 * Szabo, Janos Zoltan – initial implementation
21 ******************************************************************************/
22 #include "../common/memory.h"
23 #include "datatypes.h"
27 void def_encdec(const char *p_classname
,
28 char **p_classdef
, char **p_classsrc
,
29 boolean ber
, boolean raw
, boolean text
, boolean xer
,
30 boolean json
, boolean is_leaf
)
37 "void encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&,"
38 " TTCN_EncDec::coding_t, ...) const;\n"
39 "void decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&,"
40 " TTCN_EncDec::coding_t, ...);\n");
43 "ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td,"
44 " unsigned p_coding) const;\n"
45 "boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const"
46 " ASN_BER_TLV_t& p_tlv, unsigned L_form);\n"
50 "int RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree&) const;\n"
51 "int RAW_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&,"
52 " int, raw_order_t, boolean no_err=FALSE,"
53 "int sel_field=-1, boolean first_call=TRUE);\n"
57 "int TEXT_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;\n"
58 "int TEXT_decode(const TTCN_Typedescriptor_t&,"
59 "TTCN_Buffer&, Limit_Token_List&, boolean no_err=FALSE,"
60 "boolean first_call=TRUE);\n"
62 if (xer
) /* XERSTUFF encdec function headers */
65 "// written by %s in " __FILE__
" at %d\n"
67 "int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, "
68 "embed_values_enc_struct_t*) const;\n"
69 "int XER_decode(const XERdescriptor_t&, XmlReaderWrap&, unsigned int, "
70 "unsigned int, embed_values_dec_struct_t*);\n"
71 "static boolean can_start(const char *name, const char *uri, "
72 "XERdescriptor_t const& xd, unsigned int);\n"
75 , __FUNCTION__
, __LINE__
78 "boolean can_start_v(const char *name, const char *uri, "
79 "XERdescriptor_t const& xd, unsigned int);\n" : ""
83 "int JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&) const;\n"
84 "int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);\n");
88 "void %s::encode(const TTCN_Typedescriptor_t& p_td,"
89 " TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const\n"
92 " va_start(pvar, p_coding);\n"
93 " switch(p_coding) {\n"
94 " case TTCN_EncDec::CT_BER: {\n"
95 " TTCN_EncDec_ErrorContext ec(\"While BER-encoding type"
96 " '%%s': \", p_td.name);\n"
97 " unsigned BER_coding=va_arg(pvar, unsigned);\n"
98 " BER_encode_chk_coding(BER_coding);\n"
99 " ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);\n"
100 " tlv->put_in_buffer(p_buf);\n"
101 " ASN_BER_TLV_t::destruct(tlv);\n"
103 " case TTCN_EncDec::CT_RAW: {\n"
104 " TTCN_EncDec_ErrorContext ec(\"While RAW-encoding type"
105 " '%%s': \", p_td.name);\n"
107 " TTCN_EncDec_ErrorContext::error_internal\n"
108 " (\"No RAW descriptor available for type '%%s'.\", p_td.name);\n"
109 " RAW_enc_tr_pos rp;\n"
112 " RAW_enc_tree root(%s, NULL, &rp, 1, p_td.raw);\n"
113 " RAW_encode(p_td, root);\n"
114 " root.put_to_buf(p_buf);\n"
116 " case TTCN_EncDec::CT_TEXT: {\n"
117 " TTCN_EncDec_ErrorContext ec("
118 "\"While TEXT-encoding type '%%s': \", p_td.name);\n"
120 " TTCN_EncDec_ErrorContext::error_internal\n"
121 " (\"No TEXT descriptor available for type '%%s'.\", p_td.name);\n"
122 " TEXT_encode(p_td,p_buf);\n"
124 /* XERSTUFF encoder */
125 " case TTCN_EncDec::CT_XER: {\n"
126 " TTCN_EncDec_ErrorContext ec("
127 "\"While XER-encoding type '%%s': \", p_td.name);\n"
128 " unsigned XER_coding=va_arg(pvar, unsigned);\n"
129 " XER_encode_chk_coding(XER_coding, p_td);\n"
130 /* Do not use %s_xer_ here. It supplies the XER descriptor of oldtype
131 * even if encoding newtype for:
132 * <ttcn>type newtype oldtype;</ttcn> */
133 " XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0);\n"
134 " p_buf.put_c('\\n');\n" /* make sure it has a newline */
136 " case TTCN_EncDec::CT_JSON: {\n"
137 " TTCN_EncDec_ErrorContext ec("
138 "\"While JSON-encoding type '%%s': \", p_td.name);\n"
140 " TTCN_EncDec_ErrorContext::error_internal\n"
141 " (\"No JSON descriptor available for type '%%s'.\", p_td.name);\n"
142 " JSON_Tokenizer tok(va_arg(pvar, int) != 0);\n"
143 " JSON_encode(p_td, tok);\n"
144 " p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());\n"
147 " TTCN_error(\"Unknown coding method requested to encode"
148 " type '%%s'\", p_td.name);\n"
153 , p_classname
, is_leaf
?"TRUE":"FALSE"
158 "// written by %s in " __FILE__
" at %d\n"
160 "void %s::decode(const TTCN_Typedescriptor_t& p_td,"
161 " TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)\n"
164 " va_start(pvar, p_coding);\n"
165 " switch(p_coding) {\n"
166 " case TTCN_EncDec::CT_BER: {\n"
167 " TTCN_EncDec_ErrorContext ec(\"While BER-decoding type"
168 " '%%s': \", p_td.name);\n"
169 " unsigned L_form=va_arg(pvar, unsigned);\n"
170 " ASN_BER_TLV_t tlv;\n"
171 " BER_decode_str2TLV(p_buf, tlv, L_form);\n"
172 " BER_decode_TLV(p_td, tlv, L_form);\n"
173 " if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());\n"
175 " case TTCN_EncDec::CT_RAW: {\n"
176 " TTCN_EncDec_ErrorContext ec(\"While RAW-decoding"
177 " type '%%s': \", p_td.name);\n"
179 " TTCN_EncDec_ErrorContext::error_internal\n"
180 " (\"No RAW descriptor available for type '%%s'.\", p_td.name);\n"
181 " raw_order_t r_order;\n"
182 " switch(p_td.raw->top_bit_order) {\n"
183 " case TOP_BIT_LEFT:\n"
184 " r_order=ORDER_LSB;\n"
186 " case TOP_BIT_RIGHT:\n"
188 " r_order=ORDER_MSB;\n"
190 " int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);\n"
191 " if(rawr<0) switch (-rawr) {\n"
192 " case TTCN_EncDec::ET_INCOMPL_MSG:\n"
193 " case TTCN_EncDec::ET_LEN_ERR:\n"
194 " ec.error((TTCN_EncDec::error_type_t)-rawr, "
195 "\"Can not decode type '%%s', because incomplete message was received\", "
198 " case 1:\n" /* from the generic -1 return value */
200 " ec.error(TTCN_EncDec::ET_INVAL_MSG, "
201 "\"Can not decode type '%%s', because invalid "
202 "message was received\", p_td.name);\n"
206 " case TTCN_EncDec::CT_TEXT: {\n"
207 " Limit_Token_List limit;\n"
208 " TTCN_EncDec_ErrorContext ec(\"While TEXT-decoding type '%%s': \","
211 " TTCN_EncDec_ErrorContext::error_internal\n"
212 " (\"No TEXT descriptor available for type '%%s'.\", p_td.name);\n"
213 " const unsigned char *b_data=p_buf.get_data();\n"
214 " if(b_data[p_buf.get_len()-1]!='\\0'){\n"
215 " p_buf.set_pos(p_buf.get_len());\n"
216 " p_buf.put_zero(8,ORDER_LSB);\n"
219 " if(TEXT_decode(p_td,p_buf,limit)<0)\n"
220 " ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"
221 "\"Can not decode type '%%s', because invalid or incomplete"
222 " message was received\", p_td.name);\n"
224 /* XERSTUFF decoder */
225 " case TTCN_EncDec::CT_XER: {\n"
226 " TTCN_EncDec_ErrorContext ec("
227 "\"While XER-decoding type '%%s': \", p_td.name);\n"
228 " unsigned XER_coding=va_arg(pvar, unsigned);\n"
229 " XER_encode_chk_coding(XER_coding, p_td);\n"
230 " XmlReaderWrap reader(p_buf);\n"
231 " for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {\n"
232 " if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;\n"
234 " XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);\n"
235 " size_t bytes = reader.ByteConsumed();\n"
236 " p_buf.set_pos(bytes);\n"
238 " case TTCN_EncDec::CT_JSON: {\n"
239 " TTCN_EncDec_ErrorContext ec(\"While JSON-decoding type '%%s': \","
242 " TTCN_EncDec_ErrorContext::error_internal\n"
243 " (\"No JSON descriptor available for type '%%s'.\", p_td.name);\n"
244 " JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());\n"
245 " if(JSON_decode(p_td, tok, false)<0)\n"
246 " ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"
247 "\"Can not decode type '%%s', because invalid or incomplete"
248 " message was received\", p_td.name);\n"
249 " p_buf.set_pos(tok.get_buf_pos());\n"
252 " TTCN_error(\"Unknown coding method requested to decode"
253 " type '%%s'\", p_td.name);\n"
258 , __FUNCTION__
, __LINE__
262 *p_classdef
=mputstr(*p_classdef
, def
);
264 *p_classsrc
=mputstr(*p_classsrc
, src
);
268 char *genRawFieldChecker(char *src
, const rawAST_coding_taglist
*taglist
,
272 for (i
= 0; i
< taglist
->nElements
; i
++) {
273 rawAST_coding_field_list
*fields
= taglist
->fields
+ i
;
274 char *field_name
= NULL
;
275 boolean first_expr
= TRUE
;
277 if (i
> 0) src
= mputstr(src
, is_equal
? " || " : " && ");
278 for (j
= 0; j
< fields
->nElements
; j
++) {
279 rawAST_coding_fields
*field
= fields
->fields
+ j
;
281 /* this is the first field reference */
282 if (field
->fieldtype
== UNION_FIELD
)
283 field_name
= mputprintf(field_name
,"(*field_%s)",field
->nthfieldname
);
285 field_name
= mputprintf(field_name
,"field_%s", field
->nthfieldname
);
288 /* this is not the first field reference */
289 if (field
->fieldtype
== UNION_FIELD
) {
290 /* checking for the right selection within the union */
292 if (taglist
->nElements
> 1) src
= mputc(src
, '(');
295 else src
= mputstr(src
, is_equal
? " && " : " || ");
296 src
= mputprintf(src
, "%s.get_selection() %s %s%s%s", field_name
,
297 is_equal
? "==" : "!=", fields
->fields
[j
- 1].type
,
298 "::ALT_", field
->nthfieldname
);
300 /* appending the current field name to the field reference */
301 field_name
= mputprintf(field_name
, ".%s()", field
->nthfieldname
);
303 if (j
< fields
->nElements
- 1 && field
->fieldtype
== OPTIONAL_FIELD
) {
304 /* this is not the last field in the chain and it is optional */
306 if (taglist
->nElements
> 1) src
= mputc(src
, '(');
309 else src
= mputstr(src
, is_equal
? " && " : " || ");
310 /* check for the presence */
311 if (!is_equal
) src
= mputc(src
, '!');
312 src
= mputprintf(src
, "%s.ispresent()", field_name
);
313 /* add an extra () to the field reference */
314 field_name
= mputstr(field_name
, "()");
317 if (!first_expr
) src
= mputstr(src
, is_equal
? " && " : " || ");
318 /* compare the referred field with the given value */
319 src
= mputprintf(src
, "%s %s %s", field_name
, is_equal
? "==" : "!=",
321 if (!first_expr
&& taglist
->nElements
> 1) src
= mputc(src
, ')');
327 char *genRawTagChecker(char *src
, const rawAST_coding_taglist
*taglist
)
330 rawAST_coding_field_list temp_field
;
331 src
= mputstr(src
, " RAW_enc_tree* temp_leaf;\n");
332 for (temp_tag
= 0; temp_tag
< taglist
->nElements
; temp_tag
++) {
333 temp_field
= taglist
->fields
[temp_tag
];
334 src
= mputprintf(src
, " {\n"
335 " RAW_enc_tr_pos pr_pos%d;\n"
336 " pr_pos%d.level=myleaf.curr_pos.level+%d;\n"
337 " int new_pos%d[]={", temp_tag
, temp_tag
, temp_field
.nElements
, temp_tag
);
338 for (l
= 0; l
< temp_field
.nElements
; l
++) {
339 src
= mputprintf(src
, "%s%d", l
? "," : "", temp_field
.fields
[l
].nthfield
);
341 src
= mputprintf(src
, "};\n"
342 " pr_pos%d.pos=init_new_tree_pos(myleaf.curr_pos,%d,new_pos%d);\n"
343 " temp_leaf = myleaf.get_node(pr_pos%d);\n"
344 " if(temp_leaf != NULL){\n", temp_tag
, temp_field
.nElements
, temp_tag
, temp_tag
);
345 if (temp_field
.value
[0] != ' ') {
346 src
= mputprintf(src
, " %s new_val = %s;\n"
347 " new_val.RAW_encode(%s_descr_,*temp_leaf);\n",
348 temp_field
.fields
[temp_field
.nElements
- 1].type
, temp_field
.value
,
349 temp_field
.fields
[temp_field
.nElements
- 1].typedescr
);
352 src
= mputprintf(src
, " %s.RAW_encode(%s_descr_,*temp_leaf);\n",
353 temp_field
.value
, temp_field
.fields
[temp_field
.nElements
- 1].typedescr
);
355 src
= mputstr(src
, " } else");
357 src
= mputstr(src
, " {\n"
358 " TTCN_EncDec_ErrorContext::error\n"
359 " (TTCN_EncDec::ET_OMITTED_TAG, \"Encoding a tagged, but omitted"
362 for (temp_tag
= taglist
->nElements
- 1; temp_tag
>= 0 ; temp_tag
--) {
363 src
= mputprintf(src
, " free_tree_pos(pr_pos%d.pos);\n"