mirror of https://gerrit.osmocom.org/asn1c
XMLValueList support
git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@708 59561ff5-6e30-0410-9f3c-9617f08c8826
This commit is contained in:
parent
909b6c6271
commit
80a4859928
10
ChangeLog
10
ChangeLog
|
@ -1,11 +1,9 @@
|
||||||
|
|
||||||
0.9.10: 2005-Feb-24
|
0.9.10: 2005-Feb-25
|
||||||
|
|
||||||
* Fixed #1150856.
|
* Completed the XER XMLValueList encoding and decoding.
|
||||||
Reported by <vvvy@users.sourceforge.net>.
|
* Native integer type is now using "long".
|
||||||
* Fixed XER XMLValueList encoding and decoding.
|
* Fixed #1150856. Reported by <vvvy@users.sourceforge.net>.
|
||||||
(Test case 70) (Severity: high, Secruity impact: low)
|
|
||||||
Reported by <siden@ul-gsm.ru>.
|
|
||||||
|
|
||||||
0.9.9: 2005-Feb-22
|
0.9.9: 2005-Feb-22
|
||||||
|
|
||||||
|
|
|
@ -85,36 +85,124 @@ asn1c_lang_C_type_REAL(arg_t *arg) {
|
||||||
return asn1c_lang_C_type_SIMPLE_TYPE(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
|
int
|
||||||
asn1c_lang_C_type_common_INTEGER(arg_t *arg) {
|
asn1c_lang_C_type_common_INTEGER(arg_t *arg) {
|
||||||
asn1p_expr_t *expr = arg->expr;
|
asn1p_expr_t *expr = arg->expr;
|
||||||
asn1p_expr_t *v;
|
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));
|
OUT("typedef enum %s {\n", MKID(expr->Identifier));
|
||||||
TQ_FOR(v, &(expr->members), next) {
|
TQ_FOR(v, &(expr->members), next) {
|
||||||
switch(v->expr_type) {
|
switch(v->expr_type) {
|
||||||
case A1TC_UNIVERVAL:
|
case A1TC_UNIVERVAL:
|
||||||
OUT("\t%s\t= %" PRIdASN ",\n",
|
OUT("\t%s\t= %" PRIdASN "%s\n",
|
||||||
asn1c_make_identifier(0,
|
asn1c_make_identifier(0,
|
||||||
expr->Identifier,
|
expr->Identifier,
|
||||||
v->Identifier, 0),
|
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;
|
break;
|
||||||
case A1TC_EXTENSIBLE:
|
case A1TC_EXTENSIBLE:
|
||||||
OUT("\t/*\n");
|
OUT("\t/*\n");
|
||||||
OUT("\t * Enumeration is extensible\n");
|
OUT("\t * Enumeration is extensible\n");
|
||||||
OUT("\t */\n");
|
OUT("\t */\n");
|
||||||
|
map_is_extensible = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OUT("} %s_e;\n", MKID(expr->Identifier));
|
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);
|
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);
|
OUT("asn_DEF_%s_tag2el_cxer,\n", p);
|
||||||
else
|
else
|
||||||
OUT("asn_DEF_%s_tag2el,\t/* Same as above */\n", p);
|
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",
|
OUT("%d,\t/* Whether extensible */\n",
|
||||||
check_if_extensible(expr));
|
check_if_extensible(expr));
|
||||||
OUT("(unsigned int *)asn_DEF_%s_mmap\t/* Mandatory elements map */\n", p);
|
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(",
|
OUT("A_%s_OF(",
|
||||||
(arg->expr->expr_type == ASN_CONSTR_SET_OF)
|
(arg->expr->expr_type == ASN_CONSTR_SET_OF)
|
||||||
? "SET" : "SEQUENCE");
|
? "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;
|
arg_t tmp;
|
||||||
asn1p_expr_t tmp_memb;
|
asn1p_expr_t tmp_memb;
|
||||||
arg->embed++;
|
arg->embed++;
|
||||||
|
@ -775,6 +866,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
|
||||||
int tags_count;
|
int tags_count;
|
||||||
int all_tags_count;
|
int all_tags_count;
|
||||||
enum tvm_compat tv_mode;
|
enum tvm_compat tv_mode;
|
||||||
|
enum etd_spec etd_spec;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
if(arg->embed) {
|
if(arg->embed) {
|
||||||
|
@ -800,36 +892,49 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
|
||||||
|
|
||||||
REDIR(OT_TYPE_DECLS);
|
REDIR(OT_TYPE_DECLS);
|
||||||
|
|
||||||
OUT("%s\t", asn1c_type_name(arg, arg->expr, tnfmt | TNF_CHECK));
|
OUT("%s", asn1c_type_name(arg, arg->expr, tnfmt | TNF_CHECK));
|
||||||
OUT("%s", expr->marker.flags?"*":" ");
|
if(!expr->_anonymous_type) {
|
||||||
OUT("%s", MKID(expr->Identifier));
|
OUT("%s", expr->marker.flags?"\t*":"\t ");
|
||||||
if((expr->marker.flags & EM_DEFAULT) == EM_DEFAULT)
|
OUT("%s", MKID(expr->Identifier));
|
||||||
OUT("\t/* DEFAULT %s */",
|
if((expr->marker.flags & EM_DEFAULT) == EM_DEFAULT)
|
||||||
asn1f_printable_value(expr->marker.default_value));
|
OUT("\t/* DEFAULT %s */",
|
||||||
else if((expr->marker.flags & EM_OPTIONAL) == EM_OPTIONAL)
|
asn1f_printable_value(
|
||||||
OUT("\t/* OPTIONAL */");
|
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));
|
||||||
|
|
||||||
REDIR(OT_TYPE_DECLS);
|
REDIR(OT_TYPE_DECLS);
|
||||||
return 0;
|
|
||||||
|
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__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((expr->expr_type == ASN_BASIC_ENUMERATED)
|
||||||
GEN_INCLUDE(asn1c_type_name(arg, expr, TNF_INCLUDE));
|
|| (expr->expr_type == ASN_BASIC_INTEGER
|
||||||
|
&& expr_elements_count(arg, expr)))
|
||||||
REDIR(OT_TYPE_DECLS);
|
etd_spec = ETD_HAS_SPECIFICS;
|
||||||
|
else
|
||||||
OUT("typedef %s\t", asn1c_type_name(arg, arg->expr, TNF_CTYPE | TNF_CHECK));
|
etd_spec = ETD_NO_SPECIFICS;
|
||||||
OUT("%s", expr->marker.flags?"*":" ");
|
|
||||||
OUT("%s_t", MKID(expr->Identifier));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this type just blindly refers the other type, alias it.
|
* If this type just blindly refers the other type, alias it.
|
||||||
* Type1 ::= Type2
|
* Type1 ::= Type2
|
||||||
*/
|
*/
|
||||||
|
if(arg->embed && etd_spec == ETD_NO_SPECIFICS) {
|
||||||
|
REDIR(OT_TYPE_DECLS);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if((!expr->constraints || (arg->flags & A1C_NO_CONSTRAINTS))
|
if((!expr->constraints || (arg->flags & A1C_NO_CONSTRAINTS))
|
||||||
&& expr->tag.tag_class == TC_NOCLASS
|
&& (arg->embed || expr->tag.tag_class == TC_NOCLASS)
|
||||||
&& !TQ_FIRST(&(expr->members))
|
&& etd_spec == ETD_NO_SPECIFICS) {
|
||||||
) {
|
|
||||||
char *type_name;
|
char *type_name;
|
||||||
REDIR(OT_FUNC_DECLS);
|
REDIR(OT_FUNC_DECLS);
|
||||||
type_name = asn1c_type_name(arg, expr, TNF_SAFE);
|
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("/* ");
|
if(HIDE_INNER_DEFS) OUT("/* ");
|
||||||
OUT("#define\tasn_DEF_%s\t", MKID_nr(expr->Identifier));
|
OUT("#define\tasn_DEF_%s\t", MKID_nr(expr->Identifier));
|
||||||
type_name = asn1c_type_name(arg, expr, TNF_SAFE);
|
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)
|
if(HIDE_INNER_DEFS)
|
||||||
OUT(" // (Use -fall-defs-global to expose) */");
|
OUT("\t// (Use -fall-defs-global to expose) */");
|
||||||
|
OUT("\n");
|
||||||
REDIR(OT_CODE);
|
REDIR(OT_CODE);
|
||||||
OUT("/* This type is equivalent to %s */\n", type_name);
|
OUT("/* This type is equivalent to %s */\n", type_name);
|
||||||
OUT("\n");
|
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);
|
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,
|
emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count,
|
||||||
ETD_NO_SPECIFICS);
|
0, etd_spec);
|
||||||
|
|
||||||
REDIR(OT_CODE);
|
REDIR(OT_CODE);
|
||||||
|
|
||||||
|
@ -864,6 +970,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
|
||||||
*/
|
*/
|
||||||
if(!(arg->flags & A1C_NO_CONSTRAINTS)) {
|
if(!(arg->flags & A1C_NO_CONSTRAINTS)) {
|
||||||
p = MKID(expr->Identifier);
|
p = MKID(expr->Identifier);
|
||||||
|
if(HIDE_INNER_DEFS) OUT("static ");
|
||||||
OUT("int\n");
|
OUT("int\n");
|
||||||
OUT("%s_constraint("
|
OUT("%s_constraint("
|
||||||
"asn_TYPE_descriptor_t *td, const void *sptr,\n", p);
|
"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);
|
p = MKID(expr->Identifier);
|
||||||
OUT("%s_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {\n", p);
|
OUT("%s_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {\n", p);
|
||||||
INDENT(+1);
|
INDENT(+1);
|
||||||
{
|
{
|
||||||
asn1p_expr_t *terminal = asn1f_find_terminal_type_ex(arg->asn, expr);
|
asn1p_expr_t *terminal = asn1f_find_terminal_type_ex(arg->asn, expr);
|
||||||
char *type_name = asn1c_type_name(arg, expr, TNF_SAFE);
|
char *type_name = asn1c_type_name(arg, expr, TNF_SAFE);
|
||||||
OUT("td->free_struct = asn_DEF_%s.free_struct;\n", type_name);
|
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 = asn_DEF_%s.elements;\n", type_name);
|
||||||
OUT("td->elements_count = asn_DEF_%s.elements_count;\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");
|
||||||
OUT("\n");
|
OUT("\n");
|
||||||
|
|
||||||
p = MKID(expr->Identifier);
|
p = MKID(expr->Identifier);
|
||||||
|
if(HIDE_INNER_DEFS) OUT("static ");
|
||||||
OUT("void\n");
|
OUT("void\n");
|
||||||
OUT("%s_free(asn_TYPE_descriptor_t *td,\n", p);
|
OUT("%s_free(asn_TYPE_descriptor_t *td,\n", p);
|
||||||
INDENTED(
|
INDENTED(
|
||||||
|
@ -938,6 +1055,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
|
||||||
OUT("\n");
|
OUT("\n");
|
||||||
|
|
||||||
p = MKID(expr->Identifier);
|
p = MKID(expr->Identifier);
|
||||||
|
if(HIDE_INNER_DEFS) OUT("static ");
|
||||||
OUT("int\n");
|
OUT("int\n");
|
||||||
OUT("%s_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,\n", p);
|
OUT("%s_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,\n", p);
|
||||||
INDENTED(
|
INDENTED(
|
||||||
|
@ -949,6 +1067,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
|
||||||
OUT("\n");
|
OUT("\n");
|
||||||
|
|
||||||
p = MKID(expr->Identifier);
|
p = MKID(expr->Identifier);
|
||||||
|
if(HIDE_INNER_DEFS) OUT("static ");
|
||||||
OUT("asn_dec_rval_t\n");
|
OUT("asn_dec_rval_t\n");
|
||||||
OUT("%s_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,\n", p);
|
OUT("%s_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,\n", p);
|
||||||
INDENTED(
|
INDENTED(
|
||||||
|
@ -960,6 +1079,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
|
||||||
OUT("\n");
|
OUT("\n");
|
||||||
|
|
||||||
p = MKID(expr->Identifier);
|
p = MKID(expr->Identifier);
|
||||||
|
if(HIDE_INNER_DEFS) OUT("static ");
|
||||||
OUT("asn_enc_rval_t\n");
|
OUT("asn_enc_rval_t\n");
|
||||||
OUT("%s_encode_der(asn_TYPE_descriptor_t *td,\n", p);
|
OUT("%s_encode_der(asn_TYPE_descriptor_t *td,\n", p);
|
||||||
INDENTED(
|
INDENTED(
|
||||||
|
@ -972,6 +1092,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
|
||||||
OUT("\n");
|
OUT("\n");
|
||||||
|
|
||||||
p = MKID(expr->Identifier);
|
p = MKID(expr->Identifier);
|
||||||
|
if(HIDE_INNER_DEFS) OUT("static ");
|
||||||
OUT("asn_dec_rval_t\n");
|
OUT("asn_dec_rval_t\n");
|
||||||
OUT("%s_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,\n", p);
|
OUT("%s_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,\n", p);
|
||||||
INDENTED(
|
INDENTED(
|
||||||
|
@ -983,6 +1104,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
|
||||||
OUT("\n");
|
OUT("\n");
|
||||||
|
|
||||||
p = MKID(expr->Identifier);
|
p = MKID(expr->Identifier);
|
||||||
|
if(HIDE_INNER_DEFS) OUT("static ");
|
||||||
OUT("asn_enc_rval_t\n");
|
OUT("asn_enc_rval_t\n");
|
||||||
OUT("%s_encode_xer(asn_TYPE_descriptor_t *td, void *structure,\n", p);
|
OUT("%s_encode_xer(asn_TYPE_descriptor_t *td, void *structure,\n", p);
|
||||||
INDENTED(
|
INDENTED(
|
||||||
|
@ -997,17 +1119,19 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
|
||||||
REDIR(OT_FUNC_DECLS);
|
REDIR(OT_FUNC_DECLS);
|
||||||
|
|
||||||
p = MKID_nr(expr->Identifier);
|
p = MKID_nr(expr->Identifier);
|
||||||
if(HIDE_INNER_DEFS) OUT("/* ");
|
if(HIDE_INNER_DEFS) {
|
||||||
OUT("extern asn_TYPE_descriptor_t asn_DEF_%s;", p);
|
OUT("/* extern asn_TYPE_descriptor_t asn_DEF_%s;"
|
||||||
if(HIDE_INNER_DEFS) OUT(" // (Use -fall-defs-global to expose) */");
|
"\t// (Use -fall-defs-global to expose) */\n", p);
|
||||||
OUT("\n");
|
} else {
|
||||||
OUT("asn_struct_free_f %s_free;\n", p);
|
OUT("extern asn_TYPE_descriptor_t asn_DEF_%s;\n", p);
|
||||||
OUT("asn_struct_print_f %s_print;\n", p);
|
OUT("asn_struct_free_f %s_free;\n", p);
|
||||||
OUT("asn_constr_check_f %s_constraint;\n", p);
|
OUT("asn_struct_print_f %s_print;\n", p);
|
||||||
OUT("ber_type_decoder_f %s_decode_ber;\n", p);
|
OUT("asn_constr_check_f %s_constraint;\n", p);
|
||||||
OUT("der_type_encoder_f %s_encode_der;\n", p);
|
OUT("ber_type_decoder_f %s_decode_ber;\n", p);
|
||||||
OUT("xer_type_decoder_f %s_decode_xer;\n", p);
|
OUT("der_type_encoder_f %s_encode_der;\n", p);
|
||||||
OUT("xer_type_encoder_f %s_encode_xer;\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);
|
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) {
|
TQ_FOR(v, &(expr->members), next) {
|
||||||
if(v->expr_type == A1TC_EXTENSIBLE) {
|
if(v->expr_type == A1TC_EXTENSIBLE) {
|
||||||
/*
|
/*
|
||||||
* CANONICAL-XER mandates sorting
|
* CXER mandates sorting
|
||||||
* only for the root part.
|
* only for the root part.
|
||||||
*/
|
*/
|
||||||
if(flags == FTE_CANONICAL_XER
|
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].el_no);
|
||||||
OUT("%d, ", tag2el[i].toff_first);
|
OUT("%d, ", tag2el[i].toff_first);
|
||||||
OUT("%d ", tag2el[i].toff_last);
|
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->Identifier,
|
||||||
tag2el[i].from_expr->_lineno
|
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);
|
topmost_parent = asn1f_find_terminal_type_ex(arg->asn, expr);
|
||||||
if(!topmost_parent) return 0;
|
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;
|
return 0;
|
||||||
|
|
||||||
TQ_FOR(v, &(topmost_parent->members), next) {
|
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;
|
arg_t tmp_arg;
|
||||||
struct asn1p_type_tag_s outmost_tag_s;
|
struct asn1p_type_tag_s outmost_tag_s;
|
||||||
struct asn1p_type_tag_s *outmost_tag;
|
struct asn1p_type_tag_s *outmost_tag;
|
||||||
|
int complex_contents;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
if(asn1f_fetch_outmost_tag(arg->asn,
|
if(asn1f_fetch_outmost_tag(arg->asn,
|
||||||
|
@ -1429,11 +1557,19 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr) {
|
||||||
} else {
|
} else {
|
||||||
OUT("0,\n");
|
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(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",
|
OUT("(void *)&asn_DEF_%s_Member,\n",
|
||||||
MKID_nr(arg->expr->Identifier));
|
MKID_nr(arg->expr->Identifier));
|
||||||
} else if(expr->expr_type & ASN_CONSTR_MASK) {
|
} else if(complex_contents) {
|
||||||
OUT("(void *)&asn_DEF_%s,\n",
|
OUT("(void *)&asn_DEF_%s,\n",
|
||||||
MKID_nr(expr->Identifier));
|
MKID_nr(expr->Identifier));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -95,7 +95,7 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
|
||||||
OUT("double value;\n");
|
OUT("double value;\n");
|
||||||
break;
|
break;
|
||||||
case ASN_BASIC_BOOLEAN:
|
case ASN_BASIC_BOOLEAN:
|
||||||
OUT("int value;\n");
|
OUT("BOOLEAN_t value;\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
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_INTEGER:
|
||||||
case ASN_BASIC_ENUMERATED:
|
case ASN_BASIC_ENUMERATED:
|
||||||
if(arg->flags & A1C_USE_NATIVE_TYPES) {
|
if(arg->flags & A1C_USE_NATIVE_TYPES) {
|
||||||
OUT("value = *(const int *)sptr;\n");
|
OUT("value = *(const long *)sptr;\n");
|
||||||
} else {
|
} else {
|
||||||
if(r_value->el_count == 0
|
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;
|
break;
|
||||||
case ASN_BASIC_BOOLEAN:
|
case ASN_BASIC_BOOLEAN:
|
||||||
OUT("value = (*(const int *)sptr) ? 1 : 0;\n");
|
OUT("value = (*(const long *)sptr) ? 1 : 0;\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
WARNING("%s:%d: Value cannot be determined "
|
WARNING("%s:%d: Value cannot be determined "
|
||||||
|
|
|
@ -75,6 +75,9 @@ int asn1c_compiled_output(arg_t *arg, const char *fmt, ...);
|
||||||
OUT(fmt, ##args); \
|
OUT(fmt, ##args); \
|
||||||
INDENT_LEVEL = _saved_indent; \
|
INDENT_LEVEL = _saved_indent; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
#define OUT_DEBUG(fmt, args...) do { \
|
||||||
|
if(arg->flags & A1C_DEBUG) OUT(fmt, ##args); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
/* Generate #include line */
|
/* Generate #include line */
|
||||||
#define GEN_INCLUDE(filename) do { \
|
#define GEN_INCLUDE(filename) do { \
|
||||||
|
|
|
@ -134,10 +134,12 @@ BOOLEAN_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
|
||||||
* Decode the chunk of XML text encoding INTEGER.
|
* Decode the chunk of XML text encoding INTEGER.
|
||||||
*/
|
*/
|
||||||
static ssize_t
|
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;
|
BOOLEAN_t *st = (BOOLEAN_t *)sptr;
|
||||||
char *p = (char *)chunk_buf;
|
char *p = (char *)chunk_buf;
|
||||||
|
|
||||||
|
(void)td;
|
||||||
|
|
||||||
if(chunk_size == 0) return -1;
|
if(chunk_size == 0) return -1;
|
||||||
|
|
||||||
if(p[0] == 0x3c /* '<' */) {
|
if(p[0] == 0x3c /* '<' */) {
|
||||||
|
|
|
@ -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.
|
* Redistribution and modifications are permitted subject to BSD license.
|
||||||
*/
|
*/
|
||||||
#include <asn_internal.h>
|
#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);
|
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.
|
* INTEGER specific human-readable output.
|
||||||
*/
|
*/
|
||||||
static ssize_t
|
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 */
|
char scratch[32]; /* Enough for 64-bit integer */
|
||||||
uint8_t *buf = st->buf;
|
uint8_t *buf = st->buf;
|
||||||
uint8_t *buf_end = st->buf + st->size;
|
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;
|
char *p;
|
||||||
int ret;
|
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.
|
* Advance buf pointer until the start of the value's body.
|
||||||
* This will make us able to process large integers using simple case,
|
* 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 */
|
/* Simple case: the integer size is small */
|
||||||
if((size_t)(buf_end - buf) <= sizeof(accum)) {
|
if((size_t)(buf_end - buf) <= sizeof(accum)) {
|
||||||
accum = (*buf & 0x80) ? -1 : 0;
|
const asn_INTEGER_enum_map_t *el;
|
||||||
for(; buf < buf_end; buf++)
|
size_t scrsize;
|
||||||
accum = (accum << 8) | *buf;
|
char *scr;
|
||||||
ret = snprintf(scratch, sizeof(scratch), "%ld", accum);
|
|
||||||
assert(ret > 0 && ret < (int)sizeof(scratch));
|
if(buf == buf_end) {
|
||||||
return (cb(scratch, ret, app_key) < 0) ? -1 : ret;
|
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 */
|
/* 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)
|
if(!st && !st->buf)
|
||||||
ret = cb("<absent>", 8, app_key);
|
ret = cb("<absent>", 8, app_key);
|
||||||
else
|
else
|
||||||
ret = INTEGER__dump(st, cb, app_key);
|
ret = INTEGER__dump(td, st, cb, app_key, 0);
|
||||||
|
|
||||||
return (ret < 0) ? -1 : 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.
|
* Decode the chunk of XML text encoding INTEGER.
|
||||||
*/
|
*/
|
||||||
static ssize_t
|
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;
|
INTEGER_t *st = (INTEGER_t *)sptr;
|
||||||
long sign = 1;
|
long sign = 1;
|
||||||
long value;
|
long value;
|
||||||
char *lp;
|
const char *lp;
|
||||||
char *lstart = (char *)chunk_buf;
|
const char *lstart = (const char *)chunk_buf;
|
||||||
char *lstop = lstart + chunk_size;
|
const char *lstop = lstart + chunk_size;
|
||||||
enum {
|
enum {
|
||||||
ST_SKIPSPACE,
|
ST_SKIPSPACE,
|
||||||
ST_WAITDIGITS,
|
ST_WAITDIGITS,
|
||||||
|
@ -194,8 +307,8 @@ INTEGER__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) {
|
||||||
} state = ST_SKIPSPACE;
|
} state = ST_SKIPSPACE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We may receive a tag here. But we aren't ready to deal with it yet.
|
* We may have received a tag here. It will be processed inline.
|
||||||
* So, just use stroul()-like code and serialize the result.
|
* Use strtoul()-like code and serialize the result.
|
||||||
*/
|
*/
|
||||||
for(value = 0, lp = lstart; lp < lstop; lp++) {
|
for(value = 0, lp = lstart; lp < lstop; lp++) {
|
||||||
int lv = *lp;
|
int lv = *lp;
|
||||||
|
@ -242,6 +355,22 @@ INTEGER__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -280,7 +409,7 @@ INTEGER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
||||||
if(!st && !st->buf)
|
if(!st && !st->buf)
|
||||||
_ASN_ENCODE_FAILED;
|
_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;
|
if(er.encoded < 0) _ASN_ENCODE_FAILED;
|
||||||
|
|
||||||
return er;
|
return er;
|
||||||
|
|
|
@ -12,6 +12,22 @@ typedef ASN__PRIMITIVE_TYPE_t INTEGER_t;
|
||||||
|
|
||||||
extern asn_TYPE_descriptor_t asn_DEF_INTEGER;
|
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;
|
asn_struct_print_f INTEGER_print;
|
||||||
ber_type_decoder_f INTEGER_decode_ber;
|
ber_type_decoder_f INTEGER_decode_ber;
|
||||||
der_type_encoder_f INTEGER_encode_der;
|
der_type_encoder_f INTEGER_encode_der;
|
||||||
|
|
|
@ -68,7 +68,8 @@ NULL_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
||||||
|
|
||||||
|
|
||||||
static ssize_t
|
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;
|
(void)sptr;
|
||||||
if(xer_is_whitespace(chunk_buf, chunk_size))
|
if(xer_is_whitespace(chunk_buf, chunk_size))
|
||||||
return chunk_size;
|
return chunk_size;
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
*/
|
*/
|
||||||
#include <asn_internal.h>
|
#include <asn_internal.h>
|
||||||
#include <NativeInteger.h>
|
#include <NativeInteger.h>
|
||||||
#include <INTEGER.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -45,17 +44,17 @@ asn_TYPE_descriptor_t asn_DEF_NativeInteger = {
|
||||||
asn_dec_rval_t
|
asn_dec_rval_t
|
||||||
NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
||||||
asn_TYPE_descriptor_t *td,
|
asn_TYPE_descriptor_t *td,
|
||||||
void **int_ptr, void *buf_ptr, size_t size, int tag_mode) {
|
void **nint_ptr, void *buf_ptr, size_t size, int tag_mode) {
|
||||||
int *Int = (int *)*int_ptr;
|
long *native = (long *)*nint_ptr;
|
||||||
asn_dec_rval_t rval;
|
asn_dec_rval_t rval;
|
||||||
ber_tlv_len_t length;
|
ber_tlv_len_t length;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the structure is not there, allocate it.
|
* If the structure is not there, allocate it.
|
||||||
*/
|
*/
|
||||||
if(Int == NULL) {
|
if(native == NULL) {
|
||||||
Int = (int *)(*int_ptr = CALLOC(1, sizeof(*Int)));
|
native = (long *)(*nint_ptr = CALLOC(1, sizeof(*native)));
|
||||||
if(Int == NULL) {
|
if(native == NULL) {
|
||||||
rval.code = RC_FAIL;
|
rval.code = RC_FAIL;
|
||||||
rval.consumed = 0;
|
rval.consumed = 0;
|
||||||
return rval;
|
return rval;
|
||||||
|
@ -88,7 +87,7 @@ NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ASN.1 encoded INTEGER: buf_ptr, length
|
* 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.
|
* If overflow occured, return with RC_FAIL.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
|
@ -103,15 +102,15 @@ NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
||||||
return rval;
|
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
|
* This expression hopefully will be optimized away
|
||||||
* by compiler.
|
* by compiler.
|
||||||
*/
|
*/
|
||||||
if(sizeof(int) != sizeof(long) && ((long)*Int != l)) {
|
if(sizeof(*native) != sizeof(long) && ((long)*native != l)) {
|
||||||
*Int = 0; /* Safe value */
|
*native = 0; /* Safe value */
|
||||||
rval.code = RC_FAIL;
|
rval.code = RC_FAIL;
|
||||||
rval.consumed = 0;
|
rval.consumed = 0;
|
||||||
return rval;
|
return rval;
|
||||||
|
@ -121,8 +120,8 @@ NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
||||||
rval.code = RC_OK;
|
rval.code = RC_OK;
|
||||||
rval.consumed += length;
|
rval.consumed += length;
|
||||||
|
|
||||||
ASN_DEBUG("Took %ld/%ld bytes to encode %s (%d)",
|
ASN_DEBUG("Took %ld/%ld bytes to encode %s (%ld)",
|
||||||
(long)rval.consumed, (long)length, td->name, *Int);
|
(long)rval.consumed, (long)length, td->name, (long)*native);
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
@ -134,22 +133,22 @@ asn_enc_rval_t
|
||||||
NativeInteger_encode_der(asn_TYPE_descriptor_t *sd, void *ptr,
|
NativeInteger_encode_der(asn_TYPE_descriptor_t *sd, void *ptr,
|
||||||
int tag_mode, ber_tlv_tag_t tag,
|
int tag_mode, ber_tlv_tag_t tag,
|
||||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
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;
|
asn_enc_rval_t erval;
|
||||||
INTEGER_t tmp;
|
INTEGER_t tmp;
|
||||||
|
|
||||||
#ifdef WORDS_BIGENDIAN /* Opportunistic optimization */
|
#ifdef WORDS_BIGENDIAN /* Opportunistic optimization */
|
||||||
|
|
||||||
tmp.buf = (uint8_t *)∬
|
tmp.buf = (uint8_t *)&native;
|
||||||
tmp.size = sizeof(Int);
|
tmp.size = sizeof(native);
|
||||||
|
|
||||||
#else /* Works even if WORDS_BIGENDIAN is not set where should've been */
|
#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;
|
uint8_t *p;
|
||||||
|
|
||||||
/* Prepare a fake INTEGER */
|
/* Prepare a fake INTEGER */
|
||||||
for(p = buf + sizeof(buf) - 1; p >= buf; p--, Int >>= 8)
|
for(p = buf + sizeof(buf) - 1; p >= buf; p--, native >>= 8)
|
||||||
*p = Int;
|
*p = native;
|
||||||
|
|
||||||
tmp.buf = buf;
|
tmp.buf = buf;
|
||||||
tmp.size = sizeof(buf);
|
tmp.size = sizeof(buf);
|
||||||
|
@ -174,12 +173,12 @@ NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
|
||||||
asn_dec_rval_t rval;
|
asn_dec_rval_t rval;
|
||||||
INTEGER_t *st = 0;
|
INTEGER_t *st = 0;
|
||||||
void *st_ptr = (void *)&st;
|
void *st_ptr = (void *)&st;
|
||||||
int *Int = (int *)*sptr;
|
long *native = (long *)*sptr;
|
||||||
|
|
||||||
if(!Int) {
|
if(!native) {
|
||||||
*sptr = CALLOC(1, sizeof(int));
|
*sptr = CALLOC(1, sizeof(int));
|
||||||
Int = (int *)*sptr;
|
native = (long *)*sptr;
|
||||||
if(!Int) {
|
if(!native) {
|
||||||
rval.code = RC_FAIL;
|
rval.code = RC_FAIL;
|
||||||
rval.consumed = 0;
|
rval.consumed = 0;
|
||||||
return rval;
|
return rval;
|
||||||
|
@ -194,17 +193,23 @@ NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
|
||||||
rval.code = RC_FAIL;
|
rval.code = RC_FAIL;
|
||||||
rval.consumed = 0;
|
rval.consumed = 0;
|
||||||
} else {
|
} else {
|
||||||
*Int = l;
|
*native = l;
|
||||||
|
|
||||||
/* int might be shorter than long */
|
/* Native type might be shorter than long */
|
||||||
if(sizeof(int) != sizeof(long) && ((long)*Int != l)) {
|
if(sizeof(*native) != sizeof(long)
|
||||||
*Int = 0; /* Safe value */
|
&& ((long)*native != l)) {
|
||||||
|
*native = 0; /* Safe value */
|
||||||
rval.code = RC_FAIL;
|
rval.code = RC_FAIL;
|
||||||
rval.consumed = 0;
|
rval.consumed = 0;
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} 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;
|
rval.consumed = 0;
|
||||||
}
|
}
|
||||||
asn_DEF_INTEGER.free_struct(&asn_DEF_INTEGER, st, 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) {
|
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||||
char scratch[32]; /* Enough for 64-bit int */
|
char scratch[32]; /* Enough for 64-bit int */
|
||||||
asn_enc_rval_t er;
|
asn_enc_rval_t er;
|
||||||
const int *Int = (const int *)sptr;
|
const long *native = (const long *)sptr;
|
||||||
|
|
||||||
(void)ilevel;
|
(void)ilevel;
|
||||||
(void)flags;
|
(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)
|
if(er.encoded <= 0 || (size_t)er.encoded >= sizeof(scratch)
|
||||||
|| cb(scratch, er.encoded, app_key) < 0)
|
|| cb(scratch, er.encoded, app_key) < 0)
|
||||||
_ASN_ENCODE_FAILED;
|
_ASN_ENCODE_FAILED;
|
||||||
|
@ -239,16 +244,16 @@ NativeInteger_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
||||||
int
|
int
|
||||||
NativeInteger_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
NativeInteger_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
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 */
|
char scratch[32]; /* Enough for 64-bit int */
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
(void)td; /* Unused argument */
|
(void)td; /* Unused argument */
|
||||||
(void)ilevel; /* Unused argument */
|
(void)ilevel; /* Unused argument */
|
||||||
|
|
||||||
if(Int) {
|
if(native) {
|
||||||
ret = snprintf(scratch, sizeof(scratch), "%d", *Int);
|
ret = snprintf(scratch, sizeof(scratch), "%ld", *native);
|
||||||
assert(ret > 0 && ret < (int)sizeof(scratch));
|
assert(ret > 0 && (size_t)ret < sizeof(scratch));
|
||||||
return (cb(scratch, ret, app_key) < 0) ? -1 : 0;
|
return (cb(scratch, ret, app_key) < 0) ? -1 : 0;
|
||||||
} else {
|
} else {
|
||||||
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#define _NativeInteger_H_
|
#define _NativeInteger_H_
|
||||||
|
|
||||||
#include <asn_application.h>
|
#include <asn_application.h>
|
||||||
|
#include <INTEGER.h>
|
||||||
|
|
||||||
extern asn_TYPE_descriptor_t asn_DEF_NativeInteger;
|
extern asn_TYPE_descriptor_t asn_DEF_NativeInteger;
|
||||||
|
|
||||||
|
|
|
@ -264,7 +264,7 @@ OBJECT_IDENTIFIER__dump_body(const OBJECT_IDENTIFIER_t *st, asn_app_consume_byte
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
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;
|
OBJECT_IDENTIFIER_t *st = (OBJECT_IDENTIFIER_t *)sptr;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
long s_arcs[10];
|
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 arcs_count;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
(void)td;
|
||||||
|
|
||||||
arcs_count = OBJECT_IDENTIFIER_parse_arcs(
|
arcs_count = OBJECT_IDENTIFIER_parse_arcs(
|
||||||
(const char *)chunk_buf, chunk_size, arcs, 10, &endptr);
|
(const char *)chunk_buf, chunk_size, arcs, 10, &endptr);
|
||||||
if(arcs_count <= 0)
|
if(arcs_count <= 0)
|
||||||
|
|
|
@ -258,13 +258,15 @@ REAL_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
||||||
* Decode the chunk of XML text encoding REAL.
|
* Decode the chunk of XML text encoding REAL.
|
||||||
*/
|
*/
|
||||||
static ssize_t
|
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;
|
REAL_t *st = (REAL_t *)sptr;
|
||||||
double value;
|
double value;
|
||||||
char *xerdata = (char *)chunk_buf;
|
char *xerdata = (char *)chunk_buf;
|
||||||
char *endptr = 0;
|
char *endptr = 0;
|
||||||
char *b;
|
char *b;
|
||||||
|
|
||||||
|
(void)td;
|
||||||
|
|
||||||
if(!chunk_size) return -1;
|
if(!chunk_size) return -1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -87,7 +87,7 @@ RELATIVE_OID_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
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;
|
RELATIVE_OID_t *st = (RELATIVE_OID_t *)sptr;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
long s_arcs[6];
|
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 arcs_count;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
(void)td;
|
||||||
|
|
||||||
arcs_count = OBJECT_IDENTIFIER_parse_arcs(
|
arcs_count = OBJECT_IDENTIFIER_parse_arcs(
|
||||||
(const char *)chunk_buf, chunk_size,
|
(const char *)chunk_buf, chunk_size,
|
||||||
arcs, 6, &endptr);
|
arcs, 6, &endptr);
|
||||||
|
|
|
@ -137,9 +137,10 @@ ASN__PRIMITIVE_TYPE_free(asn_TYPE_descriptor_t *td, void *sptr,
|
||||||
* Local internal type passed around as an argument.
|
* Local internal type passed around as an argument.
|
||||||
*/
|
*/
|
||||||
struct xdp_arg_s {
|
struct xdp_arg_s {
|
||||||
|
asn_TYPE_descriptor_t *type_descriptor;
|
||||||
void *struct_key;
|
void *struct_key;
|
||||||
ssize_t (*prim_body_decode)(void *struct_key,
|
ssize_t (*prim_body_decode)(asn_TYPE_descriptor_t *td,
|
||||||
void *chunk_buf, size_t chunk_size);
|
void *struct_key, void *chunk_buf, size_t chunk_size);
|
||||||
int decoded_something;
|
int decoded_something;
|
||||||
int want_more;
|
int want_more;
|
||||||
};
|
};
|
||||||
|
@ -159,7 +160,8 @@ xer_decode__unexpected_tag(void *key, void *chunk_buf, size_t chunk_size) {
|
||||||
return -1;
|
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) {
|
if(decoded < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -196,7 +198,8 @@ xer_decode__body(void *key, void *chunk_buf, size_t chunk_size, int have_more) {
|
||||||
return -1;
|
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) {
|
if(decoded < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -213,8 +216,8 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
|
||||||
size_t struct_size,
|
size_t struct_size,
|
||||||
const char *opt_mname,
|
const char *opt_mname,
|
||||||
void *buf_ptr, size_t size,
|
void *buf_ptr, size_t size,
|
||||||
ssize_t (*prim_body_decode)(void *struct_key,
|
ssize_t (*prim_body_decode)(asn_TYPE_descriptor_t *td,
|
||||||
void *chunk_buf, size_t chunk_size)
|
void *struct_key, void *chunk_buf, size_t chunk_size)
|
||||||
) {
|
) {
|
||||||
const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
|
const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
|
||||||
asn_struct_ctx_t s_ctx;
|
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));
|
memset(&s_ctx, 0, sizeof(s_ctx));
|
||||||
|
s_arg.type_descriptor = td;
|
||||||
s_arg.struct_key = *sptr;
|
s_arg.struct_key = *sptr;
|
||||||
s_arg.prim_body_decode = prim_body_decode;
|
s_arg.prim_body_decode = prim_body_decode;
|
||||||
s_arg.decoded_something = 0;
|
s_arg.decoded_something = 0;
|
||||||
|
@ -248,7 +252,8 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
|
||||||
if(!s_arg.decoded_something) {
|
if(!s_arg.decoded_something) {
|
||||||
char ch;
|
char ch;
|
||||||
/* Opportunity has come and gone. Where's the result? */
|
/* 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.
|
* This decoder does not like empty stuff.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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,
|
void **struct_ptr, size_t struct_size,
|
||||||
const char *opt_mname,
|
const char *opt_mname,
|
||||||
void *buf_ptr, size_t size,
|
void *buf_ptr, size_t size,
|
||||||
ssize_t (*prim_body_decode)(void *struct_ptr,
|
ssize_t (*prim_body_decode)(asn_TYPE_descriptor_t *td,
|
||||||
void *chunk_buf, size_t chunk_size)
|
void *struct_ptr, void *chunk_buf, size_t chunk_size)
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif /* ASN_CODECS_PRIM_H */
|
#endif /* ASN_CODECS_PRIM_H */
|
||||||
|
|
|
@ -788,7 +788,8 @@ SET_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASN_DEBUG("Unexpected XML tag in SET");
|
ASN_DEBUG("Unexpected XML tag in SET, expected \"%s\"",
|
||||||
|
xml_tag);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -641,7 +641,7 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
||||||
int ilevel, enum xer_encoder_flags_e flags,
|
int ilevel, enum xer_encoder_flags_e flags,
|
||||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||||
asn_enc_rval_t er;
|
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;
|
asn_TYPE_member_t *element = td->elements;
|
||||||
A_SET_OF(void) *list;
|
A_SET_OF(void) *list;
|
||||||
const char *mname = specs->as_XMLValueList
|
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);
|
_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,
|
tmper = element->type->xer_encoder(element->type, memb_ptr,
|
||||||
ilevel + 1, flags, cb, app_key);
|
ilevel + 1, flags, cb, app_key);
|
||||||
if(tmper.encoded == -1) {
|
if(tmper.encoded == -1) {
|
||||||
|
@ -695,7 +697,6 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
||||||
const char *name = (*element->name)
|
const char *name = (*element->name)
|
||||||
? element->name : element->type->xml_tag;
|
? element->name : element->type->xml_tag;
|
||||||
size_t len = strlen(name);
|
size_t len = strlen(name);
|
||||||
if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel + 1);
|
|
||||||
_ASN_CALLBACK3("<", 1, name, len, "/>", 2);
|
_ASN_CALLBACK3("<", 1, name, len, "/>", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -271,7 +271,6 @@ xer_decode_general(asn_codec_ctx_t *opt_codec_ctx,
|
||||||
ctx->phase = 2; /* Phase out */
|
ctx->phase = 2; /* Phase out */
|
||||||
RETURN(RC_OK);
|
RETURN(RC_OK);
|
||||||
case XCT_UNKNOWN_BO:
|
case XCT_UNKNOWN_BO:
|
||||||
if(!ctx->phase) break;
|
|
||||||
/*
|
/*
|
||||||
* Certain tags in the body may be expected.
|
* 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) {
|
buf_ptr, ch_size) == 0) {
|
||||||
/* Tag's processed fine */
|
/* Tag's processed fine */
|
||||||
ADVANCE(ch_size);
|
ADVANCE(ch_size);
|
||||||
|
if(!ctx->phase) {
|
||||||
|
/* We are not expecting
|
||||||
|
* the closing tag anymore. */
|
||||||
|
ctx->phase = 2; /* Phase out */
|
||||||
|
RETURN(RC_OK);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
|
|
Loading…
Reference in New Issue