mirror of https://gerrit.osmocom.org/asn1c
further runtime support for information object classes
This commit is contained in:
parent
63a35237b1
commit
f6853ce38e
|
@ -974,6 +974,9 @@ ASN_MODULE_HEADERS= \
|
||||||
|
|
||||||
ASN_MODULE_HEADERS+=ANY.h
|
ASN_MODULE_HEADERS+=ANY.h
|
||||||
ASN_MODULE_SOURCES+=ANY.c
|
ASN_MODULE_SOURCES+=ANY.c
|
||||||
|
ASN_MODULE_HEADERS+=OPEN_TYPE.h
|
||||||
|
ASN_MODULE_SOURCES+=OPEN_TYPE.c
|
||||||
|
ASN_MODULE_HEADERS+=constr_CHOICE.h
|
||||||
ASN_MODULE_HEADERS+=BOOLEAN.h
|
ASN_MODULE_HEADERS+=BOOLEAN.h
|
||||||
ASN_MODULE_SOURCES+=BOOLEAN.c
|
ASN_MODULE_SOURCES+=BOOLEAN.c
|
||||||
ASN_MODULE_HEADERS+=INTEGER.h
|
ASN_MODULE_HEADERS+=INTEGER.h
|
||||||
|
@ -988,7 +991,6 @@ ASN_MODULE_HEADERS+=asn_SEQUENCE_OF.h
|
||||||
ASN_MODULE_SOURCES+=asn_SEQUENCE_OF.c
|
ASN_MODULE_SOURCES+=asn_SEQUENCE_OF.c
|
||||||
ASN_MODULE_HEADERS+=asn_SET_OF.h
|
ASN_MODULE_HEADERS+=asn_SET_OF.h
|
||||||
ASN_MODULE_SOURCES+=asn_SET_OF.c
|
ASN_MODULE_SOURCES+=asn_SET_OF.c
|
||||||
ASN_MODULE_HEADERS+=constr_CHOICE.h
|
|
||||||
ASN_MODULE_SOURCES+=constr_CHOICE.c
|
ASN_MODULE_SOURCES+=constr_CHOICE.c
|
||||||
ASN_MODULE_HEADERS+=constr_SEQUENCE.h
|
ASN_MODULE_HEADERS+=constr_SEQUENCE.h
|
||||||
ASN_MODULE_SOURCES+=constr_SEQUENCE.c
|
ASN_MODULE_SOURCES+=constr_SEQUENCE.c
|
||||||
|
|
|
@ -38,6 +38,7 @@ static int asn1c_lang_C_type_SEQUENCE_def(
|
||||||
static int asn1c_lang_C_type_SET_def(arg_t *arg);
|
static int asn1c_lang_C_type_SET_def(arg_t *arg);
|
||||||
static int asn1c_lang_C_type_CHOICE_def(arg_t *arg);
|
static int asn1c_lang_C_type_CHOICE_def(arg_t *arg);
|
||||||
static int asn1c_lang_C_type_SEx_OF_def(arg_t *arg, int seq_of);
|
static int asn1c_lang_C_type_SEx_OF_def(arg_t *arg, int seq_of);
|
||||||
|
static int asn1c_lang_C_OpenType(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc, const char *column_name);
|
||||||
static int _print_tag(arg_t *arg, struct asn1p_type_tag_s *tag_p);
|
static int _print_tag(arg_t *arg, struct asn1p_type_tag_s *tag_p);
|
||||||
static int compute_extensions_start(asn1p_expr_t *expr);
|
static int compute_extensions_start(asn1p_expr_t *expr);
|
||||||
static int expr_break_recursion(arg_t *arg, asn1p_expr_t *expr);
|
static int expr_break_recursion(arg_t *arg, asn1p_expr_t *expr);
|
||||||
|
@ -301,6 +302,30 @@ asn1c_lang_C_type_BIT_STRING(arg_t *arg) {
|
||||||
return asn1c_lang_C_type_SIMPLE_TYPE(arg);
|
return asn1c_lang_C_type_SIMPLE_TYPE(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if it is a true open type. That is, type is taken from
|
||||||
|
* the Information Object Set driven constraints.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
is_open_type(arg_t *arg, asn1p_expr_t *expr, asn1c_ioc_table_and_objset_t *opt_ioc) {
|
||||||
|
|
||||||
|
(void)arg;
|
||||||
|
|
||||||
|
if(!opt_ioc) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(expr->meta_type == AMT_TYPEREF
|
||||||
|
&& expr->expr_type == A1TC_REFERENCE
|
||||||
|
&& expr->reference->comp_count == 2
|
||||||
|
&& expr->reference->components[1].lex_type
|
||||||
|
== RLT_AmpUppercase) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
asn1c_lang_C_type_SEQUENCE(arg_t *arg) {
|
asn1c_lang_C_type_SEQUENCE(arg_t *arg) {
|
||||||
asn1p_expr_t *expr = arg->expr;
|
asn1p_expr_t *expr = arg->expr;
|
||||||
|
@ -343,7 +368,21 @@ asn1c_lang_C_type_SEQUENCE(arg_t *arg) {
|
||||||
if(comp_mode == 1)
|
if(comp_mode == 1)
|
||||||
v->marker.flags |= EM_OMITABLE | EM_INDIRECT;
|
v->marker.flags |= EM_OMITABLE | EM_INDIRECT;
|
||||||
try_inline_default(arg, v, 1);
|
try_inline_default(arg, v, 1);
|
||||||
EMBED_WITH_IOCT(v, ioc_tao);
|
if(is_open_type(arg, v, ioc_tao.ioct ? &ioc_tao : 0)) {
|
||||||
|
arg_t tmp_arg = *arg;
|
||||||
|
tmp_arg.embed++;
|
||||||
|
INDENT(+1);
|
||||||
|
tmp_arg.expr = v;
|
||||||
|
const char *column_name = v->reference->components[1].name;
|
||||||
|
if(asn1c_lang_C_OpenType(&tmp_arg, &ioc_tao, column_name)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
INDENT(-1);
|
||||||
|
tmp_arg.embed--;
|
||||||
|
if(v->expr_type != A1TC_EXTENSIBLE) OUT(";\n");
|
||||||
|
} else {
|
||||||
|
EMBED_WITH_IOCT(v, ioc_tao);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PCTX_DEF;
|
PCTX_DEF;
|
||||||
|
@ -1032,6 +1071,62 @@ asn1c_lang_C_type_CHOICE(arg_t *arg) {
|
||||||
return asn1c_lang_C_type_CHOICE_def(arg);
|
return asn1c_lang_C_type_CHOICE_def(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
find_column_index(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc, const char *column_name) {
|
||||||
|
(void)arg;
|
||||||
|
|
||||||
|
if(!opt_ioc || !opt_ioc->ioct || !column_name) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(opt_ioc->ioct->rows == 0) {
|
||||||
|
return 0; /* No big deal. Just no data */
|
||||||
|
} else {
|
||||||
|
for(size_t clmn = 0; clmn < opt_ioc->ioct->row[0]->columns; clmn++) {
|
||||||
|
if(strcmp(opt_ioc->ioct->row[0]->column[clmn].field->Identifier,
|
||||||
|
column_name) == 0) {
|
||||||
|
return clmn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
asn1c_lang_C_OpenType(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc,
|
||||||
|
const char *column_name) {
|
||||||
|
arg_t tmp_arg = *arg;
|
||||||
|
|
||||||
|
ssize_t column_index = find_column_index(arg, opt_ioc, column_name);
|
||||||
|
if(column_index < 0) {
|
||||||
|
FATAL("Open type generation attempted for %s, incomplete", column_name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
asn1p_expr_t *open_type_choice =
|
||||||
|
asn1p_expr_new(arg->expr->_lineno, arg->expr->module);
|
||||||
|
|
||||||
|
open_type_choice->Identifier = strdup(arg->expr->Identifier);
|
||||||
|
open_type_choice->meta_type = AMT_TYPE;
|
||||||
|
open_type_choice->expr_type = ASN_CONSTR_OPEN_TYPE;
|
||||||
|
open_type_choice->_type_unique_index = arg->expr->_type_unique_index;
|
||||||
|
|
||||||
|
for(size_t row = 0; row < opt_ioc->ioct->rows; row++) {
|
||||||
|
struct asn1p_ioc_cell_s *cell =
|
||||||
|
&opt_ioc->ioct->row[row]->column[column_index];
|
||||||
|
|
||||||
|
asn1p_expr_t *m = asn1p_expr_clone(cell->value, 0);
|
||||||
|
asn1p_expr_add(open_type_choice, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp_arg.expr = open_type_choice;
|
||||||
|
GEN_INCLUDE_STD("OPEN_TYPE");
|
||||||
|
asn1c_lang_C_type_CHOICE(&tmp_arg);
|
||||||
|
asn1p_expr_free(tmp_arg.expr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
asn1c_lang_C_type_CHOICE_def(arg_t *arg) {
|
asn1c_lang_C_type_CHOICE_def(arg_t *arg) {
|
||||||
asn1p_expr_t *expr = arg->expr;
|
asn1p_expr_t *expr = arg->expr;
|
||||||
|
@ -1085,7 +1180,7 @@ asn1c_lang_C_type_CHOICE_def(arg_t *arg) {
|
||||||
int i;
|
int i;
|
||||||
cmap = compute_canonical_members_order(arg, elements);
|
cmap = compute_canonical_members_order(arg, elements);
|
||||||
if(cmap) {
|
if(cmap) {
|
||||||
OUT("static const int asn_MAP_%s_cmap_%d[] = {",
|
OUT("static const unsigned asn_MAP_%s_cmap_%d[] = {",
|
||||||
MKID(expr),
|
MKID(expr),
|
||||||
expr->_type_unique_index);
|
expr->_type_unique_index);
|
||||||
for(i = 0; i < elements; i++) {
|
for(i = 0; i < elements; i++) {
|
||||||
|
@ -2652,10 +2747,11 @@ emit_member_type_selector(arg_t *arg, asn1p_expr_t *expr, asn1c_ioc_table_and_ob
|
||||||
|
|
||||||
assert(opt_ioc != NULL);
|
assert(opt_ioc != NULL);
|
||||||
|
|
||||||
asn1p_expr_t *constraining_memb = NULL;
|
asn1p_expr_t *constraining_memb = NULL;
|
||||||
TQ_FOR(constraining_memb, &(parent_expr->members), next) {
|
TQ_FOR(constraining_memb, &(parent_expr->members), next) {
|
||||||
if(strcmp(constraining_memb->Identifier, cname) == 0)
|
if(strcmp(constraining_memb->Identifier, cname) == 0) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(!constraining_memb) {
|
if(!constraining_memb) {
|
||||||
FATAL("Can not find \"%s\" in %s at line %d", cname, MKID(parent_expr),
|
FATAL("Can not find \"%s\" in %s at line %d", cname, MKID(parent_expr),
|
||||||
|
@ -2728,10 +2824,11 @@ emit_member_type_selector(arg_t *arg, asn1p_expr_t *expr, asn1c_ioc_table_and_ob
|
||||||
|
|
||||||
|
|
||||||
REDIR(OT_CODE);
|
REDIR(OT_CODE);
|
||||||
OUT("static asn_TYPE_descriptor_t *\n");
|
OUT("static asn_type_selector_result_t\n");
|
||||||
OUT("select_%s_type(const asn_TYPE_descriptor_t *parent_type, const void *parent_sptr) {\n", MKID_safe(expr));
|
OUT("select_%s_type(const asn_TYPE_descriptor_t *parent_type, const void *parent_sptr) {\n", MKID_safe(expr));
|
||||||
INDENT(+1);
|
INDENT(+1);
|
||||||
|
|
||||||
|
OUT("asn_type_selector_result_t result = {0, 0};\n");
|
||||||
OUT("const asn_ioc_set_t *itable = asn_IOS_%s_%d;\n", MKID(opt_ioc->objset),
|
OUT("const asn_ioc_set_t *itable = asn_IOS_%s_%d;\n", MKID(opt_ioc->objset),
|
||||||
opt_ioc->objset->_type_unique_index);
|
opt_ioc->objset->_type_unique_index);
|
||||||
OUT("size_t constraining_column = %zu; /* %s */\n", constraining_column, cfield);
|
OUT("size_t constraining_column = %zu; /* %s */\n", constraining_column, cfield);
|
||||||
|
@ -2744,7 +2841,7 @@ emit_member_type_selector(arg_t *arg, asn1p_expr_t *expr, asn1c_ioc_table_and_ob
|
||||||
OUT("((const char *)parent_sptr + offsetof(struct ");
|
OUT("((const char *)parent_sptr + offsetof(struct ");
|
||||||
out_name_chain(arg, ONC_avoid_keywords);
|
out_name_chain(arg, ONC_avoid_keywords);
|
||||||
OUT(", %s));", MKID_safe(constraining_memb));
|
OUT(", %s));", MKID_safe(constraining_memb));
|
||||||
OUT("if(!memb_ptr) return NULL;\n");
|
OUT("if(!memb_ptr) return result;\n");
|
||||||
OUT("\n");
|
OUT("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2774,13 +2871,15 @@ emit_member_type_selector(arg_t *arg, asn1p_expr_t *expr, asn1c_ioc_table_and_ob
|
||||||
OUT(" const asn_ioc_cell_t *type_cell = &itable->rows[row * itable->columns_count + for_column];\n");
|
OUT(" const asn_ioc_cell_t *type_cell = &itable->rows[row * itable->columns_count + for_column];\n");
|
||||||
OUT("\n");
|
OUT("\n");
|
||||||
OUT(" if(constraining_cell->type_descriptor->compare_struct(constraining_cell->type_descriptor, constraining_value, constraining_cell->value_sptr) == 0) {\n");
|
OUT(" if(constraining_cell->type_descriptor->compare_struct(constraining_cell->type_descriptor, constraining_value, constraining_cell->value_sptr) == 0) {\n");
|
||||||
OUT(" return type_cell->type_descriptor;\n");
|
OUT(" result.type_descriptor = type_cell->type_descriptor;\n");
|
||||||
|
OUT(" result.presence_index = row + 1;\n");
|
||||||
|
OUT(" break;\n");
|
||||||
OUT(" }\n");
|
OUT(" }\n");
|
||||||
OUT("}\n");
|
OUT("}\n");
|
||||||
|
|
||||||
|
|
||||||
OUT("\n");
|
OUT("\n");
|
||||||
OUT("return NULL;\n");
|
OUT("return result;\n");
|
||||||
INDENT(-1);
|
INDENT(-1);
|
||||||
OUT("}\n");
|
OUT("}\n");
|
||||||
OUT("\n");
|
OUT("\n");
|
||||||
|
@ -2810,9 +2909,11 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr, asn1c_ioc_table_and_objset_t *
|
||||||
|
|
||||||
OUT("{ ");
|
OUT("{ ");
|
||||||
|
|
||||||
if(outmost_tag && outmost_tag->tag_value == -1)
|
if((outmost_tag && outmost_tag->tag_value == -1)
|
||||||
OUT("ATF_OPEN_TYPE | ");
|
|| is_open_type(arg, expr, opt_ioc)) {
|
||||||
OUT("%s, ",
|
OUT("ATF_OPEN_TYPE | ");
|
||||||
|
}
|
||||||
|
OUT("%s, ",
|
||||||
(expr->marker.flags & EM_INDIRECT)?"ATF_POINTER":"ATF_NOFLAGS");
|
(expr->marker.flags & EM_INDIRECT)?"ATF_POINTER":"ATF_NOFLAGS");
|
||||||
if((expr->marker.flags & EM_OMITABLE) == EM_OMITABLE) {
|
if((expr->marker.flags & EM_OMITABLE) == EM_OMITABLE) {
|
||||||
asn1p_expr_t *tv;
|
asn1p_expr_t *tv;
|
||||||
|
@ -2827,19 +2928,22 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr, asn1c_ioc_table_and_objset_t *
|
||||||
} else {
|
} else {
|
||||||
OUT("0, ");
|
OUT("0, ");
|
||||||
}
|
}
|
||||||
if(expr->_anonymous_type) {
|
if(expr->_anonymous_type) {
|
||||||
assert(arg->expr->expr_type == ASN_CONSTR_SET_OF
|
assert(arg->expr->expr_type == ASN_CONSTR_SET_OF
|
||||||
|| arg->expr->expr_type == ASN_CONSTR_SEQUENCE_OF);
|
|| arg->expr->expr_type == ASN_CONSTR_SEQUENCE_OF);
|
||||||
OUT("0,\n");
|
OUT("0,\n");
|
||||||
} else {
|
} else {
|
||||||
OUT("offsetof(struct ");
|
OUT("offsetof(struct ");
|
||||||
out_name_chain(arg, ONC_avoid_keywords);
|
out_name_chain(arg, ONC_avoid_keywords);
|
||||||
OUT(", ");
|
OUT(", ");
|
||||||
if(arg->expr->expr_type == ASN_CONSTR_CHOICE
|
if((arg->expr->expr_type == ASN_CONSTR_CHOICE
|
||||||
&& (!UNNAMED_UNIONS)) OUT("choice.");
|
|| arg->expr->expr_type == ASN_CONSTR_OPEN_TYPE)
|
||||||
OUT("%s),\n", MKID_safe(expr));
|
&& (!UNNAMED_UNIONS))
|
||||||
}
|
OUT("choice.");
|
||||||
INDENT(+1);
|
OUT("%s),\n", MKID_safe(expr));
|
||||||
|
}
|
||||||
|
|
||||||
|
INDENT(+1);
|
||||||
if(C99_MODE) OUT(".tag = ");
|
if(C99_MODE) OUT(".tag = ");
|
||||||
if(outmost_tag) {
|
if(outmost_tag) {
|
||||||
if(outmost_tag->tag_value == -1)
|
if(outmost_tag->tag_value == -1)
|
||||||
|
@ -2864,7 +2968,8 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr, asn1c_ioc_table_and_objset_t *
|
||||||
}
|
}
|
||||||
|
|
||||||
complex_contents =
|
complex_contents =
|
||||||
(expr->expr_type & ASN_CONSTR_MASK)
|
is_open_type(arg, expr, opt_ioc)
|
||||||
|
|| (expr->expr_type & ASN_CONSTR_MASK)
|
||||||
|| expr->expr_type == ASN_BASIC_ENUMERATED
|
|| expr->expr_type == ASN_BASIC_ENUMERATED
|
||||||
|| (0 /* -- prohibited by X.693:8.3.4 */
|
|| (0 /* -- prohibited by X.693:8.3.4 */
|
||||||
&& expr->expr_type == ASN_BASIC_INTEGER
|
&& expr->expr_type == ASN_BASIC_INTEGER
|
||||||
|
@ -2872,15 +2977,16 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr, asn1c_ioc_table_and_objset_t *
|
||||||
|| (expr->expr_type == ASN_BASIC_INTEGER
|
|| (expr->expr_type == ASN_BASIC_INTEGER
|
||||||
&& asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN);
|
&& asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN);
|
||||||
if(C99_MODE) OUT(".type = ");
|
if(C99_MODE) OUT(".type = ");
|
||||||
OUT("&asn_DEF_");
|
|
||||||
if(complex_contents) {
|
OUT("&asn_DEF_");
|
||||||
OUT("%s", MKID(expr));
|
if(complex_contents) {
|
||||||
if(!(arg->flags & A1C_ALL_DEFS_GLOBAL))
|
OUT("%s", MKID(expr));
|
||||||
OUT("_%d", expr->_type_unique_index);
|
if(!(arg->flags & A1C_ALL_DEFS_GLOBAL))
|
||||||
} else {
|
OUT("_%d", expr->_type_unique_index);
|
||||||
OUT("%s", asn1c_type_name(arg, expr, TNF_SAFE));
|
} else {
|
||||||
}
|
OUT("%s", asn1c_type_name(arg, expr, TNF_SAFE));
|
||||||
OUT(",\n");
|
}
|
||||||
|
OUT(",\n");
|
||||||
|
|
||||||
|
|
||||||
if(C99_MODE) OUT(".type_selector = ");
|
if(C99_MODE) OUT(".type_selector = ");
|
||||||
|
@ -3001,8 +3107,9 @@ emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_
|
||||||
if(HIDE_INNER_DEFS)
|
if(HIDE_INNER_DEFS)
|
||||||
OUT("static /* Use -fall-defs-global to expose */\n");
|
OUT("static /* Use -fall-defs-global to expose */\n");
|
||||||
OUT("asn_TYPE_descriptor_t asn_DEF_%s", p);
|
OUT("asn_TYPE_descriptor_t asn_DEF_%s", p);
|
||||||
if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index);
|
if(HIDE_INNER_DEFS || (arg->flags & A1C_ALL_DEFS_GLOBAL))
|
||||||
OUT(" = {\n");
|
OUT("_%d", expr->_type_unique_index);
|
||||||
|
OUT(" = {\n");
|
||||||
INDENT(+1);
|
INDENT(+1);
|
||||||
|
|
||||||
if(expr->_anonymous_type) {
|
if(expr->_anonymous_type) {
|
||||||
|
|
|
@ -59,6 +59,7 @@ typedef enum asn1p_expr_type {
|
||||||
ASN_CONSTR_SET, /* SET */
|
ASN_CONSTR_SET, /* SET */
|
||||||
ASN_CONSTR_SEQUENCE_OF, /* SEQUENCE OF */
|
ASN_CONSTR_SEQUENCE_OF, /* SEQUENCE OF */
|
||||||
ASN_CONSTR_SET_OF, /* SET OF */
|
ASN_CONSTR_SET_OF, /* SET OF */
|
||||||
|
ASN_CONSTR_OPEN_TYPE,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ASN.1 Basic types
|
* ASN.1 Basic types
|
||||||
|
|
|
@ -17,6 +17,7 @@ static char *asn1p_expr_type2str[] __attribute__ ((unused)) = {
|
||||||
[ ASN_CONSTR_SET ] = "SET",
|
[ ASN_CONSTR_SET ] = "SET",
|
||||||
[ ASN_CONSTR_SEQUENCE_OF ] = "SEQUENCE OF",
|
[ ASN_CONSTR_SEQUENCE_OF ] = "SEQUENCE OF",
|
||||||
[ ASN_CONSTR_SET_OF ] = "SET OF",
|
[ ASN_CONSTR_SET_OF ] = "SET OF",
|
||||||
|
[ ASN_CONSTR_OPEN_TYPE ] = "OPEN TYPE",
|
||||||
[ ASN_TYPE_ANY ] = "ANY",
|
[ ASN_TYPE_ANY ] = "ANY",
|
||||||
[ ASN_BASIC_BOOLEAN ] = "BOOLEAN",
|
[ ASN_BASIC_BOOLEAN ] = "BOOLEAN",
|
||||||
[ ASN_BASIC_NULL ] = "NULL",
|
[ ASN_BASIC_NULL ] = "NULL",
|
||||||
|
|
|
@ -242,7 +242,7 @@ BOOLEAN_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BOOLEAN_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
BOOLEAN_free(const asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
||||||
if(td && ptr && !contents_only) {
|
if(td && ptr && !contents_only) {
|
||||||
FREEMEM(ptr);
|
FREEMEM(ptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -336,9 +336,9 @@ NativeInteger_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NativeInteger_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
NativeInteger_free(const asn_TYPE_descriptor_t *td, void *ptr,
|
||||||
|
int contents_only) {
|
||||||
if(!td || !ptr)
|
if(!td || !ptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ASN_DEBUG("Freeing %s as INTEGER (%d, %p, Native)",
|
ASN_DEBUG("Freeing %s as INTEGER (%d, %p, Native)",
|
||||||
|
@ -356,7 +356,7 @@ NativeInteger_compare(const asn_TYPE_descriptor_t *td, const void *aptr, const v
|
||||||
if(aptr && bptr) {
|
if(aptr && bptr) {
|
||||||
const asn_INTEGER_specifics_t *specs =
|
const asn_INTEGER_specifics_t *specs =
|
||||||
(const asn_INTEGER_specifics_t *)td->specifics;
|
(const asn_INTEGER_specifics_t *)td->specifics;
|
||||||
if(specs->field_unsigned) {
|
if(specs && specs->field_unsigned) {
|
||||||
const unsigned long *a = aptr;
|
const unsigned long *a = aptr;
|
||||||
const unsigned long *b = bptr;
|
const unsigned long *b = bptr;
|
||||||
if(*a < *b) {
|
if(*a < *b) {
|
||||||
|
@ -364,7 +364,7 @@ NativeInteger_compare(const asn_TYPE_descriptor_t *td, const void *aptr, const v
|
||||||
} else if(*a > *b) {
|
} else if(*a > *b) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const long *a = aptr;
|
const long *a = aptr;
|
||||||
|
@ -374,7 +374,7 @@ NativeInteger_compare(const asn_TYPE_descriptor_t *td, const void *aptr, const v
|
||||||
} else if(*a > *b) {
|
} else if(*a > *b) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(!aptr) {
|
} else if(!aptr) {
|
||||||
|
|
|
@ -377,9 +377,8 @@ NativeReal_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NativeReal_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
NativeReal_free(const asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
||||||
|
if(!td || !ptr)
|
||||||
if(!td || !ptr)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ASN_DEBUG("Freeing %s as REAL (%d, %p, Native)",
|
ASN_DEBUG("Freeing %s as REAL (%d, %p, Native)",
|
||||||
|
|
|
@ -1726,8 +1726,9 @@ OCTET_STRING_print_utf8(asn_TYPE_descriptor_t *td, const void *sptr,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
OCTET_STRING_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) {
|
OCTET_STRING_free(const asn_TYPE_descriptor_t *td, void *sptr,
|
||||||
OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
|
int contents_only) {
|
||||||
|
OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
|
||||||
asn_OCTET_STRING_specifics_t *specs;
|
asn_OCTET_STRING_specifics_t *specs;
|
||||||
asn_struct_ctx_t *ctx;
|
asn_struct_ctx_t *ctx;
|
||||||
struct _stack *stck;
|
struct _stack *stck;
|
||||||
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||||
|
* Redistribution and modifications are permitted subject to BSD license.
|
||||||
|
*/
|
||||||
|
#include <asn_internal.h>
|
||||||
|
#include <OPEN_TYPE.h>
|
||||||
|
#include <constr_CHOICE.h>
|
||||||
|
#include <per_opentype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
|
asn_dec_rval_t
|
||||||
|
OPEN_TYPE_uper_get(asn_codec_ctx_t *opt_codec_ctx,
|
||||||
|
asn_TYPE_descriptor_t *td, void *sptr,
|
||||||
|
asn_TYPE_member_t *elm, asn_per_data_t *pd) {
|
||||||
|
asn_type_selector_result_t selected;
|
||||||
|
void *memb_ptr; /* Pointer to the member */
|
||||||
|
void **memb_ptr2; /* Pointer to that pointer */
|
||||||
|
asn_dec_rval_t rv;
|
||||||
|
|
||||||
|
if(!(elm->flags & ATF_OPEN_TYPE) || !elm->type_selector) {
|
||||||
|
ASN__DECODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
selected = elm->type_selector(td, sptr);
|
||||||
|
if(!selected.presence_index) {
|
||||||
|
ASN__DECODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fetch the pointer to this member */
|
||||||
|
assert(elm->flags == ATF_OPEN_TYPE);
|
||||||
|
if(elm->flags & ATF_POINTER) {
|
||||||
|
memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
|
||||||
|
} else {
|
||||||
|
memb_ptr = (char *)sptr + elm->memb_offset;
|
||||||
|
memb_ptr2 = &memb_ptr;
|
||||||
|
}
|
||||||
|
if(*memb_ptr2 != NULL) {
|
||||||
|
/* Make sure we reset the structure first before encoding */
|
||||||
|
if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
|
||||||
|
!= 0) {
|
||||||
|
ASN__DECODE_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *inner_value =
|
||||||
|
(char *)*memb_ptr2
|
||||||
|
+ elm->type->elements[selected.presence_index - 1].memb_offset;
|
||||||
|
|
||||||
|
rv = uper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
|
||||||
|
&inner_value, pd);
|
||||||
|
switch(rv.code) {
|
||||||
|
case RC_OK:
|
||||||
|
if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
|
||||||
|
selected.presence_index)
|
||||||
|
== 0) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
rv.code = RC_FAIL;
|
||||||
|
}
|
||||||
|
/* Fall through */
|
||||||
|
case RC_WMORE:
|
||||||
|
case RC_FAIL:
|
||||||
|
if(*memb_ptr2) {
|
||||||
|
asn_CHOICE_specifics_t *specs = selected.type_descriptor->specifics;
|
||||||
|
if(elm->flags & ATF_POINTER) {
|
||||||
|
ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
|
||||||
|
*memb_ptr2 = NULL;
|
||||||
|
} else {
|
||||||
|
ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
|
||||||
|
inner_value);
|
||||||
|
memset(*memb_ptr2, 0, specs->struct_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
asn_dec_rval_t
|
||||||
|
OPEN_TYPE_oer_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||||
|
void *sptr, asn_TYPE_member_t *elm, const void *ptr,
|
||||||
|
size_t size) {
|
||||||
|
asn_type_selector_result_t selected;
|
||||||
|
void *memb_ptr; /* Pointer to the member */
|
||||||
|
void **memb_ptr2; /* Pointer to that pointer */
|
||||||
|
asn_dec_rval_t rv;
|
||||||
|
size_t ot_ret;
|
||||||
|
|
||||||
|
if(!(elm->flags & ATF_OPEN_TYPE) || !elm->type_selector) {
|
||||||
|
ASN__DECODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
selected = elm->type_selector(td, sptr);
|
||||||
|
if(!selected.presence_index) {
|
||||||
|
ASN__DECODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fetch the pointer to this member */
|
||||||
|
if(elm->flags & ATF_POINTER) {
|
||||||
|
memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
|
||||||
|
} else {
|
||||||
|
memb_ptr = (char *)sptr + elm->memb_offset;
|
||||||
|
memb_ptr2 = &memb_ptr;
|
||||||
|
}
|
||||||
|
if(*memb_ptr2 != NULL) {
|
||||||
|
/* Make sure we reset the structure first before encoding */
|
||||||
|
if(CHOICE_variant_set_presence(selected.type_descriptor, *memb_ptr2, 0)
|
||||||
|
!= 0) {
|
||||||
|
ASN__DECODE_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ot_ret = oer_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
|
||||||
|
memb_ptr2, ptr, size);
|
||||||
|
switch(ot_ret) {
|
||||||
|
default:
|
||||||
|
if(CHOICE_variant_set_presence(selected.type_descriptor, *memb_ptr2,
|
||||||
|
selected.presence_index)
|
||||||
|
== 0) {
|
||||||
|
rv.code = RC_OK;
|
||||||
|
rv.consumed = ot_ret;
|
||||||
|
return rv;
|
||||||
|
} else {
|
||||||
|
/* Oh, now a full-blown failure failure */
|
||||||
|
}
|
||||||
|
/* Fall through */
|
||||||
|
case -1:
|
||||||
|
rv.code = RC_FAIL;
|
||||||
|
rv.consumed = 0;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
rv.code = RC_WMORE;
|
||||||
|
rv.consumed = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*memb_ptr2) {
|
||||||
|
asn_CHOICE_specifics_t *specs = selected.type_descriptor->specifics;
|
||||||
|
if(elm->flags & ATF_POINTER) {
|
||||||
|
ASN_STRUCT_FREE(*selected.type_descriptor, *memb_ptr2);
|
||||||
|
*memb_ptr2 = NULL;
|
||||||
|
} else {
|
||||||
|
ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
|
||||||
|
*memb_ptr2);
|
||||||
|
memset(*memb_ptr2, 0, specs->struct_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
|
@ -115,9 +115,9 @@ der_encode_primitive(asn_TYPE_descriptor_t *td, void *sptr,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ASN__PRIMITIVE_TYPE_free(asn_TYPE_descriptor_t *td, void *sptr,
|
ASN__PRIMITIVE_TYPE_free(const asn_TYPE_descriptor_t *td, void *sptr,
|
||||||
int contents_only) {
|
int contents_only) {
|
||||||
ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr;
|
ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr;
|
||||||
|
|
||||||
if(!td || !sptr)
|
if(!td || !sptr)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -63,8 +63,10 @@
|
||||||
/*
|
/*
|
||||||
* See the definitions.
|
* See the definitions.
|
||||||
*/
|
*/
|
||||||
static signed _fetch_present_idx(const void *struct_ptr, int off, int size);
|
static unsigned _fetch_present_idx(const void *struct_ptr, unsigned off,
|
||||||
static void _set_present_idx(void *sptr, int offset, int size, int pres);
|
unsigned size);
|
||||||
|
static void _set_present_idx(void *sptr, unsigned offset, unsigned size,
|
||||||
|
unsigned pres);
|
||||||
static const void *_get_member_ptr(const asn_TYPE_descriptor_t *,
|
static const void *_get_member_ptr(const asn_TYPE_descriptor_t *,
|
||||||
const void *sptr, asn_TYPE_member_t **elm,
|
const void *sptr, asn_TYPE_member_t **elm,
|
||||||
unsigned *present);
|
unsigned *present);
|
||||||
|
@ -1035,8 +1037,8 @@ CHOICE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CHOICE_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
CHOICE_free(const asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
||||||
asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
|
asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
|
||||||
unsigned present;
|
unsigned present;
|
||||||
|
|
||||||
if(!td || !ptr)
|
if(!td || !ptr)
|
||||||
|
@ -1081,17 +1083,18 @@ CHOICE_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
||||||
* is guaranteed to be aligned properly. ASN.1 compiler itself does not
|
* is guaranteed to be aligned properly. ASN.1 compiler itself does not
|
||||||
* produce packed code.
|
* produce packed code.
|
||||||
*/
|
*/
|
||||||
static signed
|
static unsigned
|
||||||
_fetch_present_idx(const void *struct_ptr, int pres_offset, int pres_size) {
|
_fetch_present_idx(const void *struct_ptr, unsigned pres_offset,
|
||||||
const void *present_ptr;
|
unsigned pres_size) {
|
||||||
|
const void *present_ptr;
|
||||||
unsigned present;
|
unsigned present;
|
||||||
|
|
||||||
present_ptr = ((const char *)struct_ptr) + pres_offset;
|
present_ptr = ((const char *)struct_ptr) + pres_offset;
|
||||||
|
|
||||||
switch(pres_size) {
|
switch(pres_size) {
|
||||||
case sizeof(int): present = *(const int *)present_ptr; break;
|
case sizeof(int): present = *(const unsigned int *)present_ptr; break;
|
||||||
case sizeof(short): present = *(const short *)present_ptr; break;
|
case sizeof(short): present = *(const unsigned short *)present_ptr; break;
|
||||||
case sizeof(char): present = *(const char *)present_ptr; break;
|
case sizeof(char): present = *(const unsigned char *)present_ptr; break;
|
||||||
default:
|
default:
|
||||||
/* ANSI C mandates enum to be equivalent to integer */
|
/* ANSI C mandates enum to be equivalent to integer */
|
||||||
assert(pres_size != sizeof(int));
|
assert(pres_size != sizeof(int));
|
||||||
|
@ -1102,14 +1105,15 @@ _fetch_present_idx(const void *struct_ptr, int pres_offset, int pres_size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_set_present_idx(void *struct_ptr, int pres_offset, int pres_size, int present) {
|
_set_present_idx(void *struct_ptr, unsigned pres_offset, unsigned pres_size,
|
||||||
void *present_ptr;
|
unsigned present) {
|
||||||
|
void *present_ptr;
|
||||||
present_ptr = ((char *)struct_ptr) + pres_offset;
|
present_ptr = ((char *)struct_ptr) + pres_offset;
|
||||||
|
|
||||||
switch(pres_size) {
|
switch(pres_size) {
|
||||||
case sizeof(int): *(int *)present_ptr = present; break;
|
case sizeof(int): *(unsigned int *)present_ptr = present; break;
|
||||||
case sizeof(short): *(short *)present_ptr = present; break;
|
case sizeof(short): *(unsigned short *)present_ptr = present; break;
|
||||||
case sizeof(char): *(char *)present_ptr = present; break;
|
case sizeof(char): *(unsigned char *)present_ptr = present; break;
|
||||||
default:
|
default:
|
||||||
/* ANSI C mandates enum to be equivalent to integer */
|
/* ANSI C mandates enum to be equivalent to integer */
|
||||||
assert(pres_size != sizeof(int));
|
assert(pres_size != sizeof(int));
|
||||||
|
@ -1181,3 +1185,50 @@ CHOICE_compare(const asn_TYPE_descriptor_t *td, const void *aptr, const void *bp
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the 1-based choice variant presence index.
|
||||||
|
* Returns 0 in case of error.
|
||||||
|
*/
|
||||||
|
unsigned
|
||||||
|
CHOICE_variant_get_presence(const asn_TYPE_descriptor_t *td, const void *sptr) {
|
||||||
|
asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
|
||||||
|
return _fetch_present_idx(sptr, specs->pres_offset, specs->pres_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sets or resets the 1-based choice variant presence index.
|
||||||
|
* In case a previous index is not zero, the currently selected structure
|
||||||
|
* member is freed and zeroed-out first.
|
||||||
|
* Returns 0 on success and -1 on error.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
CHOICE_variant_set_presence(const asn_TYPE_descriptor_t *td, void *sptr,
|
||||||
|
unsigned present) {
|
||||||
|
extern asn_CHOICE_specifics_t asn_SPC_value_specs_3;
|
||||||
|
asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
|
||||||
|
unsigned old_present;
|
||||||
|
|
||||||
|
if(!sptr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(present > td->elements_count)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
old_present =
|
||||||
|
_fetch_present_idx(sptr, specs->pres_offset, specs->pres_size);
|
||||||
|
if(present == old_present)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(old_present == 0) {
|
||||||
|
assert(old_present <= td->elements_count);
|
||||||
|
ASN_STRUCT_FREE_CONTENTS_ONLY(*td, sptr);
|
||||||
|
memset(sptr, 0, specs->struct_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
_set_present_idx(sptr, specs->pres_offset, specs->pres_size, present);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ typedef const struct asn_CHOICE_specifics_s {
|
||||||
unsigned tag2el_count;
|
unsigned tag2el_count;
|
||||||
|
|
||||||
/* Canonical ordering of CHOICE elements, for PER */
|
/* Canonical ordering of CHOICE elements, for PER */
|
||||||
const int *canonical_order;
|
const unsigned *canonical_order;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Extensions-related stuff.
|
* Extensions-related stuff.
|
||||||
|
@ -51,6 +51,22 @@ per_type_decoder_f CHOICE_decode_uper;
|
||||||
per_type_encoder_f CHOICE_encode_uper;
|
per_type_encoder_f CHOICE_encode_uper;
|
||||||
asn_outmost_tag_f CHOICE_outmost_tag;
|
asn_outmost_tag_f CHOICE_outmost_tag;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the 1-based choice variant presence index.
|
||||||
|
* Returns 0 in case of error.
|
||||||
|
*/
|
||||||
|
unsigned CHOICE_variant_get_presence(const asn_TYPE_descriptor_t *td,
|
||||||
|
const void *structure_ptr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sets or resets the 1-based choice variant presence index.
|
||||||
|
* In case a previous index is not zero, the currently selected structure
|
||||||
|
* member is freed and zeroed-out first.
|
||||||
|
* Returns 0 on success and -1 on error.
|
||||||
|
*/
|
||||||
|
int CHOICE_variant_set_presence(const asn_TYPE_descriptor_t *td,
|
||||||
|
void *structure_ptr, unsigned present);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
#include <asn_internal.h>
|
#include <asn_internal.h>
|
||||||
#include <constr_SEQUENCE.h>
|
#include <constr_SEQUENCE.h>
|
||||||
|
#include <OPEN_TYPE.h>
|
||||||
#include <per_opentype.h>
|
#include <per_opentype.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -201,7 +202,7 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||||
/*
|
/*
|
||||||
* MICROPHASE 1: Synchronize decoding.
|
* MICROPHASE 1: Synchronize decoding.
|
||||||
*/
|
*/
|
||||||
ASN_DEBUG("In %s SEQUENCE left %d, edx=%d flags=%d"
|
ASN_DEBUG("In %s SEQUENCE left %d, edx=%u flags=%d"
|
||||||
" opt=%d ec=%d",
|
" opt=%d ec=%d",
|
||||||
td->name, (int)ctx->left, edx,
|
td->name, (int)ctx->left, edx,
|
||||||
elements[edx].flags, elements[edx].optional,
|
elements[edx].flags, elements[edx].optional,
|
||||||
|
@ -948,8 +949,8 @@ SEQUENCE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SEQUENCE_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) {
|
SEQUENCE_free(const asn_TYPE_descriptor_t *td, void *sptr, int contents_only) {
|
||||||
size_t edx;
|
size_t edx;
|
||||||
|
|
||||||
if(!td || !sptr)
|
if(!td || !sptr)
|
||||||
return;
|
return;
|
||||||
|
@ -1118,15 +1119,10 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch the member from the stream */
|
/* Fetch the member from the stream */
|
||||||
ASN_DEBUG("Decoding member %s in %s", elm->name, td->name);
|
ASN_DEBUG("Decoding member \"%s\" in %s", elm->name, td->name);
|
||||||
|
|
||||||
if((elm->flags & ATF_OPEN_TYPE) && elm->type_selector) {
|
if((elm->flags & ATF_OPEN_TYPE) && elm->type_selector) {
|
||||||
asn_TYPE_descriptor_t *et = elm->type_selector(td, st);
|
rv = OPEN_TYPE_uper_get(opt_codec_ctx, td, st, elm, pd);
|
||||||
if(!et) {
|
|
||||||
FREEMEM(opres);
|
|
||||||
ASN__DECODE_FAILED;
|
|
||||||
}
|
|
||||||
rv = uper_open_type_get(opt_codec_ctx, et, NULL, memb_ptr2, pd);
|
|
||||||
} else {
|
} else {
|
||||||
rv = elm->type->uper_decoder(opt_codec_ctx, elm->type,
|
rv = elm->type->uper_decoder(opt_codec_ctx, elm->type,
|
||||||
elm->per_constraints, memb_ptr2, pd);
|
elm->per_constraints, memb_ptr2, pd);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <asn_internal.h>
|
#include <asn_internal.h>
|
||||||
#include <constr_SEQUENCE.h>
|
#include <constr_SEQUENCE.h>
|
||||||
|
#include <OPEN_TYPE.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -150,8 +151,6 @@ SEQUENCE_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||||
for(edx = (ctx->step >> 1); edx < td->elements_count;
|
for(edx = (ctx->step >> 1); edx < td->elements_count;
|
||||||
edx++, ctx->step = (ctx->step & ~1) + 2) {
|
edx++, ctx->step = (ctx->step & ~1) + 2) {
|
||||||
asn_TYPE_member_t *elm = &td->elements[edx];
|
asn_TYPE_member_t *elm = &td->elements[edx];
|
||||||
void *memb_tmpptr; /* Temporary reference. */
|
|
||||||
void **memb_ptr2; /* Pointer to a pointer to a memmber */
|
|
||||||
|
|
||||||
ASN_DEBUG("Decoding %s->%s", td->name, elm->name);
|
ASN_DEBUG("Decoding %s->%s", td->name, elm->name);
|
||||||
|
|
||||||
|
@ -188,37 +187,20 @@ SEQUENCE_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||||
*/
|
*/
|
||||||
ctx->step |= 1; /* Confirm entering next microphase */
|
ctx->step |= 1; /* Confirm entering next microphase */
|
||||||
microphase2_decode_continues:
|
microphase2_decode_continues:
|
||||||
if(elm->flags & ATF_POINTER) {
|
|
||||||
/* Member is a pointer to another structure */
|
|
||||||
memb_ptr2 = (void **)((char *)st + elm->memb_offset);
|
|
||||||
} else {
|
|
||||||
memb_tmpptr = (char *)st + elm->memb_offset;
|
|
||||||
memb_ptr2 = &memb_tmpptr; /* Ensure this & remains in scope! */
|
|
||||||
}
|
|
||||||
|
|
||||||
if((elm->flags & ATF_OPEN_TYPE) && elm->type_selector) {
|
if((elm->flags & ATF_OPEN_TYPE) && elm->type_selector) {
|
||||||
asn_TYPE_descriptor_t *et = elm->type_selector(td, st);
|
rval = OPEN_TYPE_oer_get(opt_codec_ctx, td, st, elm, ptr, size);
|
||||||
ssize_t ot_ret;
|
|
||||||
if(!et) {
|
|
||||||
ASN__DECODE_FAILED;
|
|
||||||
}
|
|
||||||
ot_ret = oer_open_type_get(opt_codec_ctx, et, NULL, memb_ptr2,
|
|
||||||
ptr, size);
|
|
||||||
switch(ot_ret) {
|
|
||||||
case -1:
|
|
||||||
rval.code = RC_FAIL;
|
|
||||||
rval.consumed = 0;
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
rval.code = RC_WMORE;
|
|
||||||
rval.consumed = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
rval.code = RC_OK;
|
|
||||||
rval.consumed = ot_ret;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
void *memb_tmpptr; /* Temporary reference. */
|
||||||
|
void **memb_ptr2; /* Pointer to a pointer to a memmber */
|
||||||
|
|
||||||
|
if(elm->flags & ATF_POINTER) {
|
||||||
|
/* Member is a pointer to another structure */
|
||||||
|
memb_ptr2 = (void **)((char *)st + elm->memb_offset);
|
||||||
|
} else {
|
||||||
|
memb_tmpptr = (char *)st + elm->memb_offset;
|
||||||
|
memb_ptr2 = &memb_tmpptr; /* Ensure remains in scope! */
|
||||||
|
}
|
||||||
|
|
||||||
rval = elm->type->oer_decoder(opt_codec_ctx, elm->type,
|
rval = elm->type->oer_decoder(opt_codec_ctx, elm->type,
|
||||||
elm->oer_constraints, memb_ptr2,
|
elm->oer_constraints, memb_ptr2,
|
||||||
ptr, size);
|
ptr, size);
|
||||||
|
|
|
@ -910,8 +910,8 @@ SET_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SET_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
SET_free(const asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
||||||
size_t edx;
|
size_t edx;
|
||||||
|
|
||||||
if(!td || !ptr)
|
if(!td || !ptr)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -788,7 +788,7 @@ SET_OF_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SET_OF_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
SET_OF_free(const asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
||||||
if(td && ptr) {
|
if(td && ptr) {
|
||||||
asn_SET_OF_specifics_t *specs;
|
asn_SET_OF_specifics_t *specs;
|
||||||
asn_TYPE_member_t *elm = td->elements;
|
asn_TYPE_member_t *elm = td->elements;
|
||||||
|
|
|
@ -53,7 +53,7 @@ typedef struct asn_struct_ctx_s {
|
||||||
* dynamically.)
|
* dynamically.)
|
||||||
*/
|
*/
|
||||||
typedef void (asn_struct_free_f)(
|
typedef void (asn_struct_free_f)(
|
||||||
struct asn_TYPE_descriptor_s *type_descriptor,
|
const struct asn_TYPE_descriptor_s *type_descriptor,
|
||||||
void *struct_ptr, int free_contents_only);
|
void *struct_ptr, int free_contents_only);
|
||||||
#define ASN_STRUCT_FREE(asn_DEF, ptr) (asn_DEF).free_struct(&(asn_DEF),ptr,0)
|
#define ASN_STRUCT_FREE(asn_DEF, ptr) (asn_DEF).free_struct(&(asn_DEF),ptr,0)
|
||||||
#define ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF, ptr) \
|
#define ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF, ptr) \
|
||||||
|
@ -95,7 +95,11 @@ asn_outmost_tag_f asn_TYPE_outmost_tag;
|
||||||
* Fetch the desired type of the Open Type based on the
|
* Fetch the desired type of the Open Type based on the
|
||||||
* Information Object Set driven constraints.
|
* Information Object Set driven constraints.
|
||||||
*/
|
*/
|
||||||
typedef struct asn_TYPE_descriptor_s *(asn_type_selector_f)(
|
typedef struct asn_type_selector_result_s {
|
||||||
|
struct asn_TYPE_descriptor_s *type_descriptor; /* Type encoded. */
|
||||||
|
unsigned presence_index; /* Associated choice variant. */
|
||||||
|
} asn_type_selector_result_t;
|
||||||
|
typedef asn_type_selector_result_t(asn_type_selector_f)(
|
||||||
const struct asn_TYPE_descriptor_s *parent_type_descriptor,
|
const struct asn_TYPE_descriptor_s *parent_type_descriptor,
|
||||||
const void *parent_structure_ptr);
|
const void *parent_structure_ptr);
|
||||||
|
|
||||||
|
@ -168,7 +172,7 @@ typedef struct asn_TYPE_member_s {
|
||||||
ber_tlv_tag_t tag; /* Outmost (most immediate) tag */
|
ber_tlv_tag_t tag; /* Outmost (most immediate) tag */
|
||||||
int tag_mode; /* IMPLICIT/no/EXPLICIT tag at current level */
|
int tag_mode; /* IMPLICIT/no/EXPLICIT tag at current level */
|
||||||
asn_TYPE_descriptor_t *type; /* Member type descriptor */
|
asn_TYPE_descriptor_t *type; /* Member type descriptor */
|
||||||
asn_type_selector_f *type_selector; /* IoS selector */
|
asn_type_selector_f *type_selector; /* IoS runtime type selector */
|
||||||
asn_constr_check_f *memb_constraints; /* Constraints validator */
|
asn_constr_check_f *memb_constraints; /* Constraints validator */
|
||||||
asn_oer_constraints_t *oer_constraints; /* OER compiled constraints */
|
asn_oer_constraints_t *oer_constraints; /* OER compiled constraints */
|
||||||
asn_per_constraints_t *per_constraints; /* PER compiled constraints */
|
asn_per_constraints_t *per_constraints; /* PER compiled constraints */
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
ANY.h ANY.c
|
ANY.h ANY.c
|
||||||
|
OPEN_TYPE.h OPEN_TYPE.c constr_CHOICE.h
|
||||||
BMPString.h BMPString.c UTF8String.h
|
BMPString.h BMPString.c UTF8String.h
|
||||||
BOOLEAN.h BOOLEAN.c
|
BOOLEAN.h BOOLEAN.c
|
||||||
ENUMERATED.h ENUMERATED.c INTEGER.h NativeEnumerated.h
|
ENUMERATED.h ENUMERATED.c INTEGER.h NativeEnumerated.h
|
||||||
|
@ -34,7 +35,7 @@ VisibleString.h VisibleString.c
|
||||||
asn_SEQUENCE_OF.h asn_SEQUENCE_OF.c asn_SET_OF.h
|
asn_SEQUENCE_OF.h asn_SEQUENCE_OF.c asn_SET_OF.h
|
||||||
asn_SET_OF.h asn_SET_OF.c
|
asn_SET_OF.h asn_SET_OF.c
|
||||||
constr_CHOICE.h constr_CHOICE.c
|
constr_CHOICE.h constr_CHOICE.c
|
||||||
constr_SEQUENCE.h constr_SEQUENCE.c
|
constr_SEQUENCE.h constr_SEQUENCE.c OPEN_TYPE.h
|
||||||
constr_SEQUENCE_OF.h constr_SEQUENCE_OF.c asn_SEQUENCE_OF.h constr_SET_OF.h
|
constr_SEQUENCE_OF.h constr_SEQUENCE_OF.c asn_SEQUENCE_OF.h constr_SET_OF.h
|
||||||
constr_SET.h constr_SET.c
|
constr_SET.h constr_SET.c
|
||||||
constr_SET_OF.h constr_SET_OF.c asn_SET_OF.h
|
constr_SET_OF.h constr_SET_OF.c asn_SET_OF.h
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
ModuleComponentRelationConstraint
|
ModuleComponentRelationConstraint
|
||||||
{ iso org(3) dod(6) internet (1) private(4) enterprise(1)
|
{ iso org(3) dod(6) internet (1) private(4) enterprise(1)
|
||||||
spelio(9363) software(1) asn1c(5) test(1) 141 }
|
spelio(9363) software(1) asn1c(5) test(1) 141 }
|
||||||
DEFINITIONS ::=
|
DEFINITIONS AUTOMATIC TAGS ::=
|
||||||
BEGIN
|
BEGIN
|
||||||
|
|
||||||
Frame ::= SEQUENCE {
|
Frame ::= SEQUENCE {
|
||||||
|
|
Loading…
Reference in New Issue