From 444b5e7942a1e1297d83015c96e966f0a150c152 Mon Sep 17 00:00:00 2001
From: BenceJanosSzabo <bence.janos.szabo@ericsson.com>
Date: Fri, 24 Mar 2017 14:36:17 +0100
Subject: [PATCH] Enabled XER encoding decoding for anytype

Change-Id: I13895202c4711f9554864893257d77a4a9e81873
Signed-off-by: BenceJanosSzabo <bence.janos.szabo@ericsson.com>
---
 compiler2/Type.cc                             |   5 +-
 compiler2/Type_chk.cc                         |  18 +-
 compiler2/Type_codegen.cc                     |   4 +-
 .../XML/TTCNandXML/AnytypeTest.ttcnpp         | 188 ++++++++++++++++++
 regression_test/XML/TTCNandXML/config.cfg     |   2 +
 5 files changed, 208 insertions(+), 9 deletions(-)
 create mode 100644 regression_test/XML/TTCNandXML/AnytypeTest.ttcnpp

diff --git a/compiler2/Type.cc b/compiler2/Type.cc
index 557155148..29137564f 100644
--- a/compiler2/Type.cc
+++ b/compiler2/Type.cc
@@ -5713,7 +5713,6 @@ namespace Common {
           case T_FUNCTION:  // TTCN-3
           case T_ALTSTEP:   // TTCN-3
           case T_TESTCASE:  // TTCN-3
-          case T_ANYTYPE:   // TTCN-3 anytype
             return memory.remember(t, ANSWER_NO);
 
           case T_UNDEF:
@@ -5723,7 +5722,9 @@ namespace Common {
 
           case T_SEQ_T:
           case T_SET_T:
-          case T_CHOICE_T: {
+          case T_CHOICE_T:
+          case T_ANYTYPE:   // TTCN-3 anytype
+          {
             // No field may reject XER
             size_t ncomp = t->get_nof_comps();
             for (size_t i = 0; i < ncomp; ++i) {
diff --git a/compiler2/Type_chk.cc b/compiler2/Type_chk.cc
index e9ec54f99..29501b709 100644
--- a/compiler2/Type_chk.cc
+++ b/compiler2/Type_chk.cc
@@ -105,6 +105,12 @@ void Type::chk()
     break;
   case T_ANYTYPE:
     // TODO maybe check for address type and add it automagically, then fall through
+    // anytype has untagged automatically
+    if(!xerattrib) {
+      xerattrib = new XerAttributes;
+    }
+    xerattrib->untagged_ = true;
+    // no break
   case T_SEQ_T:
   case T_SET_T:
   case T_CHOICE_T:
@@ -933,7 +939,7 @@ Value *Type::new_value_for_dfe(Type *last, const char *dfe_str, Common::Referenc
 
     return new Value(Common::Value::V_ENUM, val_id);
   }
-
+  // No T_ANYTYPE: anytype has untagged automatically.
   case T_CHOICE_A: case T_CHOICE_T: {
     // Try to guess which alternative the given DFE text belongs to.
     // Sort the fields based on typetype, so BOOL, INT, REAL, ENUM
@@ -1548,6 +1554,7 @@ void Type::chk_xer_untagged()
     // fall through
   case T_SEQ_A: case T_SEQ_T:
   case T_SET_A: case T_SET_T:
+  case T_ANYTYPE:
   case T_CHOICE_A: case T_CHOICE_T:
   case T_SEQOF: case T_SETOF:
     break; // acceptable
@@ -1598,7 +1605,8 @@ void Type::chk_xer_untagged()
         "the member of a sequence-of or set-of"); // X.693amd1, 32.2.4 b)
       break;
 
-    case T_CHOICE_T: {
+    case T_CHOICE_T:
+    case T_ANYTYPE: {
       size_t num_fields = parent_type->get_nof_comps();
       size_t num_empty = 0;
       for (size_t i = 0; i < num_fields; ++i) {
@@ -1756,6 +1764,7 @@ void Type::chk_xer_use_nil()
     case T_SEQ_A:
     case T_SET_T:
     case T_SET_A:
+    // No T_ANYTYPE: anytype has untagged automatically.
     case T_CHOICE_T:
     case T_CHOICE_A:
     case T_SEQOF:
@@ -1995,7 +2004,7 @@ void Type::chk_xer_use_type()
   if (!prefix) error("Type has USE-TYPE, but the module has no control namespace set");
 
   switch (last->typetype) {
-  // USE-TYPE applied to anytype ? Just say no.
+  // No T_ANYTYPE: anytype has untagged automatically.
   case T_CHOICE_A: case T_CHOICE_T: { // must be CHOICE; 37.2.1
     if (xerattrib->untagged_ || xerattrib->useUnion_) { // 37.2.5
       error("A type with USE-TYPE encoding instruction shall not also have"
@@ -2408,6 +2417,7 @@ void Type::chk_xer() { // XERSTUFF semantic check
           switch (cft->get_type_refd_last()->typetype) {
           case T_SEQ_A: case T_SEQ_T:
           case T_SET_A: case T_SET_T:
+          case T_ANYTYPE:
           case T_CHOICE_A: case T_CHOICE_T:
           case T_SEQOF:
           case T_SETOF:
@@ -2449,7 +2459,7 @@ void Type::chk_xer() { // XERSTUFF semantic check
     } // if the_one
 
     if (empties.size() > 1
-      && (typetype==T_CHOICE_A || typetype==T_CHOICE_T)) {
+      && (typetype==T_CHOICE_A || typetype==T_CHOICE_T || typetype==T_ANYTYPE)) {
       warning("More than one field can have empty XML. Decoding of empty"
         " XML is ambiguous, %s chosen arbitrarily.",
         empties.get_nth_elem(empties.size()-1)->get_name().get_name().c_str());
diff --git a/compiler2/Type_codegen.cc b/compiler2/Type_codegen.cc
index b86aba055..0e7fd7ce9 100644
--- a/compiler2/Type_codegen.cc
+++ b/compiler2/Type_codegen.cc
@@ -606,9 +606,7 @@ void Type::generate_code_xerdescriptor(output_struct* target)
   size_t last_len = 2 + last_s.size();    // 2 for > \n
   size_t bxer_len = 2 + bxer_name.size(); // 2 for > \n
   
-  if ((T_SEQOF == last->typetype || T_SETOF == last->typetype) &&
-      T_ANYTYPE != last->u.seof.ofType->get_type_refd_last()->typetype) {
-    // anytypes don't have XER descriptors
+  if ((T_SEQOF == last->typetype || T_SETOF == last->typetype)) {
     oftype_descr_name = mprintf("&%s_xer_", last->u.seof.ofType->get_genname_typedescriptor(my_scope).c_str());
   }
   
diff --git a/regression_test/XML/TTCNandXML/AnytypeTest.ttcnpp b/regression_test/XML/TTCNandXML/AnytypeTest.ttcnpp
new file mode 100644
index 000000000..f93241920
--- /dev/null
+++ b/regression_test/XML/TTCNandXML/AnytypeTest.ttcnpp
@@ -0,0 +1,188 @@
+/******************************************************************************
+ * Copyright (c) 2000-2017 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
+ *
+ ******************************************************************************/
+module AnytypeTest {
+
+modulepar boolean Anytype_verbose := false;
+#define verbose Anytype_verbose
+
+#include "../macros.ttcnin"
+
+
+
+type component SAP {}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+DECLARE_XER_ENCODERS(anytype, at);
+DECLARE_EXER_ENCODERS(anytype, at);
+
+const anytype c_anytype := {charstring := "str"};
+
+const universal charstring c_anytype_str_b :=
+"<anytype>\n\t<charstring>str</charstring>\n</anytype>\n\n";
+
+const universal charstring c_anytype_str :=
+"<anytype>\n\t<charstring>str</charstring>\n</anytype>\n\n";
+
+testcase enc_anytype() runs on SAP
+{
+  CHECK_METHOD(bxer_enc_at, c_anytype, c_anytype_str_b);
+  CHECK_METHOD(exer_enc_at, c_anytype, c_anytype_str);
+}
+
+testcase dec_anytype() runs on SAP
+{
+  CHECK_DECODE(bxer_dec_at, c_anytype_str_b, anytype, c_anytype);
+  CHECK_DECODE(exer_dec_at, c_anytype_str, anytype, c_anytype);
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+type anytype MyAnytype;
+
+DECLARE_XER_ENCODERS(MyAnytype, atal);
+DECLARE_EXER_ENCODERS(MyAnytype, atal);
+
+const MyAnytype c_anytypeal := {charstring := "str"};
+
+const universal charstring c_anytypeal_str_b :=
+"<MyAnytype>\n\t<charstring>str</charstring>\n</MyAnytype>\n\n";
+
+const universal charstring c_anytypeal_str :=
+"<MyAnytype>\n\t<charstring>str</charstring>\n</MyAnytype>\n\n";
+
+testcase enc_anytypealias() runs on SAP
+{
+  CHECK_METHOD(bxer_enc_atal, c_anytypeal, c_anytypeal_str_b);
+  CHECK_METHOD(exer_enc_atal, c_anytypeal, c_anytypeal_str);
+}
+
+testcase dec_anytypealias() runs on SAP
+{
+  CHECK_DECODE(bxer_dec_atal, c_anytypeal_str_b, MyAnytype, c_anytypeal);
+  CHECK_DECODE(exer_dec_atal, c_anytypeal_str, MyAnytype, c_anytypeal);
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+type record of anytype RoAnytype;
+
+DECLARE_XER_ENCODERS(RoAnytype, roat);
+DECLARE_EXER_ENCODERS(RoAnytype, roat);
+
+const RoAnytype c_roanytype := { {charstring := "str"}, {integer := 4}, {octetstring := '012345'O}, {integer := 3}};
+
+const universal charstring c_roanytype_str_b :=
+"<RoAnytype>\n"&
+"\t<charstring>str</charstring>\n"&
+"\t<integer>4</integer>\n"&
+"\t<octetstring>012345</octetstring>\n"&
+"\t<integer>3</integer>\n"&
+"</RoAnytype>\n\n";
+
+const universal charstring c_roanytype_str :=
+"<RoAnytype>\n"&
+"\t<charstring>str</charstring>\n"&
+"\t<integer>4</integer>\n"&
+"\t<octetstring>012345</octetstring>\n"&
+"\t<integer>3</integer>\n"&
+"</RoAnytype>\n\n";
+
+testcase enc_roanytype() runs on SAP
+{
+  CHECK_METHOD(bxer_enc_roat, c_roanytype, c_roanytype_str_b);
+  CHECK_METHOD(exer_enc_roat, c_roanytype, c_roanytype_str);
+}
+
+testcase dec_roanytype() runs on SAP
+{
+  CHECK_DECODE(bxer_dec_roat, c_roanytype_str_b, RoAnytype, c_roanytype);
+  CHECK_DECODE(exer_dec_roat, c_roanytype_str, RoAnytype, c_roanytype);
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+type record MyAnytypeRec {
+  anytype anytype_field,
+  MyAnytype anytype_field_alias,
+  RoAnytype anytype_field_ro,
+  charstring str
+}
+
+DECLARE_XER_ENCODERS(MyAnytypeRec, recat);
+DECLARE_EXER_ENCODERS(MyAnytypeRec, recat);
+
+const MyAnytypeRec c_myanytyperec := 
+{anytype_field := {charstring := "abc"},
+anytype_field_alias := {charstring := "def"},
+anytype_field_ro := { {charstring := "ttt"}, {integer := 4}},
+str := "ghi"};
+
+const universal charstring c_myanytyperec_str_b :=
+"<MyAnytypeRec>\n"&
+"\t<anytype_field>\n"&
+"\t\t<charstring>abc</charstring>\n"&
+"\t</anytype_field>\n"&
+"\t<anytype_field_alias>\n"&
+"\t\t<charstring>def</charstring>\n"&
+"\t</anytype_field_alias>\n"&
+"\t<anytype_field_ro>\n"&
+"\t\t<charstring>ttt</charstring>\n"&
+"\t\t<integer>4</integer>\n"&
+"\t</anytype_field_ro>\n"&
+"\t<str>ghi</str>\n"&
+"</MyAnytypeRec>\n\n";
+
+const universal charstring c_myanytyperec_str :=
+"<MyAnytypeRec>\n"&
+"\t<charstring>abc</charstring>\n"&
+"\t<charstring>def</charstring>\n"&
+"\t<anytype_field_ro>\n"&
+"\t\t<charstring>ttt</charstring>\n"&
+"\t\t<integer>4</integer>\n"&
+"\t</anytype_field_ro>\n"&
+"\t<str>ghi</str>\n"&
+"</MyAnytypeRec>\n\n";
+
+testcase enc_myanytyperec() runs on SAP
+{
+  CHECK_METHOD(bxer_enc_recat, c_myanytyperec, c_myanytyperec_str_b);
+  CHECK_METHOD(exer_enc_recat, c_myanytyperec, c_myanytyperec_str);
+}
+
+testcase dec_myanytyperec() runs on SAP
+{
+  CHECK_DECODE(bxer_dec_recat, c_myanytyperec_str_b, MyAnytypeRec, c_myanytyperec);
+  CHECK_DECODE(exer_dec_recat, c_myanytyperec_str, MyAnytypeRec, c_myanytyperec);
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+control {
+  execute(enc_anytype());
+  execute(dec_anytype());
+
+  execute(enc_anytypealias());
+  execute(dec_anytypealias());
+
+  execute(enc_roanytype());
+  execute(dec_roanytype());
+
+  execute(enc_myanytyperec());
+  execute(dec_myanytyperec());
+}
+
+}
+with {
+  encode "XML"
+  extension "anytype integer, charstring, octetstring"}
+
diff --git a/regression_test/XML/TTCNandXML/config.cfg b/regression_test/XML/TTCNandXML/config.cfg
index 5265c7139..eac803835 100644
--- a/regression_test/XML/TTCNandXML/config.cfg
+++ b/regression_test/XML/TTCNandXML/config.cfg
@@ -8,6 +8,7 @@
 # Contributors:
 #   Balasko, Jeno
 #   Raduly, Csaba
+#   Szabo, Bence Janos
 #
 ###############################################################################
 [EXECUTE]
@@ -30,6 +31,7 @@ DFEAttribTest
 Marx
 Regressions
 FractionDigitsTest
+AnytypeTest
 
 [LOGGING]
 FileMask := LOG_ALL | USER | DEBUG_ENCDEC
-- 
GitLab