Sync with 5.3.0
[deliverable/titan.core.git] / compiler2 / record.c
index 63e68532d6b5dd9e999ca98c41ef37d836c4e2d7..eeda1762889bd0bdd63dd12f4eb2c0bd4206b604 100644 (file)
@@ -1799,11 +1799,6 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
   /* start_at is the index of the first "real" member of the record */
   size_t start_at = uo + (sdef->xerUseOrderPossible != 0);
 
-  /* Max. number of EMBED-VALUES strings. The actual number may change
-   * at runtime: omitted optional (non-attribute) members decrease the
-   * number of embed strings needed, and xsi:nil=true sets it to zero.*/
-  size_t max_embed;
-
   /* Number of optional non-attributes */
   size_t n_opt_elements = 0;
 
@@ -1828,7 +1823,6 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
       ++n_opt_elements;
     }
   }
-  max_embed = sdef->nElements - start_at - num_attributes + 1;
 
   /* Write some helper functions */
   def = mputstr(def,
@@ -1904,7 +1898,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
   /* * * * * * * * * * XER_encode * * * * * * * * * * * * * * */
   src = mputprintf(src,
     "int %s::XER_encode(const XERdescriptor_t& p_td, "
-    "TTCN_Buffer& p_buf, unsigned int p_flavor, int p_indent) const\n"
+    "TTCN_Buffer& p_buf, unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const\n"
     "{\n"
     "  if (!is_bound()) TTCN_EncDec_ErrorContext::error"
     "(TTCN_EncDec::ET_UNBOUND, \"Encoding an unbound value.\");\n"
@@ -1994,7 +1988,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
       "  if (e_xer && (p_td.xer_bits & USE_QNAME)) {\n"
       "    if (field_%s.is_value()) {\n"
       "      p_buf.put_s(11, (cbyte*)\" xmlns:b0='\");\n"
-      "      field_%s.XER_encode(%s_xer_, p_buf, p_flavor | XER_LIST, p_indent+1);\n"
+      "      field_%s.XER_encode(%s_xer_, p_buf, p_flavor | XER_LIST, p_indent+1, 0);\n"
       "      p_buf.put_c('\\'');\n"
       "    }\n"
       "    if (p_td.xer_bits & XER_ATTRIBUTE) begin_attribute(p_td, p_buf);\n"
@@ -2003,7 +1997,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
       "      p_buf.put_s(3, (cbyte*)\"b0:\");\n"
       "      sub_len += 3;\n"
       "    }\n"
-      "    sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor | XER_LIST, p_indent+1);\n"
+      "    sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor | XER_LIST, p_indent+1, 0);\n"
       "    if (p_td.xer_bits & XER_ATTRIBUTE) p_buf.put_c('\\'');\n"
       "  } else" /* no newline */
       , sdef->elements[0].name
@@ -2017,12 +2011,10 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
   /* First, the EMBED-VALUES member as an ordinary member if not doing EXER */
   if (sdef->xerEmbedValuesPossible) {
     src = mputprintf(src,
-      "  int exp_emb = %u;\n"
       "  if (!e_xer && (p_td.xer_bits & EMBED_VALUES)) {\n"
       "    ec_1.set_msg(\"%s': \");\n"
-      "    sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1);\n"
+      "    sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1, 0);\n"
       "  }\n"
-      , (unsigned int)max_embed
       , sdef->elements[0].dispname
       , sdef->elements[0].name, sdef->elements[0].typegen
     );
@@ -2031,7 +2023,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
   if (sdef->xerUseOrderPossible) {
     src = mputprintf(src,
       "  if (!e_xer && (p_td.xer_bits & USE_ORDER)) {\n"
-      "    sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1);\n"
+      "    sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1, 0);\n"
       "  }\n"
       , sdef->elements[uo].name, sdef->elements[uo].typegen
     );
@@ -2067,7 +2059,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
     if (i==0 && sdef->xerEmbedValuesPossible && (sdef->elements[i].xerAnyKind & ANY_ATTRIB_BIT)) continue ;
     src = mputprintf(src,
       "  ec_1.set_msg(\"%s': \");\n"
-      "  tmp_len = field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1);\n"
+      "  tmp_len = field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1, 0);\n"
       "  %ssub_len += tmp_len;\n" /* do not add if attribute and EXER */
       , sdef->elements[i].dispname
       , sdef->elements[i].name, sdef->elements[i].typegen
@@ -2098,46 +2090,19 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
   }
 
   if (sdef->xerEmbedValuesPossible) {
-    size_t op;
     src = mputprintf(src,
       "  ec_1.set_msg(\"%s': \");\n"
       "  if (e_xer && (p_td.xer_bits & EMBED_VALUES)) {\n"
-      , sdef->elements[0].dispname
-    );
-
-    if (sdef->xerUseNilPossible) {
-      src = mputstr(src, /* 25.2.6 a */
-        "    if ((p_td.xer_bits & USE_NIL) && nil_attribute) exp_emb = 0;\n"
-        "    else {\n");
-    }
-
-    for (op = 0; op < sdef->nElements; ++op) {
-      if (sdef->elements[op].isOptional && !sdef->elements[op].xerAttribute) {
-        src = mputprintf(src,
-          "    if (!field_%s.ispresent()) --exp_emb;\n"
-          , sdef->elements[op].name
-        );
-      }
-    }
-
-    if (sdef->xerUseNilPossible) src = mputstr(src, "    }\n");
-
-    src = mputprintf(src,
-      "    if (field_%s.size_of()!=exp_emb) "
-      "TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT, "
-      "\"Wrong number %%d of EMBED-VALUEs, expected %%d\", field_%s.size_of(), exp_emb);\n"
-      , sdef->elements[0].name
-      , sdef->elements[0].name);
     /* write the first string (must come AFTER the attributes) */
-    src = mputprintf(src,
-      "    %ssub_len += field_%s[0].XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1);\n"
+      "    if (field_%s.size_of() > 0) {\n"
+      "      sub_len += field_%s[0].XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n"
+      "    }\n"
       "  }\n"
-      , (sdef->xerUseNilPossible ? "if (exp_emb > 0) " : "")
-      , sdef->elements[0].name);
+      , sdef->elements[0].dispname, sdef->elements[0].name, sdef->elements[0].name);
     if (want_namespaces) { /* here's another chance */
       src = mputprintf(src,
         "  else if ( !(p_td.xer_bits & EMBED_VALUES)) {\n"
-        "    %sfield_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1);\n"
+        "    %sfield_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+1, 0);\n"
         "  }\n"
         , ((sdef->elements[0].xerAnyKind & ANY_ATTRIB_BIT) ? "" : "sub_len += " )
         , sdef->elements[0].name, sdef->elements[0].typegen
@@ -2148,6 +2113,24 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
   /* Then, all the non-attributes. Structuring the code like this depends on
    * all attributes appearing before all non-attributes (excluding
    * special members for EMBED-VALUES, USE-ORDER, etc.) */
+  if (sdef->xerEmbedValuesPossible) {
+    src = mputprintf(src,
+      "  embed_values_enc_struct_t* emb_val = 0;\n"
+      "  if (e_xer && (p_td.xer_bits & EMBED_VALUES) && field_%s.size_of() > 1) {\n"
+      "    emb_val = new embed_values_enc_struct_t;\n"
+      /* If the first field is a record of ANY-ELEMENTs, then it won't be a pre-generated
+       * record of universal charstring, so it needs a cast to avoid a compilation error */
+      "    emb_val->embval_array%s = (const PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING%s*)&field_%s;\n"
+      "    emb_val->embval_array%s = NULL;\n"
+      "    emb_val->embval_index = 1;\n"
+      "  }\n"
+      , sdef->elements[0].name
+      , sdef->elements[0].optimizedMemAlloc ? "_opt" : "_reg"
+      , sdef->elements[0].optimizedMemAlloc ? "__OPTIMIZED" : ""
+      , sdef->elements[0].name
+      , sdef->elements[0].optimizedMemAlloc ? "_reg" : "_opt");
+  }
+  
   if (sdef->xerUseOrderPossible) {
     int max_ordered = sdef->nElements - start_at - num_attributes;
     int min_ordered = max_ordered - n_opt_elements;
@@ -2169,7 +2152,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
       src = mputprintf(src,
         "  if (!nil_attribute) {\n"
         "%s"
-        "  if (!e_xer) sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+!omit_tag);\n"
+        "  if (!e_xer) sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+!omit_tag, 0);\n"
         "  else" /* no newline */
         , (sdef->xerUseNilPossible ? "  if (!(p_td.xer_bits & USE_ORDER)) p_flavor |= (p_td.xer_bits & USE_NIL);\n" : "")
         /* If USE-ORDER is on, the tag-removing effect of USE-NIL has been
@@ -2224,7 +2207,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
       src = mputprintf(src,
         "    case %lu:\n"
         "      ec_1.set_msg(\"%s': \");\n"
-        "      sub_len += field_%s%s%s%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+!omit_tag);\n"
+        "      sub_len += field_%s%s%s%s.XER_encode(%s_xer_, p_buf, p_flavor, p_indent+!omit_tag, %s);\n"
 
         , (unsigned long)offset++
         , sdef->elements[i].dispname
@@ -2233,7 +2216,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
         , (sdef->xerUseNilPossible ? sdef->elements[i].name : "")
         , (sdef->xerUseNilPossible ? "()" : "")
         , sdef->elements[i].typegen
-
+        , sdef->xerEmbedValuesPossible ? "emb_val" : "0"
       );
 
       src = mputstr(src, "    break;\n");
@@ -2246,10 +2229,13 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
 
     if (sdef->xerEmbedValuesPossible) {
       src = mputprintf(src,
-        "    if (e_xer && i+1 < exp_emb && (p_td.xer_bits & EMBED_VALUES)) { // embed-val\n"
-        "      field_%s[i+1].XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1);\n"
+        "    if (e_xer && (p_td.xer_bits & EMBED_VALUES) && 0 != emb_val &&\n"
+        "        emb_val->embval_index < field_%s.size_of()) { // embed-val\n"
+        "      field_%s[emb_val->embval_index].XER_encode(\n"
+        "        UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n"
+        "      ++emb_val->embval_index;\n"
         "    }\n"
-        , sdef->elements[0].name);
+        , sdef->elements[0].name, sdef->elements[0].name);
     }
 
 
@@ -2267,22 +2253,38 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
         , sdef->elements[i].dispname
       );
       src = mputprintf(src,
-        "  sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor%s, p_indent+!omit_tag);\n"
+        "  sub_len += field_%s.XER_encode(%s_xer_, p_buf, p_flavor%s, p_indent+!omit_tag, %s);\n"
         , sdef->elements[i].name, sdef->elements[i].typegen
         , sdef->xerUseNilPossible ? "| (p_td.xer_bits & USE_NIL)" : ""
+        , sdef->xerEmbedValuesPossible ? "emb_val" : "0"
       );
 
       if (sdef->xerEmbedValuesPossible) {
-        unsigned long idx = i - start_at - num_attributes + 1;
         src = mputprintf(src,
-          "  if (e_xer && exp_emb > %lu && (p_td.xer_bits & EMBED_VALUES)) {\n"
-          "    field_%s[%lu].XER_encode(UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1);\n"
+          "  if (e_xer && (p_td.xer_bits & EMBED_VALUES) && 0 != emb_val &&\n"
+          "      emb_val->embval_index < field_%s.size_of()) {\n"
+          "    field_%s[emb_val->embval_index].XER_encode(\n"
+          "      UNIVERSAL_CHARSTRING_xer_, p_buf, p_flavor | EMBED_VALUES, p_indent+1, 0);\n"
+          "    ++emb_val->embval_index;\n"
           "  }\n"
-          , idx
-          , sdef->elements[0].name, idx);
+          , sdef->elements[0].name, sdef->elements[0].name);
       }
     } /* next field when not USE-ORDER */
 
+  if (sdef->xerEmbedValuesPossible) {
+    src = mputprintf(src,
+      "  if (0 != emb_val) {\n"
+      "    if (emb_val->embval_index < field_%s.size_of()) {\n"
+      "      ec_1.set_msg(\"%s': \");\n"
+      "      TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_CONSTRAINT,\n"
+      "        \"Too many EMBED-VALUEs specified: %%d (expected %%d or less)\",\n"
+      "        field_%s.size_of(), emb_val->embval_index);\n"
+      "    }\n"
+      "    delete emb_val;\n"
+      "  }\n"
+      , sdef->elements[0].name, sdef->elements[0].name, sdef->elements[0].name);
+  }
+
   src = mputstr(src, "  } // QN?\n");
 
   {
@@ -2335,7 +2337,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
 
   src = mputprintf(src, /* XERSTUFF decodegen for record/SEQUENCE*/
     "int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader,"
-    " unsigned int p_flavor)\n"
+    " unsigned int p_flavor, embed_values_dec_struct_t*)\n"
     "{\n"
     "  bound_flag = TRUE;\n"
     /* Remove XER_LIST, XER_RECOF from p_flavor. This is not required
@@ -2441,8 +2443,9 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
       }
       else { /* must be the ANY-ATTRIBUTES */
         src = mputprintf(src,
-          "  field_%s.set_size(0);\n",
-          sdef->elements[aaa].name);
+          "  field_%s%s;\n"
+        , sdef->elements[aaa].name
+        , sdef->elements[aaa].isOptional ? " = OMIT_VALUE" : ".set_size(0)");
       }
     }
 
@@ -2493,7 +2496,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
       src = mputprintf(src,
         "    if (check_name(attr_name, %s_xer_, 1) && check_namespace(ns_uri, %s_xer_)) {\n"
         "      ec_1.set_msg(\"%s': \");\n"
-        "      field_%s.XER_decode(%s_xer_, p_reader, p_flavor | (p_td.xer_bits & USE_NIL));\n"
+        "      field_%s.XER_decode(%s_xer_, p_reader, p_flavor | (p_td.xer_bits & USE_NIL), 0);\n"
         "    } else"
         , sdef->elements[i].typegen, sdef->elements[i].typegen
         , sdef->elements[i].dispname /* set_msg */
@@ -2514,8 +2517,8 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
       /* we are at a dangling else */
       src = mputprintf(src,
         "    {\n"
-        "      TTCN_EncDec_ErrorContext ec_0(\"Attribute %%d: \", (int)num_aa);"
-        "      UNIVERSAL_CHARSTRING& new_elem = field_%s[num_aa++];\n"
+        "      TTCN_EncDec_ErrorContext ec_0(\"Attribute %%d: \", (int)num_aa);\n"
+        "      UNIVERSAL_CHARSTRING& new_elem = field_%s%s[num_aa++];\n"
         /* Construct the AnyAttributeFormat (X.693amd1, 18.2.6) */
         "      TTCN_Buffer aabuf;\n"
         "      const xmlChar *x_name = p_reader.LocalName();\n"
@@ -2536,6 +2539,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
         "      new_elem.decode_utf8(aabuf.get_len(), aabuf.get_data());\n"
         "    } \n"
         , sdef->elements[aa_index].name
+        , sdef->elements[aa_index].isOptional ? "()" : ""
         , sdef->elements[aa_index].typegen, sdef->elements[aa_index].typegen
       );
     }
@@ -2584,7 +2588,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
       "  if (!(p_td.xer_bits & EMBED_VALUES)) {\n"
       "    ec_1.set_msg(\"%s': \");\n"
       "    field_%s.XER_decode(%s_xer_, p_reader, "
-      "p_flavor | (p_td.xer_bits & USE_NIL)| (tag_closed ? PARENT_CLOSED : 0));\n"
+      "p_flavor | (p_td.xer_bits & USE_NIL)| (tag_closed ? PARENT_CLOSED : 0), 0);\n"
       "  }\n"
       , sdef->elements[0].dispname
       , sdef->elements[0].name, sdef->elements[0].typegen
@@ -2618,7 +2622,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
       src = mputprintf(src,
         "  {\n"
         "    ec_1.set_msg(\"%s': \");\n"
-        "    field_%s.XER_decode(%s_xer_, p_reader, p_flavor | (p_td.xer_bits & USE_NIL));\n"
+        "    field_%s.XER_decode(%s_xer_, p_reader, p_flavor | (p_td.xer_bits & USE_NIL), 0);\n"
         "  }\n"
         , sdef->elements[i].dispname
         , sdef->elements[i].name, sdef->elements[i].typegen
@@ -2633,6 +2637,25 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
   if (num_attributes || sdef->xerEmbedValuesPossible || sdef->xerUseOrderPossible) {
     src = mputstr(src, "}\n");
   }
+  
+  if (sdef->xerEmbedValuesPossible) {
+    src = mputprintf(src,
+      "  embed_values_dec_struct_t* emb_val = 0;\n"
+      "  if (e_xer && (p_td.xer_bits & EMBED_VALUES)) {\n"
+      "    emb_val = new embed_values_dec_struct_t;\n"
+      /* If the first field is a record of ANY-ELEMENTs, then it won't be a pre-generated
+       * record of universal charstring, so it needs a cast to avoid a compilation error */
+      "    emb_val->embval_array%s = (PreGenRecordOf::PREGEN__RECORD__OF__UNIVERSAL__CHARSTRING%s*)&field_%s;\n"
+      "    emb_val->embval_array%s = NULL;\n"
+      "    emb_val->embval_index = 0;\n"
+      "    field_%s.set_size(0);\n"
+      "  }\n"
+      , sdef->elements[0].optimizedMemAlloc ? "_opt" : "_reg"
+      , sdef->elements[0].optimizedMemAlloc ? "__OPTIMIZED" : ""
+      , sdef->elements[0].name
+      , sdef->elements[0].optimizedMemAlloc ? "_reg" : "_opt"
+      , sdef->elements[0].name);
+  }
 
   if (sdef->xerUseOrderPossible) {
     size_t begin = start_at + num_attributes; /* first non-attribute */
@@ -2657,23 +2680,6 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
       }
     }
 
-    if (sdef->xerEmbedValuesPossible) { /* EMBED-VALUES with USE-ORDER */
-      src = mputprintf(src,
-        "    if (p_td.xer_bits & EMBED_VALUES) {\n"
-        "    field_%s.set_size(%lu);\n"
-        "    %s::of_type empty_string(\"\");\n"
-        "    for (int j_j=0; j_j<%lu; ++j_j) {\n"
-        "      field_%s[j_j] = empty_string;\n"
-        "    }\n"
-        "    }\n"
-        , sdef->elements[0].name
-        , (unsigned long)(n_embed + 1)
-        , sdef->elements[0].type
-        , (unsigned long)(n_embed + 1)
-        , sdef->elements[0].name
-      );
-    }
-
     if (sdef->xerUseNilPossible) { /* USE-NIL and USE-ORDER */
       src = mputprintf(src,
         "    if (nil_attribute) field_%s.set_size(0);\n    else"
@@ -2684,18 +2690,26 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
       "    {\n"
       "    field_%s.set_size(0);\n"
       "    int e_val, num_seen = 0, *seen_f = new int[%lu];\n"
-      "    for (int i=0; i < %lu; ++i) {\n"
-      "      for (rd_ok=p_reader.Ok(); rd_ok==1; rd_ok=p_reader.Read()) {\n"
       , sdef->elements[uo].name
       , (unsigned long)(n_embed)
+    );
+    if (sdef->xerEmbedValuesPossible) {
+      // The index of the latest embedded value can change outside of this function
+      // (if the field is a untagged record of), in this case the next value should
+      // be ignored, as it's already been handled by the record of
+      src = mputstr(src, "    int last_embval_index = 0;\n");
+    }
+    src = mputprintf(src,
+      "    for (int i=0; i < %lu; ++i) {\n"
+      "      for (rd_ok=p_reader.Ok(); rd_ok==1; rd_ok=p_reader.Read()) {\n"
       , (unsigned long)(n_embed));
 
     if (sdef->xerEmbedValuesPossible) {
       /* read and store embedValues text if present */
       src = mputprintf(src,
-        "        if ((p_td.xer_bits & EMBED_VALUES) && (p_reader.NodeType()==XML_READER_TYPE_TEXT)) {\n"
+        "        if (0 != emb_val && p_reader.NodeType()==XML_READER_TYPE_TEXT) {\n"
         "          UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
-        "          field_%s[i] = emb_ustr;\n"
+        "          field_%s[emb_val->embval_index] = emb_ustr;\n"
         "        }\n"
         , sdef->elements[0].name);
     }
@@ -2706,7 +2720,16 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
       "      }\n"
       "      if (rd_ok != 1) break;\n"
       "      const char * x_name = (const char*)p_reader.LocalName();\n" /* Name or LocalName ? */);
-      
+    
+    if (sdef->xerEmbedValuesPossible) {
+      src = mputstr(src,
+        "      if (0 != emb_val) {\n"
+        "        if (last_embval_index == emb_val->embval_index) {\n"
+        "          ++emb_val->embval_index;\n"
+        "        }\n"
+        "        last_embval_index = emb_val->embval_index;\n"
+        "      }\n");
+    }
 
     /* * * * * code for USE-ORDER * * * * */
 
@@ -2716,20 +2739,20 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
         src = mputprintf(src,
           "      if (check_name(x_name, %s_xer_, 1)) {\n"
           "        ec_1.set_msg(\"%s': \");\n"
-          "        field_%s%s%s%s.XER_decode(%s_xer_, p_reader, p_flavor);\n"
+          "        field_%s%s%s%s.XER_decode(%s_xer_, p_reader, p_flavor, %s);\n"
           , sdef->elements[i].typegen
           , sdef->elements[i].dispname
-
           , (sdef->xerUseNilPossible ? sdef->elements[sdef->nElements-1].name: sdef->elements[i].name)
           , (sdef->xerUseNilPossible ? "()." : "")
           , (sdef->xerUseNilPossible ? sdef->elements[i].name : "")
           , (sdef->xerUseNilPossible ? "()" : "")
           , sdef->elements[i].typegen
+          , sdef->xerEmbedValuesPossible ? "emb_val" : "0"
         );
         src = mputprintf(src,
-          "        field_%s[i] = e_val = %s::of_type::%s;\n"
-          , sdef->elements[uo].name
-          , sdef->elements[uo].typegen, sdef->elements[i].name);
+        "        field_%s[i] = e_val = %s::of_type::%s;\n"
+        , sdef->elements[uo].name
+        , sdef->elements[uo].typegen, sdef->elements[i].name);
         src = mputstr(src, "      }\n      else");
       }
     }
@@ -2753,7 +2776,7 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
           "          }\n"
           "          if (!next_any) {\n"
           "            ec_1.set_msg(\"%s': \");\n"
-          "            field_%s%s%s%s.XER_decode(%s_xer_, p_reader, p_flavor);\n"
+          "            field_%s%s%s%s.XER_decode(%s_xer_, p_reader, p_flavor, 0);\n"
           "            field_%s[i] = e_val;\n"
           "            any_found = true;\n"
           "          }\n"
@@ -2781,11 +2804,16 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
     if (sdef->xerEmbedValuesPossible) {
       /* read and store embedValues text if present */
       src = mputprintf(src,
-        "    if ((p_td.xer_bits & EMBED_VALUES) && (p_reader.NodeType()==XML_READER_TYPE_TEXT)) {\n"
-        "      UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
-        "      field_%s[%lu] = emb_ustr;\n"
+        "    if (0 != emb_val) {\n"
+        "      if (p_reader.NodeType()==XML_READER_TYPE_TEXT) {\n"
+        "        UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
+        "        field_%s[emb_val->embval_index] = emb_ustr;\n"
+        "      }\n"
+        "      if (last_embval_index == emb_val->embval_index) {\n"
+        "        ++emb_val->embval_index;\n"
+        "      }\n"
         "    }\n"
-        , sdef->elements[0].name, (unsigned long)(n_embed));
+        , sdef->elements[0].name);
     }
 
     src = mputprintf(src,
@@ -2816,16 +2844,29 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
       "    p_reader.MoveToElement();\n"
       "  } else {\n");
   }
+  if (sdef->xerEmbedValuesPossible) {
+    // The index of the latest embedded value can change outside of this function
+    // (if the field is a untagged record of), in this case the next value should
+    // be ignored, as it's already been handled by the record of
+    // Omitted fields can also reset this value
+    src = mputstr(src, "  int last_embval_index = 0;\n");
+  }
   /* for all the non-attribute fields... */
   for (i = start_at + num_attributes; i < sdef->nElements; ++i) {
     if (sdef->xerEmbedValuesPossible) {
       /* read and store embedValues text if present */
       src = mputprintf(src,
-        "  if ((p_td.xer_bits & EMBED_VALUES) && (p_reader.NodeType()==XML_READER_TYPE_TEXT)) {\n"
-        "    UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
-        "    field_%s[%lu] = emb_ustr;\n"
+        "  if (0 != emb_val) {\n"
+        "    if (p_reader.NodeType()==XML_READER_TYPE_TEXT) {\n"
+        "      UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
+        "      field_%s[emb_val->embval_index] = emb_ustr;\n"
+        "    }\n"
+        "    if (last_embval_index == emb_val->embval_index) {\n"
+        "      ++emb_val->embval_index;\n"
+        "    }\n"
+        "    last_embval_index = emb_val->embval_index;\n"
         "  }\n"
-        , sdef->elements[0].name, (unsigned long)(i-(start_at+num_attributes)));
+        , sdef->elements[0].name);
     }
     /* The DEFAULT-FOR-EMPTY member can not be involved with EMBED-VALUES,
      * so we can use the same pattern: optional "if(...) else" before {}
@@ -2860,69 +2901,59 @@ void gen_xer(const struct_def *sdef, char **pdef, char **psrc)
     
     src = mputprintf(src, 
       "    field_%s.XER_decode(%s_xer_, p_reader, p_flavor"
-      " | (p_td.xer_bits & USE_NIL)| (tag_closed ? PARENT_CLOSED : 0));\n"
+      " | (p_td.xer_bits & USE_NIL)| (tag_closed ? PARENT_CLOSED : 0), %s);\n"
       "  }\n"
-      , sdef->elements[i].name, sdef->elements[i].typegen);
+      , sdef->elements[i].name, sdef->elements[i].typegen
+      , sdef->xerEmbedValuesPossible ? "emb_val" : "0");
+    if (sdef->xerEmbedValuesPossible) {
+      src = mputprintf(src,
+        "  if (!field_%s.is_present()) {\n"
+        // there was no new element, the last embedded value is for the next field
+        // (or the end of the record if this is the last field) 
+        "    last_embval_index = -1;\n"
+        "  }\n"
+        , sdef->elements[i].name);
+    }
   } /* next field */
   
-  if (sdef->xerUseNilPossible) {
-    src = mputstr(src, "  } // use_nil\n");
-  }
-
   if (sdef->xerEmbedValuesPossible) {
     /* read and store embedValues text if present */
     src = mputprintf(src,
-      "  if ((p_td.xer_bits & EMBED_VALUES) && (p_reader.NodeType()==XML_READER_TYPE_TEXT)) {\n"
-      "    UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
-      "    field_%s[%lu] = emb_ustr;\n"
+      "  if (0 != emb_val) {\n"
+      "    if (p_reader.NodeType()==XML_READER_TYPE_TEXT) {\n"
+      "      UNIVERSAL_CHARSTRING emb_ustr((const char*)p_reader.Value());\n"
+      "      field_%s[emb_val->embval_index] = emb_ustr;\n"
+      "    }\n"
+      "    if (last_embval_index == emb_val->embval_index) {\n"
+      "      ++emb_val->embval_index;\n"
+      "    }\n"
       "  }\n"
-      , sdef->elements[0].name, (unsigned long)(i-(start_at+num_attributes)));
+      , sdef->elements[0].name);
+  }
+  
+  if (sdef->xerUseNilPossible) {
+    src = mputstr(src, "  } // use_nil\n");
   }
 
+  if (sdef->xerUseOrderPossible) {
+    src = mputstr(src,  "  } // uo\n");
+  }
+  
   if (sdef->xerEmbedValuesPossible) {
-    size_t op;
     src = mputprintf(src,
-      /* Set the embed-values member to the correct nr of strings */
-      "  if (e_xer && (p_td.xer_bits & EMBED_VALUES)) {\n"
-      "    int exp_embed = %lu;\n"
-      , (unsigned long)max_embed
-    );
-
-    if (sdef->xerUseNilPossible) {
-      src = mputstr(src,
-        "    if (nil_attribute) exp_embed = 0;\n"
-        "    else {");
-    }
-
-    for (op = 0; op < sdef->nElements; ++op) {
-      if (sdef->elements[op].isOptional && !sdef->elements[op].xerAttribute) {
-        src = mputprintf(src,
-          "    if (!field_%s.ispresent()) --exp_embed;\n"
-          , sdef->elements[op].name
-        );
-      }
-    }
-
-    if (sdef->xerUseNilPossible) src = mputstr(src, "    }\n");
-
-    src = mputprintf(src,
-      "    field_%s.set_size(exp_embed);//normal\n"
+      "  if (0 != emb_val) {\n"
       "    %s::of_type empty_string(\"\");\n"
-      "    for (int j_j=0; j_j<exp_embed; ++j_j) {\n"
+      "    for (int j_j = 0; j_j < emb_val->embval_index; ++j_j) {\n"
       "      if (!field_%s[j_j].is_bound()) field_%s[j_j] = empty_string;\n"
       "    }\n"
-      "  }"
-      , sdef->elements[0].name
+      "    delete emb_val;\n"
+      "  }\n"
       , sdef->elements[0].type
       , sdef->elements[0].name
       , sdef->elements[0].name
     );
   }
 
-  if (sdef->xerUseOrderPossible) {
-    src = mputstr(src,  "  } // uo\n");
-  }
-
   if (sdef->xerUseQName) {
     src = mputstr(src, "  } // qn\n");
   }
@@ -3980,8 +4011,7 @@ void defRecordClass1(const struct_def *sdef, output_struct *output)
       src = mputprintf(src,
       "int %s::TEXT_decode(const TTCN_Typedescriptor_t& p_td,"
       " TTCN_Buffer& p_buf, Limit_Token_List& limit, boolean no_err, boolean){\n"
-      "  if (!is_bound()) TTCN_EncDec_ErrorContext::error"
-      "(TTCN_EncDec::ET_UNBOUND, \"Encoding an unbound value.\");\n"
+      "  bound_flag = TRUE;\n"
       "  int decoded_length=0;\n"
       "  int decoded_field_length=0;\n"
       "%s"
@@ -4242,28 +4272,28 @@ void defRecordClass1(const struct_def *sdef, output_struct *output)
     src = mputprintf(src,
       "int %s::JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer& p_tok, boolean p_silent)\n"
       "{\n"
-      "  json_token_t token = JSON_TOKEN_NONE;\n"
-      "  int dec_len = p_tok.get_next_token(&token, NULL, NULL);\n"
-      "  if (JSON_TOKEN_ERROR == token) {\n"
+      "  json_token_t j_token = JSON_TOKEN_NONE;\n"
+      "  int dec_len = p_tok.get_next_token(&j_token, NULL, NULL);\n"
+      "  if (JSON_TOKEN_ERROR == j_token) {\n"
       "    JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_BAD_TOKEN_ERROR, \"\");\n"
       "    return JSON_ERROR_FATAL;\n"
       "  }\n"
-      "  else if (JSON_TOKEN_OBJECT_START != token) {\n"
+      "  else if (JSON_TOKEN_OBJECT_START != j_token) {\n"
       "    return JSON_ERROR_INVALID_TOKEN;\n"
       "  }\n"
       "  bound_flag = TRUE;\n\n"
          // Read name - value token pairs until we reach some other token
       "  while (true) {\n"
-      "    char* name = 0;\n"
+      "    char* fld_name = 0;\n"
       "    size_t name_len = 0;\n"
       "    size_t buf_pos = p_tok.get_buf_pos();\n"
-      "    dec_len += p_tok.get_next_token(&token, &name, &name_len);\n"
-      "    if (JSON_TOKEN_ERROR == token) {\n"
+      "    dec_len += p_tok.get_next_token(&j_token, &fld_name, &name_len);\n"
+      "    if (JSON_TOKEN_ERROR == j_token) {\n"
       "      JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_NAME_TOKEN_ERROR);\n"
       "      return JSON_ERROR_FATAL;\n"
       "    }\n"
            // undo the last action on the buffer
-      "    else if (JSON_TOKEN_NAME != token) {\n"
+      "    else if (JSON_TOKEN_NAME != j_token) {\n"
       "      p_tok.set_buf_pos(buf_pos);\n"
       "      break;\n"
       "    }\n"
@@ -4272,7 +4302,7 @@ void defRecordClass1(const struct_def *sdef, output_struct *output)
     for (i = 0; i < sdef->nElements; ++i) {
       src = mputprintf(src,
         // check field name
-        "if (%d == name_len && 0 == strncmp(name, \"%s\", name_len)) {\n"
+        "if (%d == name_len && 0 == strncmp(fld_name, \"%s\", name_len)) {\n"
         "        int ret_val = field_%s.JSON_decode(%s_descr_, p_tok, p_silent);\n"        
         "        if (0 > ret_val) {\n"
         "          if (JSON_ERROR_INVALID_TOKEN) {\n"
@@ -4290,23 +4320,23 @@ void defRecordClass1(const struct_def *sdef, output_struct *output)
     src = mputstr(src,
       "{\n"
                // invalid field name
-      "        char* name2 = mcopystrn(name, name_len);\n"
-      "        JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_INVALID_NAME_ERROR, name2);\n"
+      "        char* fld_name2 = mcopystrn(fld_name, name_len);\n"
+      "        JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_INVALID_NAME_ERROR, fld_name2);\n"
                // if this is set to a warning, skip the value of the field
-      "        dec_len += p_tok.get_next_token(&token, NULL, NULL);\n"
-      "        if (JSON_TOKEN_NUMBER != token && JSON_TOKEN_STRING != token &&\n"
-      "            JSON_TOKEN_LITERAL_TRUE != token && JSON_TOKEN_LITERAL_FALSE != token &&\n"
-      "            JSON_TOKEN_LITERAL_NULL != token) {\n"
-      "          JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, name2);\n"
-      "          Free(name2);\n"
+      "        dec_len += p_tok.get_next_token(&j_token, NULL, NULL);\n"
+      "        if (JSON_TOKEN_NUMBER != j_token && JSON_TOKEN_STRING != j_token &&\n"
+      "            JSON_TOKEN_LITERAL_TRUE != j_token && JSON_TOKEN_LITERAL_FALSE != j_token &&\n"
+      "            JSON_TOKEN_LITERAL_NULL != j_token) {\n"
+      "          JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_FIELD_TOKEN_ERROR, fld_name2);\n"
+      "          Free(fld_name2);\n"
       "          return JSON_ERROR_FATAL;\n"
       "        }\n"
-      "        Free(name2);\n"
+      "        Free(fld_name2);\n"
       "      }\n"
       "    }\n"
       "  }\n\n"
-      "  dec_len += p_tok.get_next_token(&token, NULL, NULL);\n"
-      "  if (JSON_TOKEN_OBJECT_END != token) {\n"
+      "  dec_len += p_tok.get_next_token(&j_token, NULL, NULL);\n"
+      "  if (JSON_TOKEN_OBJECT_END != j_token) {\n"
       "    JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_OBJECT_END_TOKEN_ERROR, \"\");\n"
       "    return JSON_ERROR_FATAL;\n"
       "  }\n\n");
@@ -4334,7 +4364,7 @@ void defRecordClass1(const struct_def *sdef, output_struct *output)
         "  }\n");
     }
     src = mputstr(src,
-      "\n  return dec_len;"
+      "\n  return dec_len;\n"
       "}\n\n");
   }
   
@@ -5706,6 +5736,7 @@ static void defEmptyRecordClass(const struct_def *sdef,
     src = mputprintf(src,
       "int %s::TEXT_decode(const TTCN_Typedescriptor_t& p_td,"
       " TTCN_Buffer& p_buf, Limit_Token_List& limit, boolean no_err, boolean){\n"
+      "  bound_flag = TRUE;\n"
       "  int decoded_length=0;\n"
       "  if(p_td.text->begin_decode){\n"
       "    int tl;\n"
@@ -5733,7 +5764,6 @@ static void defEmptyRecordClass(const struct_def *sdef,
       "    decoded_length+=tl;\n"
       "    p_buf.increase_pos(tl);\n"
       "  }\n"
-           "bound_flag = TRUE;\n"
       "  return decoded_length;\n"
       "}\n"
       ,name
@@ -5774,8 +5804,8 @@ static void defEmptyRecordClass(const struct_def *sdef,
 
         );
       src = mputprintf(src,
-        "int %s::XER_encode(const XERdescriptor_t& p_td,"
-        " TTCN_Buffer& p_buf, unsigned int p_flavor, int p_indent) const{\n"
+        "int %s::XER_encode(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf, "
+        "unsigned int p_flavor, int p_indent, embed_values_enc_struct_t*) const{\n"
         "  int encoded_length=(int)p_buf.get_len();\n"
         "  int is_indented = !is_canonical(p_flavor);\n"
         "  int e_xer = is_exer(p_flavor);\n"
@@ -5792,7 +5822,7 @@ static void defEmptyRecordClass(const struct_def *sdef,
         "// written by %s in " __FILE__ " at %d\n"
 #endif
         "int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader, "
-        "unsigned int p_flavor)\n"
+        "unsigned int p_flavor, embed_values_dec_struct_t*)\n"
         "{\n"
         "  int e_xer = is_exer(p_flavor);\n"
         "  bound_flag = true;\n"
This page took 0.034112 seconds and 5 git commands to generate.