XER support
git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@365 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index a5d04c6..179161f 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -27,6 +27,7 @@
static int _print_tag(arg_t *arg, struct asn1p_type_tag_s *tag_p);
static int check_if_extensible(asn1p_expr_t *expr);
static int expr_better_indirect(arg_t *arg, asn1p_expr_t *expr);
+static int expr_as_xmlvaluelist(arg_t *arg, asn1p_expr_t *expr);
static int expr_elements_count(arg_t *arg, asn1p_expr_t *expr);
static int emit_member_table(arg_t *arg, asn1p_expr_t *expr);
static int emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count);
@@ -156,7 +157,6 @@
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *v;
int elements; /* Number of elements */
- int comp_mode = 0; /* {root,ext=1,root,root,...} */
int ext_start = -1;
int ext_stop = -1;
tag2el_t *tag2el = NULL;
@@ -183,22 +183,28 @@
/*
* Print out the table according to which the parsing is performed.
*/
- p = MKID(expr->Identifier);
- OUT("static asn1_TYPE_member_t asn1_MBR_%s[] = {\n", p);
+ if(expr_elements_count(arg, expr)) {
+ int comp_mode = 0; /* {root,ext=1,root,root,...} */
- elements = 0;
- INDENTED(TQ_FOR(v, &(expr->members), next) {
- if(v->expr_type == A1TC_EXTENSIBLE) {
- if((++comp_mode) == 1)
- ext_start = elements - 1;
- else
- ext_stop = elements - 1;
- continue;
- }
- elements++;
- emit_member_table(arg, v);
- });
- OUT("};\n");
+ p = MKID(expr->Identifier);
+ OUT("static asn1_TYPE_member_t asn1_MBR_%s[] = {\n", p);
+
+ elements = 0;
+ INDENTED(TQ_FOR(v, &(expr->members), next) {
+ if(v->expr_type == A1TC_EXTENSIBLE) {
+ if((++comp_mode) == 1)
+ ext_start = elements - 1;
+ else
+ ext_stop = elements - 1;
+ continue;
+ }
+ elements++;
+ emit_member_table(arg, v);
+ });
+ OUT("};\n");
+ } else {
+ elements = 0;
+ }
/*
* Print out asn1_DEF_<type>_[all_]tags[] vectors.
@@ -307,7 +313,6 @@
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *v;
int elements;
- int comp_mode = 0; /* {root,ext=1,root,root,...} */
tag2el_t *tag2el = NULL;
int tag2el_count = 0;
int tags_count;
@@ -332,22 +337,28 @@
/*
* Print out the table according to which the parsing is performed.
*/
- p = MKID(expr->Identifier);
- OUT("static asn1_TYPE_member_t asn1_MBR_%s[] = {\n", p);
+ if(expr_elements_count(arg, expr)) {
+ int comp_mode = 0; /* {root,ext=1,root,root,...} */
- elements = 0;
- INDENTED(TQ_FOR(v, &(expr->members), next) {
- if(v->expr_type == A1TC_EXTENSIBLE) {
- if(comp_mode < 3) comp_mode++;
- } else {
- if(comp_mode == 1
- || expr_better_indirect(arg, v))
- v->marker.flags |= EM_INDIRECT;
- elements++;
- emit_member_table(arg, v);
- }
- });
- OUT("};\n");
+ p = MKID(expr->Identifier);
+ OUT("static asn1_TYPE_member_t asn1_MBR_%s[] = {\n", p);
+
+ elements = 0;
+ INDENTED(TQ_FOR(v, &(expr->members), next) {
+ if(v->expr_type == A1TC_EXTENSIBLE) {
+ if(comp_mode < 3) comp_mode++;
+ } else {
+ if(comp_mode == 1
+ || expr_better_indirect(arg, v))
+ v->marker.flags |= EM_INDIRECT;
+ elements++;
+ emit_member_table(arg, v);
+ }
+ });
+ OUT("};\n");
+ } else {
+ elements = 0;
+ }
/*
* Print out asn1_DEF_<type>_[all_]tags[] vectors.
@@ -443,12 +454,15 @@
tmp.expr = &tmp_memb;
tmp_memb = *memb;
tmp_memb._anonymous_type = 1;
- tmp_memb.Identifier = strdup(
- asn1c_make_identifier(0,
- expr->Identifier, "member", 0));
- assert(tmp_memb.Identifier);
+ if(tmp_memb.Identifier == 0) {
+ tmp_memb.Identifier = strdup(
+ asn1c_make_identifier(0,
+ expr->Identifier, "member", 0));
+ assert(tmp_memb.Identifier);
+ }
tmp.default_cb(&tmp);
- free(tmp_memb.Identifier);
+ if(tmp_memb.Identifier != memb->Identifier)
+ free(tmp_memb.Identifier);
arg->embed--;
assert(arg->target->target == OT_TYPE_DECLS);
} else {
@@ -496,11 +510,17 @@
*/
p = MKID(expr->Identifier);
OUT("static asn1_TYPE_member_t asn1_MBR_%s[] = {\n", p);
-
- INDENTED(
+ INDENT(+1);
v = TQ_FIRST(&(expr->members));
+ if(!v->Identifier) {
+ v->Identifier = strdup("member");
+ assert(v->Identifier);
+ }
+ v->_anonymous_type = 1;
+ arg->embed++;
emit_member_table(arg, v);
- );
+ arg->embed--;
+ INDENT(-1);
OUT("};\n");
/*
@@ -513,6 +533,10 @@
INDENTED(
OUT("sizeof(struct %s),\n", p);
OUT("offsetof(struct %s, _ber_dec_ctx),\n", p);
+ if(expr_as_xmlvaluelist(arg, v))
+ OUT("1,\t/* XER encoding is XMLValueList */\n");
+ else
+ OUT("0,\t/* XER encoding is XMLDelimitedItemList */\n");
);
OUT("};\n");
@@ -589,7 +613,6 @@
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *v;
int elements; /* Number of elements */
- int comp_mode = 0; /* {root,ext=1,root,root,...} */
tag2el_t *tag2el = NULL;
int tag2el_count = 0;
int tags_count;
@@ -614,22 +637,28 @@
/*
* Print out the table according to which the parsing is performed.
*/
- p = MKID(expr->Identifier);
- OUT("static asn1_TYPE_member_t asn1_MBR_%s[] = {\n", p);
+ if(expr_elements_count(arg, expr)) {
+ int comp_mode = 0; /* {root,ext=1,root,root,...} */
- elements = 0;
- INDENTED(TQ_FOR(v, &(expr->members), next) {
- if(v->expr_type == A1TC_EXTENSIBLE) {
- if(comp_mode < 3) comp_mode++;
- } else {
- if(comp_mode == 1
- || expr_better_indirect(arg, v))
- v->marker.flags |= EM_INDIRECT;
- elements++;
- emit_member_table(arg, v);
- }
- });
- OUT("};\n");
+ p = MKID(expr->Identifier);
+ OUT("static asn1_TYPE_member_t asn1_MBR_%s[] = {\n", p);
+
+ elements = 0;
+ INDENTED(TQ_FOR(v, &(expr->members), next) {
+ if(v->expr_type == A1TC_EXTENSIBLE) {
+ if(comp_mode < 3) comp_mode++;
+ } else {
+ if(comp_mode == 1
+ || expr_better_indirect(arg, v))
+ v->marker.flags |= EM_INDIRECT;
+ elements++;
+ emit_member_table(arg, v);
+ }
+ });
+ OUT("};\n");
+ } else {
+ elements = 0;
+ }
if(arg->embed) {
@@ -683,7 +712,7 @@
arg_t tmp;
int ret;
- extract = asn1f_class_access_ex(arg->asn, arg->mod,
+ extract = asn1f_class_access_ex(arg->asn, arg->expr->module,
arg->expr, ref);
if(extract == NULL)
return -1;
@@ -808,12 +837,14 @@
OUT("%s_inherit_TYPE_descriptor(asn1_TYPE_descriptor_t *td) {\n", p);
INDENT(+1);
{
- asn1p_expr_t *terminal = asn1f_find_terminal_type_ex(arg->asn, arg->mod, expr);
+ asn1p_expr_t *terminal = asn1f_find_terminal_type_ex(arg->asn, expr);
char *type_name = asn1c_type_name(arg, expr, TNF_SAFE);
- OUT("td->ber_decoder = asn1_DEF_%s.ber_decoder;\n", type_name);
- OUT("td->der_encoder = asn1_DEF_%s.der_encoder;\n", type_name);
OUT("td->free_struct = asn1_DEF_%s.free_struct;\n", type_name);
OUT("td->print_struct = asn1_DEF_%s.print_struct;\n", type_name);
+ OUT("td->ber_decoder = asn1_DEF_%s.ber_decoder;\n", type_name);
+ OUT("td->der_encoder = asn1_DEF_%s.der_encoder;\n", type_name);
+ OUT("td->xer_decoder = asn1_DEF_%s.xer_decoder;\n", type_name);
+ OUT("td->xer_encoder = asn1_DEF_%s.xer_encoder;\n", type_name);
if(!terminal && !tags_count) {
OUT("/* The next four lines are here because of -fknown-extern-type */\n");
OUT("td->tags = asn1_DEF_%s.tags;\n", type_name);
@@ -832,24 +863,12 @@
OUT("\n");
p = MKID(expr->Identifier);
- OUT("ber_dec_rval_t\n");
- OUT("%s_decode_ber(asn1_TYPE_descriptor_t *td,\n", p);
+ OUT("void\n");
+ OUT("%s_free(asn1_TYPE_descriptor_t *td,\n", p);
INDENTED(
- OUT("\tvoid **structure, void *bufptr, size_t size, int tag_mode) {\n");
+ OUT("\tvoid *struct_ptr, int contents_only) {\n");
OUT("%s_inherit_TYPE_descriptor(td);\n", p);
- OUT("return td->ber_decoder(td, structure, bufptr, size, tag_mode);\n");
- );
- OUT("}\n");
- OUT("\n");
-
- p = MKID(expr->Identifier);
- OUT("der_enc_rval_t\n");
- OUT("%s_encode_der(asn1_TYPE_descriptor_t *td,\n", p);
- INDENTED(
- OUT("\tvoid *structure, int tag_mode, ber_tlv_tag_t tag,\n");
- OUT("\tasn_app_consume_bytes_f *cb, void *app_key) {\n");
- OUT("%s_inherit_TYPE_descriptor(td);\n", p);
- OUT("return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);\n");
+ OUT("td->free_struct(td, struct_ptr, contents_only);\n");
);
OUT("}\n");
OUT("\n");
@@ -866,12 +885,36 @@
OUT("\n");
p = MKID(expr->Identifier);
- OUT("void\n");
- OUT("%s_free(asn1_TYPE_descriptor_t *td,\n", p);
+ OUT("ber_dec_rval_t\n");
+ OUT("%s_decode_ber(asn1_TYPE_descriptor_t *td,\n", p);
INDENTED(
- OUT("\tvoid *struct_ptr, int contents_only) {\n");
+ OUT("\tvoid **structure, void *bufptr, size_t size, int tag_mode) {\n");
OUT("%s_inherit_TYPE_descriptor(td);\n", p);
- OUT("td->free_struct(td, struct_ptr, contents_only);\n");
+ OUT("return td->ber_decoder(td, structure, bufptr, size, tag_mode);\n");
+ );
+ OUT("}\n");
+ OUT("\n");
+
+ p = MKID(expr->Identifier);
+ OUT("asn_enc_rval_t\n");
+ OUT("%s_encode_der(asn1_TYPE_descriptor_t *td,\n", p);
+ INDENTED(
+ OUT("\tvoid *structure, int tag_mode, ber_tlv_tag_t tag,\n");
+ OUT("\tasn_app_consume_bytes_f *cb, void *app_key) {\n");
+ OUT("%s_inherit_TYPE_descriptor(td);\n", p);
+ OUT("return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);\n");
+ );
+ OUT("}\n");
+ OUT("\n");
+
+ p = MKID(expr->Identifier);
+ OUT("asn_enc_rval_t\n");
+ OUT("%s_encode_xer(asn1_TYPE_descriptor_t *td, void *structure,\n", p);
+ INDENTED(
+ OUT("\tint ilevel, enum xer_encoder_flags_e flags,\n");
+ OUT("\tasn_app_consume_bytes_f *cb, void *app_key) {\n");
+ OUT("%s_inherit_TYPE_descriptor(td);\n", p);
+ OUT("return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);\n");
);
OUT("}\n");
OUT("\n");
@@ -883,11 +926,12 @@
OUT("extern asn1_TYPE_descriptor_t asn1_DEF_%s;", p);
if(HIDE_INNER_DEFS) OUT(" // (Use -fall-defs-global to expose) */");
OUT("\n");
+ OUT("asn_struct_free_f %s_free;\n", p);
+ OUT("asn_struct_print_f %s_print;\n", p);
OUT("asn_constr_check_f %s_constraint;\n", p);
OUT("ber_type_decoder_f %s_decode_ber;\n", p);
OUT("der_type_encoder_f %s_encode_der;\n", p);
- OUT("asn_struct_print_f %s_print;\n", p);
- OUT("asn_struct_free_f %s_free;\n", p);
+ OUT("xer_type_encoder_f %s_encode_xer;\n", p);
REDIR(OT_TYPE_DECLS);
@@ -1031,7 +1075,8 @@
assert(el_no >= 0);
- ret = asn1f_fetch_outmost_tag(arg->asn, arg->mod, arg->expr, &tag, 1);
+ ret = asn1f_fetch_outmost_tag(arg->asn, arg->expr->module,
+ arg->expr, &tag, 1);
if(ret == 0) {
tag2el_t *te;
int new_count = (*count) + 1;
@@ -1137,12 +1182,12 @@
*all_tags_count_r = 0;
/* Fetch a chain of tags */
- tags_count = asn1f_fetch_tags(arg->asn, arg->mod, expr, &tags, 0);
+ tags_count = asn1f_fetch_tags(arg->asn, expr->module, expr, &tags, 0);
if(tags_count < 0)
return -1;
/* Fetch a chain of tags */
- all_tags_count = asn1f_fetch_tags(arg->asn, arg->mod, expr,
+ all_tags_count = asn1f_fetch_tags(arg->asn, expr->module, expr,
&all_tags, AFT_FULL_COLLECT);
if(all_tags_count < 0) {
if(tags) free(tags);
@@ -1207,7 +1252,7 @@
asn1p_expr_t *v;
int elements = 0;
- topmost_parent = asn1f_find_terminal_type_ex(arg->asn, arg->mod, expr);
+ topmost_parent = asn1f_find_terminal_type_ex(arg->asn, expr);
if(!topmost_parent) return 0;
if(!(topmost_parent->expr_type & ASN_CONSTR_MASK))
@@ -1254,15 +1299,15 @@
} else {
OUT("0, ");
}
- if(expr->Identifier) {
+ if(expr->_anonymous_type) {
+ assert(arg->expr->expr_type == ASN_CONSTR_SET_OF
+ || arg->expr->expr_type == ASN_CONSTR_SEQUENCE_OF);
+ OUT("0,\n");
+ } else {
OUT("offsetof(struct %s, ", MKID(arg->expr->Identifier));
if(arg->expr->expr_type == ASN_CONSTR_CHOICE
&& (!UNNAMED_UNIONS)) OUT("choice.");
OUT("%s),\n", MKID(expr->Identifier));
- } else {
- assert(arg->expr->expr_type == ASN_CONSTR_SET_OF
- || arg->expr->expr_type == ASN_CONSTR_SEQUENCE_OF);
- OUT("0,\n");
}
INDENT(+1);
if(C99_MODE) OUT(".tag = ");
@@ -1286,9 +1331,7 @@
OUT("0,\n");
}
if(C99_MODE) OUT(".type = ");
- if((expr->expr_type & ASN_CONSTR_MASK)
- && (arg->expr->expr_type == ASN_CONSTR_SEQUENCE_OF
- || arg->expr->expr_type == ASN_CONSTR_SET_OF)) {
+ if(expr->_anonymous_type && (expr->expr_type & ASN_CONSTR_MASK)) {
OUT("(void *)&asn1_DEF_%s_member,\n",
MKID(arg->expr->Identifier));
} else if(expr->expr_type & ASN_CONSTR_MASK) {
@@ -1301,7 +1344,7 @@
if(C99_MODE) OUT(".memb_constraints = ");
if(expr->constraints) {
char *id = MKID(expr->Identifier);
- if(!expr->Identifier)
+ if(expr->_anonymous_type && !strcmp(expr->Identifier, "member"))
id = asn1c_type_name(arg, expr, TNF_SAFE);
OUT("memb_%s_%d_constraint,\n", id,
++global_memb_unique);
@@ -1309,7 +1352,7 @@
OUT("0,\t/* Defer to actual type */\n");
}
if(C99_MODE) OUT(".name = ");
- OUT("\"%s\"\n", expr->Identifier ? expr->Identifier : "");
+ OUT("\"%s\"\n", expr->_anonymous_type ? "" : expr->Identifier);
OUT("},\n");
INDENT(-1);
@@ -1319,10 +1362,10 @@
save_target = arg->target->target;
REDIR(OT_CODE);
- if(expr->Identifier)
- p = MKID(expr->Identifier);
- else
+ if(expr->_anonymous_type && !strcmp(expr->Identifier, "member"))
p = asn1c_type_name(arg, expr, TNF_SAFE);
+ else
+ p = MKID(expr->Identifier);
OUT("static int\n");
OUT("memb_%s_%d_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,\n", p, global_memb_unique);
INDENT(+1);
@@ -1357,11 +1400,13 @@
p = asn1c_type_name(arg, arg->expr, TNF_SAFE);
}
+ OUT("%s_free,\n", p);
+ OUT("%s_print,\n", p);
OUT("%s_constraint,\n", p);
OUT("%s_decode_ber,\n", p);
OUT("%s_encode_der,\n", p);
- OUT("%s_print,\n", p);
- OUT("%s_free,\n", p);
+ OUT("0, /* Not implemented yet */\n");
+ OUT("%s_encode_xer,\n", p);
p = MKID(expr->Identifier);
@@ -1468,7 +1513,24 @@
return 0;
}
- terminal = asn1f_find_terminal_type_ex(arg->asn, arg->mod, expr);
+ terminal = asn1f_find_terminal_type_ex(arg->asn, expr);
return (terminal == top_parent);
}
+
+static int
+expr_as_xmlvaluelist(arg_t *arg, asn1p_expr_t *expr) {
+ expr = asn1f_find_terminal_type_ex(arg->asn, expr);
+ if(!expr) return 0;
+
+ /* X.680, 25.5, Table 5 */
+ switch(expr->expr_type) {
+ case ASN_CONSTR_CHOICE:
+ case ASN_BASIC_BOOLEAN:
+ case ASN_BASIC_ENUMERATED:
+ case ASN_BASIC_NULL:
+ return 1;
+ default:
+ return 0;
+ }
+}