mirror of https://gerrit.osmocom.org/asn1c
upgrade: PER related changes
parent
708530582f
commit
59b176ee35
|
@ -1,9 +1,11 @@
|
|||
|
||||
0.9.20: 2005-Nov-07
|
||||
0.9.20: 2005-Nov-13
|
||||
|
||||
* SET OF CHOICE, SEQUENCE OF CHOICE and a certain named S/O types
|
||||
are represented differently in XER. THIS IS AN ICOMPATIBLE CHANGE.
|
||||
(Test case 70) (Severity: low; Security impact: low)
|
||||
* PER implementation has started
|
||||
* asn1c: Removed -ftypes88 command line option.
|
||||
|
||||
0.9.19: 2005-Oct-06
|
||||
|
||||
|
|
7
TODO
7
TODO
|
@ -1,7 +1,6 @@
|
|||
1. MAJOR:
|
||||
|
||||
1.1 Support for PER encoding. Requires advanced subtype constraints support,
|
||||
which is already completed.
|
||||
1.1 Support for PER encoding. PER decoding is already supported.
|
||||
|
||||
1.2 Support for Information Object Classes.
|
||||
Status: Support for parsing IOCs is mostly present.
|
||||
|
@ -12,7 +11,3 @@ which is already completed.
|
|||
|
||||
2.1 Support for EXTERNAL, EMBEDDED-PDV and CHARACTER STRING types.
|
||||
Requires something from 1.2 (Information Object Classes).
|
||||
|
||||
3. MINOR:
|
||||
|
||||
3.1 Support for DEFAULT encoding and decoding, at least in INTEGER/ENUMERATED types.
|
||||
|
|
|
@ -4,7 +4,7 @@ asn1c \- ASN.1 Compiler
|
|||
.SH SYNOPSIS
|
||||
asn1c [\fB\-E\fR [\fB-F\fR] | \fB\-P\fR | \fB\-R\fR]
|
||||
[\fB\-S\fR\fIdir\fR] [\fB-X\fR]
|
||||
[\fB\-W\fR\fIdebug-\fR...] [\fB\-f\fR\fIoption\fR...] [\fB\-p\fR\fIrint-\fR...]
|
||||
[\fB\-W\fR\fIdebug-\fR...] [\fB\-f\fR\fIoption\fR] [\fB\-gen-\fR\fIoption\fR] [\fB\-print-\fR\fIoption\fR]
|
||||
\fIinfile\fR...
|
||||
.SH DESCRIPTION
|
||||
asn1c compiles the ASN.1 specifications into the set of
|
||||
|
@ -25,7 +25,11 @@ and other encoding standards.
|
|||
.br
|
||||
\fB\-fall-defs-global \-fbless-SIZE \-fcompound-names \-findirect-choice
|
||||
.BI "\-fknown-extern-type="<name>
|
||||
\fB\-fnative-types \-fno-constraints \-fno-include-deps \-funnamed-unions \-fskeletons-copy \-ftypes88\fR
|
||||
\fB\-fnative-types \-fno-constraints \-fno-include-deps \-funnamed-unions \-fskeletons-copy
|
||||
.TP
|
||||
\fICodecs Generation Options\fR
|
||||
.br
|
||||
.B \-gen-PER
|
||||
.TP
|
||||
\fIOutput Options\fR
|
||||
.br
|
||||
|
@ -117,11 +121,10 @@ Enable unnamed unions in the definitions of target language's structures.
|
|||
.TP
|
||||
.B \-fskeletons-copy
|
||||
Copy support files (skeletons) rather than symlink them.
|
||||
.SH CODECS GENERATION OPTIONS
|
||||
.TP
|
||||
.B \-ftypes88
|
||||
Pretend to support only ASN.1:1988 embedded types. Certain reserved words,
|
||||
such as UniversalString and BMPString, become ordinary type references
|
||||
and may be redefined by the specification.
|
||||
.B \-gen-PER
|
||||
Generate Packed Encoding Rules (PER) support code.
|
||||
.SH OUTPUT OPTIONS
|
||||
.TP
|
||||
.B \-print-constraints
|
||||
|
|
|
@ -62,7 +62,7 @@ main(int ac, char **av) {
|
|||
/*
|
||||
* Process command-line options.
|
||||
*/
|
||||
while((ch = getopt(ac, av, "EFf:hLPp:RS:vW:X")) != -1)
|
||||
while((ch = getopt(ac, av, "EFf:g:hLPp:RS:vW:X")) != -1)
|
||||
switch(ch) {
|
||||
case 'E':
|
||||
print_arg__print_out = 1;
|
||||
|
@ -95,13 +95,19 @@ main(int ac, char **av) {
|
|||
asn1_compiler_flags |= A1C_UNNAMED_UNIONS;
|
||||
} else if(strcmp(optarg, "skeletons-copy") == 0) {
|
||||
asn1_compiler_flags |= A1C_SKELETONS_COPY;
|
||||
} else if(strcmp(optarg, "types88") == 0) {
|
||||
asn1_parser_flags |= A1P_TYPES_RESTRICT_TO_1988;
|
||||
} else {
|
||||
fprintf(stderr, "-f%s: Invalid argument\n", optarg);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
break;
|
||||
case 'g':
|
||||
if(strcmp(optarg, "en-PER") == 0) {
|
||||
asn1_compiler_flags |= A1C_GEN_PER;
|
||||
} else {
|
||||
fprintf(stderr, "-g%s: Invalid argument\n", optarg);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
usage(av[0]);
|
||||
case 'P':
|
||||
|
@ -109,7 +115,15 @@ main(int ac, char **av) {
|
|||
asn1_compiler_flags &= ~A1C_NO_C99;
|
||||
break;
|
||||
case 'p':
|
||||
if(strcmp(optarg, "rint-constraints") == 0) {
|
||||
if(strncmp(optarg, "du=", 3) == 0) {
|
||||
char *pduname = optarg + 3;
|
||||
if(strcmp(pduname, "auto")) {
|
||||
fprintf(stderr, "-pdu=%s: expected -pdu=auto\n",
|
||||
pduname);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
asn1_compiler_flags |= A1C_PDU_AUTO;
|
||||
} else if(strcmp(optarg, "rint-constraints") == 0) {
|
||||
asn1_printer_flags |= APF_DEBUG_CONSTRAINTS;
|
||||
} else if(strcmp(optarg, "rint-lines") == 0) {
|
||||
asn1_printer_flags |= APF_LINE_COMMENTS;
|
||||
|
@ -250,7 +264,8 @@ main(int ac, char **av) {
|
|||
/*
|
||||
* Make sure the skeleton directory is out there.
|
||||
*/
|
||||
if(skeletons_dir == NULL) {
|
||||
if((asn1_compiler_flags & A1C_OMIT_SUPPORT_CODE) == 0
|
||||
&& skeletons_dir == NULL) {
|
||||
struct stat sb;
|
||||
skeletons_dir = DATADIR;
|
||||
if((av[-optind][0] == '.' || av[-optind][1] == '/')
|
||||
|
@ -326,7 +341,10 @@ usage(const char *av0) {
|
|||
" -fno-include-deps Do not generate courtesy #includes for dependencies\n"
|
||||
" -funnamed-unions Enable unnamed unions in structures\n"
|
||||
" -fskeletons-copy Force copying the support files\n"
|
||||
" -ftypes88 Pretend to support only ASN.1:1988 embedded types\n"
|
||||
"\n"
|
||||
|
||||
" -gen-PER Generate PER support code\n"
|
||||
" -pdu=auto Generate PDU table (discover PDUs automatically)\n"
|
||||
"\n"
|
||||
|
||||
" -print-constraints Explain subtype constraints (debug)\n"
|
||||
|
|
|
@ -102,8 +102,8 @@ check(int is_ok, uint8_t *buf, int size, size_t consumed) {
|
|||
assert(rval.code == RC_OK);
|
||||
assert(rval.consumed == consumed);
|
||||
|
||||
assert(strcmp(t.e->buf, "xyz") == 0);
|
||||
assert(strcmp(t.f->buf, "love_it") == 0);
|
||||
assert(strcmp((char *)t.e->buf, "xyz") == 0);
|
||||
assert(strcmp((char *)t.f->buf, "love_it") == 0);
|
||||
|
||||
assert(t.g->size == 2);
|
||||
assert(t.g->bits_unused == 2);
|
||||
|
|
|
@ -36,8 +36,12 @@ _buf_writer(const void *buffer, size_t size, void *app_key) {
|
|||
b = buf + buf_offset;
|
||||
bend = b + size;
|
||||
fprintf(stderr, "=> [");
|
||||
for(; b < bend; b++)
|
||||
fprintf(stderr, "%c", *b);
|
||||
for(; b < bend; b++) {
|
||||
if(*b >= 32 && *b < 127 && *b != '%')
|
||||
fprintf(stderr, "%c", *b);
|
||||
else
|
||||
fprintf(stderr, "%%02x", *b);
|
||||
}
|
||||
fprintf(stderr, "]:%ld\n", (long)size);
|
||||
buf_offset += size;
|
||||
return 0;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,7 +4,7 @@
|
|||
#include "asn1c_out.h"
|
||||
|
||||
#include <asn1fix_crange.h> /* constraint groker from libasn1fix */
|
||||
#include <asn1fix_export.h> /* other exportable stuff from libasn1fix */
|
||||
#include <asn1fix_export.h> /* other exportables from libasn1fix */
|
||||
|
||||
static int asn1c_emit_constraint_tables(arg_t *arg, int got_size);
|
||||
static int emit_alphabet_check_loop(arg_t *arg, asn1cnst_range_t *range);
|
||||
|
|
|
@ -66,7 +66,12 @@ asn1c_read_file_dependencies(arg_t *arg, const char *datadir) {
|
|||
asn1c_fdeps_t *cur;
|
||||
char buf[4096];
|
||||
FILE *f;
|
||||
int hit_COMMON_FILES = 0;
|
||||
enum {
|
||||
SS_DYNAMIC, /* Dynamic list of dependencies */
|
||||
SS_CODEC_PER, /* Use contents only if -gen-PER */
|
||||
SS_COMMON_FILES, /* Section for dependencies */
|
||||
SS_IGNORE /* Ignore contents of this section */
|
||||
} special_section = SS_DYNAMIC;
|
||||
|
||||
(void)arg;
|
||||
|
||||
|
@ -91,17 +96,27 @@ asn1c_read_file_dependencies(arg_t *arg, const char *datadir) {
|
|||
for(p = strtok(buf, " \t\r\n"); p;
|
||||
p = strtok(NULL, " \t\r\n")) {
|
||||
asn1c_fdeps_t *d;
|
||||
|
||||
/*
|
||||
* If hit "COMMON-FILES:", treat everything else
|
||||
* as a huge dependency.
|
||||
* Special "prefix" section.
|
||||
*/
|
||||
if(strcmp(p, "COMMON-FILES:") == 0) {
|
||||
hit_COMMON_FILES = 1;
|
||||
if(strchr(p, ':')) {
|
||||
special_section = SS_IGNORE;
|
||||
if(strcmp(p, "COMMON-FILES:") == 0) {
|
||||
special_section = SS_COMMON_FILES;
|
||||
} else if((arg->flags & A1C_GEN_PER)
|
||||
&& strcmp(p, "CODEC-PER:") == 0) {
|
||||
special_section = SS_CODEC_PER;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(special_section == SS_IGNORE)
|
||||
continue;
|
||||
|
||||
d = asn1c_new_dep(p);
|
||||
assert(d);
|
||||
d->used_somewhere = hit_COMMON_FILES;
|
||||
d->used_somewhere = special_section;
|
||||
|
||||
if(asn1c_dep_add(cur, d) == 1)
|
||||
cur = d;
|
||||
|
|
|
@ -11,6 +11,7 @@ static int asn1c_print_streams(arg_t *arg);
|
|||
static int asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *);
|
||||
static int asn1c_copy_over(arg_t *arg, char *path);
|
||||
static int identical_files(const char *fname1, const char *fname2);
|
||||
static int generate_pdu_collection_file(arg_t *arg);
|
||||
|
||||
int
|
||||
asn1c_save_compiled_output(arg_t *arg, const char *datadir,
|
||||
|
@ -18,7 +19,7 @@ asn1c_save_compiled_output(arg_t *arg, const char *datadir,
|
|||
asn1c_fdeps_t *deps = 0;
|
||||
asn1c_fdeps_t *dlist;
|
||||
asn1p_module_t *mod;
|
||||
FILE *mkf;
|
||||
FILE *mkf; /* Makefile.am.sample */
|
||||
int i;
|
||||
|
||||
deps = asn1c_read_file_dependencies(arg, datadir);
|
||||
|
@ -108,6 +109,12 @@ asn1c_save_compiled_output(arg_t *arg, const char *datadir,
|
|||
}
|
||||
}
|
||||
|
||||
if(arg->flags & A1C_PDU_AUTO) {
|
||||
fprintf(mkf, "ASN_MODULE_SOURCES+=pdu_collection.c\n");
|
||||
if(generate_pdu_collection_file(arg))
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(mkf, "\n\n"
|
||||
"lib_LTLIBRARIES=libsomething.la\n"
|
||||
"libsomething_la_SOURCES="
|
||||
|
@ -438,3 +445,62 @@ asn1c_copy_over(arg_t *arg, char *path) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
generate_pdu_collection_file(arg_t *arg) {
|
||||
asn1p_module_t *mod;
|
||||
FILE *fp;
|
||||
|
||||
fp = asn1c_open_file("pdu_collection", ".c", 0);
|
||||
if(fp == NULL) {
|
||||
perror("pdu_collection.c");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(fp,
|
||||
"/*\n"
|
||||
" * Generated by asn1c-" VERSION " (http://lionet.info/asn1c)\n"
|
||||
" */\n\n");
|
||||
fprintf(fp, "struct asn_TYPE_descriptor_s;\t"
|
||||
"/* Forward declaration */\n\n");
|
||||
|
||||
TQ_FOR(mod, &(arg->asn->modules), mod_next) {
|
||||
TQ_FOR(arg->expr, &(mod->members), next) {
|
||||
if(arg->expr->_type_referenced
|
||||
|| !asn1_lang_map[arg->expr->meta_type]
|
||||
[arg->expr->expr_type].type_cb)
|
||||
continue;
|
||||
fprintf(fp, "extern struct asn_TYPE_descriptor_s "
|
||||
"asn_DEF_%s;\n",
|
||||
asn1c_make_identifier(0, arg->expr->Identifier,
|
||||
NULL));
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fp, "\n\n");
|
||||
fprintf(fp, "struct asn_TYPE_descriptor_s *asn_pdu_collection[] = {\n");
|
||||
TQ_FOR(mod, &(arg->asn->modules), mod_next) {
|
||||
int mod_printed = 0;
|
||||
TQ_FOR(arg->expr, &(mod->members), next) {
|
||||
if(arg->expr->_type_referenced
|
||||
|| !asn1_lang_map[arg->expr->meta_type]
|
||||
[arg->expr->expr_type].type_cb)
|
||||
continue;
|
||||
if(!mod_printed++)
|
||||
fprintf(fp, "\t/* From module %s in %s */\n",
|
||||
arg->expr->module->ModuleName,
|
||||
arg->expr->module->source_file_name);
|
||||
fprintf(fp, "\t&asn_DEF_%s,\t\n",
|
||||
asn1c_make_identifier(0, arg->expr->Identifier,
|
||||
NULL));
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fp, "\t0\n};\n\n");
|
||||
|
||||
fclose(fp);
|
||||
fprintf(stderr, "Generated pdu_collection.c\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,16 @@ enum asn1c_flags {
|
|||
* Copy support files rather than symlink them.
|
||||
*/
|
||||
A1C_SKELETONS_COPY = 0x0800,
|
||||
/*
|
||||
* -gen-PER
|
||||
* Generate PER support code
|
||||
*/
|
||||
A1C_GEN_PER = 0x1000,
|
||||
/*
|
||||
* -pdu=auto
|
||||
* Generate PDU table
|
||||
*/
|
||||
A1C_PDU_AUTO = 0x2000
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include "asn1fix_internal.h"
|
||||
|
||||
#define AFT_MAGIC_ANY 1 /* _fetch_tag() flag */
|
||||
|
||||
static int _asn1f_check_if_tag_must_be_explicit(arg_t *arg, asn1p_expr_t *v);
|
||||
static int _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b);
|
||||
static int _asn1f_fix_type_tag(arg_t *arg, asn1p_expr_t *expr);
|
||||
|
@ -337,6 +335,7 @@ asn1f_check_constr_tags_distinct(arg_t *arg) {
|
|||
case ASN_CONSTR_SEQUENCE:
|
||||
case ASN_CONSTR_SET:
|
||||
case ASN_CONSTR_CHOICE:
|
||||
DEBUG("Checking tags of members of constructed types");
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
|
@ -353,6 +352,8 @@ asn1f_check_constr_tags_distinct(arg_t *arg) {
|
|||
if(expr->expr_type != ASN_CONSTR_SEQUENCE || v->marker.flags) {
|
||||
asn1p_expr_t *nv;
|
||||
for(nv = v; (nv = TQ_NEXT(nv, next));) {
|
||||
DEBUG("S/C comparing tags %s s. %s",
|
||||
v->Identifier, nv->Identifier);
|
||||
if(_asn1f_compare_tags(arg, v, nv))
|
||||
r_value = -1;
|
||||
if(expr->expr_type == ASN_CONSTR_SEQUENCE
|
||||
|
@ -404,12 +405,15 @@ _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {
|
|||
int ra, rb;
|
||||
int ret;
|
||||
|
||||
ra = asn1f_fetch_outmost_tag(arg->asn, arg->mod, a, &ta, AFT_MAGIC_ANY);
|
||||
rb = asn1f_fetch_outmost_tag(arg->asn, arg->mod, b, &tb, AFT_MAGIC_ANY);
|
||||
ra = asn1f_fetch_outmost_tag(arg->asn, arg->mod, a,
|
||||
&ta, AFT_IMAGINARY_ANY);
|
||||
rb = asn1f_fetch_outmost_tag(arg->asn, arg->mod, b,
|
||||
&tb, AFT_IMAGINARY_ANY);
|
||||
|
||||
/*
|
||||
* If both tags are explicitly or implicitly given, use them.
|
||||
*/
|
||||
DEBUG("Fetching outmost tags: %d, %d", ra, rb);
|
||||
if(ra == 0 && rb == 0) {
|
||||
/*
|
||||
* Simple case: fetched both tags.
|
||||
|
|
|
@ -370,6 +370,7 @@ asn1f_find_terminal_thing(arg_t *arg, asn1p_expr_t *expr, enum ftt_what what) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
tc->_type_referenced = 1;
|
||||
tc->_mark |= TM_RECURSION;
|
||||
WITH_MODULE(tc->module,
|
||||
expr = asn1f_find_terminal_thing(arg, tc, what));
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
if((flags & AFT_FETCH_OUTMOST)) return count; \
|
||||
} while(0)
|
||||
|
||||
/* X.691, #22.2 */
|
||||
static int asn1f_fetch_minimal_choice_root_tag(arg_t *arg, struct asn1p_type_tag_s *tag, enum asn1f_aft_flags_e flags);
|
||||
|
||||
static int
|
||||
asn1f_fetch_tags_impl(arg_t *arg, struct asn1p_type_tag_s **tags, int count, int skip, enum asn1f_aft_flags_e flags) {
|
||||
asn1p_expr_t *expr = arg->expr;
|
||||
|
@ -44,9 +47,13 @@ asn1f_fetch_tags_impl(arg_t *arg, struct asn1p_type_tag_s **tags, int count, int
|
|||
if(expr->expr_type == ASN_TYPE_ANY
|
||||
&& (flags & AFT_IMAGINARY_ANY))
|
||||
tt.tag_value = -1;
|
||||
else if(expr->expr_type == ASN_CONSTR_CHOICE)
|
||||
return count ? count : -1;
|
||||
else
|
||||
else if(expr->expr_type != ASN_CONSTR_CHOICE)
|
||||
return -1;
|
||||
else if(count) return count;
|
||||
else if((flags & AFT_CANON_CHOICE) == 0)
|
||||
return -1;
|
||||
else if(asn1f_fetch_minimal_choice_root_tag(arg,
|
||||
&tt, flags))
|
||||
return -1;
|
||||
}
|
||||
ADD_TAG(skip, tt);
|
||||
|
@ -55,6 +62,7 @@ asn1f_fetch_tags_impl(arg_t *arg, struct asn1p_type_tag_s **tags, int count, int
|
|||
|
||||
if(expr->meta_type == AMT_TYPEREF) {
|
||||
asn1p_expr_t *nexpr;
|
||||
DEBUG("Following the reference %s", expr->Identifier);
|
||||
nexpr = asn1f_lookup_symbol(arg, expr->module, expr->reference);
|
||||
if(nexpr == NULL) {
|
||||
if(errno != EEXIST) /* -fknown-extern-type */
|
||||
|
@ -87,18 +95,52 @@ asn1f_fetch_tags_impl(arg_t *arg, struct asn1p_type_tag_s **tags, int count, int
|
|||
return count;
|
||||
}
|
||||
|
||||
DEBUG("No tags discovered for type %d", expr->expr_type);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
asn1f_fetch_minimal_choice_root_tag(arg_t *arg, struct asn1p_type_tag_s *tag, enum asn1f_aft_flags_e flags) {
|
||||
struct asn1p_type_tag_s min_tag;
|
||||
asn1p_expr_t *v;
|
||||
|
||||
memset(&min_tag, 0, sizeof(min_tag));
|
||||
min_tag.tag_class = TC_PRIVATE + 1;
|
||||
|
||||
TQ_FOR(v, &(arg->expr->members), next) {
|
||||
arg_t tmparg = *arg;
|
||||
struct asn1p_type_tag_s *tags = 0;
|
||||
int count;
|
||||
|
||||
if(v->expr_type == A1TC_EXTENSIBLE)
|
||||
break; /* Search only within extension root */
|
||||
|
||||
tmparg.expr = v;
|
||||
count = asn1f_fetch_tags_impl(&tmparg, &tags, 0, 0, flags);
|
||||
if(count <= 0) continue;
|
||||
|
||||
if(tags[0].tag_class < min_tag.tag_class)
|
||||
min_tag = tags[0];
|
||||
else if(tags[0].tag_class == min_tag.tag_class
|
||||
&& tags[0].tag_value < min_tag.tag_value)
|
||||
min_tag = tags[0];
|
||||
free(tags);
|
||||
}
|
||||
|
||||
if(min_tag.tag_class == TC_PRIVATE + 1)
|
||||
return -1;
|
||||
else
|
||||
*tag = min_tag;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
asn1f_fetch_outmost_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag, int _aft_imaginary_any) {
|
||||
asn1f_fetch_outmost_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag, enum asn1f_aft_flags_e flags) {
|
||||
struct asn1p_type_tag_s *tags;
|
||||
enum asn1f_aft_flags_e flags;
|
||||
int count;
|
||||
|
||||
flags = AFT_FETCH_OUTMOST;
|
||||
flags |= AFT_IMAGINARY_ANY * _aft_imaginary_any;
|
||||
flags |= AFT_FETCH_OUTMOST;
|
||||
|
||||
count = asn1f_fetch_tags(asn, mod, expr, &tags, flags);
|
||||
if(count <= 0) return count;
|
||||
|
|
|
@ -5,6 +5,7 @@ enum asn1f_aft_flags_e {
|
|||
AFT_IMAGINARY_ANY = 0x01, /* Treat ANY tag as [IMAGINARY ANY] */
|
||||
AFT_FETCH_OUTMOST = 0x02, /* Fetch only outmost tag */
|
||||
AFT_FULL_COLLECT = 0x04, /* Collect all tags */
|
||||
AFT_CANON_CHOICE = 0x08, /* Fetch the minimal CHOICE root tag */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -24,6 +25,6 @@ int asn1f_fetch_tags(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr,
|
|||
* Type3 ::= SEQUENCE { ... }
|
||||
* Will yield [2] for Type1.
|
||||
*/
|
||||
int asn1f_fetch_outmost_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag, int _aft_imaginary_any);
|
||||
int asn1f_fetch_outmost_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag, enum asn1f_aft_flags_e);
|
||||
|
||||
#endif /* _ASN1FIX_TAGS_H_ */
|
||||
|
|
|
@ -21,8 +21,10 @@ asn_TYPE_descriptor_t asn_DEF_ANY = {
|
|||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_hex,
|
||||
ANY_encode_xer,
|
||||
0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
0, 0, 0, 0,
|
||||
0, /* No PER visible constraints */
|
||||
0, 0, /* No members */
|
||||
&asn_DEF_ANY_specs,
|
||||
};
|
||||
|
|
|
@ -27,6 +27,7 @@ asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
|
|||
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
|
||||
OCTET_STRING_decode_xer_binary,
|
||||
BIT_STRING_encode_xer,
|
||||
OCTET_STRING_decode_uper, /* Unaligned PER decoder */
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_BIT_STRING_tags,
|
||||
sizeof(asn_DEF_BIT_STRING_tags)
|
||||
|
@ -34,6 +35,7 @@ asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
|
|||
asn_DEF_BIT_STRING_tags, /* Same as above */
|
||||
sizeof(asn_DEF_BIT_STRING_tags)
|
||||
/ sizeof(asn_DEF_BIT_STRING_tags[0]),
|
||||
0, /* No PER visible constraints */
|
||||
0, 0, /* No members */
|
||||
&asn_DEF_BIT_STRING_specs
|
||||
};
|
||||
|
@ -124,9 +126,7 @@ BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
|||
|
||||
if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
|
||||
|
||||
er.structure_ptr = 0;
|
||||
er.failed_type = 0;
|
||||
return er;
|
||||
_ASN_ENCODED_OK(er);
|
||||
cb_failed:
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ asn_TYPE_descriptor_t asn_DEF_BMPString = {
|
|||
OCTET_STRING_encode_der,
|
||||
BMPString_decode_xer, /* Convert from UTF-8 */
|
||||
BMPString_encode_xer, /* Convert to UTF-8 */
|
||||
0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_BMPString_tags,
|
||||
sizeof(asn_DEF_BMPString_tags)
|
||||
|
@ -30,6 +31,7 @@ asn_TYPE_descriptor_t asn_DEF_BMPString = {
|
|||
asn_DEF_BMPString_tags,
|
||||
sizeof(asn_DEF_BMPString_tags)
|
||||
/ sizeof(asn_DEF_BMPString_tags[0]),
|
||||
0, /* No PER visible constraints */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
@ -156,7 +158,7 @@ BMPString_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
|||
er.encoded = BMPString__dump(st, cb, app_key);
|
||||
if(er.encoded < 0) _ASN_ENCODE_FAILED;
|
||||
|
||||
return er;
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
|
@ -22,11 +22,13 @@ asn_TYPE_descriptor_t asn_DEF_BOOLEAN = {
|
|||
BOOLEAN_encode_der,
|
||||
BOOLEAN_decode_xer,
|
||||
BOOLEAN_encode_xer,
|
||||
BOOLEAN_decode_uper, /* Unaligned PER decoder */
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_BOOLEAN_tags,
|
||||
sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]),
|
||||
asn_DEF_BOOLEAN_tags, /* Same as above */
|
||||
sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]),
|
||||
0, /* No PER visible constraints */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
@ -126,7 +128,7 @@ BOOLEAN_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
|
|||
|
||||
erval.encoded += 1;
|
||||
|
||||
return erval;
|
||||
_ASN_ENCODED_OK(erval);
|
||||
}
|
||||
|
||||
|
||||
|
@ -196,7 +198,7 @@ BOOLEAN_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
|||
er.encoded = 8;
|
||||
}
|
||||
|
||||
return er;
|
||||
_ASN_ENCODED_OK(er);
|
||||
cb_failed:
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
|
@ -234,3 +236,33 @@ BOOLEAN_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
|||
}
|
||||
}
|
||||
|
||||
asn_dec_rval_t
|
||||
BOOLEAN_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
|
||||
asn_dec_rval_t rv;
|
||||
BOOLEAN_t *st = (BOOLEAN_t *)*sptr;
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
(void)constraints;
|
||||
|
||||
if(!st) {
|
||||
st = (BOOLEAN_t *)(*sptr = MALLOC(sizeof(*st)));
|
||||
if(!st) _ASN_DECODE_FAILED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract a single bit
|
||||
*/
|
||||
switch(per_get_few_bits(pd, 1)) {
|
||||
case 1: *st = 1; break;
|
||||
case 0: *st = 0; break;
|
||||
case -1: default: _ASN_DECODE_FAILED;
|
||||
}
|
||||
|
||||
ASN_DEBUG("%s decoded as %s", td->name, *st ? "TRUE" : "FALSE");
|
||||
|
||||
rv.code = RC_OK;
|
||||
rv.consumed = 1;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ ber_type_decoder_f BOOLEAN_decode_ber;
|
|||
der_type_encoder_f BOOLEAN_encode_der;
|
||||
xer_type_decoder_f BOOLEAN_decode_xer;
|
||||
xer_type_encoder_f BOOLEAN_encode_xer;
|
||||
per_type_decoder_f BOOLEAN_decode_uper;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
/*-
|
||||
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
#include <ENUMERATED.h>
|
||||
#include <NativeEnumerated.h>
|
||||
#include <asn_codecs_prim.h> /* Encoder and decoder of a primitive type */
|
||||
|
||||
/*
|
||||
|
@ -22,12 +23,33 @@ asn_TYPE_descriptor_t asn_DEF_ENUMERATED = {
|
|||
INTEGER_encode_der, /* Implemented in terms of INTEGER */
|
||||
INTEGER_decode_xer, /* This is temporary! */
|
||||
INTEGER_encode_xer,
|
||||
ENUMERATED_decode_uper, /* Unaligned PER decoder */
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_ENUMERATED_tags,
|
||||
sizeof(asn_DEF_ENUMERATED_tags) / sizeof(asn_DEF_ENUMERATED_tags[0]),
|
||||
asn_DEF_ENUMERATED_tags, /* Same as above */
|
||||
sizeof(asn_DEF_ENUMERATED_tags) / sizeof(asn_DEF_ENUMERATED_tags[0]),
|
||||
0, /* No PER visible constraints */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
asn_dec_rval_t
|
||||
ENUMERATED_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
|
||||
asn_dec_rval_t rval;
|
||||
ENUMERATED_t *st = (ENUMERATED_t *)*sptr;
|
||||
long value, *vptr = &value;
|
||||
|
||||
if(!st) {
|
||||
st = (ENUMERATED_t *)(*sptr = CALLOC(1, sizeof(*st)));
|
||||
if(!st) _ASN_DECODE_FAILED;
|
||||
}
|
||||
|
||||
rval = NativeEnumerated_decode_uper(opt_codec_ctx, td, constraints,
|
||||
(void **)&vptr, pd);
|
||||
if(rval.code == RC_OK)
|
||||
if(asn_long2INTEGER(st, value))
|
||||
rval.code = RC_FAIL;
|
||||
return rval;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#ifndef _ENUMERATED_H_
|
||||
|
@ -15,6 +15,8 @@ typedef INTEGER_t ENUMERATED_t; /* Implemented via INTEGER */
|
|||
|
||||
extern asn_TYPE_descriptor_t asn_DEF_ENUMERATED;
|
||||
|
||||
per_type_decoder_f ENUMERATED_decode_uper;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_GeneralString = {
|
|||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_hex,
|
||||
OCTET_STRING_encode_xer,
|
||||
0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_GeneralString_tags,
|
||||
sizeof(asn_DEF_GeneralString_tags)
|
||||
|
@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_GeneralString = {
|
|||
asn_DEF_GeneralString_tags,
|
||||
sizeof(asn_DEF_GeneralString_tags)
|
||||
/ sizeof(asn_DEF_GeneralString_tags[0]),
|
||||
0, /* No PER visible constraints */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
|
|
@ -128,6 +128,7 @@ asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = {
|
|||
GeneralizedTime_encode_der,
|
||||
OCTET_STRING_decode_xer_utf8,
|
||||
GeneralizedTime_encode_xer,
|
||||
0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_GeneralizedTime_tags,
|
||||
sizeof(asn_DEF_GeneralizedTime_tags)
|
||||
|
@ -135,6 +136,7 @@ asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = {
|
|||
asn_DEF_GeneralizedTime_tags,
|
||||
sizeof(asn_DEF_GeneralizedTime_tags)
|
||||
/ sizeof(asn_DEF_GeneralizedTime_tags[0]),
|
||||
0, /* No PER visible constraints */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
|
|
@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_GraphicString = {
|
|||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_hex,
|
||||
OCTET_STRING_encode_xer, /* Can't expect it to be ASCII/UTF8 */
|
||||
0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_GraphicString_tags,
|
||||
sizeof(asn_DEF_GraphicString_tags)
|
||||
|
@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_GraphicString = {
|
|||
asn_DEF_GraphicString_tags,
|
||||
sizeof(asn_DEF_GraphicString_tags)
|
||||
/ sizeof(asn_DEF_GraphicString_tags[0]),
|
||||
0, /* No PER visible constraints */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
|
|
@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_IA5String = {
|
|||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_utf8,
|
||||
OCTET_STRING_encode_xer_utf8,
|
||||
0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_IA5String_tags,
|
||||
sizeof(asn_DEF_IA5String_tags)
|
||||
|
@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_IA5String = {
|
|||
asn_DEF_IA5String_tags,
|
||||
sizeof(asn_DEF_IA5String_tags)
|
||||
/ sizeof(asn_DEF_IA5String_tags[0]),
|
||||
0, /* No PER visible constraints */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
|
|
@ -24,11 +24,13 @@ asn_TYPE_descriptor_t asn_DEF_INTEGER = {
|
|||
INTEGER_encode_der,
|
||||
INTEGER_decode_xer,
|
||||
INTEGER_encode_xer,
|
||||
INTEGER_decode_uper, /* Unaligned PER decoder */
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_INTEGER_tags,
|
||||
sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]),
|
||||
asn_DEF_INTEGER_tags, /* Same as above */
|
||||
sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]),
|
||||
0, /* No PER visible constraints */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
@ -430,9 +432,102 @@ INTEGER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
|||
er.encoded = INTEGER__dump(td, st, cb, app_key, 1);
|
||||
if(er.encoded < 0) _ASN_ENCODE_FAILED;
|
||||
|
||||
er.structure_ptr = 0;
|
||||
er.failed_type = 0;
|
||||
return er;
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
|
||||
asn_dec_rval_t
|
||||
INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
|
||||
asn_dec_rval_t rval = { RC_OK, 0 };
|
||||
INTEGER_t *st = (INTEGER_t *)*sptr;
|
||||
asn_per_constraint_t *ct;
|
||||
int repeat;
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
|
||||
if(!st) {
|
||||
st = (INTEGER_t *)(*sptr = CALLOC(1, sizeof(*st)));
|
||||
if(!st) _ASN_DECODE_FAILED;
|
||||
}
|
||||
|
||||
if(!constraints) constraints = td->per_constraints;
|
||||
ct = constraints ? &constraints->value : 0;
|
||||
|
||||
if(ct && ct->flags & APC_EXTENSIBLE) {
|
||||
int inext = per_get_few_bits(pd, 1);
|
||||
if(inext < 0) _ASN_DECODE_FAILED;
|
||||
if(inext) ct = 0;
|
||||
}
|
||||
|
||||
FREEMEM(st->buf);
|
||||
if(ct) {
|
||||
if(ct->flags & APC_SEMI_CONSTRAINED) {
|
||||
st->buf = (uint8_t *)CALLOC(1, 2);
|
||||
if(!st->buf) _ASN_DECODE_FAILED;
|
||||
st->size = 1;
|
||||
} else if(ct->flags & APC_CONSTRAINED && ct->range_bits >= 0) {
|
||||
size_t size = (ct->range_bits + 7) >> 3;
|
||||
st->buf = (uint8_t *)MALLOC(1 + size + 1);
|
||||
if(!st->buf) _ASN_DECODE_FAILED;
|
||||
st->size = size;
|
||||
} else {
|
||||
st->size = 0;
|
||||
}
|
||||
} else {
|
||||
st->size = 0;
|
||||
}
|
||||
|
||||
/* X.691, #12.2.2 */
|
||||
if(ct && ct->flags != APC_UNCONSTRAINED) {
|
||||
/* #10.5.6 */
|
||||
ASN_DEBUG("Integer with range %d bits", ct->range_bits);
|
||||
if(ct->range_bits >= 0) {
|
||||
long value = per_get_few_bits(pd, ct->range_bits);
|
||||
if(value < 0) _ASN_DECODE_FAILED;
|
||||
ASN_DEBUG("Got value %ld + low %ld",
|
||||
value, ct->lower_bound);
|
||||
value += ct->lower_bound;
|
||||
if(asn_long2INTEGER(st, value))
|
||||
_ASN_DECODE_FAILED;
|
||||
return rval;
|
||||
}
|
||||
} else {
|
||||
ASN_DEBUG("Decoding unconstrained integer %s", td->name);
|
||||
}
|
||||
|
||||
/* X.691, #12.2.3, #12.2.4 */
|
||||
do {
|
||||
ssize_t len;
|
||||
void *p;
|
||||
int ret;
|
||||
|
||||
/* Get the PER length */
|
||||
len = uper_get_length(pd, -1, &repeat);
|
||||
if(len < 0) _ASN_DECODE_FAILED;
|
||||
|
||||
p = REALLOC(st->buf, st->size + len + 1);
|
||||
if(!p) _ASN_DECODE_FAILED;
|
||||
st->buf = (uint8_t *)p;
|
||||
|
||||
ret = per_get_many_bits(pd, &st->buf[st->size], 0, 8 * len);
|
||||
if(ret < 0) _ASN_DECODE_FAILED;
|
||||
st->size += len;
|
||||
} while(repeat);
|
||||
st->buf[st->size] = 0; /* JIC */
|
||||
|
||||
/* #12.2.3 */
|
||||
if(ct && ct->lower_bound) {
|
||||
/*
|
||||
* TODO: replace by in-place arithmetics.
|
||||
*/
|
||||
long value;
|
||||
if(asn_INTEGER2long(st, &value))
|
||||
_ASN_DECODE_FAILED;
|
||||
if(asn_long2INTEGER(st, value + ct->lower_bound))
|
||||
_ASN_DECODE_FAILED;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -28,7 +28,7 @@ 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 extension; /* This map is extensible */
|
||||
int strict_enumeration; /* Enumeration set is fixed */
|
||||
} asn_INTEGER_specifics_t;
|
||||
|
||||
|
@ -37,6 +37,7 @@ ber_type_decoder_f INTEGER_decode_ber;
|
|||
der_type_encoder_f INTEGER_encode_der;
|
||||
xer_type_decoder_f INTEGER_decode_xer;
|
||||
xer_type_encoder_f INTEGER_encode_xer;
|
||||
per_type_decoder_f INTEGER_decode_uper;
|
||||
|
||||
/***********************************
|
||||
* Some handy conversion routines. *
|
||||
|
|
|
@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_ISO646String = {
|
|||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_utf8,
|
||||
OCTET_STRING_encode_xer_utf8,
|
||||
0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_ISO646String_tags,
|
||||
sizeof(asn_DEF_ISO646String_tags)
|
||||
|
@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_ISO646String = {
|
|||
asn_DEF_ISO646String_tags,
|
||||
sizeof(asn_DEF_ISO646String_tags)
|
||||
/ sizeof(asn_DEF_ISO646String_tags[0]),
|
||||
0, /* No PER visible constraints */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
|
@ -23,11 +23,13 @@ asn_TYPE_descriptor_t asn_DEF_NULL = {
|
|||
NULL_encode_der, /* Special handling of DER encoding */
|
||||
NULL_decode_xer,
|
||||
NULL_encode_xer,
|
||||
NULL_decode_uper, /* Unaligned PER decoder */
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_NULL_tags,
|
||||
sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]),
|
||||
asn_DEF_NULL_tags, /* Same as above */
|
||||
sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]),
|
||||
0, /* No PER visible constraints */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
@ -44,7 +46,7 @@ NULL_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
|
|||
erval.structure_ptr = ptr;
|
||||
}
|
||||
|
||||
return erval;
|
||||
_ASN_ENCODED_OK(erval);
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
|
@ -62,8 +64,7 @@ NULL_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
|||
|
||||
/* XMLNullValue is empty */
|
||||
er.encoded = 0;
|
||||
|
||||
return er;
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
|
||||
|
||||
|
@ -101,3 +102,31 @@ NULL_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
|||
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
asn_dec_rval_t
|
||||
NULL_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
|
||||
asn_dec_rval_t rv;
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
(void)td;
|
||||
(void)constraints;
|
||||
(void)pd;
|
||||
|
||||
if(!*sptr) {
|
||||
*sptr = MALLOC(sizeof(NULL_t));
|
||||
if(*sptr) {
|
||||
*(NULL_t *)*sptr = 0;
|
||||
} else {
|
||||
_ASN_DECODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* NULL type does not have content octets.
|
||||
*/
|
||||
|
||||
rv.code = RC_OK;
|
||||
rv.consumed = 0;
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ asn_struct_print_f NULL_print;
|
|||
der_type_encoder_f NULL_encode_der;
|
||||
xer_type_decoder_f NULL_decode_xer;
|
||||
xer_type_encoder_f NULL_encode_xer;
|
||||
per_type_decoder_f NULL_decode_uper;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -28,11 +28,13 @@ asn_TYPE_descriptor_t asn_DEF_NativeEnumerated = {
|
|||
NativeInteger_encode_der,
|
||||
NativeInteger_decode_xer,
|
||||
NativeEnumerated_encode_xer,
|
||||
NativeEnumerated_decode_uper,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_NativeEnumerated_tags,
|
||||
sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
|
||||
asn_DEF_NativeEnumerated_tags, /* Same as above */
|
||||
sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
|
||||
0, /* No PER visible constraints */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
@ -59,13 +61,65 @@ NativeEnumerated_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
|||
er.encoded = snprintf(src, srcsize, "<%s/>", el->enum_name);
|
||||
assert(er.encoded > 0 && (size_t)er.encoded < srcsize);
|
||||
if(cb(src, er.encoded, app_key) < 0) _ASN_ENCODE_FAILED;
|
||||
return er;
|
||||
_ASN_ENCODED_OK(er);
|
||||
} else {
|
||||
ASN_DEBUG("ASN.1 forbids dealing with "
|
||||
"unknown value of ENUMERATED type");
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
|
||||
return er;
|
||||
}
|
||||
|
||||
asn_dec_rval_t
|
||||
NativeEnumerated_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
|
||||
asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_dec_rval_t rval = { RC_OK, 0 };
|
||||
long *native = (long *)*sptr;
|
||||
asn_per_constraint_t *ct;
|
||||
long value;
|
||||
|
||||
(void)opt_codec_ctx;
|
||||
|
||||
if(constraints) ct = &constraints->value;
|
||||
else if(td->per_constraints) ct = &td->per_constraints->value;
|
||||
else _ASN_DECODE_FAILED; /* Mandatory! */
|
||||
if(!specs) _ASN_DECODE_FAILED;
|
||||
|
||||
if(!native) {
|
||||
native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
|
||||
if(!native) _ASN_DECODE_FAILED;
|
||||
}
|
||||
|
||||
ASN_DEBUG("Decoding %s as NativeEnumerated", td->name);
|
||||
|
||||
if(ct->flags & APC_EXTENSIBLE) {
|
||||
int inext = per_get_few_bits(pd, 1);
|
||||
if(inext < 0) _ASN_DECODE_FAILED;
|
||||
if(inext) ct = 0;
|
||||
}
|
||||
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
value = per_get_few_bits(pd, ct->range_bits);
|
||||
if(value < 0) _ASN_DECODE_FAILED;
|
||||
if(value >= (specs->extension
|
||||
? specs->extension - 1 : specs->map_count))
|
||||
_ASN_DECODE_FAILED;
|
||||
} else {
|
||||
if(!specs->extension)
|
||||
_ASN_DECODE_FAILED;
|
||||
/*
|
||||
* X.691, #10.6: normally small non-negative whole number;
|
||||
*/
|
||||
value = uper_get_nsnnwn(pd);
|
||||
if(value < 0) _ASN_DECODE_FAILED;
|
||||
value += specs->extension - 1;
|
||||
if(value >= specs->map_count)
|
||||
_ASN_DECODE_FAILED;
|
||||
}
|
||||
|
||||
*native = specs->value2enum[value].nat_value;
|
||||
ASN_DEBUG("Decoded %s = %ld", td->name, *native);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ extern "C" {
|
|||
extern asn_TYPE_descriptor_t asn_DEF_NativeEnumerated;
|
||||
|
||||
xer_type_encoder_f NativeEnumerated_encode_xer;
|
||||
per_type_decoder_f NativeEnumerated_decode_uper;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -28,11 +28,13 @@ asn_TYPE_descriptor_t asn_DEF_NativeInteger = {
|
|||
NativeInteger_encode_der,
|
||||
NativeInteger_decode_xer,
|
||||
NativeInteger_encode_xer,
|
||||
NativeInteger_decode_uper, /* Unaligned PER decoder */
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_NativeInteger_tags,
|
||||
sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
|
||||
asn_DEF_NativeInteger_tags, /* Same as above */
|
||||
sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
|
||||
0, /* No PER visible constraints */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
@ -108,18 +110,6 @@ NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
|
|||
}
|
||||
|
||||
*native = l;
|
||||
|
||||
/*
|
||||
* Note that native integer size might be other than long.
|
||||
* This expression hopefully will be optimized away
|
||||
* by compiler.
|
||||
*/
|
||||
if(sizeof(*native) != sizeof(long) && ((long)*native != l)) {
|
||||
*native = 0; /* Safe value */
|
||||
rval.code = RC_FAIL;
|
||||
rval.consumed = 0;
|
||||
return rval;
|
||||
}
|
||||
}
|
||||
|
||||
rval.code = RC_OK;
|
||||
|
@ -176,38 +166,25 @@ NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
|
|||
asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname,
|
||||
const void *buf_ptr, size_t size) {
|
||||
asn_dec_rval_t rval;
|
||||
INTEGER_t *st = 0;
|
||||
INTEGER_t st;
|
||||
void *st_ptr = (void *)&st;
|
||||
long *native = (long *)*sptr;
|
||||
|
||||
if(!native) {
|
||||
*sptr = CALLOC(1, sizeof(int));
|
||||
native = (long *)*sptr;
|
||||
if(!native) {
|
||||
rval.code = RC_FAIL;
|
||||
rval.consumed = 0;
|
||||
return rval;
|
||||
}
|
||||
native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
|
||||
if(!native) _ASN_DECODE_FAILED;
|
||||
}
|
||||
|
||||
rval = INTEGER_decode_xer(opt_codec_ctx, td, (void **)st_ptr,
|
||||
memset(&st, 0, sizeof(st));
|
||||
rval = INTEGER_decode_xer(opt_codec_ctx, td, &st_ptr,
|
||||
opt_mname, buf_ptr, size);
|
||||
if(rval.code == RC_OK) {
|
||||
long l;
|
||||
if(asn_INTEGER2long(st, &l)) {
|
||||
if(asn_INTEGER2long(&st, &l)) {
|
||||
rval.code = RC_FAIL;
|
||||
rval.consumed = 0;
|
||||
} else {
|
||||
*native = l;
|
||||
|
||||
/* Native type might be shorter than long */
|
||||
if(sizeof(*native) != sizeof(long)
|
||||
&& ((long)*native != l)) {
|
||||
*native = 0; /* Safe value */
|
||||
rval.code = RC_FAIL;
|
||||
rval.consumed = 0;
|
||||
return rval;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
|
@ -217,7 +194,7 @@ NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
|
|||
*/
|
||||
rval.consumed = 0;
|
||||
}
|
||||
asn_DEF_INTEGER.free_struct(&asn_DEF_INTEGER, st, 0);
|
||||
asn_DEF_INTEGER.free_struct(&asn_DEF_INTEGER, &st, 1);
|
||||
return rval;
|
||||
}
|
||||
|
||||
|