diff options
author | Lev Walkin <vlm@lionet.info> | 2005-02-25 12:10:27 +0000 |
---|---|---|
committer | Lev Walkin <vlm@lionet.info> | 2005-02-25 12:10:27 +0000 |
commit | e0b56e0d581fab0b62db2dae062eb9c472488bc6 (patch) | |
tree | 5df7cc6c038e921195c257e80c15441773790f7e | |
parent | 475d91f0d2674a9dfe9d022241567d3a33686e19 (diff) |
XMLValueList support
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | libasn1compiler/asn1c_C.c | 238 | ||||
-rw-r--r-- | libasn1compiler/asn1c_constraint.c | 6 | ||||
-rw-r--r-- | libasn1compiler/asn1c_out.h | 3 | ||||
-rw-r--r-- | skeletons/BOOLEAN.c | 4 | ||||
-rw-r--r-- | skeletons/INTEGER.c | 169 | ||||
-rw-r--r-- | skeletons/INTEGER.h | 16 | ||||
-rw-r--r-- | skeletons/NULL.c | 3 | ||||
-rw-r--r-- | skeletons/NativeInteger.c | 73 | ||||
-rw-r--r-- | skeletons/NativeInteger.h | 1 | ||||
-rw-r--r-- | skeletons/OBJECT_IDENTIFIER.c | 4 | ||||
-rw-r--r-- | skeletons/REAL.c | 4 | ||||
-rw-r--r-- | skeletons/RELATIVE-OID.c | 4 | ||||
-rw-r--r-- | skeletons/asn_codecs_prim.c | 19 | ||||
-rw-r--r-- | skeletons/asn_codecs_prim.h | 4 | ||||
-rw-r--r-- | skeletons/constr_SET.c | 3 | ||||
-rw-r--r-- | skeletons/constr_SET_OF.c | 5 | ||||
-rw-r--r-- | skeletons/xer_decoder.c | 7 |
18 files changed, 441 insertions, 132 deletions
@@ -1,11 +1,9 @@ -0.9.10: 2005-Feb-24 +0.9.10: 2005-Feb-25 - * Fixed #1150856. - Reported by <vvvy@users.sourceforge.net>. - * Fixed XER XMLValueList encoding and decoding. - (Test case 70) (Severity: high, Secruity impact: low) - Reported by <siden@ul-gsm.ru>. + * Completed the XER XMLValueList encoding and decoding. + * Native integer type is now using "long". + * Fixed #1150856. Reported by <vvvy@users.sourceforge.net>. 0.9.9: 2005-Feb-22 diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c index 883644b4..c0ff5a1e 100644 --- a/libasn1compiler/asn1c_C.c +++ b/libasn1compiler/asn1c_C.c @@ -85,36 +85,124 @@ asn1c_lang_C_type_REAL(arg_t *arg) { return asn1c_lang_C_type_SIMPLE_TYPE(arg); } +struct value2enum { + asn1c_integer_t value; + const char *name; + int idx; +}; +static int compar_enumMap_byName(const void *ap, const void *bp) { + const struct value2enum *a = (const struct value2enum *)ap; + const struct value2enum *b = (const struct value2enum *)bp; + return strcmp(a->name, b->name); +} +static int compar_enumMap_byValue(const void *ap, const void *bp) { + const struct value2enum *a = (const struct value2enum *)ap; + const struct value2enum *b = (const struct value2enum *)bp; + if(a->value < b->value) + return -1; + else if(a->value == b->value) + return 0; + return 1; +} + int asn1c_lang_C_type_common_INTEGER(arg_t *arg) { asn1p_expr_t *expr = arg->expr; asn1p_expr_t *v; + int el_count = expr_elements_count(arg, expr); + struct value2enum *v2e; + int map_is_extensible = (expr->expr_type == ASN_BASIC_INTEGER); - REDIR(OT_DEPS); + v2e = alloca((el_count + 1) * sizeof(*v2e)); - if(expr->expr_type == ASN_BASIC_ENUMERATED - || TQ_FIRST(&(expr->members)) - ) { + /* + * For all ENUMERATED types and for those INTEGER types which + * have identifiers, print out an enumeration table and a mapping + * between identifiers and associated values. + */ + if(expr->expr_type == ASN_BASIC_ENUMERATED || el_count) { + int eidx = 0; + + REDIR(OT_DEPS); OUT("typedef enum %s {\n", MKID(expr->Identifier)); TQ_FOR(v, &(expr->members), next) { switch(v->expr_type) { case A1TC_UNIVERVAL: - OUT("\t%s\t= %" PRIdASN ",\n", + OUT("\t%s\t= %" PRIdASN "%s\n", asn1c_make_identifier(0, expr->Identifier, v->Identifier, 0), - v->value->value.v_integer); + v->value->value.v_integer, + (eidx+1 < el_count) ? "," : "" + ); + v2e[eidx].name = v->Identifier; + v2e[eidx].value = v->value->value.v_integer; + eidx++; break; case A1TC_EXTENSIBLE: OUT("\t/*\n"); OUT("\t * Enumeration is extensible\n"); OUT("\t */\n"); + map_is_extensible = 1; break; default: return -1; } } OUT("} %s_e;\n", MKID(expr->Identifier)); + assert(eidx == el_count); + + /* + * Generate a enumerationName<->value map for XER codec. + */ + REDIR(OT_STAT_DEFS); + + OUT("static asn_INTEGER_enum_map_t asn_MAP_%s_value2enum[] = {\n", + MKID_nr(expr->Identifier)); + qsort(v2e, el_count, sizeof(v2e[0]), compar_enumMap_byValue); + for(eidx = 0; eidx < el_count; eidx++) { + v2e[eidx].idx = eidx; + OUT("\t{ %" PRIdASN ",\t%ld,\t\"%s\" }%s\n", + v2e[eidx].value, + (long)strlen(v2e[eidx].name), v2e[eidx].name, + (eidx + 1 < el_count) ? "," : ""); + } + if(map_is_extensible) + OUT("\t/* This list is extensible */\n"); + OUT("};\n"); + + OUT("static unsigned int asn_MAP_%s_enum2value[] = {\n", + MKID_nr(expr->Identifier)); + qsort(v2e, el_count, sizeof(v2e[0]), compar_enumMap_byName); + for(eidx = 0; eidx < el_count; eidx++) { + OUT("\t%d%s\t/* %s(%" PRIdASN ") */\n", + v2e[eidx].idx, + (eidx + 1 < el_count) ? "," : "", + v2e[eidx].name, v2e[eidx].value); + } + if(map_is_extensible) + OUT("\t/* This list is extensible */\n"); + OUT("};\n"); + + OUT("static asn_INTEGER_specifics_t asn_DEF_%s_specs = {\n", + MKID_nr(expr->Identifier)); + INDENT(+1); + OUT("asn_MAP_%s_value2enum,\t" + "/* \"tag\" => N; sorted by tag */\n", + MKID_nr(expr->Identifier)); + OUT("asn_MAP_%s_enum2value,\t" + "/* N => \"tag\"; sorted by N */\n", + MKID_nr(expr->Identifier)); + OUT("%d,\t/* Number of elements in the maps */\n", + el_count); + OUT("%d,\t/* Enumeration is %sextensible */\n", + map_is_extensible, map_is_extensible ? "": "not "); + if(expr->expr_type == ASN_BASIC_ENUMERATED) + OUT("1\t/* Strict enumeration */\n"); + else + OUT("0\n"); + INDENT(-1); + OUT("};\n"); } return asn1c_lang_C_type_SIMPLE_TYPE(arg); @@ -434,7 +522,7 @@ asn1c_lang_C_type_SET_def(arg_t *arg) { OUT("asn_DEF_%s_tag2el_cxer,\n", p); else OUT("asn_DEF_%s_tag2el,\t/* Same as above */\n", p); - OUT("%d,\t/* Count of tags in the CANONICAL-XER map */\n", tag2el_cxer_count); + OUT("%d,\t/* Count of tags in the CXER map */\n", tag2el_cxer_count); OUT("%d,\t/* Whether extensible */\n", check_if_extensible(expr)); OUT("(unsigned int *)asn_DEF_%s_mmap\t/* Mandatory elements map */\n", p); @@ -471,7 +559,10 @@ asn1c_lang_C_type_SEx_OF(arg_t *arg) { OUT("A_%s_OF(", (arg->expr->expr_type == ASN_CONSTR_SET_OF) ? "SET" : "SEQUENCE"); - if(memb->expr_type & ASN_CONSTR_MASK) { + if(memb->expr_type & ASN_CONSTR_MASK + || ((memb->expr_type == ASN_BASIC_ENUMERATED + || memb->expr_type == ASN_BASIC_INTEGER) + && expr_elements_count(arg, memb))) { arg_t tmp; asn1p_expr_t tmp_memb; arg->embed++; @@ -775,6 +866,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { int tags_count; int all_tags_count; enum tvm_compat tv_mode; + enum etd_spec etd_spec; char *p; if(arg->embed) { @@ -800,36 +892,49 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { REDIR(OT_TYPE_DECLS); - OUT("%s\t", asn1c_type_name(arg, arg->expr, tnfmt | TNF_CHECK)); - OUT("%s", expr->marker.flags?"*":" "); - OUT("%s", MKID(expr->Identifier)); - if((expr->marker.flags & EM_DEFAULT) == EM_DEFAULT) - OUT("\t/* DEFAULT %s */", - asn1f_printable_value(expr->marker.default_value)); - else if((expr->marker.flags & EM_OPTIONAL) == EM_OPTIONAL) - OUT("\t/* OPTIONAL */"); - - REDIR(OT_TYPE_DECLS); - return 0; - } + OUT("%s", asn1c_type_name(arg, arg->expr, tnfmt | TNF_CHECK)); + if(!expr->_anonymous_type) { + OUT("%s", expr->marker.flags?"\t*":"\t "); + OUT("%s", MKID(expr->Identifier)); + if((expr->marker.flags & EM_DEFAULT) == EM_DEFAULT) + OUT("\t/* DEFAULT %s */", + asn1f_printable_value( + expr->marker.default_value)); + else if((expr->marker.flags & EM_OPTIONAL) == EM_OPTIONAL) + OUT("\t/* OPTIONAL */"); + } + } else { + GEN_INCLUDE(asn1c_type_name(arg, expr, TNF_INCLUDE)); - GEN_INCLUDE(asn1c_type_name(arg, expr, TNF_INCLUDE)); + REDIR(OT_TYPE_DECLS); - REDIR(OT_TYPE_DECLS); + OUT("typedef %s\t", + asn1c_type_name(arg, arg->expr, TNF_CTYPE | TNF_CHECK)); + OUT("%s%s_t", + expr->marker.flags?"*":" ", + MKID(expr->Identifier)); + OUT_DEBUG("\t/* %s:%d */", __FILE__, __LINE__); + } - OUT("typedef %s\t", asn1c_type_name(arg, arg->expr, TNF_CTYPE | TNF_CHECK)); - OUT("%s", expr->marker.flags?"*":" "); - OUT("%s_t", MKID(expr->Identifier)); + if((expr->expr_type == ASN_BASIC_ENUMERATED) + || (expr->expr_type == ASN_BASIC_INTEGER + && expr_elements_count(arg, expr))) + etd_spec = ETD_HAS_SPECIFICS; + else + etd_spec = ETD_NO_SPECIFICS; /* * If this type just blindly refers the other type, alias it. * Type1 ::= Type2 */ + if(arg->embed && etd_spec == ETD_NO_SPECIFICS) { + REDIR(OT_TYPE_DECLS); + return 0; + } if((!expr->constraints || (arg->flags & A1C_NO_CONSTRAINTS)) - && expr->tag.tag_class == TC_NOCLASS - && !TQ_FIRST(&(expr->members)) - ) { + && (arg->embed || expr->tag.tag_class == TC_NOCLASS) + && etd_spec == ETD_NO_SPECIFICS) { char *type_name; REDIR(OT_FUNC_DECLS); type_name = asn1c_type_name(arg, expr, TNF_SAFE); @@ -837,9 +942,10 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { if(HIDE_INNER_DEFS) OUT("/* "); OUT("#define\tasn_DEF_%s\t", MKID_nr(expr->Identifier)); type_name = asn1c_type_name(arg, expr, TNF_SAFE); - OUT("asn_DEF_%s\n", type_name); + OUT("asn_DEF_%s", type_name); if(HIDE_INNER_DEFS) - OUT(" // (Use -fall-defs-global to expose) */"); + OUT("\t// (Use -fall-defs-global to expose) */"); + OUT("\n"); REDIR(OT_CODE); OUT("/* This type is equivalent to %s */\n", type_name); OUT("\n"); @@ -854,8 +960,8 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { */ tv_mode = emit_tags_vectors(arg, expr, &tags_count, &all_tags_count); - emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count, 0, - ETD_NO_SPECIFICS); + emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count, + 0, etd_spec); REDIR(OT_CODE); @@ -864,6 +970,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { */ if(!(arg->flags & A1C_NO_CONSTRAINTS)) { p = MKID(expr->Identifier); + if(HIDE_INNER_DEFS) OUT("static "); OUT("int\n"); OUT("%s_constraint(" "asn_TYPE_descriptor_t *td, const void *sptr,\n", p); @@ -901,7 +1008,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { p = MKID(expr->Identifier); OUT("%s_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {\n", p); INDENT(+1); - { + { asn1p_expr_t *terminal = asn1f_find_terminal_type_ex(arg->asn, expr); char *type_name = asn1c_type_name(arg, expr, TNF_SAFE); OUT("td->free_struct = asn_DEF_%s.free_struct;\n", type_name); @@ -920,13 +1027,23 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { } OUT("td->elements = asn_DEF_%s.elements;\n", type_name); OUT("td->elements_count = asn_DEF_%s.elements_count;\n", type_name); - OUT("td->specifics = asn_DEF_%s.specifics;\n", type_name); + if(etd_spec != ETD_NO_SPECIFICS) { + INDENT(-1); + OUT(" /* "); } - INDENT(-1); + OUT("td->specifics = asn_DEF_%s.specifics;", type_name); + if(etd_spec == ETD_NO_SPECIFICS) { + INDENT(-1); + OUT("\n"); + } else { + OUT("\t// Defined explicitly */\n"); + } + } OUT("}\n"); OUT("\n"); p = MKID(expr->Identifier); + if(HIDE_INNER_DEFS) OUT("static "); OUT("void\n"); OUT("%s_free(asn_TYPE_descriptor_t *td,\n", p); INDENTED( @@ -938,6 +1055,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { OUT("\n"); p = MKID(expr->Identifier); + if(HIDE_INNER_DEFS) OUT("static "); OUT("int\n"); OUT("%s_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,\n", p); INDENTED( @@ -949,6 +1067,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { OUT("\n"); p = MKID(expr->Identifier); + if(HIDE_INNER_DEFS) OUT("static "); OUT("asn_dec_rval_t\n"); OUT("%s_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,\n", p); INDENTED( @@ -960,6 +1079,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { OUT("\n"); p = MKID(expr->Identifier); + if(HIDE_INNER_DEFS) OUT("static "); OUT("asn_enc_rval_t\n"); OUT("%s_encode_der(asn_TYPE_descriptor_t *td,\n", p); INDENTED( @@ -972,6 +1092,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { OUT("\n"); p = MKID(expr->Identifier); + if(HIDE_INNER_DEFS) OUT("static "); OUT("asn_dec_rval_t\n"); OUT("%s_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,\n", p); INDENTED( @@ -983,6 +1104,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { OUT("\n"); p = MKID(expr->Identifier); + if(HIDE_INNER_DEFS) OUT("static "); OUT("asn_enc_rval_t\n"); OUT("%s_encode_xer(asn_TYPE_descriptor_t *td, void *structure,\n", p); INDENTED( @@ -997,17 +1119,19 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { REDIR(OT_FUNC_DECLS); p = MKID_nr(expr->Identifier); - if(HIDE_INNER_DEFS) OUT("/* "); - OUT("extern asn_TYPE_descriptor_t asn_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("xer_type_decoder_f %s_decode_xer;\n", p); - OUT("xer_type_encoder_f %s_encode_xer;\n", p); + if(HIDE_INNER_DEFS) { + OUT("/* extern asn_TYPE_descriptor_t asn_DEF_%s;" + "\t// (Use -fall-defs-global to expose) */\n", p); + } else { + OUT("extern asn_TYPE_descriptor_t asn_DEF_%s;\n", p); + 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("xer_type_decoder_f %s_decode_xer;\n", p); + OUT("xer_type_encoder_f %s_encode_xer;\n", p); + } REDIR(OT_TYPE_DECLS); @@ -1103,7 +1227,7 @@ _fill_tag2el_map(arg_t *arg, tag2el_t **tag2el, int *count, int el_no, fte_e fla TQ_FOR(v, &(expr->members), next) { if(v->expr_type == A1TC_EXTENSIBLE) { /* - * CANONICAL-XER mandates sorting + * CXER mandates sorting * only for the root part. */ if(flags == FTE_CANONICAL_XER @@ -1256,7 +1380,8 @@ emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count, const char * OUT("%d, ", tag2el[i].el_no); OUT("%d, ", tag2el[i].toff_first); OUT("%d ", tag2el[i].toff_last); - OUT("}, /* %s at %d */\n", + OUT("}%s /* %s at %d */\n", + (i + 1 < tag2el_count) ? "," : "", tag2el[i].from_expr->Identifier, tag2el[i].from_expr->_lineno ); @@ -1354,7 +1479,9 @@ expr_elements_count(arg_t *arg, asn1p_expr_t *expr) { topmost_parent = asn1f_find_terminal_type_ex(arg->asn, expr); if(!topmost_parent) return 0; - if(!(topmost_parent->expr_type & ASN_CONSTR_MASK)) + if(!(topmost_parent->expr_type & ASN_CONSTR_MASK) + && !topmost_parent->expr_type == ASN_BASIC_INTEGER + && !topmost_parent->expr_type == ASN_BASIC_ENUMERATED) return 0; TQ_FOR(v, &(topmost_parent->members), next) { @@ -1372,6 +1499,7 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr) { arg_t tmp_arg; struct asn1p_type_tag_s outmost_tag_s; struct asn1p_type_tag_s *outmost_tag; + int complex_contents; char *p; if(asn1f_fetch_outmost_tag(arg->asn, @@ -1429,11 +1557,19 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr) { } else { OUT("0,\n"); } + + complex_contents = + (expr->expr_type & ASN_CONSTR_MASK) + || expr->expr_type == ASN_BASIC_ENUMERATED + || (expr->expr_type == ASN_BASIC_INTEGER + && expr_elements_count(arg, expr)); if(C99_MODE) OUT(".type = "); - if(expr->_anonymous_type && (expr->expr_type & ASN_CONSTR_MASK)) { + if(complex_contents + && expr->_anonymous_type + && !strcmp(expr->Identifier, "Member")) { OUT("(void *)&asn_DEF_%s_Member,\n", MKID_nr(arg->expr->Identifier)); - } else if(expr->expr_type & ASN_CONSTR_MASK) { + } else if(complex_contents) { OUT("(void *)&asn_DEF_%s,\n", MKID_nr(expr->Identifier)); } else { diff --git a/libasn1compiler/asn1c_constraint.c b/libasn1compiler/asn1c_constraint.c index b586d4db..67b45bfc 100644 --- a/libasn1compiler/asn1c_constraint.c +++ b/libasn1compiler/asn1c_constraint.c @@ -95,7 +95,7 @@ asn1c_emit_constraint_checking_code(arg_t *arg) { OUT("double value;\n"); break; case ASN_BASIC_BOOLEAN: - OUT("int value;\n"); + OUT("BOOLEAN_t value;\n"); break; default: break; @@ -557,7 +557,7 @@ emit_value_determination_code(arg_t *arg, asn1p_expr_type_e etype, asn1cnst_rang case ASN_BASIC_INTEGER: case ASN_BASIC_ENUMERATED: if(arg->flags & A1C_USE_NATIVE_TYPES) { - OUT("value = *(const int *)sptr;\n"); + OUT("value = *(const long *)sptr;\n"); } else { if(r_value->el_count == 0 && ( @@ -601,7 +601,7 @@ emit_value_determination_code(arg_t *arg, asn1p_expr_type_e etype, asn1cnst_rang } break; case ASN_BASIC_BOOLEAN: - OUT("value = (*(const int *)sptr) ? 1 : 0;\n"); + OUT("value = (*(const long *)sptr) ? 1 : 0;\n"); break; default: WARNING("%s:%d: Value cannot be determined " diff --git a/libasn1compiler/asn1c_out.h b/libasn1compiler/asn1c_out.h index 8f032211..5a0a1f2b 100644 --- a/libasn1compiler/asn1c_out.h +++ b/libasn1compiler/asn1c_out.h @@ -75,6 +75,9 @@ int asn1c_compiled_output(arg_t *arg, const char *fmt, ...); OUT(fmt, ##args); \ INDENT_LEVEL = _saved_indent; \ } while(0) +#define OUT_DEBUG(fmt, args...) do { \ + if(arg->flags & A1C_DEBUG) OUT(fmt, ##args); \ + } while(0) /* Generate #include line */ #define GEN_INCLUDE(filename) do { \ diff --git a/skeletons/BOOLEAN.c b/skeletons/BOOLEAN.c index 6a4cdc7e..ad7321ce 100644 --- a/skeletons/BOOLEAN.c +++ b/skeletons/BOOLEAN.c @@ -134,10 +134,12 @@ BOOLEAN_encode_der(asn_TYPE_descriptor_t *td, void *sptr, * Decode the chunk of XML text encoding INTEGER. */ static ssize_t -BOOLEAN__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) { +BOOLEAN__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, size_t chunk_size) { BOOLEAN_t *st = (BOOLEAN_t *)sptr; char *p = (char *)chunk_buf; + (void)td; + if(chunk_size == 0) return -1; if(p[0] == 0x3c /* '<' */) { diff --git a/skeletons/INTEGER.c b/skeletons/INTEGER.c index db289cb2..de856d8f 100644 --- a/skeletons/INTEGER.c +++ b/skeletons/INTEGER.c @@ -1,5 +1,6 @@ /*- - * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>. + * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #include <asn_internal.h> @@ -92,11 +93,15 @@ INTEGER_encode_der(asn_TYPE_descriptor_t *td, void *sptr, return der_encode_primitive(td, sptr, tag_mode, tag, cb, app_key); } +static const asn_INTEGER_enum_map_t *INTEGER__map_value2enum(asn_INTEGER_specifics_t *specs, long value); +static const asn_INTEGER_enum_map_t *INTEGER__map_enum2value(asn_INTEGER_specifics_t *specs, const char *lstart, const char *lstop); + /* * INTEGER specific human-readable output. */ static ssize_t -INTEGER__dump(const INTEGER_t *st, asn_app_consume_bytes_f *cb, void *app_key) { +INTEGER__dump(asn_TYPE_descriptor_t *td, const INTEGER_t *st, asn_app_consume_bytes_f *cb, void *app_key, int plainOrXER) { + asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; char scratch[32]; /* Enough for 64-bit integer */ uint8_t *buf = st->buf; uint8_t *buf_end = st->buf + st->size; @@ -105,10 +110,6 @@ INTEGER__dump(const INTEGER_t *st, asn_app_consume_bytes_f *cb, void *app_key) { char *p; int ret; - if(st->size == 0) { - return (cb("0", 1, app_key) < 0) ? -1 : 1; - } - /* * Advance buf pointer until the start of the value's body. * This will make us able to process large integers using simple case, @@ -126,12 +127,49 @@ INTEGER__dump(const INTEGER_t *st, asn_app_consume_bytes_f *cb, void *app_key) { /* Simple case: the integer size is small */ if((size_t)(buf_end - buf) <= sizeof(accum)) { - accum = (*buf & 0x80) ? -1 : 0; - for(; buf < buf_end; buf++) - accum = (accum << 8) | *buf; - ret = snprintf(scratch, sizeof(scratch), "%ld", accum); - assert(ret > 0 && ret < (int)sizeof(scratch)); - return (cb(scratch, ret, app_key) < 0) ? -1 : ret; + const asn_INTEGER_enum_map_t *el; + size_t scrsize; + char *scr; + + if(buf == buf_end) { + accum = 0; + } else { + accum = (*buf & 0x80) ? -1 : 0; + for(; buf < buf_end; buf++) + accum = (accum << 8) | *buf; + } + + el = INTEGER__map_value2enum(specs, accum); + if(el) { + scrsize = el->enum_len + 32; + scr = (char *)alloca(scrsize); + if(plainOrXER == 0) + ret = snprintf(scr, scrsize, + "%ld (%s)", accum, el->enum_name); + else + ret = snprintf(scr, scrsize, + "<%s/>", el->enum_name); + } else if(plainOrXER && specs && specs->strict_enumeration) { + ASN_DEBUG("ASN.1 forbids dealing with " + "unknown value of ENUMERATED type"); + errno = EPERM; + return -1; + } else { + scrsize = sizeof(scratch); + scr = scratch; + ret = snprintf(scr, scrsize, "%ld", accum); + } + assert(ret > 0 && (size_t)ret < scrsize); + return (cb(scr, ret, app_key) < 0) ? -1 : ret; + } else if(plainOrXER && specs && specs->strict_enumeration) { + /* + * Here and earlier, we cannot encode the ENUMERATED values + * if there is no corresponding identifier. + */ + ASN_DEBUG("ASN.1 forbids dealing with " + "unknown value of ENUMERATED type"); + errno = EPERM; + return -1; } /* Output in the long xx:yy:zz... format */ @@ -171,22 +209,97 @@ INTEGER_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, if(!st && !st->buf) ret = cb("<absent>", 8, app_key); else - ret = INTEGER__dump(st, cb, app_key); + ret = INTEGER__dump(td, st, cb, app_key, 0); return (ret < 0) ? -1 : 0; } +struct e2v_key { + const char *start; + const char *stop; + asn_INTEGER_enum_map_t *vemap; + unsigned int *evmap; +}; +static int +INTEGER__compar_enum2value(const void *kp, const void *am) { + const struct e2v_key *key = (const struct e2v_key *)kp; + const asn_INTEGER_enum_map_t *el = (const asn_INTEGER_enum_map_t *)am; + const char *ptr, *end, *name; + + /* Remap the element (sort by different criterion) */ + el = key->vemap + key->evmap[el - key->vemap]; + + /* Compare strings */ + for(ptr = key->start, end = key->stop, name = el->enum_name; + ptr < end; ptr++, name++) { + if(*ptr != *name) + return *(const unsigned char *)ptr + - *(const unsigned char *)name; + } + return name[0] ? -1 : 0; +} + +static const asn_INTEGER_enum_map_t * +INTEGER__map_enum2value(asn_INTEGER_specifics_t *specs, const char *lstart, const char *lstop) { + int count = specs ? specs->map_count : 0; + struct e2v_key key; + const char *lp; + + if(!count) return NULL; + + /* Guaranteed: assert(lstart < lstop); */ + /* Figure out the tag name */ + for(lstart++, lp = lstart; lp < lstop; lp++) { + switch(*lp) { + case 9: case 10: case 11: case 12: case 13: case 32: /* WSP */ + case 0x2f: /* '/' */ case 0x3e: /* '>' */ + break; + default: + continue; + } + break; + } + if(lp == lstop) return NULL; /* No tag found */ + lstop = lp; + + key.start = lstart; + key.stop = lstop; + key.vemap = specs->value2enum; + key.evmap = specs->enum2value; + return (asn_INTEGER_enum_map_t *)bsearch(&key, specs->value2enum, count, + sizeof(specs->value2enum[0]), INTEGER__compar_enum2value); +} + +static int +INTEGER__compar_value2enum(const void *kp, const void *am) { + long a = *(const long *)kp; + const asn_INTEGER_enum_map_t *el = (const asn_INTEGER_enum_map_t *)am; + long b = el->nat_value; + if(a < b) return -1; + else if(a == b) return 0; + else return 1; +} + +static const asn_INTEGER_enum_map_t * +INTEGER__map_value2enum(asn_INTEGER_specifics_t *specs, long value) { + int count = specs ? specs->map_count : 0; + if(!count) return 0; + return (asn_INTEGER_enum_map_t *)bsearch(&value, specs->value2enum, + count, sizeof(specs->value2enum[0]), + INTEGER__compar_value2enum); +} + /* * Decode the chunk of XML text encoding INTEGER. */ static ssize_t -INTEGER__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) { +INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, size_t chunk_size) { INTEGER_t *st = (INTEGER_t *)sptr; long sign = 1; long value; - char *lp; - char *lstart = (char *)chunk_buf; - char *lstop = lstart + chunk_size; + const char *lp; + const char *lstart = (const char *)chunk_buf; + const char *lstop = lstart + chunk_size; enum { ST_SKIPSPACE, ST_WAITDIGITS, @@ -194,8 +307,8 @@ INTEGER__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) { } state = ST_SKIPSPACE; /* - * We may receive a tag here. But we aren't ready to deal with it yet. - * So, just use stroul()-like code and serialize the result. + * We may have received a tag here. It will be processed inline. + * Use strtoul()-like code and serialize the result. */ for(value = 0, lp = lstart; lp < lstop; lp++) { int lv = *lp; @@ -242,6 +355,22 @@ INTEGER__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) { } } continue; + case 0x3c: /* '<' */ + if(state == ST_SKIPSPACE) { + const asn_INTEGER_enum_map_t *el; + el = INTEGER__map_enum2value( + (asn_INTEGER_specifics_t *) + td->specifics, lstart, lstop); + if(el) { + ASN_DEBUG("Found \"%s\" => %ld", + el->enum_name, el->nat_value); + state = ST_DIGITS; + value = el->nat_value; + break; + } + ASN_DEBUG("Unknown identifier for INTEGER"); + } + return -1; } break; } @@ -280,7 +409,7 @@ INTEGER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, if(!st && !st->buf) _ASN_ENCODE_FAILED; - er.encoded = INTEGER__dump(st, cb, app_key); + er.encoded = INTEGER__dump(td, st, cb, app_key, 1); if(er.encoded < 0) _ASN_ENCODE_FAILED; return er; diff --git a/skeletons/INTEGER.h b/skeletons/INTEGER.h index 45259e23..a1b555f3 100644 --- a/skeletons/INTEGER.h +++ b/skeletons/INTEGER.h @@ -12,6 +12,22 @@ typedef ASN__PRIMITIVE_TYPE_t INTEGER_t; extern asn_TYPE_descriptor_t asn_DEF_INTEGER; +/* Map with <tag> to integer value association */ +typedef struct asn_INTEGER_enum_map_s { + long nat_value; /* associated native integer value */ + size_t enum_len; /* strlen("tag") */ + const char *enum_name; /* "tag" */ +} asn_INTEGER_enum_map_t; + +/* This type describes an enumeration for INTEGER and ENUMERATED types */ +typedef struct asn_INTEGER_specifics_s { + asn_INTEGER_enum_map_t *value2enum; /* N -> "tag"; sorted by N */ + unsigned int *enum2value; /* "tag" => N; sorted by tag */ + int map_count; /* Elements in either map */ + int extensible; /* This map is extensible */ + int strict_enumeration; /* Enumeration set is fixed */ +} asn_INTEGER_specifics_t; + asn_struct_print_f INTEGER_print; ber_type_decoder_f INTEGER_decode_ber; der_type_encoder_f INTEGER_encode_der; diff --git a/skeletons/NULL.c b/skeletons/NULL.c index 8cccc66c..6a813fcf 100644 --- a/skeletons/NULL.c +++ b/skeletons/NULL.c @@ -68,7 +68,8 @@ NULL_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, static ssize_t -NULL__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) { +NULL__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, size_t chunk_size) { + (void)td; (void)sptr; if(xer_is_whitespace(chunk_buf, chunk_size)) return chunk_size; diff --git a/skeletons/NativeInteger.c b/skeletons/NativeInteger.c index d6d1fd88..102372c4 100644 --- a/skeletons/NativeInteger.c +++ b/skeletons/NativeInteger.c @@ -11,7 +11,6 @@ */ #include <asn_internal.h> #include <NativeInteger.h> -#include <INTEGER.h> #include <assert.h> /* @@ -45,17 +44,17 @@ asn_TYPE_descriptor_t asn_DEF_NativeInteger = { asn_dec_rval_t NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **int_ptr, void *buf_ptr, size_t size, int tag_mode) { - int *Int = (int *)*int_ptr; + void **nint_ptr, void *buf_ptr, size_t size, int tag_mode) { + long *native = (long *)*nint_ptr; asn_dec_rval_t rval; ber_tlv_len_t length; /* * If the structure is not there, allocate it. */ - if(Int == NULL) { - Int = (int *)(*int_ptr = CALLOC(1, sizeof(*Int))); - if(Int == NULL) { + if(native == NULL) { + native = (long *)(*nint_ptr = CALLOC(1, sizeof(*native))); + if(native == NULL) { rval.code = RC_FAIL; rval.consumed = 0; return rval; @@ -88,7 +87,7 @@ NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx, /* * ASN.1 encoded INTEGER: buf_ptr, length - * Fill the Int, at the same time checking for overflow. + * Fill the native, at the same time checking for overflow. * If overflow occured, return with RC_FAIL. */ { @@ -103,15 +102,15 @@ NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx, return rval; } - *Int = l; + *native = l; /* - * Note that int might be shorter than long. + * Note that native integer size might be other than long. * This expression hopefully will be optimized away * by compiler. */ - if(sizeof(int) != sizeof(long) && ((long)*Int != l)) { - *Int = 0; /* Safe value */ + if(sizeof(*native) != sizeof(long) && ((long)*native != l)) { + *native = 0; /* Safe value */ rval.code = RC_FAIL; rval.consumed = 0; return rval; @@ -121,8 +120,8 @@ NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx, rval.code = RC_OK; rval.consumed += length; - ASN_DEBUG("Took %ld/%ld bytes to encode %s (%d)", - (long)rval.consumed, (long)length, td->name, *Int); + ASN_DEBUG("Took %ld/%ld bytes to encode %s (%ld)", + (long)rval.consumed, (long)length, td->name, (long)*native); return rval; } @@ -134,22 +133,22 @@ asn_enc_rval_t NativeInteger_encode_der(asn_TYPE_descriptor_t *sd, void *ptr, int tag_mode, ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, void *app_key) { - unsigned int Int = *(unsigned int *)ptr; /* Disable sign ext. */ + unsigned long native = *(unsigned long *)ptr; /* Disable sign ext. */ asn_enc_rval_t erval; INTEGER_t tmp; #ifdef WORDS_BIGENDIAN /* Opportunistic optimization */ - tmp.buf = (uint8_t *)∬ - tmp.size = sizeof(Int); + tmp.buf = (uint8_t *)&native; + tmp.size = sizeof(native); #else /* Works even if WORDS_BIGENDIAN is not set where should've been */ - uint8_t buf[sizeof(int)]; + uint8_t buf[sizeof(native)]; uint8_t *p; /* Prepare a fake INTEGER */ - for(p = buf + sizeof(buf) - 1; p >= buf; p--, Int >>= 8) - *p = Int; + for(p = buf + sizeof(buf) - 1; p >= buf; p--, native >>= 8) + *p = native; tmp.buf = buf; tmp.size = sizeof(buf); @@ -174,12 +173,12 @@ NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_dec_rval_t rval; INTEGER_t *st = 0; void *st_ptr = (void *)&st; - int *Int = (int *)*sptr; + long *native = (long *)*sptr; - if(!Int) { + if(!native) { *sptr = CALLOC(1, sizeof(int)); - Int = (int *)*sptr; - if(!Int) { + native = (long *)*sptr; + if(!native) { rval.code = RC_FAIL; rval.consumed = 0; return rval; @@ -194,17 +193,23 @@ NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx, rval.code = RC_FAIL; rval.consumed = 0; } else { - *Int = l; + *native = l; - /* int might be shorter than long */ - if(sizeof(int) != sizeof(long) && ((long)*Int != l)) { - *Int = 0; /* Safe value */ + /* Native type might be shorter than long */ + if(sizeof(*native) != sizeof(long) + && ((long)*native != l)) { + *native = 0; /* Safe value */ rval.code = RC_FAIL; rval.consumed = 0; return rval; } } } else { + /* + * Cannot restart from the middle; + * there is no place to save state in the native type. + * Request a continuation from the very beginning. + */ rval.consumed = 0; } asn_DEF_INTEGER.free_struct(&asn_DEF_INTEGER, st, 0); @@ -218,14 +223,14 @@ NativeInteger_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) { char scratch[32]; /* Enough for 64-bit int */ asn_enc_rval_t er; - const int *Int = (const int *)sptr; + const long *native = (const long *)sptr; (void)ilevel; (void)flags; - if(!Int) _ASN_ENCODE_FAILED; + if(!native) _ASN_ENCODE_FAILED; - er.encoded = snprintf(scratch, sizeof(scratch), "%d", *Int); + er.encoded = snprintf(scratch, sizeof(scratch), "%ld", *native); if(er.encoded <= 0 || (size_t)er.encoded >= sizeof(scratch) || cb(scratch, er.encoded, app_key) < 0) _ASN_ENCODE_FAILED; @@ -239,16 +244,16 @@ NativeInteger_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, int NativeInteger_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { - const int *Int = (const int *)sptr; + const long *native = (const long *)sptr; char scratch[32]; /* Enough for 64-bit int */ int ret; (void)td; /* Unused argument */ (void)ilevel; /* Unused argument */ - if(Int) { - ret = snprintf(scratch, sizeof(scratch), "%d", *Int); - assert(ret > 0 && ret < (int)sizeof(scratch)); + if(native) { + ret = snprintf(scratch, sizeof(scratch), "%ld", *native); + assert(ret > 0 && (size_t)ret < sizeof(scratch)); return (cb(scratch, ret, app_key) < 0) ? -1 : 0; } else { return (cb("<absent>", 8, app_key) < 0) ? -1 : 0; diff --git a/skeletons/NativeInteger.h b/skeletons/NativeInteger.h index 777f8e65..b66d29ad 100644 --- a/skeletons/NativeInteger.h +++ b/skeletons/NativeInteger.h @@ -13,6 +13,7 @@ #define _NativeInteger_H_ #include <asn_application.h> +#include <INTEGER.h> extern asn_TYPE_descriptor_t asn_DEF_NativeInteger; diff --git a/skeletons/OBJECT_IDENTIFIER.c b/skeletons/OBJECT_IDENTIFIER.c index 3f2454c3..4128e765 100644 --- a/skeletons/OBJECT_IDENTIFIER.c +++ b/skeletons/OBJECT_IDENTIFIER.c @@ -264,7 +264,7 @@ OBJECT_IDENTIFIER__dump_body(const OBJECT_IDENTIFIER_t *st, asn_app_consume_byte } static ssize_t -OBJECT_IDENTIFIER__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) { +OBJECT_IDENTIFIER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, size_t chunk_size) { OBJECT_IDENTIFIER_t *st = (OBJECT_IDENTIFIER_t *)sptr; char *endptr; long s_arcs[10]; @@ -272,6 +272,8 @@ OBJECT_IDENTIFIER__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_siz int arcs_count; int ret; + (void)td; + arcs_count = OBJECT_IDENTIFIER_parse_arcs( (const char *)chunk_buf, chunk_size, arcs, 10, &endptr); if(arcs_count <= 0) diff --git a/skeletons/REAL.c b/skeletons/REAL.c index bf03db30..717db899 100644 --- a/skeletons/REAL.c +++ b/skeletons/REAL.c @@ -258,13 +258,15 @@ REAL_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, * Decode the chunk of XML text encoding REAL. */ static ssize_t -REAL__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) { +REAL__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, size_t chunk_size) { REAL_t *st = (REAL_t *)sptr; double value; char *xerdata = (char *)chunk_buf; char *endptr = 0; char *b; + (void)td; + if(!chunk_size) return -1; /* diff --git a/skeletons/RELATIVE-OID.c b/skeletons/RELATIVE-OID.c index d36d1f78..b0f6f64f 100644 --- a/skeletons/RELATIVE-OID.c +++ b/skeletons/RELATIVE-OID.c @@ -87,7 +87,7 @@ RELATIVE_OID_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, } static ssize_t -RELATIVE_OID__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) { +RELATIVE_OID__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, size_t chunk_size) { RELATIVE_OID_t *st = (RELATIVE_OID_t *)sptr; char *endptr; long s_arcs[6]; @@ -95,6 +95,8 @@ RELATIVE_OID__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) { int arcs_count; int ret; + (void)td; + arcs_count = OBJECT_IDENTIFIER_parse_arcs( (const char *)chunk_buf, chunk_size, arcs, 6, &endptr); diff --git a/skeletons/asn_codecs_prim.c b/skeletons/asn_codecs_prim.c index 03f107b6..5fe09adb 100644 --- a/skeletons/asn_codecs_prim.c +++ b/skeletons/asn_codecs_prim.c @@ -137,9 +137,10 @@ ASN__PRIMITIVE_TYPE_free(asn_TYPE_descriptor_t *td, void *sptr, * Local internal type passed around as an argument. */ struct xdp_arg_s { + asn_TYPE_descriptor_t *type_descriptor; void *struct_key; - ssize_t (*prim_body_decode)(void *struct_key, - void *chunk_buf, size_t chunk_size); + ssize_t (*prim_body_decode)(asn_TYPE_descriptor_t *td, + void *struct_key, void *chunk_buf, size_t chunk_size); int decoded_something; int want_more; }; @@ -159,7 +160,8 @@ xer_decode__unexpected_tag(void *key, void *chunk_buf, size_t chunk_size) { return -1; } - decoded = arg->prim_body_decode(arg->struct_key, chunk_buf, chunk_size); + decoded = arg->prim_body_decode(arg->type_descriptor, + arg->struct_key, chunk_buf, chunk_size); if(decoded < 0) { return -1; } else { @@ -196,7 +198,8 @@ xer_decode__body(void *key, void *chunk_buf, size_t chunk_size, int have_more) { return -1; } - decoded = arg->prim_body_decode(arg->struct_key, chunk_buf, chunk_size); + decoded = arg->prim_body_decode(arg->type_descriptor, + arg->struct_key, chunk_buf, chunk_size); if(decoded < 0) { return -1; } else { @@ -213,8 +216,8 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, size_t struct_size, const char *opt_mname, void *buf_ptr, size_t size, - ssize_t (*prim_body_decode)(void *struct_key, - void *chunk_buf, size_t chunk_size) + ssize_t (*prim_body_decode)(asn_TYPE_descriptor_t *td, + void *struct_key, void *chunk_buf, size_t chunk_size) ) { const char *xml_tag = opt_mname ? opt_mname : td->xml_tag; asn_struct_ctx_t s_ctx; @@ -235,6 +238,7 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, } memset(&s_ctx, 0, sizeof(s_ctx)); + s_arg.type_descriptor = td; s_arg.struct_key = *sptr; s_arg.prim_body_decode = prim_body_decode; s_arg.decoded_something = 0; @@ -248,7 +252,8 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, if(!s_arg.decoded_something) { char ch; /* Opportunity has come and gone. Where's the result? */ - if(prim_body_decode(s_arg.struct_key, &ch, 0) != 0) { + if(prim_body_decode(s_arg.type_descriptor, + s_arg.struct_key, &ch, 0) != 0) { /* * This decoder does not like empty stuff. */ diff --git a/skeletons/asn_codecs_prim.h b/skeletons/asn_codecs_prim.h index c235f35b..7a6723d3 100644 --- a/skeletons/asn_codecs_prim.h +++ b/skeletons/asn_codecs_prim.h @@ -25,8 +25,8 @@ asn_dec_rval_t xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, void **struct_ptr, size_t struct_size, const char *opt_mname, void *buf_ptr, size_t size, - ssize_t (*prim_body_decode)(void *struct_ptr, - void *chunk_buf, size_t chunk_size) + ssize_t (*prim_body_decode)(asn_TYPE_descriptor_t *td, + void *struct_ptr, void *chunk_buf, size_t chunk_size) ); #endif /* ASN_CODECS_PRIM_H */ diff --git a/skeletons/constr_SET.c b/skeletons/constr_SET.c index 2ee3b81a..4099186c 100644 --- a/skeletons/constr_SET.c +++ b/skeletons/constr_SET.c @@ -788,7 +788,8 @@ SET_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, break; } - ASN_DEBUG("Unexpected XML tag in SET"); + ASN_DEBUG("Unexpected XML tag in SET, expected \"%s\"", + xml_tag); break; } diff --git a/skeletons/constr_SET_OF.c b/skeletons/constr_SET_OF.c index 931aab27..c6ec6af2 100644 --- a/skeletons/constr_SET_OF.c +++ b/skeletons/constr_SET_OF.c @@ -641,7 +641,7 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) { asn_enc_rval_t er; - asn_SET_OF_specifics_t *specs=(asn_SET_OF_specifics_t *)td->specifics; + asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics; asn_TYPE_member_t *element = td->elements; A_SET_OF(void) *list; const char *mname = specs->as_XMLValueList @@ -684,6 +684,8 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1); } + if(!xcan && specs->as_XMLValueList) + _i_ASN_TEXT_INDENT(1, ilevel + 1); tmper = element->type->xer_encoder(element->type, memb_ptr, ilevel + 1, flags, cb, app_key); if(tmper.encoded == -1) { @@ -695,7 +697,6 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, const char *name = (*element->name) ? element->name : element->type->xml_tag; size_t len = strlen(name); - if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel + 1); _ASN_CALLBACK3("<", 1, name, len, "/>", 2); } diff --git a/skeletons/xer_decoder.c b/skeletons/xer_decoder.c index 82c084e2..0de6e33f 100644 --- a/skeletons/xer_decoder.c +++ b/skeletons/xer_decoder.c @@ -271,7 +271,6 @@ xer_decode_general(asn_codec_ctx_t *opt_codec_ctx, ctx->phase = 2; /* Phase out */ RETURN(RC_OK); case XCT_UNKNOWN_BO: - if(!ctx->phase) break; /* * Certain tags in the body may be expected. */ @@ -280,6 +279,12 @@ xer_decode_general(asn_codec_ctx_t *opt_codec_ctx, buf_ptr, ch_size) == 0) { /* Tag's processed fine */ ADVANCE(ch_size); + if(!ctx->phase) { + /* We are not expecting + * the closing tag anymore. */ + ctx->phase = 2; /* Phase out */ + RETURN(RC_OK); + } continue; } /* Fall through */ |