Commit 7f3b23c6 authored by BenceJanosSzabo's avatar BenceJanosSzabo
Browse files

XER: union fields are encoded correctly (Bug 506917)



Change-Id: Ic8951f1bcb01e72520913b101b9a1d269baa1e39
Signed-off-by: default avatarBenceJanosSzabo <bence.janos.szabo@ericsson.com>
parent 957aa022
......@@ -87,7 +87,7 @@ CompField.cc CompType.cc EnumItem.cc Identifier.cc Int.cc \
main.cc Real.cc Setting.cc SigParam.cc string.cc subtype.cc Stopwatch.cc \
Type.cc Type_chk.cc Type_codegen.cc TypeCompat.cc \
Typestuff.cc ustring.cc Value.cc Valuestuff.cc XerAttributes.cc subtypestuff.cc \
CodeGenHelper.cc DebuggerStuff.cc
CodeGenHelper.cc DebuggerStuff.cc XSD_Types.cc
MFGEN_SOURCES := makefile.c xpather.cc ProjectGenHelper.cc
......
......@@ -28,6 +28,7 @@
#include "union.h"
#include "record_of.h"
#include "functionref.h"
#include "XSD_Types.hh"
#include "ttcn3/Ttcnstuff.hh"
......@@ -506,6 +507,7 @@ void Type::generate_code_xerdescriptor(output_struct* target)
text=0, untagged=0, use_nil=0, use_number=0, use_order=0, use_qname=0,
use_type_attr=0, ws=0, has_1untag=0, form_qualified=0, any_from=0,
any_except=0, nof_ns_uris=0, blocked=0, fractionDigits=-1;
const char* xsd_type = "XSD_NONE";
const char* dfe_str = 0;
char** ns_uris = 0;
char* oftype_descr_name = 0;
......@@ -541,6 +543,8 @@ void Type::generate_code_xerdescriptor(output_struct* target)
// (encoder's choice) for USE-UNION. However, TTCN-3 removes this choice:
// it is mandatory to use it when possible (valid choice for ASN.1 too).
use_type_attr = xerattrib->useType_ || xerattrib->useUnion_;
xsd_type = XSD_type_to_string(xerattrib->xsd_type);
if (xerattrib->defaultValue_) {
Type *t = xerattrib->defaultValue_->get_my_governor();
......@@ -625,7 +629,7 @@ void Type::generate_code_xerdescriptor(output_struct* target)
target->source.global_vars = mputprintf(target->source.global_vars,
"const XERdescriptor_t %s_xer_ = { {\"%s>\\n\", \"%s>\\n\"},"
" {%lu, %lu}, %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s, WHITESPACE_%s, %c%s, "
"&%s, %ld, %u, %s, %s, %i };\n",
"&%s, %ld, %u, %s, %s, %i, %s };\n",
gennameown_str,
bxer_name.c_str(), last_s.c_str(), // names
(unsigned long)bxer_len, (unsigned long)last_len, // lengths
......@@ -656,7 +660,8 @@ void Type::generate_code_xerdescriptor(output_struct* target)
nof_ns_uris,
(ns_uris_var ? ns_uris_var : "NULL"),
(oftype_descr_name ? oftype_descr_name : "NULL"),
fractionDigits
fractionDigits,
xsd_type
);
Free(ns_uris_var);
......@@ -1182,6 +1187,10 @@ void Type::generate_code_Choice(output_struct *target)
if (xerattrib) {
if (cftype->has_empty_xml()) sdef.exerMaybeEmptyIndex = i;
// This will overwrite lower values, which is what we want.
if (cftype->xerattrib != NULL) {
sdef.elements[i].xsd_type = cftype->xerattrib->xsd_type;
}
}
if (sdef.jsonAsValue) {
// Determine the JSON value type of each field to make decoding faster
......@@ -1336,7 +1345,7 @@ void Type::generate_code_Choice(output_struct *target)
sdef.control_ns_prefix = prefix;
sdef.xerUseUnion = xerattrib->useUnion_;
sdef.xerUseTypeAttr = xerattrib->useType_ || xerattrib->useUnion_;
}
}
defUnionClass(&sdef, target);
defUnionTemplate(&sdef, target);
......
/******************************************************************************
* Copyright (c) 2000-2016 Ericsson Telecom AB
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Szabo, Bence Janos
*
******************************************************************************/
#include "XSD_Types.hh"
#include <cstddef>
#include "error.h"
// Used in the code generation of the xer descriptor, and the union generation
const char * XSD_type_to_string(const XSD_types xsd_type) {
switch (xsd_type) {
case XSD_NONE:
return "XSD_NONE";
case XSD_ANYSIMPLETYPE:
return "XSD_ANYSIMPLETYPE";
case XSD_ANYTYPE:
return "XSD_ANYTYPE";
case XSD_STRING:
return "XSD_STRING";
case XSD_NORMALIZEDSTRING:
return "XSD_NORMALIZEDSTRING";
case XSD_TOKEN:
return "XSD_TOKEN";
case XSD_NAME:
return "XSD_NAME";
case XSD_NMTOKEN:
return "XSD_NMTOKEN";
case XSD_NCName:
return "XSD_NCName";
case XSD_ID:
return "XSD_ID";
case XSD_IDREF:
return "XSD_IDREF";
case XSD_ENTITY:
return "XSD_ENTITY";
case XSD_HEXBINARY:
return "XSD_HEXBINARY";
case XSD_BASE64BINARY:
return "XSD_BASE64BINARY";
case XSD_ANYURI:
return "XSD_ANYURI";
case XSD_LANGUAGE:
return "XSD_LANGUAGE";
case XSD_INTEGER:
return "XSD_INTEGER";
case XSD_POSITIVEINTEGER:
return "XSD_POSITIVEINTEGER";
case XSD_NONPOSITIVEINTEGER:
return "XSD_NONPOSITIVEINTEGER";
case XSD_NEGATIVEINTEGER:
return "XSD_NEGATIVEINTEGER";
case XSD_NONNEGATIVEINTEGER:
return "XSD_NONNEGATIVEINTEGER";
case XSD_LONG:
return "XSD_LONG";
case XSD_UNSIGNEDLONG:
return "XSD_UNSIGNEDLONG";
case XSD_INT:
return "XSD_INT";
case XSD_UNSIGNEDINT:
return "XSD_UNSIGNEDINT";
case XSD_SHORT:
return "XSD_SHORT";
case XSD_UNSIGNEDSHORT:
return "XSD_UNSIGNEDSHORT";
case XSD_BYTE:
return "XSD_BYTE";
case XSD_UNSIGNEDBYTE:
return "XSD_UNSIGNEDBYTE";
case XSD_DECIMAL:
return "XSD_DECIMAL";
case XSD_FLOAT:
return "XSD_FLOAT";
case XSD_DOUBLE:
return "XSD_DOUBLE";
case XSD_DURATION:
return "XSD_DURATION";
case XSD_DATETIME:
return "XSD_DATETIME";
case XSD_TIME:
return "XSD_TIME";
case XSD_DATE:
return "XSD_DATE";
case XSD_GYEARMONTH:
return "XSD_GYEARMONTH";
case XSD_GYEAR:
return "XSD_GYEAR";
case XSD_GMONTHDAY:
return "XSD_GMONTHDAY";
case XSD_GDAY:
return "XSD_GDAY";
case XSD_GMONTH:
return "XSD_GMONTH";
case XSD_NMTOKENS:
return "XSD_NMTOKENS";
case XSD_IDREFS:
return "XSD_IDREFS";
case XSD_ENTITIES:
return "XSD_ENTITIES";
case XSD_QNAME:
return "XSD_QNAME";
case XSD_BOOLEAN:
return "XSD_BOOLEAN";
default:
FATAL_ERROR("XSD_Types::XSD_type_to_string - invalid XSD type");
return NULL;
}
}
// Used in the union XER encoder and decoder code generation
const char * XSD_type_to_xml_type(const XSD_types xsd_type) {
switch (xsd_type) {
case XSD_NONE:
return "";
case XSD_ANYSIMPLETYPE:
return "anySimpleType";
case XSD_ANYTYPE:
return "anyType";
case XSD_STRING:
return "string";
case XSD_NORMALIZEDSTRING:
return "normalizedString";
case XSD_TOKEN:
return "token";
case XSD_NAME:
return "Name";
case XSD_NMTOKEN:
return "NMTOKEN";
case XSD_NCName:
return "NCName";
case XSD_ID:
return "ID";
case XSD_IDREF:
return "IDREF";
case XSD_ENTITY:
return "ENTITY";
case XSD_HEXBINARY:
return "hexBinary";
case XSD_BASE64BINARY:
return "base64Binary";
case XSD_ANYURI:
return "anyURI";
case XSD_LANGUAGE:
return "language";
case XSD_INTEGER:
return "integer";
case XSD_POSITIVEINTEGER:
return "positiveInteger";
case XSD_NONPOSITIVEINTEGER:
return "nonPositiveInteger";
case XSD_NEGATIVEINTEGER:
return "negativeInteger";
case XSD_NONNEGATIVEINTEGER:
return "nonNegativeInteger";
case XSD_LONG:
return "long";
case XSD_UNSIGNEDLONG:
return "unsignedLong";
case XSD_INT:
return "int";
case XSD_UNSIGNEDINT:
return "unsignedInt";
case XSD_SHORT:
return "short";
case XSD_UNSIGNEDSHORT:
return "unsignedShort";
case XSD_BYTE:
return "byte";
case XSD_UNSIGNEDBYTE:
return "unsignedByte";
case XSD_DECIMAL:
return "decimal";
case XSD_FLOAT:
return "float";
case XSD_DOUBLE:
return "double";
case XSD_DURATION:
return "duration";
case XSD_DATETIME:
return "dateTime";
case XSD_TIME:
return "time";
case XSD_DATE:
return "date";
case XSD_GYEARMONTH:
return "gYearMonth";
case XSD_GYEAR:
return "gYear";
case XSD_GMONTHDAY:
return "gMonthDay";
case XSD_GDAY:
return "gDay";
case XSD_GMONTH:
return "gMonth";
case XSD_NMTOKENS:
return "NMTOKENS";
case XSD_IDREFS:
return "IDREFS";
case XSD_ENTITIES:
return "ENTITIES";
case XSD_QNAME:
return "QName";
case XSD_BOOLEAN:
return "boolean";
default:
FATAL_ERROR("XSD_Types::XSD_type_to_xml_type - invalid XSD type");
return NULL;
}
}
\ No newline at end of file
/******************************************************************************
* Copyright (c) 2000-2016 Ericsson Telecom AB
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Szabo, Bence Janos
*
******************************************************************************/
#ifndef XSD_TYPES_HH_
#define XSD_TYPES_HH_
/**
* XSD type variants. For example: XSD:integer XSD:binary etc.
* A field can only have one of these variants.
* This enum should be in sync with the XSD_types enum in XER.hh
*/
typedef enum {
XSD_NONE = 0, // XER_NONE should be zero
XSD_ANYSIMPLETYPE, // Unused
XSD_ANYTYPE, // Unused
XSD_STRING,
XSD_NORMALIZEDSTRING,
XSD_TOKEN,
XSD_NAME,
XSD_NMTOKEN,
XSD_NCName,
XSD_ID,
XSD_IDREF,
XSD_ENTITY,
XSD_HEXBINARY,
XSD_BASE64BINARY,
XSD_ANYURI,
XSD_LANGUAGE,
XSD_INTEGER,
XSD_POSITIVEINTEGER,
XSD_NONPOSITIVEINTEGER,
XSD_NEGATIVEINTEGER,
XSD_NONNEGATIVEINTEGER,
XSD_LONG,
XSD_UNSIGNEDLONG,
XSD_INT,
XSD_UNSIGNEDINT,
XSD_SHORT,
XSD_UNSIGNEDSHORT,
XSD_BYTE,
XSD_UNSIGNEDBYTE,
XSD_DECIMAL,
XSD_FLOAT,
XSD_DOUBLE,
XSD_DURATION,
XSD_DATETIME,
XSD_TIME,
XSD_DATE,
XSD_GYEARMONTH,
XSD_GYEAR,
XSD_GMONTHDAY,
XSD_GDAY,
XSD_GMONTH,
XSD_NMTOKENS, // Unused
XSD_IDREFS, // Unused
XSD_ENTITIES, // Unused
XSD_QNAME, // Unused
XSD_BOOLEAN
} XSD_types;
#ifdef __cplusplus
extern "C" {
#endif
const char * XSD_type_to_string(const XSD_types xsd_type);
const char * XSD_type_to_xml_type(const XSD_types xsd_type);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*XSD_TYPES_HH*/
\ No newline at end of file
......@@ -62,6 +62,7 @@ XerAttributes::XerAttributes()
, useType_(false)
, useUnion_(false)
, whitespace_(PRESERVE)
, xsd_type(XSD_NONE)
{
//__asm("int3");
//fprintf(stderr, "XER attributes(%p) new\n", (void*)this);
......@@ -378,6 +379,10 @@ other.print("other");
useType_ |= other.useType_;
useUnion_ |= other.useUnion_;
whitespace_ = other.whitespace_;
if (other.xsd_type != XSD_NONE) {
xsd_type = other.xsd_type;
}
return *this;
}
......@@ -407,6 +412,7 @@ bool XerAttributes::empty() const
&& !useQName_
&& !useType_
&& !useUnion_
&& whitespace_ == PRESERVE;
&& whitespace_ == PRESERVE
&& xsd_type == XSD_NONE;
}
......@@ -25,6 +25,7 @@
#include <stddef.h>
#include <limits.h>
#include "../common/memory.h"
#include "datatypes.h"
namespace Common {
class Value;
......@@ -187,6 +188,7 @@ public:
bool useType_;
bool useUnion_;
WhitespaceAction whitespace_;
XSD_types xsd_type;
void print(const char *type_name) const;
......
......@@ -15,6 +15,7 @@
* Raduly, Csaba
* Szabados, Kristof
* Szabo, Janos Zoltan – initial implementation
* Szabo, Bence Janos
* Szalai, Gabor
*
******************************************************************************/
......@@ -23,6 +24,7 @@
#include "asn1/asn1p_old.h"
#include "ttcn3/rawASTspec.h"
#include "XSD_Types.hh"
/* Common types */
typedef int boolean;
......@@ -87,6 +89,7 @@ typedef struct {
const char* jsonDefaultValue;
/** true if the field is a record-of or set-of with optimized memory allocation */
boolean optimizedMemAlloc;
XSD_types xsd_type;
} struct_field;
/** Structure (record, set, union, anytype) descriptor for code generation */
......
......@@ -10,6 +10,7 @@
* Baranyi, Botond
* Raduly, Csaba
* Szabo, Janos Zoltan – initial implementation
* Szabo, Bence Janos
* Szalai, Gabor
* Zalanyi, Balazs Andor
*
......@@ -1502,60 +1503,64 @@ whiteSpace:
xsddata: /* XSD:something */
XSDbase64Binary {
xerstruct->base64_ = true;
xerstruct->xsd_type = XSD_BASE64BINARY;
}
| XSDdecimal {
xerstruct->decimal_ = true;
xerstruct->xsd_type = XSD_DECIMAL;
}
| XSDhexBinary {
xerstruct->hex_ = true;
xerstruct->xsd_type = XSD_HEXBINARY;
}
| XSDQName {
xerstruct->useQName_ = true;
xerstruct->xsd_type = XSD_QNAME;
}
/* everything below is recognized and ignored */
| XKWshort {}
| XKWlong {}
| XSDstring {}
| XSDnormalizedString {}
| XSDtoken {}
| XSDName {}
| XSDNMTOKEN {}
| XSDNCName {}
| XSDID {}
| XSDIDREF {}
| XSDENTITY {}
| XSDanyURI {}
| XSDlanguage {}
/* everything below is recognized */
| XKWshort { xerstruct->xsd_type = XSD_SHORT; }
| XKWlong { xerstruct->xsd_type = XSD_LONG; }
| XSDstring { xerstruct->xsd_type = XSD_STRING; }
| XSDnormalizedString { xerstruct->xsd_type = XSD_NORMALIZEDSTRING; }
| XSDtoken { xerstruct->xsd_type = XSD_TOKEN; }
| XSDName { xerstruct->xsd_type = XSD_NAME; }
| XSDNMTOKEN { xerstruct->xsd_type = XSD_NMTOKEN; }
| XSDNCName { xerstruct->xsd_type = XSD_NCName; }
| XSDID { xerstruct->xsd_type = XSD_ID; }
| XSDIDREF { xerstruct->xsd_type = XSD_IDREF; }
| XSDENTITY { xerstruct->xsd_type = XSD_ENTITY; }
| XSDanyURI { xerstruct->xsd_type = XSD_ANYURI; }
| XSDlanguage { xerstruct->xsd_type = XSD_LANGUAGE; }
/* TODO apply subtype to the types below */
| XSDinteger {}
| XSDpositiveInteger {}
| XSDnonPositiveInteger {}
| XSDnegativeInteger {}
| XSDnonNegativeInteger {}
| XSDunsignedLong {}
| XSDint {}
| XSDunsignedInt {}
| XSDunsignedShort {}
| XSDbyte {}
| XSDunsignedByte {}
| XSDfloat {}
| XSDdouble {}
| XSDduration {}
| XSDdateTime {}
| XSDtime {}
| XSDdate {}
| XSDgYearMonth {}
| XSDgYear {}
| XSDgMonthDay {}
| XSDgDay {}
| XSDgMonth {}
| XSDNMTOKENS {}
| XSDIDREFS {}
| XSDENTITIES {}
| XSDboolean {}
| XSDanySimpleType {}
| XSDanyType {}
| XSDinteger { xerstruct->xsd_type = XSD_INTEGER; }
| XSDpositiveInteger { xerstruct->xsd_type = XSD_POSITIVEINTEGER; }
| XSDnonPositiveInteger { xerstruct->xsd_type = XSD_NONPOSITIVEINTEGER; }
| XSDnegativeInteger { xerstruct->xsd_type = XSD_NEGATIVEINTEGER; }
| XSDnonNegativeInteger { xerstruct->xsd_type = XSD_NONNEGATIVEINTEGER; }
| XSDunsignedLong { xerstruct->xsd_type = XSD_UNSIGNEDLONG; }
| XSDint { xerstruct->xsd_type = XSD_INT; }
| XSDunsignedInt { xerstruct->xsd_type = XSD_UNSIGNEDINT; }
| XSDunsignedShort { xerstruct->xsd_type = XSD_UNSIGNEDSHORT; }
| XSDbyte { xerstruct->xsd_type = XSD_BYTE; }
| XSDunsignedByte { xerstruct->xsd_type = XSD_UNSIGNEDBYTE; }
| XSDfloat { xerstruct->xsd_type = XSD_FLOAT; }
| XSDdouble { xerstruct->xsd_type = XSD_DOUBLE; }
| XSDduration { xerstruct->xsd_type = XSD_DURATION; }
| XSDdateTime { xerstruct->xsd_type = XSD_DATETIME; }
| XSDtime { xerstruct->xsd_type = XSD_TIME; }
| XSDdate { xerstruct->xsd_type = XSD_DATE; }
| XSDgYearMonth { xerstruct->xsd_type = XSD_GYEARMONTH; }
| XSDgYear { xerstruct->xsd_type = XSD_GYEAR; }
| XSDgMonthDay { xerstruct->xsd_type = XSD_GMONTHDAY; }
| XSDgDay { xerstruct->xsd_type = XSD_GDAY; }
| XSDgMonth { xerstruct->xsd_type = XSD_GMONTH; }
| XSDNMTOKENS { xerstruct->xsd_type = XSD_NMTOKENS; }
| XSDIDREFS { xerstruct->xsd_type = XSD_IDREFS; }
| XSDENTITIES { xerstruct->xsd_type = XSD_ENTITIES; }
| XSDboolean { xerstruct->xsd_type = XSD_BOOLEAN; }
| XSDanySimpleType { xerstruct->xsd_type = XSD_ANYSIMPLETYPE; }
| XSDanyType { xerstruct->xsd_type = XSD_ANYTYPE; }
;
......
......@@ -32,6 +32,7 @@
#include "datatypes.h"
#include "union.h"
#include "encdec.h"
#include "XSD_Types.hh"
#include "main.hh"
#include "ttcn3/compiler.h"
......@@ -1374,9 +1375,11 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
, sdef->elements[i].typegen
);
/* Type id attribute not needed for the first field in case of USE-TYPE */
// TODO: if USE-UNION there is no need to check the namelens
if (sdef->xerUseUnion || i > 0) src = mputprintf(src,
" need_type = (%s_xer_.namelens[1] > 2);\n"
, sdef->elements[i].typegen);
" need_type = (%s_xer_.namelens[1] > 2) || %s_xer_.xsd_type != XSD_NONE;\n"
, sdef->elements[i].typegen
, sdef->elements[i].typegen);
src = mputstr(src, " break;\n");
}
......@@ -1423,6 +1426,26 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
if (sdef->xerUseTypeAttr) {
src = mputstr(src,
" const boolean e_xer = is_exer(p_flavor);\n"
" boolean need_schema = FALSE;\n"
" char *schema_prefix = mprintf(\"xsd\");\n"
" int counter = 0;\n"
" // Find a unique prefix for the xsd schema\n"
" while (1) {\n"
" boolean changed = FALSE;\n"
" for (size_t i = 0; i < p_td.my_module->get_num_ns(); i++) {\n"
" if (p_td.my_module->get_ns(i)->px != NULL &&\n"
" strcmp(p_td.my_module->get_ns(i)->px, schema_prefix) == 0) {\n"
" Free(schema_prefix);\n"
" schema_prefix = mprintf(\"xsd%i\", counter);\n"
" counter++;\n"
" changed = TRUE;\n"
" break; // new maybe unique prefix found\n"
" }\n"
" }\n"
" if (!changed) {\n"
" break; //break when a unique prefix found\n"
" }\n"
" }\n"
" char *type_atr = NULL;\n"
" if (e_xer && (p_td.xer_bits & USE_TYPE_ATTR)) {\n"
" char *type_name = 0;\n"
......@@ -1433,29 +1456,44 @@ void defUnionClass(struct_def const *sdef, output_struct *output)
for (i = start_at; i < sdef->nElements; i++) {
src = mputprintf(src,
" case %s_%s:\n"
" if (%s_xer_.my_module != 0 && %s_xer_.ns_index != -1 &&\n"
" %s_xer_.namelens[1] > 2) {\n"
/* add the namespace prefix to the type attribute (if the name is not empty) */
" const namespace_t *my_ns = %s_xer_.my_module->get_ns(%s_xer_.ns_index);\n"
" if (my_ns->px[0] != 0) {\n"
" type_name = mprintf(\"%%s:\", my_ns->px);\n"
" }\n"
" }\n"
" type_name = mputstrn(type_name, %s_xer_.names[1], %s_xer_.namelens[1] - 2);\n"
, selection_prefix, sdef->elements[i].name);
if (!sdef->xerUseUnion) { // UseType
src = mputprintf(src,
" if (%s_xer_.my_module != 0 && %s_xer_.ns_index != -1 &&\n"
" %s_xer_.namelens[1] > 2) {\n"
/* add the namespace prefix to the type attribute (if the name is not empty) */
" const namespace_t *my_ns = %s_xer_.my_module->get_ns(%s_xer_.ns_index);\n"
" if (my_ns->px[0] != 0) {\n"
" type_name = mprintf(\"%%s:\", my_ns->px);\n"
" }\n"
" }\n"
" type_name = mputstrn(type_name, %s_xer_.names[1], %s_xer_.namelens[1] - 2);\n"
, sdef->elements[i].typegen, sdef->elements[i].typegen
, sdef->elements[i].typegen, sdef->elements[i].typegen
, sdef->elements[i].typegen, sdef->elements[i].typegen
, sdef->elements[i].typegen);