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