Commit 6a82db01 authored by BenceJanosSzabo's avatar BenceJanosSzabo
Browse files

Added seq,set,union extension coding in OER (Bug 527653)



Change-Id: I91636927293f28ef552e314c0cd8f8ba8007cdc6
Signed-off-by: default avatarBenceJanosSzabo <bence.janos.szabo@ericsson.com>
parent 08327474
...@@ -3098,10 +3098,92 @@ void Type::chk_oer() { ...@@ -3098,10 +3098,92 @@ void Type::chk_oer() {
} }
} }
break; } break; }
case T_CHOICE_A:
oerattrib->extendable = t->u.secho.ctss->has_ellipsis();
if (oerattrib->extendable) {
oerattrib->nr_of_root_comps = t->u.secho.ctss->get_nof_root_comps();
}
break;
case T_SET_A: {
oerattrib->extendable = t->u.secho.ctss->has_ellipsis();
if (oerattrib->extendable) {
oerattrib->nr_of_root_comps = t->u.secho.ctss->get_nof_root_comps();
}
// TITAN will reorder the fields for DER coding, which is mostly fine.
// Until the extensions... In OER the DER ordering is good, but the extended
// fields do not need the reordering.
// Here a "map" called p is created which contains the good indexes of the fields.
size_t nElements = t->get_nof_comps();
vector<CompField> se_comps;
map<Tag, CompField> se_comps_map;
for(size_t i=0; i<nElements; i++) {
CompField* cf=t->get_comp_byIndex(i);
Tag *tag = cf->get_type()->get_smallest_tag();
se_comps_map.add(*tag, cf);
delete tag;
}
for(size_t i=0; i<nElements; i++)
se_comps.add(se_comps_map.get_nth_elem(i));
se_comps_map.clear();
size_t limit = oerattrib->extendable ? oerattrib->nr_of_root_comps : nElements;
vector<CompField> se_comps2;
for(size_t i=0; i<limit; i++) {
CompField* cf=t->get_comp_byIndex(i);
Tag *tag = cf->get_type()->get_smallest_tag();
se_comps_map.add(*tag, cf);
delete tag;
}
for(size_t i=0; i<limit; i++)
se_comps2.add(se_comps_map.get_nth_elem(i));
se_comps_map.clear();
for(size_t i=limit; i<nElements; i++)
se_comps2.add(t->get_comp_byIndex(i));
for (size_t i = 0; i < nElements; i++) {
const Identifier& id = se_comps[i]->get_name();
for (size_t j = 0; j < nElements; j++) {
if (id == se_comps2[j]->get_name()) {
oerattrib->p.add(new int(j));
break;
}
}
}
se_comps.clear();
se_comps2.clear();
}
case T_SEQ_A: { case T_SEQ_A: {
// extendable is always false. Probably a bug with is_extendable() oerattrib->extendable = t->u.secho.ctss->has_ellipsis();
if (t->get_sub_type()) { if (oerattrib->extendable) {
oerattrib->extendable = t->get_sub_type()->is_extendable(); oerattrib->nr_of_root_comps = t->u.secho.ctss->get_nof_root_comps();
ExtAdds* eas = t->u.secho.ctss->get_ext_and_exc()->get_eas();
int last_idx = 0;
for (size_t i = 0; i < eas->get_nof_comps(); i++) {
int idx = eas->get_group_byIndex(i);
if (last_idx != 0 && last_idx == idx) {
// do nothing, the field is part of the group
} else if (last_idx != 0 && idx == 0) {
// the group is ended
oerattrib->ext_attr_groups.add(new int(i));
last_idx = 0;
} else if (last_idx != 0 && idx != 0) {
// The group is ended, but new one comes immediately
last_idx = idx;
oerattrib->ext_attr_groups.add(new int(i));
oerattrib->ext_attr_groups.add(new int(i));
} else if (last_idx == 0 && idx != 0) {
// new group
last_idx = idx;
oerattrib->ext_attr_groups.add(new int(i));
}
}
if (last_idx != 0) {
oerattrib->ext_attr_groups.add(new int(eas->get_nof_comps()));
}
}
if (t->typetype != T_SET_A) {
for (size_t i = 0; i < t->get_nof_comps(); i++)
oerattrib->p.add(new int(i));
} }
break; } break; }
case T_SEQOF: case T_SEQOF:
......
...@@ -1087,16 +1087,47 @@ void Type::generate_code_oerdescriptor(output_struct *target) ...@@ -1087,16 +1087,47 @@ void Type::generate_code_oerdescriptor(output_struct *target)
if (NULL == oerattrib) { if (NULL == oerattrib) {
target->source.global_vars = mputprintf(target->source.global_vars, target->source.global_vars = mputprintf(target->source.global_vars,
"const TTCN_OERdescriptor_t %s_oer_ = { -1, FALSE, -1, FALSE };\n" "const TTCN_OERdescriptor_t %s_oer_ = { -1, FALSE, -1, FALSE, 0, 0, NULL, 0, NULL };\n"
, get_genname_own().c_str()); , get_genname_own().c_str());
} else { } else {
target->source.global_vars = mputprintf(target->source.global_vars,
"const int %s_oer_ext_arr_[%lu] = {"
, get_genname_own().c_str()
, oerattrib->ext_attr_groups.size());
for (size_t i = 0; i < oerattrib->ext_attr_groups.size(); i++) {
target->source.global_vars = mputprintf(target->source.global_vars,
"%i", *oerattrib->ext_attr_groups[i]);
if (i != oerattrib->ext_attr_groups.size() - 1) {
target->source.global_vars = mputstr(target->source.global_vars, ", ");
}
}
target->source.global_vars = mputstr(target->source.global_vars, "};\n");
target->source.global_vars = mputprintf(target->source.global_vars,
"const int %s_oer_p_[%lu] = {"
, get_genname_own().c_str()
, oerattrib->p.size());
for (size_t i = 0; i < oerattrib->p.size(); i++) {
target->source.global_vars = mputprintf(target->source.global_vars,
"%i", *oerattrib->p[i]);
if (i != oerattrib->p.size() - 1) {
target->source.global_vars = mputstr(target->source.global_vars, ", ");
}
}
target->source.global_vars = mputstr(target->source.global_vars, "};\n");
target->source.global_vars = mputprintf(target->source.global_vars, target->source.global_vars = mputprintf(target->source.global_vars,
"const TTCN_OERdescriptor_t %s_oer_ = { %i, %s, %i, %s };\n" "const TTCN_OERdescriptor_t %s_oer_ = { %i, %s, %i, %s, %i, %lu, %s_oer_ext_arr_, %lu, %s_oer_p_"
, get_genname_own().c_str() , get_genname_own().c_str()
, oerattrib->bytes , oerattrib->bytes
, oerattrib->signed_ ? "TRUE" : "FALSE" , oerattrib->signed_ ? "TRUE" : "FALSE"
, oerattrib->length , oerattrib->length
, oerattrib->extendable ? "TRUE" : "FALSE"); , oerattrib->extendable ? "TRUE" : "FALSE"
, oerattrib->nr_of_root_comps
, oerattrib->ext_attr_groups.size()
, get_genname_own().c_str()
, oerattrib->p.size()
, get_genname_own().c_str());
target->source.global_vars = mputstr(target->source.global_vars, "};\n");
} }
} }
...@@ -1219,6 +1250,10 @@ void Type::generate_code_Choice(output_struct *target) ...@@ -1219,6 +1250,10 @@ void Type::generate_code_Choice(output_struct *target)
get_gen_coder_functions(CT_XER); get_gen_coder_functions(CT_XER);
sdef.hasJson = get_gen_coder_functions(CT_JSON); sdef.hasJson = get_gen_coder_functions(CT_JSON);
sdef.hasOer = get_gen_coder_functions(CT_OER); sdef.hasOer = get_gen_coder_functions(CT_OER);
if (oerattrib) {
sdef.oerExtendable = oerattrib->extendable;
sdef.oerNrOrRootcomps = oerattrib->nr_of_root_comps;
}
sdef.has_opentypes = get_has_opentypes(); sdef.has_opentypes = get_has_opentypes();
sdef.opentype_outermost = get_is_opentype_outermost(); sdef.opentype_outermost = get_is_opentype_outermost();
sdef.ot = generate_code_ot(pool); sdef.ot = generate_code_ot(pool);
...@@ -1632,6 +1667,20 @@ void Type::generate_code_Se(output_struct *target) ...@@ -1632,6 +1667,20 @@ void Type::generate_code_Se(output_struct *target)
get_gen_coder_functions(CT_XER); get_gen_coder_functions(CT_XER);
sdef.hasJson = get_gen_coder_functions(CT_JSON); sdef.hasJson = get_gen_coder_functions(CT_JSON);
sdef.hasOer = get_gen_coder_functions(CT_OER); sdef.hasOer = get_gen_coder_functions(CT_OER);
if (oerattrib) {
sdef.oerExtendable = oerattrib->extendable;
sdef.oerNrOrRootcomps = oerattrib->nr_of_root_comps;
sdef.oerEagNum = oerattrib->ext_attr_groups.size();
sdef.oerEag = (int*)Malloc(sdef.oerEagNum*sizeof(int));
for (int i = 0; i < sdef.oerEagNum; i++) {
sdef.oerEag[i] = *(oerattrib->ext_attr_groups[i]);
}
sdef.oerPNum = oerattrib->p.size();
sdef.oerP = (int*)Malloc(sdef.oerPNum*sizeof(int));
for (int i = 0; i < sdef.oerPNum; i++) {
sdef.oerP[i] = *(oerattrib->p[i]);
}
}
if (xerattrib){ if (xerattrib){
Module *my_module = get_my_scope()->get_scope_mod(); Module *my_module = get_my_scope()->get_scope_mod();
sdef.xerHasNamespaces = my_module->get_nof_ns() != 0; sdef.xerHasNamespaces = my_module->get_nof_ns() != 0;
...@@ -2046,6 +2095,12 @@ void Type::generate_code_Se(output_struct *target) ...@@ -2046,6 +2095,12 @@ void Type::generate_code_Se(output_struct *target)
} }
} }
Free(sdef.elements); Free(sdef.elements);
if (sdef.oerEag) {
Free(sdef.oerEag);
}
if (sdef.oerP) {
Free(sdef.oerP);
}
} }
bool Type::is_untagged() const { return xerattrib && xerattrib->untagged_; } bool Type::is_untagged() const { return xerattrib && xerattrib->untagged_; }
......
...@@ -709,6 +709,19 @@ namespace Common { ...@@ -709,6 +709,19 @@ namespace Common {
get_fullname().c_str(), (unsigned long) n); get_fullname().c_str(), (unsigned long) n);
return 0; return 0;
} }
int ExtAdds::get_group_byIndex(size_t n) const
{
size_t offset = n;
for(size_t i = 0; i < eas.size(); i++) {
size_t size = eas[i]->get_nof_comps();
if (offset < size) return eas[i]->get_group_number();
else offset -= size;
}
FATAL_ERROR("%s: Requested index %lu does not exist.", \
get_fullname().c_str(), (unsigned long) n);
return 0;
}
bool ExtAdds::has_comp_withName(const Identifier& p_name) const bool ExtAdds::has_comp_withName(const Identifier& p_name) const
{ {
...@@ -737,6 +750,10 @@ namespace Common { ...@@ -737,6 +750,10 @@ namespace Common {
{ {
if(!p_ea) if(!p_ea)
FATAL_ERROR("NULL parameter: Asn::ExtAdds::add_ea()"); FATAL_ERROR("NULL parameter: Asn::ExtAdds::add_ea()");
if (p_ea->is_ext_attr_group()) {
num_of_groups++;
p_ea->set_group_number(num_of_groups);
}
eas.add(p_ea); eas.add(p_ea);
} }
......
...@@ -130,6 +130,7 @@ namespace Common { ...@@ -130,6 +130,7 @@ namespace Common {
bool has_comp_withName(const Identifier& p_name); bool has_comp_withName(const Identifier& p_name);
CompField* get_comp_byName(const Identifier& p_name); CompField* get_comp_byName(const Identifier& p_name);
void tr_compsof(ReferenceChain *refch, bool in_ellipsis); void tr_compsof(ReferenceChain *refch, bool in_ellipsis);
ExtAndExc* get_ext_and_exc() const { return ee; }
bool has_ellipsis() const { return ee != 0; } bool has_ellipsis() const { return ee != 0; }
bool needs_auto_tags(); bool needs_auto_tags();
void add_auto_tags(); void add_auto_tags();
...@@ -160,6 +161,9 @@ namespace Common { ...@@ -160,6 +161,9 @@ namespace Common {
virtual bool has_comp_withName(const Identifier& p_name) const = 0; virtual bool has_comp_withName(const Identifier& p_name) const = 0;
virtual CompField* get_comp_byName(const Identifier& p_name) const = 0; virtual CompField* get_comp_byName(const Identifier& p_name) const = 0;
virtual void tr_compsof(ReferenceChain *refch, bool is_set) = 0; virtual void tr_compsof(ReferenceChain *refch, bool is_set) = 0;
virtual bool is_ext_attr_group() const { return false; }
virtual int get_group_number() const { return 0; }
virtual void set_group_number(int) {}
}; };
/** /**
...@@ -168,18 +172,21 @@ namespace Common { ...@@ -168,18 +172,21 @@ namespace Common {
class ExtAdds : public Node { class ExtAdds : public Node {
private: private:
vector<ExtAdd> eas; vector<ExtAdd> eas;
// The number of ExtAddGrps
int num_of_groups;
/** Copy constructor not implemented */ /** Copy constructor not implemented */
ExtAdds(const ExtAdds& p); ExtAdds(const ExtAdds& p);
/** Assignment disabled */ /** Assignment disabled */
ExtAdds& operator=(const ExtAdds& p); ExtAdds& operator=(const ExtAdds& p);
public: public:
ExtAdds() : Node(), eas() { } ExtAdds() : Node(), eas(), num_of_groups(0) { }
virtual ~ExtAdds(); virtual ~ExtAdds();
virtual ExtAdds *clone() const; virtual ExtAdds *clone() const;
virtual void set_fullname(const string& p_fullname); virtual void set_fullname(const string& p_fullname);
virtual void set_my_scope(Scope *p_scope); virtual void set_my_scope(Scope *p_scope);
size_t get_nof_comps() const; size_t get_nof_comps() const;
CompField* get_comp_byIndex(size_t n) const; CompField* get_comp_byIndex(size_t n) const;
int get_group_byIndex(size_t n) const;
bool has_comp_withName(const Identifier& p_name) const; bool has_comp_withName(const Identifier& p_name) const;
CompField* get_comp_byName(const Identifier& p_name) const; CompField* get_comp_byName(const Identifier& p_name) const;
void tr_compsof(ReferenceChain *refch, bool is_set); void tr_compsof(ReferenceChain *refch, bool is_set);
...@@ -215,6 +222,7 @@ namespace Common { ...@@ -215,6 +222,7 @@ namespace Common {
void tr_compsof(ReferenceChain *refch, bool is_set) void tr_compsof(ReferenceChain *refch, bool is_set)
{ eas->tr_compsof(refch, is_set); } { eas->tr_compsof(refch, is_set); }
void set_eas(ExtAdds *p_eas); void set_eas(ExtAdds *p_eas);
ExtAdds * get_eas() const { return eas; }
virtual void dump(unsigned level) const; virtual void dump(unsigned level) const;
}; };
...@@ -226,6 +234,8 @@ namespace Common { ...@@ -226,6 +234,8 @@ namespace Common {
/** can be NULL if not present */ /** can be NULL if not present */
Value *versionnumber; Value *versionnumber;
CTs *cts; CTs *cts;
// Needed for oer coding
int groupnumber;
/** Copy constructor not implemented */ /** Copy constructor not implemented */
ExtAddGrp(const ExtAddGrp& p); ExtAddGrp(const ExtAddGrp& p);
/** Assignment disabled */ /** Assignment disabled */
...@@ -242,6 +252,10 @@ namespace Common { ...@@ -242,6 +252,10 @@ namespace Common {
virtual CompField* get_comp_byName(const Identifier& p_name) const; virtual CompField* get_comp_byName(const Identifier& p_name) const;
virtual void tr_compsof(ReferenceChain *refch, bool is_set); virtual void tr_compsof(ReferenceChain *refch, bool is_set);
virtual void dump(unsigned level) const; virtual void dump(unsigned level) const;
virtual bool is_ext_attr_group() const { return true; }
virtual int get_group_number() const { return groupnumber; }
virtual void set_group_number(int num) { groupnumber = num; }
}; };
/** /**
......
...@@ -104,6 +104,12 @@ typedef struct { ...@@ -104,6 +104,12 @@ typedef struct {
boolean hasXer; boolean hasXer;
boolean hasJson; boolean hasJson;
boolean hasOer; boolean hasOer;
boolean oerExtendable;
int oerNrOrRootcomps;
int oerEagNum;
int* oerEag;
int oerPNum;
int* oerP;
boolean xerUntagged; boolean xerUntagged;
boolean xerUntaggedOne; /**< from Type::u.secho.has_single_charenc */ boolean xerUntaggedOne; /**< from Type::u.secho.has_single_charenc */
boolean xerUseNilPossible; /* for sequence */ boolean xerUseNilPossible; /* for sequence */
......
...@@ -4655,56 +4655,193 @@ void defRecordClass1(const struct_def *sdef, output_struct *output) ...@@ -4655,56 +4655,193 @@ void defRecordClass1(const struct_def *sdef, output_struct *output)
if (oer_needed) { if (oer_needed) {
// OER encode, RT1 // OER encode, RT1
src = mputprintf(src, src = mputprintf(src,
"int %s::OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer& p_buf) const\n" "int %s::OER_encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf) const\n"
"{\n" "{\n"
" if (!is_bound()) {\n" " if (!is_bound()) {\n"
" TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,\n" " TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_UNBOUND,\n"
" \"Encoding an unbound %s value.\");\n" " \"Encoding an unbound %s value.\");\n"
" return -1;\n" " return -1;\n"
" }\n", name, sdef->kind == SET ? "set" : "record"); " }\n", name, sdef->kind == SET ? "set" : "record");
if (sdef->oerExtendable && sdef->oerNrOrRootcomps != sdef->nElements) {
src = mputstr(src,
" boolean has_extension = FALSE;\n");
for (i = sdef->oerNrOrRootcomps; i < sdef->nElements; i++) {
src = mputprintf(src,
" has_extension = has_extension || (field_%s.is_bound() && field_%s.is_present());\n",
sdef->elements[i].name, sdef->elements[sdef->oerP[i]].name);
}
}
size_t opt_elements = 0; size_t opt_elements = 0;
for (i = 0; i < sdef->nElements; i++) { size_t limit = sdef->oerExtendable ? sdef->oerNrOrRootcomps : sdef->nElements;
if (sdef->elements[i].isOptional || sdef->elements[i].isDefault) { for (i = 0; i < limit; i++) {
if (sdef->elements[sdef->oerP[i]].isOptional || sdef->elements[sdef->oerP[i]].isDefault) {
opt_elements++; opt_elements++;
} }
} }
int needed_bytes = opt_elements / 8 + 1; int bits = opt_elements+(sdef->oerExtendable == TRUE);
int needed_bytes = bits / 8 + (bits % 8 == 0 ? 0 : 1);
if (opt_elements != 0) { int pos = 8;
src = mputprintf(src, if (opt_elements != 0 || sdef->oerExtendable) {
" unsigned char c[%i] = {0};\n" src = mputstr(src,
, needed_bytes); " char c = 0;\n");
if (sdef->oerExtendable && sdef->oerNrOrRootcomps != sdef->nElements) {
pos--;
src = mputprintf(src,
" if (has_extension) {\n"
" c += %i;\n"
" }\n", 1 << 7);
}
} }
int ind = 0; int ind = 0;
int pos = 8; for (i = 0; i < limit; i++) {
for (i = 0; i < sdef->nElements; i++) { if (sdef->elements[sdef->oerP[i]].isOptional || sdef->elements[sdef->oerP[i]].isDefault) {
if (sdef->elements[i].isOptional || sdef->elements[i].isDefault) {
pos--; pos--;
src = mputprintf(src, src = mputprintf(src,
" if (field_%s.is_present()) {\n" " if (field_%s.is_present()) {\n"
" c[%i] += 1 << %i;\n" " c += %i;\n"
" }\n" " }\n"
, sdef->elements[i].name, ind, pos); , sdef->elements[sdef->oerP[i]].name
, 1 << pos);
if (pos == 0) { if (pos == 0) {
pos = 8; pos = 8;
ind++; ind++;
src = mputstr(src,
" p_buf.put_c(c);\n"
" c = 0\n;");
} }
} }
} }
if (opt_elements != 0) { if (opt_elements != 0 || sdef->oerExtendable) {
src = mputprintf(src, if (pos != 8 || ind == 0) {
" p_buf.put_s(%i, c);\n" src = mputstr(src,
, needed_bytes); " p_buf.put_c(c);\n");
}
} }
for (i = 0; i < sdef->nElements; i++) { for (i = 0; i < limit; i++) {
if (sdef->elements[i].isOptional || sdef->elements[i].isDefault) { if (sdef->elements[sdef->oerP[i]].isOptional || sdef->elements[sdef->oerP[i]].isDefault) {
src = mputprintf(src, src = mputprintf(src,
" if (field_%s.is_present())\n " " if (field_%s.is_present())\n "
, sdef->elements[i].name); , sdef->elements[sdef->oerP[i]].name);
} }
src = mputprintf(src, src = mputprintf(src,
" field_%s.OER_encode(%s_descr_, p_buf);\n" " field_%s.OER_encode(%s_descr_, p_buf);\n"
, sdef->elements[i].name, sdef->elements[i].typedescrname); , sdef->elements[sdef->oerP[i]].name, sdef->elements[sdef->oerP[i]].typedescrname);
}
if (sdef->oerExtendable && sdef->oerNrOrRootcomps != sdef->nElements) {
bits = 0;
int eag_pos = 0;
for (i = limit; i < sdef->nElements; i++) {
if (sdef->oerEagNum != 0 && sdef->oerEag[eag_pos] == i - limit) {
eag_pos++;
bits++;
i += sdef->oerEag[eag_pos] - sdef->oerEag[eag_pos-1] - 1;
eag_pos++;
} else {
bits++;
}
}
needed_bytes = bits / 8 + (bits % 8 == 0 ? 0 : 1);
src = mputprintf(src,
" if (has_extension) {\n"
"%s"
" TTCN_Buffer tmp_buf;\n"
" TTCN_Buffer tmp_buf2;\n"
" TTCN_Buffer tmp_buf3;\n"
" c = 0;\n"
, sdef->oerEagNum != 0 ? " boolean has_present = FALSE;\n" : "");
eag_pos = 0;
pos = 8;
ind = 0;
for (i = limit; i < sdef->nElements; i++) {
pos--;
if (sdef->oerEagNum != 0 && sdef->oerEag[eag_pos] == i - limit) {
eag_pos++;
int opt_elems = 0;
for (int j = i; j < limit + sdef->oerEag[eag_pos]; j++) {
if (sdef->elements[sdef->oerP[j]].isOptional || sdef->elements[sdef->oerP[j]].isDefault) {
opt_elems++;
}
src = mputprintf(src,
" has_present = has_present || field_%s.is_present();\n", sdef->elements[sdef->oerP[j]].name);
}
src = mputprintf(src,
" if (has_present) {\n"
" has_present = FALSE;\n"
" c += %i;\n", 1 << pos);
if (opt_elems != 0) {
src = mputstr(src,
" char c2 = 0;\n");
int pos2 = 8;
int ind2 = 0;
for (int j = i; j < limit + sdef->oerEag[eag_pos]; j++) {
if (sdef->elements[sdef->oerP[j]].isOptional || sdef->elements[sdef->oerP[j]].isDefault) {
pos2--;
src = mputprintf(src,
" if (field_%s.is_present()) {\n"
" c2 += %i;\n"
" }\n"
, sdef->elements[sdef->oerP[j]].name, 1 << pos2);
if (pos2 == 0) {
pos2 = 8;
ind2++;
src = mputstr(src,
" tmp_buf2.put_c(c2);\n"
" c2 = 0;\n");
}
}
}
if (pos2 != 8) {
src = mputstr(src,
" tmp_buf2.put_c(c2);\n");
}
}
for (int j = i; j < limit + sdef->oerEag[eag_pos]; j++) {
src = mputprintf(src,
" field_%s.OER_encode(%s_descr_, tmp_buf2);\n"
, sdef->elements[sdef->oerP[j]].name, sdef->elements[sdef->oerP[j]].typedescrname);
}
src = mputstr(src,
" encode_oer_length(tmp_buf2.get_len(), tmp_buf, FALSE);\n"
" tmp_buf.put_buf(tmp_buf2);\n"
" tmp_buf2.clear();\n"
" }\n");
i += sdef->oerEag[eag_pos] - sdef->oerEag[eag_pos-1] - 1;
eag_pos++;
} else {
src = mputprintf(src,
" if (field_%s.is_present()) {\n"
" c += %i;\n"
" field_%s.OER_encode(%s_descr_, tmp_buf2);\n"