2dc6e6642702670f744191ba06d44c22293dc78c
[deliverable/titan.core.git] / compiler2 / encdec.c
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 "../common/memory.h"
9 #include "datatypes.h"
10 #include "main.hh"
11 #include "encdec.h"
12
13 void def_encdec(const char *p_classname,
14 char **p_classdef, char **p_classsrc,
15 boolean ber, boolean raw, boolean text, boolean xer,
16 boolean json, boolean is_leaf)
17 {
18 char *def=NULL;
19 char *src=NULL;
20
21 def=mputstr
22 (def,
23 "void encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&,"
24 " TTCN_EncDec::coding_t, ...) const;\n"
25 "void decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&,"
26 " TTCN_EncDec::coding_t, ...);\n");
27 if(ber)
28 def=mputstr(def,
29 "ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td,"
30 " unsigned p_coding) const;\n"
31 "boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const"
32 " ASN_BER_TLV_t& p_tlv, unsigned L_form);\n"
33 );
34 if(raw)
35 def=mputprintf(def,
36 "int RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree&) const;\n"
37 "int RAW_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&,"
38 " int, raw_order_t, boolean no_err=FALSE,"
39 "int sel_field=-1, boolean first_call=TRUE);\n"
40 );
41 if(text)
42 def=mputprintf(def,
43 "int TEXT_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;\n"
44 "int TEXT_decode(const TTCN_Typedescriptor_t&,"
45 "TTCN_Buffer&, Limit_Token_List&, boolean no_err=FALSE,"
46 "boolean first_call=TRUE);\n"
47 );
48 if (xer) /* XERSTUFF encdec function headers */
49 def=mputprintf(def,
50 #ifndef NDEBUG
51 "// written by %s in " __FILE__ " at %d\n"
52 #endif
53 "int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int) const;\n"
54 "int XER_decode(const XERdescriptor_t&, XmlReaderWrap&, unsigned int);\n"
55 "static boolean can_start(const char *name, const char *uri, "
56 "XERdescriptor_t const& xd, unsigned int);\n"
57 "%s"
58 #ifndef NDEBUG
59 , __FUNCTION__, __LINE__
60 #endif
61 , use_runtime_2 ?
62 "boolean can_start_v(const char *name, const char *uri, "
63 "XERdescriptor_t const& xd, unsigned int);\n" : ""
64 );
65 if(json) {
66 def = mputprintf(def,
67 "int JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&) const;\n"
68 "int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);\n");
69 }
70
71 src=mputprintf(src,
72 "void %s::encode(const TTCN_Typedescriptor_t& p_td,"
73 " TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const\n"
74 "{\n"
75 " va_list pvar;\n"
76 " va_start(pvar, p_coding);\n"
77 " switch(p_coding) {\n"
78 " case TTCN_EncDec::CT_BER: {\n"
79 " TTCN_EncDec_ErrorContext ec(\"While BER-encoding type"
80 " '%%s': \", p_td.name);\n"
81 " unsigned BER_coding=va_arg(pvar, unsigned);\n"
82 " BER_encode_chk_coding(BER_coding);\n"
83 " ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);\n"
84 " tlv->put_in_buffer(p_buf);\n"
85 " ASN_BER_TLV_t::destruct(tlv);\n"
86 " break;}\n"
87 " case TTCN_EncDec::CT_RAW: {\n"
88 " TTCN_EncDec_ErrorContext ec(\"While RAW-encoding type"
89 " '%%s': \", p_td.name);\n"
90 " if(!p_td.raw)\n"
91 " TTCN_EncDec_ErrorContext::error_internal\n"
92 " (\"No RAW descriptor available for type '%%s'.\", p_td.name);\n"
93 " RAW_enc_tr_pos rp;\n"
94 " rp.level=0;\n"
95 " rp.pos=NULL;\n"
96 " RAW_enc_tree root(%s, NULL, &rp, 1, p_td.raw);\n"
97 " RAW_encode(p_td, root);\n"
98 " root.put_to_buf(p_buf);\n"
99 " break;}\n"
100 " case TTCN_EncDec::CT_TEXT: {\n"
101 " TTCN_EncDec_ErrorContext ec("
102 "\"While TEXT-encoding type '%%s': \", p_td.name);\n"
103 " if(!p_td.text)\n"
104 " TTCN_EncDec_ErrorContext::error_internal\n"
105 " (\"No TEXT descriptor available for type '%%s'.\", p_td.name);\n"
106 " TEXT_encode(p_td,p_buf);\n"
107 " break;}\n"
108 /* XERSTUFF encoder */
109 " case TTCN_EncDec::CT_XER: {\n"
110 " TTCN_EncDec_ErrorContext ec("
111 "\"While XER-encoding type '%%s': \", p_td.name);\n"
112 " unsigned XER_coding=va_arg(pvar, unsigned);\n"
113 " XER_encode_chk_coding(XER_coding, p_td);\n"
114 /* Do not use %s_xer_ here. It supplies the XER descriptor of oldtype
115 * even if encoding newtype for:
116 * <ttcn>type newtype oldtype;</ttcn> */
117 " XER_encode(*(p_td.xer),p_buf, XER_coding, 0);\n"
118 " p_buf.put_c('\\n');\n" /* make sure it has a newline */
119 " break;}\n"
120 " case TTCN_EncDec::CT_JSON: {\n"
121 " TTCN_EncDec_ErrorContext ec("
122 "\"While JSON-encoding type '%%s': \", p_td.name);\n"
123 " if(!p_td.json)\n"
124 " TTCN_EncDec_ErrorContext::error_internal\n"
125 " (\"No JSON descriptor available for type '%%s'.\", p_td.name);\n"
126 " JSON_Tokenizer tok(va_arg(pvar, int) != 0);\n"
127 " JSON_encode(p_td, tok);\n"
128 " p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());\n"
129 " break;}\n"
130 " default:\n"
131 " TTCN_error(\"Unknown coding method requested to encode"
132 " type '%%s'\", p_td.name);\n"
133 " }\n"
134 " va_end(pvar);\n"
135 "}\n"
136 "\n"
137 , p_classname, is_leaf?"TRUE":"FALSE"
138 );
139
140 src=mputprintf(src,
141 #ifndef NDEBUG
142 "// written by %s in " __FILE__ " at %d\n"
143 #endif
144 "void %s::decode(const TTCN_Typedescriptor_t& p_td,"
145 " TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)\n"
146 "{\n"
147 " va_list pvar;\n"
148 " va_start(pvar, p_coding);\n"
149 " switch(p_coding) {\n"
150 " case TTCN_EncDec::CT_BER: {\n"
151 " TTCN_EncDec_ErrorContext ec(\"While BER-decoding type"
152 " '%%s': \", p_td.name);\n"
153 " unsigned L_form=va_arg(pvar, unsigned);\n"
154 " ASN_BER_TLV_t tlv;\n"
155 " BER_decode_str2TLV(p_buf, tlv, L_form);\n"
156 " BER_decode_TLV(p_td, tlv, L_form);\n"
157 " if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());\n"
158 " break;}\n"
159 " case TTCN_EncDec::CT_RAW: {\n"
160 " TTCN_EncDec_ErrorContext ec(\"While RAW-decoding"
161 " type '%%s': \", p_td.name);\n"
162 " if(!p_td.raw)\n"
163 " TTCN_EncDec_ErrorContext::error_internal\n"
164 " (\"No RAW descriptor available for type '%%s'.\", p_td.name);\n"
165 " raw_order_t r_order;\n"
166 " switch(p_td.raw->top_bit_order) {\n"
167 " case TOP_BIT_LEFT:\n"
168 " r_order=ORDER_LSB;\n"
169 " break;\n"
170 " case TOP_BIT_RIGHT:\n"
171 " default:\n"
172 " r_order=ORDER_MSB;\n"
173 " }\n"
174 " int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);\n"
175 " if(rawr<0) switch (-rawr) {\n"
176 " case TTCN_EncDec::ET_INCOMPL_MSG:\n"
177 " case TTCN_EncDec::ET_LEN_ERR:\n"
178 " ec.error((TTCN_EncDec::error_type_t)-rawr, "
179 "\"Can not decode type '%%s', because incomplete message was received\", "
180 "p_td.name);\n"
181 " break;\n"
182 " case 1:\n" /* from the generic -1 return value */
183 " default:\n"
184 " ec.error(TTCN_EncDec::ET_INVAL_MSG, "
185 "\"Can not decode type '%%s', because invalid "
186 "message was received\", p_td.name);\n"
187 " break;\n"
188 " }\n"
189 " break;}\n"
190 " case TTCN_EncDec::CT_TEXT: {\n"
191 " Limit_Token_List limit;\n"
192 " TTCN_EncDec_ErrorContext ec(\"While TEXT-decoding type '%%s': \","
193 " p_td.name);\n"
194 " if(!p_td.text)\n"
195 " TTCN_EncDec_ErrorContext::error_internal\n"
196 " (\"No TEXT descriptor available for type '%%s'.\", p_td.name);\n"
197 " const unsigned char *b_data=p_buf.get_data();\n"
198 " if(b_data[p_buf.get_len()-1]!='\\0'){\n"
199 " p_buf.set_pos(p_buf.get_len());\n"
200 " p_buf.put_zero(8,ORDER_LSB);\n"
201 " p_buf.rewind();\n"
202 " }\n"
203 " if(TEXT_decode(p_td,p_buf,limit)<0)\n"
204 " ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"
205 "\"Can not decode type '%%s', because invalid or incomplete"
206 " message was received\", p_td.name);\n"
207 " break;}\n"
208 /* XERSTUFF decoder */
209 " case TTCN_EncDec::CT_XER: {\n"
210 " TTCN_EncDec_ErrorContext ec("
211 "\"While XER-decoding type '%%s': \", p_td.name);\n"
212 " unsigned XER_coding=va_arg(pvar, unsigned);\n"
213 " XER_encode_chk_coding(XER_coding, p_td);\n"
214 " XmlReaderWrap reader(p_buf);\n"
215 " for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {\n"
216 " if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;\n"
217 " }\n"
218 " XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL);\n"
219 " size_t bytes = reader.ByteConsumed();\n"
220 " p_buf.set_pos(bytes);\n"
221 " break;}\n"
222 " case TTCN_EncDec::CT_JSON: {\n"
223 " TTCN_EncDec_ErrorContext ec(\"While JSON-decoding type '%%s': \","
224 " p_td.name);\n"
225 " if(!p_td.json)\n"
226 " TTCN_EncDec_ErrorContext::error_internal\n"
227 " (\"No JSON descriptor available for type '%%s'.\", p_td.name);\n"
228 " JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());\n"
229 " if(JSON_decode(p_td, tok, false)<0)\n"
230 " ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"
231 "\"Can not decode type '%%s', because invalid or incomplete"
232 " message was received\", p_td.name);\n"
233 " p_buf.set_pos(tok.get_buf_pos());\n"
234 " break;}\n"
235 " default:\n"
236 " TTCN_error(\"Unknown coding method requested to decode"
237 " type '%%s'\", p_td.name);\n"
238 " }\n"
239 " va_end(pvar);\n"
240 "}\n\n"
241 #ifndef NDEBUG
242 , __FUNCTION__, __LINE__
243 #endif
244 , p_classname);
245
246 *p_classdef=mputstr(*p_classdef, def);
247 Free(def);
248 *p_classsrc=mputstr(*p_classsrc, src);
249 Free(src);
250 }
251
252 char *genRawFieldChecker(char *src, const rawAST_coding_taglist *taglist,
253 boolean is_equal)
254 {
255 int i;
256 for (i = 0; i < taglist->nElements; i++) {
257 rawAST_coding_field_list *fields = taglist->fields + i;
258 char *field_name = NULL;
259 boolean first_expr = TRUE;
260 int j;
261 if (i > 0) src = mputstr(src, is_equal ? " || " : " && ");
262 for (j = 0; j < fields->nElements; j++) {
263 rawAST_coding_fields *field = fields->fields + j;
264 if (j == 0) {
265 /* this is the first field reference */
266 if (field->fieldtype == UNION_FIELD)
267 field_name = mputprintf(field_name,"(*field_%s)",field->nthfieldname);
268 else
269 field_name = mputprintf(field_name,"field_%s", field->nthfieldname);
270 }
271 else {
272 /* this is not the first field reference */
273 if (field->fieldtype == UNION_FIELD) {
274 /* checking for the right selection within the union */
275 if (first_expr) {
276 if (taglist->nElements > 1) src = mputc(src, '(');
277 first_expr = FALSE;
278 }
279 else src = mputstr(src, is_equal ? " && " : " || ");
280 src = mputprintf(src, "%s.get_selection() %s %s%s%s", field_name,
281 is_equal ? "==" : "!=", fields->fields[j - 1].type,
282 "::ALT_", field->nthfieldname);
283 }
284 /* appending the current field name to the field reference */
285 field_name = mputprintf(field_name, ".%s()", field->nthfieldname);
286 }
287 if (j < fields->nElements - 1 && field->fieldtype == OPTIONAL_FIELD) {
288 /* this is not the last field in the chain and it is optional */
289 if (first_expr) {
290 if (taglist->nElements > 1) src = mputc(src, '(');
291 first_expr = FALSE;
292 }
293 else src = mputstr(src, is_equal ? " && " : " || ");
294 /* check for the presence */
295 if (!is_equal) src = mputc(src, '!');
296 src = mputprintf(src, "%s.ispresent()", field_name);
297 /* add an extra () to the field reference */
298 field_name = mputstr(field_name, "()");
299 }
300 }
301 if (!first_expr) src = mputstr(src, is_equal ? " && " : " || ");
302 /* compare the referred field with the given value */
303 src = mputprintf(src, "%s %s %s", field_name, is_equal ? "==" : "!=",
304 fields->value);
305 if (!first_expr && taglist->nElements > 1) src = mputc(src, ')');
306 Free(field_name);
307 }
308 return src;
309 }
310
311 char *genRawTagChecker(char *src, const rawAST_coding_taglist *taglist)
312 {
313 int temp_tag, l;
314 rawAST_coding_field_list temp_field;
315 src = mputstr(src, " RAW_enc_tree* temp_leaf;\n");
316 for (temp_tag = 0; temp_tag < taglist->nElements; temp_tag++) {
317 temp_field = taglist->fields[temp_tag];
318 src = mputprintf(src, " {\n"
319 " RAW_enc_tr_pos pr_pos;\n"
320 " pr_pos.level=myleaf.curr_pos.level+%d;\n"
321 " int new_pos[]={", temp_field.nElements);
322 for (l = 0; l < temp_field.nElements; l++) {
323 src= mputprintf(src, "%s%d", l ? "," : "", temp_field.fields[l].nthfield);
324 }
325 src = mputprintf(src, "};\n"
326 " pr_pos.pos=init_new_tree_pos(myleaf.curr_pos,%d,new_pos);\n"
327 " temp_leaf = myleaf.get_node(pr_pos);\n"
328 " if(temp_leaf != NULL){\n", temp_field.nElements);
329 if (temp_field.value[0] != ' ') {
330 src = mputprintf(src, " %s new_val = %s;\n"
331 " new_val.RAW_encode(%s_descr_,*temp_leaf);\n",
332 temp_field.fields[temp_field.nElements - 1].type, temp_field.value,
333 temp_field.fields[temp_field.nElements - 1].typedescr);
334 }
335 else {
336 src = mputprintf(src, " %s.RAW_encode(%s_descr_,*temp_leaf);\n",
337 temp_field.value, temp_field.fields[temp_field.nElements - 1].typedescr);
338 }
339 src = mputstr(src, " } else");
340 }
341 src = mputstr(src, " {\n"
342 " TTCN_EncDec_ErrorContext::error\n"
343 " (TTCN_EncDec::ET_OMITTED_TAG, \"Encoding a tagged, but omitted"
344 " value.\");\n"
345 " }\n");
346 for (temp_tag = 0; temp_tag < taglist->nElements; temp_tag++) {
347 src = mputstr(src, " free_tree_pos(pr_pos.pos);\n"
348 " }\n");
349 }
350 return src;
351 }
This page took 0.054043 seconds and 4 git commands to generate.