diff options
62 files changed, 1752 insertions, 348 deletions
@@ -1,7 +1,12 @@ -0.9.22: 2006-Sep-22 +0.9.22: 2006-Oct-08 * Added -pdu=all and -pdu=<type> switches to asn1c. + * Added PER support for most known-multiplier string types: + IA5String, VisibleString, PrintableString; + useful types: GeneralizedTime, UTCTime, ObjectDescriptor; + as well as REAL and OBJECT IDENTIFIER. + TODO: SET, UniversalString and BMPString. 0.9.21: 2006-Sep-17 diff --git a/asn1c/tests/Makefile.am b/asn1c/tests/Makefile.am index 16e78886..85b0856c 100644 --- a/asn1c/tests/Makefile.am +++ b/asn1c/tests/Makefile.am @@ -11,7 +11,8 @@ EXTRA_DIST = \ $(check_SCRIPTS) \ check-*.c* \ data-62 \ - data-70 + data-70 \ + data-119 dist-hook: rm -rf `find $(distdir) -name CVS -or -name .cvsignore` diff --git a/asn1c/tests/Makefile.in b/asn1c/tests/Makefile.in index 829a42f9..c264d27d 100644 --- a/asn1c/tests/Makefile.in +++ b/asn1c/tests/Makefile.in @@ -165,7 +165,8 @@ EXTRA_DIST = \ $(check_SCRIPTS) \ check-*.c* \ data-62 \ - data-70 + data-70 \ + data-119 all: all-am diff --git a/asn1c/tests/check-119.-fnative-types.-gen-PER.c b/asn1c/tests/check-119.-fnative-types.-gen-PER.c new file mode 100644 index 00000000..ca881615 --- /dev/null +++ b/asn1c/tests/check-119.-fnative-types.-gen-PER.c @@ -0,0 +1,363 @@ +/* + * Mode of operation: + * Each of the *.in files is XER-decoded, then converted into DER, + * then decoded from DER and encoded into XER again. The resulting + * stream is compared with the corresponding .out file. + */ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <unistd.h> /* for chdir(2) */ +#include <string.h> +#include <dirent.h> +#include <assert.h> +#include <ctype.h> +#include <errno.h> + +#include <PDU.h> + +enum expectation { + EXP_OK, /* Encoding/decoding must succeed */ + EXP_CXER_EXACT, /* Encoding/decoding using CXER must be exact */ + EXP_CXER_DIFF, /* Encoding/decoding using CXER must be different */ + EXP_BROKEN, /* Decoding must fail */ + EXP_DIFFERENT, /* Reconstruction will yield different encoding */ + EXP_PER_NOCOMP, /* Not PER compatible */ +}; + +static unsigned char buf[4096]; +static int buf_offset; + +static int +_buf_writer(const void *buffer, size_t size, void *app_key) { + unsigned char *b, *bend; + (void)app_key; + assert(buf_offset + size < sizeof(buf)); + memcpy(buf + buf_offset, buffer, size); + b = buf + buf_offset; + bend = b + size; + fprintf(stderr, "=> ["); + 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; +} + +enum enctype { + AS_PER, + AS_DER, + AS_XER, + AS_CXER, +}; + +static void +save_object_as(PDU_t *st, enum expectation exp, enum enctype how) { + asn_enc_rval_t rval; /* Return value */ + + buf_offset = 0; + + /* + * Save object using specified method. + */ + switch(how) { + case AS_PER: + rval = uper_encode(&asn_DEF_PDU, st, + _buf_writer, 0); + if(exp == EXP_PER_NOCOMP) + assert(rval.encoded == -1); + else + assert(rval.encoded > 0); + fprintf(stderr, "SAVED OBJECT IN SIZE %d\n", buf_offset); + return; + case AS_DER: + rval = der_encode(&asn_DEF_PDU, st, + _buf_writer, 0); + break; + case AS_XER: + rval = xer_encode(&asn_DEF_PDU, st, XER_F_BASIC, + _buf_writer, 0); + break; + case AS_CXER: + rval = xer_encode(&asn_DEF_PDU, st, XER_F_CANONICAL, + _buf_writer, 0); + break; + } + + if (rval.encoded == -1) { + fprintf(stderr, + "Cannot encode %s: %s\n", + rval.failed_type->name, strerror(errno)); + assert(rval.encoded != -1); + return; + } + + fprintf(stderr, "SAVED OBJECT IN SIZE %d\n", buf_offset); +} + +static PDU_t * +load_object_from(const char *fname, enum expectation expectation, char *fbuf, int size, enum enctype how) { + asn_dec_rval_t rval; + PDU_t *st = 0; + int csize = 1; + + if(getenv("INITIAL_CHUNK_SIZE")) + csize = atoi(getenv("INITIAL_CHUNK_SIZE")); + + /* Perform multiple iterations with multiple chunks sizes */ + for(; csize < 20; csize += 1) { + int fbuf_offset = 0; + int fbuf_left = size; + int fbuf_chunk = csize; + + fprintf(stderr, "LOADING OBJECT OF SIZE %d FROM [%s] as %s," + " chunks %d\n", + size, fname, how==AS_PER?"PER":"XER", csize); + + if(st) asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); + st = 0; + + do { + fprintf(stderr, "Decoding bytes %d..%d (left %d)\n", + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left, + fbuf_left); + if(st) { + fprintf(stderr, "=== currently ===\n"); + asn_fprint(stderr, &asn_DEF_PDU, st); + fprintf(stderr, "=== end ===\n"); + } + switch(how) { + case AS_XER: + rval = xer_decode(0, &asn_DEF_PDU, (void **)&st, + fbuf + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left); + break; + case AS_PER: + rval = uper_decode(0, &asn_DEF_PDU, + (void **)&st, fbuf + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left, 0, 0); + if(rval.code == RC_WMORE) { + rval.consumed = 0; /* Not restartable */ + ASN_STRUCT_FREE(asn_DEF_PDU, st); + st = 0; + fprintf(stderr, "-> PER wants more\n"); + } else { + fprintf(stderr, "-> PER ret %d/%d\n", + rval.code, rval.consumed); + /* uper_decode() returns _bits_ */ + rval.consumed += 7; + rval.consumed /= 8; + } + break; + } + fbuf_offset += rval.consumed; + fbuf_left -= rval.consumed; + if(rval.code == RC_WMORE) + fbuf_chunk += 1; /* Give little more */ + else + fbuf_chunk = csize; /* Back off */ + } while(fbuf_left && rval.code == RC_WMORE); + + if(expectation != EXP_BROKEN) { + assert(rval.code == RC_OK); + if(how == AS_PER) { + fprintf(stderr, "[left %d, off %d, size %d]\n", + fbuf_left, fbuf_offset, size); + assert(fbuf_offset == size); + } else { + assert(fbuf_offset - size < 2 + || (fbuf_offset + 1 /* "\n" */ == size + && fbuf[size - 1] == '\n') + || (fbuf_offset + 2 /* "\r\n" */ == size + && fbuf[size - 2] == '\r' + && fbuf[size - 1] == '\n') + ); + } + } else { + assert(rval.code != RC_OK); + fprintf(stderr, "Failed, but this was expected\n"); + asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); + st = 0; /* ignore leak for now */ + } + } + + if(st) asn_fprint(stderr, &asn_DEF_PDU, st); + return st; +} + +static int +xer_encoding_equal(char *obuf, size_t osize, char *nbuf, size_t nsize) { + char *oend = obuf + osize; + char *nend = nbuf + nsize; + + if((osize && !nsize) || (!osize && nsize)) + return 0; /* not equal apriori */ + + while(1) { + while(obuf < oend && isspace(*obuf)) obuf++; + while(nbuf < nend && isspace(*nbuf)) nbuf++; + + if(obuf == oend || nbuf == nend) { + if(obuf == oend && nbuf == nend) + break; + fprintf(stderr, "%s data in reconstructed encoding\n", + (obuf == oend) ? "More" : "Less"); + return 0; + } + + if(*obuf != *nbuf) { + printf("%c%c != %c%c\n", + obuf[0], obuf[1], + nbuf[0], nbuf[1]); + return 0; + } + obuf++, nbuf++; + } + + return 1; +} + +static void +process_XER_data(const char *fname, enum expectation expectation, char *fbuf, int size) { + PDU_t *st; + int ret; + + st = load_object_from(fname, expectation, fbuf, size, AS_XER); + if(!st) return; + + /* Save and re-load as DER */ + save_object_as(st, expectation, AS_PER); + if(expectation == EXP_PER_NOCOMP) + return; /* Already checked */ + st = load_object_from("buffer", expectation, buf, buf_offset, AS_PER); + assert(st); + + save_object_as(st, + expectation, + (expectation == EXP_CXER_EXACT + || expectation == EXP_CXER_DIFF) + ? AS_CXER : AS_XER); + fprintf(stderr, "=== original ===\n"); + fwrite(fbuf, 1, size, stderr); + fprintf(stderr, "=== re-encoded ===\n"); + fwrite(buf, 1, buf_offset, stderr); + fprintf(stderr, "=== end ===\n"); + + switch(expectation) { + case EXP_DIFFERENT: + assert(!xer_encoding_equal(fbuf, size, buf, buf_offset)); + break; + case EXP_BROKEN: + assert(!xer_encoding_equal(fbuf, size, buf, buf_offset)); + break; + case EXP_CXER_EXACT: + buf[buf_offset++] = '\n'; + assert(size == buf_offset); + assert(memcmp(fbuf, buf, size) == 0); + break; + case EXP_CXER_DIFF: + buf[buf_offset++] = '\n'; + assert(size != buf_offset + || memcmp(fbuf, buf, size)); + break; + case EXP_OK: + case EXP_PER_NOCOMP: + assert(xer_encoding_equal(fbuf, size, buf, buf_offset)); + break; + } + + asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); +} + +/* + * Decode the .der files and try to regenerate them. + */ +static int +process(const char *fname) { + char fbuf[4096]; + char *ext = strrchr(fname, '.'); + enum expectation expectation; + int ret; + int rd; + FILE *fp; + + if(ext == 0 || strcmp(ext, ".in")) + return 0; + + switch(ext[-1]) { + case 'B': /* The file is intentionally broken */ + expectation = EXP_BROKEN; break; + case 'D': /* Reconstructing should yield different data */ + expectation = EXP_DIFFERENT; break; + case 'E': /* Byte to byte exact reconstruction */ + expectation = EXP_CXER_EXACT; break; + case 'X': /* Should fail byte-to-byte comparison */ + expectation = EXP_CXER_DIFF; break; + case 'P': /* Incompatible with PER */ + expectation = EXP_PER_NOCOMP; break; + default: + expectation = EXP_OK; break; + } + + fprintf(stderr, "\nProcessing file [../%s]\n", fname); + + ret = chdir("../data-119"); + assert(ret == 0); + fp = fopen(fname, "r"); + ret = chdir("../test-check-119.-gen-PER"); + assert(ret == 0); + assert(fp); + + rd = fread(fbuf, 1, sizeof(fbuf), fp); + fclose(fp); + + assert(rd < sizeof(fbuf)); /* expect small files */ + + process_XER_data(fname, expectation, fbuf, rd); + + fprintf(stderr, "Finished [%s]\n", fname); + + return 1; +} + +int +main() { + DIR *dir; + struct dirent *dent; + int processed_files = 0; + char *str; + + /* Process a specific test file */ + str = getenv("DATA_119_FILE"); + if(str && strncmp(str, "data-119-", 9) == 0) { + process(str); + return 0; + } + + dir = opendir("../data-119"); + assert(dir); + + /* + * Process each file in that directory. + */ + while((dent = readdir(dir))) { + if(strncmp(dent->d_name, "data-119-", 9) == 0) + if(process(dent->d_name)) + processed_files++; + } + + assert(processed_files); + closedir(dir); + + return 0; +} + diff --git a/asn1c/tests/check-119.-gen-PER.c b/asn1c/tests/check-119.-gen-PER.c new file mode 100644 index 00000000..ca881615 --- /dev/null +++ b/asn1c/tests/check-119.-gen-PER.c @@ -0,0 +1,363 @@ +/* + * Mode of operation: + * Each of the *.in files is XER-decoded, then converted into DER, + * then decoded from DER and encoded into XER again. The resulting + * stream is compared with the corresponding .out file. + */ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <unistd.h> /* for chdir(2) */ +#include <string.h> +#include <dirent.h> +#include <assert.h> +#include <ctype.h> +#include <errno.h> + +#include <PDU.h> + +enum expectation { + EXP_OK, /* Encoding/decoding must succeed */ + EXP_CXER_EXACT, /* Encoding/decoding using CXER must be exact */ + EXP_CXER_DIFF, /* Encoding/decoding using CXER must be different */ + EXP_BROKEN, /* Decoding must fail */ + EXP_DIFFERENT, /* Reconstruction will yield different encoding */ + EXP_PER_NOCOMP, /* Not PER compatible */ +}; + +static unsigned char buf[4096]; +static int buf_offset; + +static int +_buf_writer(const void *buffer, size_t size, void *app_key) { + unsigned char *b, *bend; + (void)app_key; + assert(buf_offset + size < sizeof(buf)); + memcpy(buf + buf_offset, buffer, size); + b = buf + buf_offset; + bend = b + size; + fprintf(stderr, "=> ["); + 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; +} + +enum enctype { + AS_PER, + AS_DER, + AS_XER, + AS_CXER, +}; + +static void +save_object_as(PDU_t *st, enum expectation exp, enum enctype how) { + asn_enc_rval_t rval; /* Return value */ + + buf_offset = 0; + + /* + * Save object using specified method. + */ + switch(how) { + case AS_PER: + rval = uper_encode(&asn_DEF_PDU, st, + _buf_writer, 0); + if(exp == EXP_PER_NOCOMP) + assert(rval.encoded == -1); + else + assert(rval.encoded > 0); + fprintf(stderr, "SAVED OBJECT IN SIZE %d\n", buf_offset); + return; + case AS_DER: + rval = der_encode(&asn_DEF_PDU, st, + _buf_writer, 0); + break; + case AS_XER: + rval = xer_encode(&asn_DEF_PDU, st, XER_F_BASIC, + _buf_writer, 0); + break; + case AS_CXER: + rval = xer_encode(&asn_DEF_PDU, st, XER_F_CANONICAL, + _buf_writer, 0); + break; + } + + if (rval.encoded == -1) { + fprintf(stderr, + "Cannot encode %s: %s\n", + rval.failed_type->name, strerror(errno)); + assert(rval.encoded != -1); + return; + } + + fprintf(stderr, "SAVED OBJECT IN SIZE %d\n", buf_offset); +} + +static PDU_t * +load_object_from(const char *fname, enum expectation expectation, char *fbuf, int size, enum enctype how) { + asn_dec_rval_t rval; + PDU_t *st = 0; + int csize = 1; + + if(getenv("INITIAL_CHUNK_SIZE")) + csize = atoi(getenv("INITIAL_CHUNK_SIZE")); + + /* Perform multiple iterations with multiple chunks sizes */ + for(; csize < 20; csize += 1) { + int fbuf_offset = 0; + int fbuf_left = size; + int fbuf_chunk = csize; + + fprintf(stderr, "LOADING OBJECT OF SIZE %d FROM [%s] as %s," + " chunks %d\n", + size, fname, how==AS_PER?"PER":"XER", csize); + + if(st) asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); + st = 0; + + do { + fprintf(stderr, "Decoding bytes %d..%d (left %d)\n", + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left, + fbuf_left); + if(st) { + fprintf(stderr, "=== currently ===\n"); + asn_fprint(stderr, &asn_DEF_PDU, st); + fprintf(stderr, "=== end ===\n"); + } + switch(how) { + case AS_XER: + rval = xer_decode(0, &asn_DEF_PDU, (void **)&st, + fbuf + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left); + break; + case AS_PER: + rval = uper_decode(0, &asn_DEF_PDU, + (void **)&st, fbuf + fbuf_offset, + fbuf_chunk < fbuf_left + ? fbuf_chunk : fbuf_left, 0, 0); + if(rval.code == RC_WMORE) { + rval.consumed = 0; /* Not restartable */ + ASN_STRUCT_FREE(asn_DEF_PDU, st); + st = 0; + fprintf(stderr, "-> PER wants more\n"); + } else { + fprintf(stderr, "-> PER ret %d/%d\n", + rval.code, rval.consumed); + /* uper_decode() returns _bits_ */ + rval.consumed += 7; + rval.consumed /= 8; + } + break; + } + fbuf_offset += rval.consumed; + fbuf_left -= rval.consumed; + if(rval.code == RC_WMORE) + fbuf_chunk += 1; /* Give little more */ + else + fbuf_chunk = csize; /* Back off */ + } while(fbuf_left && rval.code == RC_WMORE); + + if(expectation != EXP_BROKEN) { + assert(rval.code == RC_OK); + if(how == AS_PER) { + fprintf(stderr, "[left %d, off %d, size %d]\n", + fbuf_left, fbuf_offset, size); + assert(fbuf_offset == size); + } else { + assert(fbuf_offset - size < 2 + || (fbuf_offset + 1 /* "\n" */ == size + && fbuf[size - 1] == '\n') + || (fbuf_offset + 2 /* "\r\n" */ == size + && fbuf[size - 2] == '\r' + && fbuf[size - 1] == '\n') + ); + } + } else { + assert(rval.code != RC_OK); + fprintf(stderr, "Failed, but this was expected\n"); + asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); + st = 0; /* ignore leak for now */ + } + } + + if(st) asn_fprint(stderr, &asn_DEF_PDU, st); + return st; +} + +static int +xer_encoding_equal(char *obuf, size_t osize, char *nbuf, size_t nsize) { + char *oend = obuf + osize; + char *nend = nbuf + nsize; + + if((osize && !nsize) || (!osize && nsize)) + return 0; /* not equal apriori */ + + while(1) { + while(obuf < oend && isspace(*obuf)) obuf++; + while(nbuf < nend && isspace(*nbuf)) nbuf++; + + if(obuf == oend || nbuf == nend) { + if(obuf == oend && nbuf == nend) + break; + fprintf(stderr, "%s data in reconstructed encoding\n", + (obuf == oend) ? "More" : "Less"); + return 0; + } + + if(*obuf != *nbuf) { + printf("%c%c != %c%c\n", + obuf[0], obuf[1], + nbuf[0], nbuf[1]); + return 0; + } + obuf++, nbuf++; + } + + return 1; +} + +static void +process_XER_data(const char *fname, enum expectation expectation, char *fbuf, int size) { + PDU_t *st; + int ret; + + st = load_object_from(fname, expectation, fbuf, size, AS_XER); + if(!st) return; + + /* Save and re-load as DER */ + save_object_as(st, expectation, AS_PER); + if(expectation == EXP_PER_NOCOMP) + return; /* Already checked */ + st = load_object_from("buffer", expectation, buf, buf_offset, AS_PER); + assert(st); + + save_object_as(st, + expectation, + (expectation == EXP_CXER_EXACT + || expectation == EXP_CXER_DIFF) + ? AS_CXER : AS_XER); + fprintf(stderr, "=== original ===\n"); + fwrite(fbuf, 1, size, stderr); + fprintf(stderr, "=== re-encoded ===\n"); + fwrite(buf, 1, buf_offset, stderr); + fprintf(stderr, "=== end ===\n"); + + switch(expectation) { + case EXP_DIFFERENT: + assert(!xer_encoding_equal(fbuf, size, buf, buf_offset)); + break; + case EXP_BROKEN: + assert(!xer_encoding_equal(fbuf, size, buf, buf_offset)); + break; + case EXP_CXER_EXACT: + buf[buf_offset++] = '\n'; + assert(size == buf_offset); + assert(memcmp(fbuf, buf, size) == 0); + break; + case EXP_CXER_DIFF: + buf[buf_offset++] = '\n'; + assert(size != buf_offset + || memcmp(fbuf, buf, size)); + break; + case EXP_OK: + case EXP_PER_NOCOMP: + assert(xer_encoding_equal(fbuf, size, buf, buf_offset)); + break; + } + + asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); +} + +/* + * Decode the .der files and try to regenerate them. + */ +static int +process(const char *fname) { + char fbuf[4096]; + char *ext = strrchr(fname, '.'); + enum expectation expectation; + int ret; + int rd; + FILE *fp; + + if(ext == 0 || strcmp(ext, ".in")) + return 0; + + switch(ext[-1]) { + case 'B': /* The file is intentionally broken */ + expectation = EXP_BROKEN; break; + case 'D': /* Reconstructing should yield different data */ + expectation = EXP_DIFFERENT; break; + case 'E': /* Byte to byte exact reconstruction */ + expectation = EXP_CXER_EXACT; break; + case 'X': /* Should fail byte-to-byte comparison */ + expectation = EXP_CXER_DIFF; break; + case 'P': /* Incompatible with PER */ + expectation = EXP_PER_NOCOMP; break; + default: + expectation = EXP_OK; break; + } + + fprintf(stderr, "\nProcessing file [../%s]\n", fname); + + ret = chdir("../data-119"); + assert(ret == 0); + fp = fopen(fname, "r"); + ret = chdir("../test-check-119.-gen-PER"); + assert(ret == 0); + assert(fp); + + rd = fread(fbuf, 1, sizeof(fbuf), fp); + fclose(fp); + + assert(rd < sizeof(fbuf)); /* expect small files */ + + process_XER_data(fname, expectation, fbuf, rd); + + fprintf(stderr, "Finished [%s]\n", fname); + + return 1; +} + +int +main() { + DIR *dir; + struct dirent *dent; + int processed_files = 0; + char *str; + + /* Process a specific test file */ + str = getenv("DATA_119_FILE"); + if(str && strncmp(str, "data-119-", 9) == 0) { + process(str); + return 0; + } + + dir = opendir("../data-119"); + assert(dir); + + /* + * Process each file in that directory. + */ + while((dent = readdir(dir))) { + if(strncmp(dent->d_name, "data-119-", 9) == 0) + if(process(dent->d_name)) + processed_files++; + } + + assert(processed_files); + closedir(dir); + + return 0; +} + diff --git a/asn1c/tests/check-70.c b/asn1c/tests/check-70.c index 4b51065f..124c800f 100644 --- a/asn1c/tests/check-70.c +++ b/asn1c/tests/check-70.c @@ -40,7 +40,7 @@ _buf_writer(const void *buffer, size_t size, void *app_key) { if(*b >= 32 && *b < 127 && *b != '%') fprintf(stderr, "%c", *b); else - fprintf(stderr, "%%02x", *b); + fprintf(stderr, "%%%02x", *b); } fprintf(stderr, "]:%ld\n", (long)size); buf_offset += size; diff --git a/asn1c/tests/data-119/README b/asn1c/tests/data-119/README new file mode 100644 index 00000000..044f5b84 --- /dev/null +++ b/asn1c/tests/data-119/README @@ -0,0 +1,13 @@ +Mode of operation: + + Each of the *.in files is XER-decoded, then converted into PER, + then decoded back from PER, then encoded into XER again, + and finally compared to the original encoding. + +Naming conventions: + +*-B.in - The file is intentionally broken +*-P.in - Is not PER compatible, PER encoding must fail. +*-E.in - CXER reconstruction should yield byte-wise identical data. + +Otherwise, a reconstructed buffer should loosely match the original. diff --git a/asn1c/tests/data-119/data-119-01.in b/asn1c/tests/data-119/data-119-01.in new file mode 100644 index 00000000..47e83a00 --- /dev/null +++ b/asn1c/tests/data-119/data-119-01.in @@ -0,0 +1,3 @@ +<PDU> + <ns></ns> +</PDU> diff --git a/asn1c/tests/data-119/data-119-02.in b/asn1c/tests/data-119/data-119-02.in new file mode 100644 index 00000000..c7f53b4d --- /dev/null +++ b/asn1c/tests/data-119/data-119-02.in @@ -0,0 +1,3 @@ +<PDU> + <ns>0123456789</ns> +</PDU> diff --git a/asn1c/tests/data-119/data-119-03.in b/asn1c/tests/data-119/data-119-03.in new file mode 100644 index 00000000..f51836da --- /dev/null +++ b/asn1c/tests/data-119/data-119-03.in @@ -0,0 +1,3 @@ +<PDU> + <ns> </ns> +</PDU> diff --git a/asn1c/tests/data-119/data-119-04-P.in b/asn1c/tests/data-119/data-119-04-P.in new file mode 100644 index 00000000..df606c98 --- /dev/null +++ b/asn1c/tests/data-119/data-119-04-P.in @@ -0,0 +1,3 @@ +<PDU> + <ns>z</ns> +</PDU> diff --git a/asn1c/tests/data-119/data-119-05.in b/asn1c/tests/data-119/data-119-05.in new file mode 100644 index 00000000..632652d9 --- /dev/null +++ b/asn1c/tests/data-119/data-119-05.in @@ -0,0 +1,4 @@ +<PDU> + <ia5>yabloko</ia5> + <vs>yabloko</vs> +</PDU> diff --git a/asn1c/tests/data-119/data-119-06-P.in b/asn1c/tests/data-119/data-119-06-P.in new file mode 100644 index 00000000..6eddf52c --- /dev/null +++ b/asn1c/tests/data-119/data-119-06-P.in @@ -0,0 +1,3 @@ +<PDU> + <ia5>ÑÂÌÏËÏ</ia5> +</PDU> diff --git a/asn1c/tests/data-119/data-119-07-P.in b/asn1c/tests/data-119/data-119-07-P.in new file mode 100644 index 00000000..9f7ace88 --- /dev/null +++ b/asn1c/tests/data-119/data-119-07-P.in @@ -0,0 +1,3 @@ +<PDU> + <ia5-c>non-capitals</ia5-c> +</PDU> diff --git a/asn1c/tests/data-119/data-119-08.in b/asn1c/tests/data-119/data-119-08.in new file mode 100644 index 00000000..5916078e --- /dev/null +++ b/asn1c/tests/data-119/data-119-08.in @@ -0,0 +1,4 @@ +<PDU> + <ia5-c>CAPITALS</ia5-c> + <vs-c>CAPITALS</vs-c> +</PDU> diff --git a/asn1c/tests/data-119/data-119-09.in b/asn1c/tests/data-119/data-119-09.in new file mode 100644 index 00000000..b20ca47e --- /dev/null +++ b/asn1c/tests/data-119/data-119-09.in @@ -0,0 +1,8 @@ +<PDU> + <ia5></ia5> + <ia5-c></ia5-c> + <ia5-ce></ia5-ce> + <vs></vs> + <vs-c></vs-c> + <vs-ce></vs-ce> +</PDU> diff --git a/asn1c/tests/data-119/data-119-10.in b/asn1c/tests/data-119/data-119-10.in new file mode 100644 index 00000000..afe04b0f --- /dev/null +++ b/asn1c/tests/data-119/data-119-10.in @@ -0,0 +1,9 @@ +<PDU> + <ia5-ir>BAZ</ia5-ir> + <vs-ir>BAZ</vs-ir> + <pr-ir>BAZ</pr-ir> + <ns-ir>19</ns-ir> + <ut-c>Do not respect SIZE constraint</ut-c> + <ut-ce>Do not respect SIZE constraint</ut-ce> + <ut-ir>ABCabc</ut-ir> +</PDU> diff --git a/asn1c/tests/data-119/data-119-11-P.in b/asn1c/tests/data-119/data-119-11-P.in new file mode 100644 index 00000000..4a7d4d23 --- /dev/null +++ b/asn1c/tests/data-119/data-119-11-P.in @@ -0,0 +1,3 @@ +<PDU> + <ia5-ir>FAIL</ia5-ir> +</PDU> diff --git a/asn1c/tests/data-119/data-119-12-P.in b/asn1c/tests/data-119/data-119-12-P.in new file mode 100644 index 00000000..bd45e2e4 --- /dev/null +++ b/asn1c/tests/data-119/data-119-12-P.in @@ -0,0 +1,3 @@ +<PDU> + <vs-ir>FAIL</vs-ir> +</PDU> diff --git a/asn1c/tests/data-119/data-119-13-P.in b/asn1c/tests/data-119/data-119-13-P.in new file mode 100644 index 00000000..c2396c13 --- /dev/null +++ b/asn1c/tests/data-119/data-119-13-P.in @@ -0,0 +1,3 @@ +<PDU> + <pr-ir>FAIL</pr-ir> +</PDU> diff --git a/asn1c/tests/data-119/data-119-14-P.in b/asn1c/tests/data-119/data-119-14-P.in new file mode 100644 index 00000000..0f2d9ecc --- /dev/null +++ b/asn1c/tests/data-119/data-119-14-P.in @@ -0,0 +1,3 @@ +<PDU> + <ns-ir>13</ns-ir> +</PDU> diff --git a/asn1c/tests/data-119/data-119-15.in b/asn1c/tests/data-119/data-119-15.in new file mode 100644 index 00000000..296dc2d3 --- /dev/null +++ b/asn1c/tests/data-119/data-119-15.in @@ -0,0 +1,3 @@ +<PDU> + <ut-ir>ABCabc,12234</ut-ir> +</PDU> diff --git a/asn1c/tests/data-119/data-119-16.in b/asn1c/tests/data-119/data-119-16.in new file mode 100644 index 00000000..2a117faf --- /dev/null +++ b/asn1c/tests/data-119/data-119-16.in @@ -0,0 +1,3 @@ +<PDU> + <real>3.14159265</real> +</PDU> diff --git a/asn1c/tests/data-119/data-119-17.in b/asn1c/tests/data-119/data-119-17.in new file mode 100644 index 00000000..862efc13 --- /dev/null +++ b/asn1c/tests/data-119/data-119-17.in @@ -0,0 +1,3 @@ +<PDU> + <oid>1.3.6.1.4.1.9363.1.5.1</oid> +</PDU> diff --git a/asn1c/tests/data-70/README b/asn1c/tests/data-70/README index 91019add..64eca8b7 100644 --- a/asn1c/tests/data-70/README +++ b/asn1c/tests/data-70/README @@ -1,7 +1,7 @@ Mode of operation: - Each of the *.in files is XER-decoded, then converted into DER or PER, - then decoded back from DER (PER), then encoded into XER again, + Each of the *.in files is XER-decoded, then converted into DER, + then decoded back from DER, then encoded into XER again, and finally compared to the original encoding. Naming conventions: diff --git a/asn1c/unber.c b/asn1c/unber.c index 4edf18f0..69736988 100644 --- a/asn1c/unber.c +++ b/asn1c/unber.c @@ -768,4 +768,8 @@ ssize_t der_write_tags(asn_TYPE_descriptor_t *td, size_t slen, int tag_mode, int asn_dec_rval_t xer_decode_general(asn_codec_ctx_t *opt_codec_ctx, asn_struct_ctx_t *ctx, void *struct_key, const char *xml_tag, const void *buf_ptr, size_t size, int (*otd)(void *struct_key, const void *chunk_buf, size_t chunk_size), ssize_t (*br)(void *struct_key, const void *chunk_buf, size_t chunk_size, int have_more)) { asn_dec_rval_t rv = { 0, 0 }; (void)opt_codec_ctx; (void)ctx; (void)struct_key; (void)xml_tag; (void)buf_ptr; (void)size; (void)otd; (void)br; return rv; } +asn_dec_rval_t OCTET_STRING_decode_uper(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void **sptr, asn_per_data_t *pd) { asn_dec_rval_t rv = { 0, 0 }; (void)ctx; (void)td; (void)cts; (void)sptr; (void)pd; return rv; } + +asn_enc_rval_t OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void *sptr, asn_per_outp_t *po) { asn_enc_rval_t er = { 0, 0, 0 }; (void)td; (void)cts; (void)sptr; (void)po; return er; } + int xer_is_whitespace(const void *b, size_t s) { (void)b; (void)s; return 0; } diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c index 2acb5ea3..f7a6c89c 100644 --- a/libasn1compiler/asn1c_C.c +++ b/libasn1compiler/asn1c_C.c @@ -40,9 +40,8 @@ static int compute_extensions_start(asn1p_expr_t *expr); static int expr_break_recursion(arg_t *arg, asn1p_expr_t *expr); static int expr_as_xmlvaluelist(arg_t *arg, asn1p_expr_t *expr); static int expr_elements_count(arg_t *arg, asn1p_expr_t *expr); -static int emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, char *type); -static int emit_single_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr); -static int emit_members_PER_constraints(arg_t *arg); +static int emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, int juscountvalues, char *type); +static int emit_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr); static int emit_member_table(arg_t *arg, asn1p_expr_t *expr); static int emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count, const char *opt_modifier); static int emit_include_dependencies(arg_t *arg); @@ -340,8 +339,6 @@ asn1c_lang_C_type_SEQUENCE_def(arg_t *arg) { if(expr_elements_count(arg, expr)) { int comp_mode = 0; /* {root,ext=1,root,root,...} */ - if(emit_members_PER_constraints(arg)) - return -1; OUT("static asn_TYPE_member_t asn_MBR_%s_%d[] = {\n", MKID(expr), expr->_type_unique_index); @@ -580,8 +577,6 @@ asn1c_lang_C_type_SET_def(arg_t *arg) { if(expr_elements_count(arg, expr)) { int comp_mode = 0; /* {root,ext=1,root,root,...} */ - if(emit_members_PER_constraints(arg)) - return -1; OUT("static asn_TYPE_member_t asn_MBR_%s_%d[] = {\n", MKID(expr), expr->_type_unique_index); @@ -782,8 +777,6 @@ asn1c_lang_C_type_SEx_OF_def(arg_t *arg, int seq_of) { /* * Print out the table according to which parsing is performed. */ - if(emit_members_PER_constraints(arg)) - return -1; OUT("static asn_TYPE_member_t asn_MBR_%s_%d[] = {\n", MKID(expr), expr->_type_unique_index); INDENT(+1); @@ -932,8 +925,6 @@ asn1c_lang_C_type_CHOICE_def(arg_t *arg) { */ if(expr_elements_count(arg, expr)) { - if(emit_members_PER_constraints(arg)) - return -1; OUT("static asn_TYPE_member_t asn_MBR_%s_%d[] = {\n", MKID(expr), expr->_type_unique_index); @@ -1157,16 +1148,6 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { return 0; } - REDIR(OT_STAT_DEFS); - - /* - * Print out asn_DEF_<type>_[all_]tags[] vectors. - */ - tv_mode = emit_tags_vectors(arg, expr, &tags_count, &all_tags_count); - - emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count, - 0, etd_spec); - REDIR(OT_CODE); /* @@ -1182,6 +1163,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { INDENT(+1); OUT("\t\tasn_app_constraint_failed_f *ctfailcb, void *app_key) {"); OUT("\n"); + DEBUG("expr constraint checking code for %s", p); if(asn1c_emit_constraint_checking_code(arg) == 1) { OUT("/* Replace with underlying type checker */\n"); OUT("td->check_constraints " @@ -1195,6 +1177,20 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { OUT("\n"); } + REDIR(OT_STAT_DEFS); + + /* + * Print out asn_DEF_<type>_[all_]tags[] vectors. + */ + tv_mode = emit_tags_vectors(arg, expr, &tags_count, &all_tags_count); + DEBUG("emit tag vectors for %s %d, %d, %d", expr->Identifier, + tv_mode, tags_count, all_tags_count); + + emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count, + 0, etd_spec); + + REDIR(OT_CODE); + /* * Emit suicidal functions. */ @@ -1588,7 +1584,7 @@ _add_tag2el_member(arg_t *arg, tag2el_t **tag2el, int *count, int el_no, fte_e f if(p) *tag2el = p; else return -1; - DEBUG("Found tag for %s: %ld", + if(0) DEBUG("Found tag for %s: %ld", arg->expr->Identifier, (long)tag.tag_value); @@ -1678,14 +1674,17 @@ emit_tags_vectors(arg_t *arg, asn1p_expr_t *expr, int *tags_count_r, int *all_ta /* Fetch a chain of tags */ tags_count = asn1f_fetch_tags(arg->asn, expr->module, expr, &tags, 0); - if(tags_count < 0) + if(tags_count < 0) { + DEBUG("fail to fetch tags for %s", expr->Identifier); return -1; + } /* Fetch a chain of tags */ all_tags_count = asn1f_fetch_tags(arg->asn, expr->module, expr, &all_tags, AFT_FULL_COLLECT); if(all_tags_count < 0) { if(tags) free(tags); + DEBUG("fail to fetch tags chain for %s", expr->Identifier); return -1; } @@ -1772,8 +1771,24 @@ expr_get_type(arg_t *arg, asn1p_expr_t *expr) { return A1TC_INVALID; } +static asn1c_integer_t +PER_FROM_alphabet_characters(asn1cnst_range_t *range) { + asn1c_integer_t numchars = 0; + if(range->el_count) { + int i; + for(i = 0; i < range->el_count; i++) + numchars + += PER_FROM_alphabet_characters(range->elements[i]); + } else { + assert(range->left.type == ARE_VALUE); + assert(range->right.type == ARE_VALUE); + numchars = 1 + (range->right.value - range->left.value); + } + return numchars; +} + static int -emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, char *type) { +emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, int alphabetsize, char *type) { if(!range || range->incompatible || range->not_PER_visible) { OUT("{ APC_UNCONSTRAINED,\t-1, -1, 0, 0 }"); return 0; @@ -1790,6 +1805,11 @@ emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, char *typ if(range->empty_constraint) r = 0; + if(alphabetsize) { + /* X.691: 27.5.2 */ + r = PER_FROM_alphabet_characters(range); + } + /* Compute real constraint */ for(rbits = 0; rbits < (8 * sizeof(r)); rbits++) { if(r <= cover) @@ -1823,6 +1843,7 @@ emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, char *typ ebits = -1; } } + OUT("{ APC_CONSTRAINED%s,%s% d, % d, ", range->extensible ? " | APC_EXTENSIBLE" : "", @@ -1867,10 +1888,27 @@ emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, char *typ } static int -emit_single_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr) { +emit_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr) { + int save_target = arg->target->target; asn1cnst_range_t *range; asn1p_expr_type_e etype; + if((arg->flags & A1C_GEN_PER) + && (expr->constraints + || expr->expr_type == ASN_BASIC_ENUMERATED + || expr->expr_type == ASN_CONSTR_CHOICE) + ) { + /* Fall through */ + } else { + return 0; + } + + REDIR(OT_CTDEFS); + + OUT("static asn_per_constraints_t " + "asn_PER_%s_constr_%d = {\n", + MKID(expr), expr->_type_unique_index); + etype = expr_get_type(arg, expr); INDENT(+1); @@ -1903,20 +1941,21 @@ emit_single_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr) { tmprng.left.value = 0; tmprng.right.type = ARE_VALUE; tmprng.right.value = eidx < 0 ? 0 : eidx; - if(emit_single_member_PER_constraint(arg, &tmprng, 0)) + if(emit_single_member_PER_constraint(arg, &tmprng, 0, 0)) return -1; } else if(etype & ASN_STRING_KM_MASK) { range = asn1constraint_compute_PER_range(etype, expr->combined_constraints, ACT_CT_FROM, 0, 0, 0); - if(emit_single_member_PER_constraint(arg, range, 0)) + DEBUG("Emitting FROM constraint for %s", expr->Identifier); + if(emit_single_member_PER_constraint(arg, range, 1, 0)) return -1; asn1constraint_range_free(range); } else { range = asn1constraint_compute_PER_range(etype, expr->combined_constraints, ACT_EL_RANGE, 0, 0, 0); - if(emit_single_member_PER_constraint(arg, range, 0)) + if(emit_single_member_PER_constraint(arg, range, 0, 0)) return -1; asn1constraint_range_free(range); } @@ -1924,37 +1963,56 @@ emit_single_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr) { range = asn1constraint_compute_PER_range(etype, expr->combined_constraints, ACT_CT_SIZE, 0, 0, 0); - if(emit_single_member_PER_constraint(arg, range, "SIZE")) + if(emit_single_member_PER_constraint(arg, range, 0, "SIZE")) return -1; asn1constraint_range_free(range); - OUT("\n"); + OUT(",\n"); - INDENT(-1); + if((etype & ASN_STRING_KM_MASK) && (expr->_mark & TM_PERFROMCT)) { + int old_target = arg->target->target; + REDIR(OT_CODE); - return 0; -} + OUT("static int asn_PER_MAP_%s_%d_v2c(unsigned int value) {\n", + MKID(expr), expr->_type_unique_index); + OUT("\tif(value >= sizeof(permitted_alphabet_table_%d)/" + "sizeof(permitted_alphabet_table_%d[0]))\n", + expr->_type_unique_index, + expr->_type_unique_index); + OUT("\t\treturn -1;\n"); + OUT("\treturn permitted_alphabet_table_%d[value] - 1;\n", + expr->_type_unique_index); + OUT("}\n"); -static int -emit_members_PER_constraints(arg_t *arg) { - asn1p_expr_t *expr = arg->expr; - asn1p_expr_t *v; + OUT("static int asn_PER_MAP_%s_%d_c2v(unsigned int code) {\n", + MKID(expr), expr->_type_unique_index); + OUT("\tif(code >= sizeof(permitted_alphabet_code2value_%d)/" + "sizeof(permitted_alphabet_code2value_%d[0]))\n", + expr->_type_unique_index, + expr->_type_unique_index); + OUT("\t\treturn -1;\n"); + OUT("\treturn permitted_alphabet_code2value_%d[code];\n", + expr->_type_unique_index); + OUT("}\n"); - if(!(arg->flags & A1C_GEN_PER)) - return 0; + REDIR(old_target); - TQ_FOR(v, &(expr->members), next) { - if(v->constraints - || v->expr_type == ASN_BASIC_ENUMERATED - || v->expr_type == ASN_CONSTR_CHOICE) { - OUT("static asn_per_constraints_t " - "asn_PER_memb_%s_constr_%d = {\n", - MKID(v), v->_type_unique_index); - if(emit_single_member_PER_constraints(arg, v)) - return -1; - OUT("};\n"); - } + OUT("asn_PER_MAP_%s_%d_v2c,\t/* Value to PER code map */\n", + MKID(expr), expr->_type_unique_index); + OUT("asn_PER_MAP_%s_%d_c2v\t/* PER code to value map */\n", + MKID(expr), expr->_type_unique_index); + } else if(etype & ASN_STRING_KM_MASK) { + DEBUG("No PER value map necessary for %s", MKID(expr)); + OUT("0, 0\t/* No PER character map necessary */\n"); + } else { + OUT("0, 0\t/* No PER value map */\n"); } + INDENT(-1); + + OUT("};\n"); + + REDIR(save_target); + return 0; } @@ -2138,7 +2196,7 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr) { if(expr->constraints || expr->expr_type == ASN_BASIC_ENUMERATED || expr->expr_type == ASN_CONSTR_CHOICE) { - OUT("&asn_PER_memb_%s_constr_%d,\n", + OUT("&asn_PER_%s_constr_%d,\n", MKID(expr), expr->_type_unique_index); } else { @@ -2182,6 +2240,7 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr) { OUT("\t\tasn_app_constraint_failed_f *ctfailcb, void *app_key) {\n"); tmp_arg = *arg; tmp_arg.expr = expr; + DEBUG("member constraint checking code for %s", p); if(asn1c_emit_constraint_checking_code(&tmp_arg) == 1) { OUT("return td->check_constraints" "(td, sptr, ctfailcb, app_key);\n"); @@ -2190,6 +2249,9 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr) { OUT("}\n"); OUT("\n"); + if(emit_member_PER_constraints(arg, expr)) + return -1; + REDIR(save_target); return 0; @@ -2206,17 +2268,8 @@ emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_ terminal = asn1f_find_terminal_type_ex(arg->asn, expr); - if((arg->flags & A1C_GEN_PER) - && (expr->constraints - || expr->expr_type == ASN_BASIC_ENUMERATED - || expr->expr_type == ASN_CONSTR_CHOICE) - ) { - OUT("static asn_per_constraints_t asn_PER_%s_constr_%d = {\n", - p, expr->_type_unique_index); - if(emit_single_member_PER_constraints(arg, expr)) - return -1; - OUT("};\n"); - } + if(emit_member_PER_constraints(arg, expr)) + return -1; if(HIDE_INNER_DEFS) OUT("static /* Use -fall-defs-global to expose */\n"); diff --git a/libasn1compiler/asn1c_constraint.c b/libasn1compiler/asn1c_constraint.c index da54f440..2fd8885f 100644 --- a/libasn1compiler/asn1c_constraint.c +++ b/libasn1compiler/asn1c_constraint.c @@ -316,7 +316,8 @@ asn1c_emit_constraint_tables(arg_t *arg, int got_size) { } OUT("};\n"); - if((arg->flags & A1C_GEN_PER)) { + if((arg->flags & A1C_GEN_PER) + && (etype & ASN_STRING_KM_MASK)) { int c; OUT("static int permitted_alphabet_code2value_%d[%d] = {\n", arg->expr->_type_unique_index, cardinal); @@ -328,6 +329,8 @@ asn1c_emit_constraint_tables(arg_t *arg, int got_size) { } OUT("};\n"); OUT("\n"); + DEBUG("code2value map gen for %s", arg->expr->Identifier); + arg->expr->_mark |= TM_PERFROMCT; } OUT("\n"); diff --git a/libasn1compiler/asn1c_misc.c b/libasn1compiler/asn1c_misc.c index c8adce66..543a165b 100644 --- a/libasn1compiler/asn1c_misc.c +++ b/libasn1compiler/asn1c_misc.c @@ -158,7 +158,8 @@ asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) { while(top_parent->parent_expr) top_parent = top_parent->parent_expr; - DEBUG("asn1c_type_name(%s: 0x%x)", expr->Identifier, expr->expr_type); + if(0) DEBUG("asn1c_type_name(%s: 0x%x)", + expr->Identifier, expr->expr_type); switch(expr->expr_type) { case A1TC_REFERENCE: diff --git a/libasn1compiler/asn1c_out.h b/libasn1compiler/asn1c_out.h index 3b1f055d..0523cbcf 100644 --- a/libasn1compiler/asn1c_out.h +++ b/libasn1compiler/asn1c_out.h @@ -22,6 +22,7 @@ typedef struct compiler_streams { OT_POST_INCLUDE,/* #include after type definition */ OT_CTABLES, /* Constraint tables */ OT_CODE, /* Some code */ + OT_CTDEFS, /* Constraint definitions */ OT_STAT_DEFS, /* Static definitions */ OT_MAX } target; @@ -34,7 +35,7 @@ typedef struct compiler_streams { } compiler_streams_t; static char *_compiler_stream2str[] __attribute__ ((unused)) - = { "IGNORE", "INCLUDES", "DEPS", "FWD-DECLS", "TYPE-DECLS", "FUNC-DECLS", "POST-INCLUDE", "CTABLES", "CODE", "STAT-DEFS" }; + = { "IGNORE", "INCLUDES", "DEPS", "FWD-DECLS", "TYPE-DECLS", "FUNC-DECLS", "POST-INCLUDE", "CTABLES", "CODE", "CTDEFS", "STAT-DEFS" }; int asn1c_compiled_output(arg_t *arg, const char *fmt, ...); diff --git a/libasn1compiler/asn1c_save.c b/libasn1compiler/asn1c_save.c index 4236e95a..1785d7d1 100644 --- a/libasn1compiler/asn1c_save.c +++ b/libasn1compiler/asn1c_save.c @@ -273,10 +273,12 @@ asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *deps, int optc, char **argv) { fwrite(ot->buf, ot->len, 1, fp_c); TQ_FOR(ot, &(cs->destination[OT_CODE].chunks), next) fwrite(ot->buf, ot->len, 1, fp_c); + TQ_FOR(ot, &(cs->destination[OT_CTDEFS].chunks), next) + fwrite(ot->buf, ot->len, 1, fp_c); TQ_FOR(ot, &(cs->destination[OT_STAT_DEFS].chunks), next) fwrite(ot->buf, ot->len, 1, fp_c); - assert(OT_MAX == 10); /* Protection from reckless changes */ + assert(OT_MAX == 11); /* Protection from reckless changes */ fclose(fp_c); fclose(fp_h); diff --git a/libasn1fix/asn1fix_constr.c b/libasn1fix/asn1fix_constr.c index 0421a52b..47c210f9 100644 --- a/libasn1fix/asn1fix_constr.c +++ b/libasn1fix/asn1fix_constr.c @@ -436,6 +436,10 @@ _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) { b->Identifier, b->_lineno ); + FATAL("Consider adding AUTOMATIC TAGS " + "after module %s DEFINITIONS, " + "or manually tag components", + arg->expr->module->ModuleName); DEBUG("Tags: %s %s vs. %s %s", asn1p_tag2string(&ta, tagbuf[0]), a->Identifier, diff --git a/libasn1parser/asn1p_expr.h b/libasn1parser/asn1p_expr.h index babe53f5..4e12c898 100644 --- a/libasn1parser/asn1p_expr.h +++ b/libasn1parser/asn1p_expr.h @@ -247,9 +247,10 @@ typedef struct asn1p_expr_s { * Here are some predefined ones. */ enum { - TM_NOMARK, - TM_RECURSION, /* Used to break recursion */ - TM_BROKEN, /* A warning was already issued */ + TM_NOMARK = 0, + TM_RECURSION = (1<<0), /* Used to break recursion */ + TM_BROKEN = (1<<1), /* A warning was already issued */ + TM_PERFROMCT = (1<<2), /* PER FROM() constraint tables emitted */ } _mark; /* diff --git a/skeletons/GeneralString.c b/skeletons/GeneralString.c index 55bb6643..01b606be 100644 --- a/skeletons/GeneralString.c +++ b/skeletons/GeneralString.c @@ -22,7 +22,8 @@ asn_TYPE_descriptor_t asn_DEF_GeneralString = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_hex, OCTET_STRING_encode_xer, - 0, 0, + OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ + OCTET_STRING_encode_uper, 0, /* Use generic outmost tag fetcher */ asn_DEF_GeneralString_tags, sizeof(asn_DEF_GeneralString_tags) diff --git a/skeletons/GeneralizedTime.c b/skeletons/GeneralizedTime.c index f864d830..982cca56 100644 --- a/skeletons/GeneralizedTime.c +++ b/skeletons/GeneralizedTime.c @@ -147,6 +147,11 @@ static ber_tlv_tag_t asn_DEF_GeneralizedTime_tags[] = { (ASN_TAG_CLASS_UNIVERSAL | (26 << 2)), /* [UNIVERSAL 26] IMPLICIT ...*/ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */ }; +static asn_per_constraints_t asn_DEF_GeneralizedTime_constraints = { + { APC_CONSTRAINED, 7, 7, 0x20, 0x7e }, /* Value */ + { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */ + 0, 0 +}; asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = { "GeneralizedTime", "GeneralizedTime", @@ -157,7 +162,8 @@ asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = { GeneralizedTime_encode_der, OCTET_STRING_decode_xer_utf8, GeneralizedTime_encode_xer, - 0, 0, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, 0, /* Use generic outmost tag fetcher */ asn_DEF_GeneralizedTime_tags, sizeof(asn_DEF_GeneralizedTime_tags) @@ -165,7 +171,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 */ + &asn_DEF_GeneralizedTime_constraints, 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/skeletons/GraphicString.c b/skeletons/GraphicString.c index 135cd733..7d59d522 100644 --- a/skeletons/GraphicString.c +++ b/skeletons/GraphicString.c @@ -22,7 +22,8 @@ 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, + OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ + OCTET_STRING_encode_uper, 0, /* Use generic outmost tag fetcher */ asn_DEF_GraphicString_tags, sizeof(asn_DEF_GraphicString_tags) diff --git a/skeletons/IA5String.c b/skeletons/IA5String.c index 5c000b03..8d81e446 100644 --- a/skeletons/IA5String.c +++ b/skeletons/IA5String.c @@ -12,6 +12,11 @@ static ber_tlv_tag_t asn_DEF_IA5String_tags[] = { (ASN_TAG_CLASS_UNIVERSAL | (22 << 2)), /* [UNIVERSAL 22] IMPLICIT ...*/ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */ }; +static asn_per_constraints_t asn_DEF_IA5String_constraints = { + { APC_CONSTRAINED, 7, 7, 0, 0x7f }, /* Value */ + { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */ + 0, 0 +}; asn_TYPE_descriptor_t asn_DEF_IA5String = { "IA5String", "IA5String", @@ -22,7 +27,8 @@ asn_TYPE_descriptor_t asn_DEF_IA5String = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, - 0, 0, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, 0, /* Use generic outmost tag fetcher */ asn_DEF_IA5String_tags, sizeof(asn_DEF_IA5String_tags) @@ -30,7 +36,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 */ + &asn_DEF_IA5String_constraints, 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/skeletons/ISO646String.c b/skeletons/ISO646String.c index d164aa7b..d6ded0ef 100644 --- a/skeletons/ISO646String.c +++ b/skeletons/ISO646String.c @@ -12,6 +12,11 @@ static ber_tlv_tag_t asn_DEF_ISO646String_tags[] = { (ASN_TAG_CLASS_UNIVERSAL | (26 << 2)), /* [UNIVERSAL 26] IMPLICIT ...*/ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */ }; +static asn_per_constraints_t asn_DEF_ISO646String_constraints = { + { APC_CONSTRAINED, 7, 7, 0x20, 0x7e }, /* Value */ + { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */ + 0, 0 +}; asn_TYPE_descriptor_t asn_DEF_ISO646String = { "ISO646String", "ISO646String", @@ -22,7 +27,8 @@ asn_TYPE_descriptor_t asn_DEF_ISO646String = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, - 0, 0, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, 0, /* Use generic outmost tag fetcher */ asn_DEF_ISO646String_tags, sizeof(asn_DEF_ISO646String_tags) @@ -30,8 +36,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 */ + &asn_DEF_ISO646String_constraints, 0, 0, /* No members */ 0 /* No specifics */ }; - diff --git a/skeletons/NativeReal.c b/skeletons/NativeReal.c index 2b8ec166..a1ff91e1 100644 --- a/skeletons/NativeReal.c +++ b/skeletons/NativeReal.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Copyright (c) 2004, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ /* @@ -12,6 +12,7 @@ #include <asn_internal.h> #include <NativeReal.h> #include <REAL.h> +#include <OCTET_STRING.h> /* * NativeReal basic type description. @@ -29,7 +30,8 @@ asn_TYPE_descriptor_t asn_DEF_NativeReal = { NativeReal_encode_der, NativeReal_decode_xer, NativeReal_encode_xer, - 0, 0, + NativeReal_decode_uper, + NativeReal_encode_uper, 0, /* Use generic outmost tag fetcher */ asn_DEF_NativeReal_tags, sizeof(asn_DEF_NativeReal_tags) / sizeof(asn_DEF_NativeReal_tags[0]), @@ -157,7 +159,74 @@ NativeReal_encode_der(asn_TYPE_descriptor_t *td, void *ptr, return erval; } +/* + * Decode REAL type using PER. + */ +asn_dec_rval_t +NativeReal_decode_uper(asn_codec_ctx_t *opt_codec_ctx, + asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, + void **dbl_ptr, asn_per_data_t *pd) { + double *Dbl = (double *)*dbl_ptr; + asn_dec_rval_t rval; + REAL_t tmp; + void *ptmp = &tmp; + int ret; + + (void)constraints; + + /* + * If the structure is not there, allocate it. + */ + if(Dbl == NULL) { + *dbl_ptr = CALLOC(1, sizeof(*Dbl)); + Dbl = (double *)*dbl_ptr; + if(Dbl == NULL) + _ASN_DECODE_FAILED; + } + + memset(&tmp, 0, sizeof(tmp)); + rval = OCTET_STRING_decode_uper(opt_codec_ctx, td, NULL, + &ptmp, pd); + if(rval.code != RC_OK) { + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp); + return rval; + } + + ret = asn_REAL2double(&tmp, Dbl); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp); + if(ret) _ASN_DECODE_FAILED; + return rval; +} + +/* + * Encode the NativeReal using the OCTET STRING PER encoder. + */ +asn_enc_rval_t +NativeReal_encode_uper(asn_TYPE_descriptor_t *td, + asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { + double Dbl = *(const double *)sptr; + asn_enc_rval_t erval; + REAL_t tmp; + + (void)constraints; + + /* Prepare a temporary clean structure */ + memset(&tmp, 0, sizeof(tmp)); + + if(asn_double2REAL(&tmp, Dbl)) + _ASN_ENCODE_FAILED; + + /* Encode a DER REAL */ + erval = OCTET_STRING_encode_uper(td, NULL, &tmp, po); + if(erval.encoded == -1) + erval.structure_ptr = sptr; + + /* Free possibly allocated members of the temporary structure */ + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_REAL, &tmp); + + return erval; +} /* * Decode the chunk of XML text encoding REAL. diff --git a/skeletons/NativeReal.h b/skeletons/NativeReal.h index 1f5266cc..68a81d9b 100644 --- a/skeletons/NativeReal.h +++ b/skeletons/NativeReal.h @@ -6,7 +6,7 @@ * This type differs from the standard REAL in that it is modelled using * the fixed machine type (double), so it can hold only values of * limited precision. There is no explicit type (i.e., NativeReal_t). - * Use of this type is normally enabled by -fnative-integers. + * Use of this type is normally enabled by -fnative-types. */ #ifndef ASN_TYPE_NativeReal_H #define ASN_TYPE_NativeReal_H @@ -25,6 +25,8 @@ ber_type_decoder_f NativeReal_decode_ber; der_type_encoder_f NativeReal_encode_der; xer_type_decoder_f NativeReal_decode_xer; xer_type_encoder_f NativeReal_encode_xer; +per_type_decoder_f NativeReal_decode_uper; +per_type_encoder_f NativeReal_encode_uper; #ifdef __cplusplus } diff --git a/skeletons/NumericString.c b/skeletons/NumericString.c index cef64ea6..7c4cc95e 100644 --- a/skeletons/NumericString.c +++ b/skeletons/NumericString.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Copyright (c) 2003, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #include <asn_internal.h> @@ -12,6 +12,31 @@ static ber_tlv_tag_t asn_DEF_NumericString_tags[] = { (ASN_TAG_CLASS_UNIVERSAL | (18 << 2)), /* [UNIVERSAL 18] IMPLICIT ...*/ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */ }; +static int asn_DEF_NumericString_v2c(unsigned int value) { + switch(value) { + case 0x20: return 0; + case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: + case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: + return value - (0x30 - 1); + } + return -1; +} +static int asn_DEF_NumericString_c2v(unsigned int code) { + if(code > 0) { + if(code <= 10) + return code + (0x30 - 1); + else + return -1; + } else { + return 0x20; + } +} +static asn_per_constraints_t asn_DEF_NumericString_constraints = { + { APC_CONSTRAINED, 4, 4, 0x20, 0x39 }, /* Value */ + { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */ + asn_DEF_NumericString_v2c, + asn_DEF_NumericString_c2v +}; asn_TYPE_descriptor_t asn_DEF_NumericString = { "NumericString", "NumericString", @@ -22,7 +47,8 @@ asn_TYPE_descriptor_t asn_DEF_NumericString = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, - 0, 0, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, 0, /* Use generic outmost tag fetcher */ asn_DEF_NumericString_tags, sizeof(asn_DEF_NumericString_tags) @@ -30,7 +56,7 @@ asn_TYPE_descriptor_t asn_DEF_NumericString = { asn_DEF_NumericString_tags, sizeof(asn_DEF_NumericString_tags) / sizeof(asn_DEF_NumericString_tags[0]), - 0, /* No PER visible constraints */ + &asn_DEF_NumericString_constraints, 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/skeletons/OBJECT_IDENTIFIER.c b/skeletons/OBJECT_IDENTIFIER.c index b1666dc6..9f6402e1 100644 --- a/skeletons/OBJECT_IDENTIFIER.c +++ b/skeletons/OBJECT_IDENTIFIER.c @@ -4,6 +4,7 @@ */ #include <asn_internal.h> #include <OBJECT_IDENTIFIER.h> +#include <OCTET_STRING.h> #include <limits.h> /* for CHAR_BIT */ #include <errno.h> @@ -23,7 +24,8 @@ asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = { der_encode_primitive, OBJECT_IDENTIFIER_decode_xer, OBJECT_IDENTIFIER_encode_xer, - 0, 0, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, 0, /* Use generic outmost tag fetcher */ asn_DEF_OBJECT_IDENTIFIER_tags, sizeof(asn_DEF_OBJECT_IDENTIFIER_tags) diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c index 3a83bd98..a9747c4d 100644 --- a/skeletons/OCTET_STRING.c +++ b/skeletons/OCTET_STRING.c @@ -1197,6 +1197,93 @@ OCTET_STRING_decode_xer_utf8(asn_codec_ctx_t *opt_codec_ctx, OCTET_STRING__convert_entrefs); } +static int +OCTET_STRING_per_get_expanded(asn_per_data_t *po, uint8_t *buf, + size_t size, long lb, long ub, int (*code2value)(unsigned int), + int unit_bits) { + uint8_t *end = buf + size; + + ASN_DEBUG("Expanding %d characters into (%ld..%ld):%d", + (int)size, lb, ub, unit_bits); + + /* X.691: 27.5.4 */ + if(ub <= (2 << (unit_bits - 1))) { + /* Decode without translation */ + lb = 0; + } else if(code2value) { + for(; buf < end; buf++) { + int code = per_get_few_bits(po, unit_bits); + int value; + if(code < 0) return -1; /* WMORE */ + value = code2value(code); + if(value < 0) { + ASN_DEBUG("Code %d (0x%02x) is" + " not in map (%ld..%ld)", + code, code, lb, ub); + return 1; /* FATAL */ + } + *buf = value; + } + return 0; + } + + for(; buf < end; buf++) { + int code = per_get_few_bits(po, unit_bits); + int ch = code + lb; + if(code < 0) return -1; /* WMORE */ + if(ch > ub) { + ASN_DEBUG("Code %d is out of range (%ld..%ld)", + ch, lb, ub); + return 1; /* FATAL */ + } + *buf = ch; + } + + return 0; +} + +static int +OCTET_STRING_per_put_squeezed(asn_per_outp_t *po, const uint8_t *buf, + size_t size, long lb, long ub, int (*value2code)(unsigned int), + int unit_bits) { + const uint8_t *end = buf + size; + + ASN_DEBUG("Squeezing %d bytes into (%ld..%ld):%d", + (int)size, lb, ub, unit_bits); + + /* X.691: 27.5.4 */ + if(ub <= (2 << (unit_bits - 1))) { + /* Encode as is */ + lb = 0; + } else if(value2code) { + for(; buf < end; buf++) { + int code = value2code(*buf); + if(code < 0) { + ASN_DEBUG("Character %d (0x%02x) is" + " not in map (%ld..%ld)", + *buf, *buf, lb, ub); + return -1; + } + if(per_put_few_bits(po, code, unit_bits)) + return -1; + } + } + + for(ub -= lb; buf < end; buf++) { + int ch = *buf - lb; + if(ch < 0 || ch > ub) { + ASN_DEBUG("Character %d (0x%02x)" + " is out of range (%ld..%ld)", + *buf, *buf, lb, ub + lb); + return -1; + } + if(per_put_few_bits(po, ch, unit_bits)) + return -1; + } + + return 0; +} + asn_dec_rval_t OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, @@ -1205,15 +1292,17 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_OCTET_STRING_specifics_t *specs = td->specifics ? (asn_OCTET_STRING_specifics_t *)td->specifics : &asn_DEF_OCTET_STRING_specs; - asn_per_constraint_t *ct = constraints ? &constraints->size - : (td->per_constraints - ? &td->per_constraints->size - : &asn_DEF_OCTET_STRING_constraint); + asn_per_constraints_t *pc = constraints ? constraints + : td->per_constraints; + asn_per_constraint_t *cv = pc ? &pc->value : 0; + asn_per_constraint_t *ct = pc ? &pc->size + : &asn_DEF_OCTET_STRING_constraint; asn_dec_rval_t rval = { RC_OK, 0 }; BIT_STRING_t *st = (BIT_STRING_t *)*sptr; ssize_t consumed_myself = 0; int repeat; int unit_bits = (specs->subvariant != 1) * 7 + 1; + int expand = 0; (void)opt_codec_ctx; @@ -1225,8 +1314,13 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx, if(!st) RETURN(RC_FAIL); } - ASN_DEBUG("PER Decoding %s %ld .. %ld bits %d", - ct->flags & APC_EXTENSIBLE ? "extensible" : "fixed", + if(cv && (cv->flags & APC_CONSTRAINED)) { + unit_bits = cv->range_bits; + if(unit_bits != 8) expand = 1; + } + + ASN_DEBUG("PER Decoding %s size %ld .. %ld bits %d", + ct->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible", ct->lower_bound, ct->upper_bound, ct->effective_bits); if(ct->flags & APC_EXTENSIBLE) { @@ -1252,8 +1346,17 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx, /* X.691, #16.6: short fixed length encoding (up to 2 octets) */ /* X.691, #16.7: long fixed length encoding (up to 64K octets) */ if(ct->effective_bits == 0) { - int ret = per_get_many_bits(pd, st->buf, 0, + int ret; + if(expand) { + ret = OCTET_STRING_per_get_expanded(pd, st->buf, + cv->upper_bound, + cv->lower_bound, cv->upper_bound, + pc->code2value, unit_bits); + if(ret > 0) RETURN(RC_FAIL); + } else { + ret = per_get_many_bits(pd, st->buf, 0, unit_bits * ct->upper_bound); + } if(ret < 0) RETURN(RC_WMORE); consumed_myself += unit_bits * ct->upper_bound; st->buf[st->size] = 0; @@ -1277,7 +1380,7 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx, ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)", (long)ct->effective_bits, (long)len_bits, repeat ? "repeat" : "once", td->name); - if(unit_bits == 1) { + if(unit_bits == 1 && !expand) { len_bytes = (len_bits + 7) >> 3; if(len_bits & 0x7) st->bits_unused = 8 - (len_bits & 0x7); @@ -1290,7 +1393,16 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx, if(!p) RETURN(RC_FAIL); st->buf = (uint8_t *)p; - ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits); + if(expand) { + ret = OCTET_STRING_per_get_expanded(pd, + &st->buf[st->size], len_bytes, + cv->lower_bound, cv->upper_bound, + pc->code2value, unit_bits); + if(ret > 0) RETURN(RC_FAIL); + } else { + ret = per_get_many_bits(pd, &st->buf[st->size], + 0, len_bits); + } if(ret < 0) RETURN(RC_WMORE); st->size += len_bytes; } while(repeat); @@ -1306,17 +1418,19 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, asn_OCTET_STRING_specifics_t *specs = td->specifics ? (asn_OCTET_STRING_specifics_t *)td->specifics : &asn_DEF_OCTET_STRING_specs; - asn_per_constraint_t *ct = constraints ? &constraints->size - : (td->per_constraints - ? &td->per_constraints->size - : &asn_DEF_OCTET_STRING_constraint); + asn_per_constraints_t *pc = constraints ? constraints + : td->per_constraints; + asn_per_constraint_t *cv = pc ? &pc->value : 0; + asn_per_constraint_t *ct = pc ? &pc->size + : &asn_DEF_OCTET_STRING_constraint; const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; - int unit_bits = (specs->subvariant != 1) * 7 + 1; asn_enc_rval_t er; int ct_extensible = ct->flags & APC_EXTENSIBLE; int inext = 0; /* Lies not within extension root */ + int unit_bits = (specs->subvariant != 1) * 7 + 1; int sizeinunits = st->size; const uint8_t *buf; + int squeeze = 0; int ret; if(!st || !st->buf) @@ -1328,13 +1442,18 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, sizeinunits = sizeinunits * 8 - (st->bits_unused & 0x07); } + if(cv && (cv->flags & APC_CONSTRAINED)) { + unit_bits = cv->range_bits; + if(unit_bits != 8) squeeze = 1; + } + ASN_DEBUG("Encoding %s into %d units of %d bits" - " (%d..%d, effective %d)%s", + " (%ld..%ld, effective %d)%s", td->name, sizeinunits, unit_bits, ct->lower_bound, ct->upper_bound, ct->effective_bits, ct_extensible ? " EXT" : ""); - /* Figure out wheter size lies within PER visible consrtaint */ + /* Figure out wheter size lies within PER visible constraint */ if(ct->effective_bits >= 0) { if(sizeinunits < ct->lower_bound @@ -1365,7 +1484,14 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, ret = per_put_few_bits(po, sizeinunits - ct->lower_bound, ct->effective_bits); if(ret) _ASN_ENCODE_FAILED; - ret = per_put_many_bits(po, st->buf, sizeinunits * unit_bits); + if(squeeze) { + ret = OCTET_STRING_per_put_squeezed(po, st->buf, + sizeinunits, cv->lower_bound, cv->upper_bound, + pc->value2code, unit_bits); + } else { + ret = per_put_many_bits(po, st->buf, + sizeinunits * unit_bits); + } if(ret) _ASN_ENCODE_FAILED; _ASN_ENCODED_OK(er); } @@ -1385,10 +1511,16 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, ASN_DEBUG("Encoding %d of %d", maySave, sizeinunits); - ret = per_put_many_bits(po, buf, maySave * unit_bits); + if(squeeze) { + ret = OCTET_STRING_per_put_squeezed(po, buf, + maySave, cv->lower_bound, cv->upper_bound, + pc->value2code, unit_bits); + } else { + ret = per_put_many_bits(po, buf, maySave * unit_bits); + } if(ret) _ASN_ENCODE_FAILED; - if(unit_bits == 1) + if(unit_bits == 1 && !squeeze) buf += maySave >> 3; else buf += maySave; diff --git a/skeletons/ObjectDescriptor.c b/skeletons/ObjectDescriptor.c index 44cb5f66..cd8e8a38 100644 --- a/skeletons/ObjectDescriptor.c +++ b/skeletons/ObjectDescriptor.c @@ -22,7 +22,8 @@ asn_TYPE_descriptor_t asn_DEF_ObjectDescriptor = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, - 0, 0, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, 0, /* Use generic outmost tag fetcher */ asn_DEF_ObjectDescriptor_tags, sizeof(asn_DEF_ObjectDescriptor_tags) diff --git a/skeletons/PrintableString.c b/skeletons/PrintableString.c index f5880832..318bff1e 100644 --- a/skeletons/PrintableString.c +++ b/skeletons/PrintableString.c @@ -1,17 +1,52 @@ /*- - * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Copyright (c) 2003, 2004, 2006 Lev Walkin <vlm@lionet.info>. + * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #include <asn_internal.h> #include <PrintableString.h> /* + * ASN.1:1984 (X.409) + */ +static int _PrintableString_alphabet[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* */ + 1, 0, 0, 0, 0, 0, 0, 2, 3, 4, 0, 5, 6, 7, 8, 9, /* . '() +,-./ */ +10,11,12,13,14,15,16,17,18,19,20, 0, 0,21, 0,22, /* 0123456789: = ? */ + 0,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37, /* ABCDEFGHIJKLMNO */ +38,39,40,41,42,43,44,45,46,47,48, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ */ + 0,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, /* abcdefghijklmno */ +64,65,66,67,68,69,70,71,72,73,74, 0, 0, 0, 0, 0, /* pqrstuvwxyz */ +}; +static int _PrintableString_code2value[74] = { +32,39,40,41,43,44,45,46,47,48,49,50,51,52,53,54, +55,56,57,58,61,63,65,66,67,68,69,70,71,72,73,74, +75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90, +97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112, +113,114,115,116,117,118,119,120,121,122}; + +/* * PrintableString basic type description. */ static ber_tlv_tag_t asn_DEF_PrintableString_tags[] = { (ASN_TAG_CLASS_UNIVERSAL | (19 << 2)), /* [UNIVERSAL 19] IMPLICIT ...*/ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */ }; +static int asn_DEF_PrintableString_v2c(unsigned int value) { + return _PrintableString_alphabet[value > 255 ? 0 : value] - 1; +} +static int asn_DEF_PrintableString_c2v(unsigned int code) { + if(code < 74) + return _PrintableString_code2value[code]; + return -1; +} +static asn_per_constraints_t asn_DEF_PrintableString_constraints = { + { APC_CONSTRAINED, 4, 4, 0x20, 0x39 }, /* Value */ + { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */ + asn_DEF_PrintableString_v2c, + asn_DEF_PrintableString_c2v +}; asn_TYPE_descriptor_t asn_DEF_PrintableString = { "PrintableString", "PrintableString", @@ -22,7 +57,8 @@ asn_TYPE_descriptor_t asn_DEF_PrintableString = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, - 0, 0, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, 0, /* Use generic outmost tag fetcher */ asn_DEF_PrintableString_tags, sizeof(asn_DEF_PrintableString_tags) @@ -30,34 +66,12 @@ asn_TYPE_descriptor_t asn_DEF_PrintableString = { asn_DEF_PrintableString_tags, sizeof(asn_DEF_PrintableString_tags) / sizeof(asn_DEF_PrintableString_tags[0]), - 0, /* No PER visible constraints */ + &asn_DEF_PrintableString_constraints, 0, 0, /* No members */ 0 /* No specifics */ }; -/* - * ASN.1:1984 (X.409) - */ -static int _PrintableString_alphabet[256] = { -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* ' */ -0x41, 0x42, 0x00, 0x43, 0x44, 0x45, 0x46, 0x47, /* ( ) + , - . / */ -0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, /* 0 1 2 3 4 5 6 7 */ -0x3d, 0x3e, 0x48, 0x00, 0x00, 0x49, 0x00, 0x4a, /* 8 9 : = ? */ -0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* A B C D E F G */ -0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* H I J K L M N O */ -0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* P Q R S T U V W */ -0x18, 0x19, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, /* X Y Z */ -0x00, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, /* a b c d e f g */ -0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, /* h i j k l m n o */ -0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, /* p q r s t u v w */ -0x32, 0x33, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, /* x y z */ -}; - int PrintableString_constraint(asn_TYPE_descriptor_t *td, const void *sptr, asn_app_constraint_failed_f *ctfailcb, void *app_key) { diff --git a/skeletons/REAL.c b/skeletons/REAL.c index 51098c00..32f92211 100644 --- a/skeletons/REAL.c +++ b/skeletons/REAL.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Copyright (c) 2004, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #if defined(__alpha) @@ -12,6 +12,7 @@ #include <math.h> #include <errno.h> #include <REAL.h> +#include <OCTET_STRING.h> #undef INT_MAX #define INT_MAX ((int)(((unsigned int)-1) >> 1)) @@ -42,7 +43,8 @@ asn_TYPE_descriptor_t asn_DEF_REAL = { der_encode_primitive, REAL_decode_xer, REAL_encode_xer, - 0, 0, + REAL_decode_uper, + REAL_encode_uper, 0, /* Use generic outmost tag fetcher */ asn_DEF_REAL_tags, sizeof(asn_DEF_REAL_tags) / sizeof(asn_DEF_REAL_tags[0]), @@ -341,6 +343,20 @@ REAL_decode_xer(asn_codec_ctx_t *opt_codec_ctx, buf_ptr, size, REAL__xer_body_decode); } +asn_dec_rval_t +REAL_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) { + (void)constraints; /* No PER visible constraints */ + return OCTET_STRING_decode_uper(opt_codec_ctx, td, 0, sptr, pd); +} + +asn_enc_rval_t +REAL_encode_uper(asn_TYPE_descriptor_t *td, + asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { + (void)constraints; /* No PER visible constraints */ + return OCTET_STRING_encode_uper(td, 0, sptr, po); +} int asn_REAL2double(const REAL_t *st, double *dbl_value) { diff --git a/skeletons/REAL.h b/skeletons/REAL.h index 28ccf28d..af3e84cc 100644 --- a/skeletons/REAL.h +++ b/skeletons/REAL.h @@ -19,6 +19,8 @@ extern asn_TYPE_descriptor_t asn_DEF_REAL; asn_struct_print_f REAL_print; xer_type_decoder_f REAL_decode_xer; xer_type_encoder_f REAL_encode_xer; +per_type_decoder_f REAL_decode_uper; +per_type_encoder_f REAL_encode_uper; /*********************************** * Some handy conversion routines. * diff --git a/skeletons/RELATIVE-OID.c b/skeletons/RELATIVE-OID.c index 01814342..983fc094 100644 --- a/skeletons/RELATIVE-OID.c +++ b/skeletons/RELATIVE-OID.c @@ -5,6 +5,7 @@ */ #include <asn_internal.h> #include <RELATIVE-OID.h> +#include <OCTET_STRING.h> #include <asn_codecs_prim.h> /* Encoder and decoder of a primitive type */ #include <limits.h> /* for CHAR_BIT */ #include <errno.h> @@ -25,7 +26,8 @@ asn_TYPE_descriptor_t asn_DEF_RELATIVE_OID = { der_encode_primitive, RELATIVE_OID_decode_xer, RELATIVE_OID_encode_xer, - 0, 0, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, 0, /* Use generic outmost tag fetcher */ asn_DEF_RELATIVE_OID_tags, sizeof(asn_DEF_RELATIVE_OID_tags) diff --git a/skeletons/T61String.c b/skeletons/T61String.c index 25d887ae..98461bbb 100644 --- a/skeletons/T61String.c +++ b/skeletons/T61String.c @@ -22,7 +22,8 @@ asn_TYPE_descriptor_t asn_DEF_T61String = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_hex, OCTET_STRING_encode_xer, - 0, 0, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, 0, /* Use generic outmost tag fetcher */ asn_DEF_T61String_tags, sizeof(asn_DEF_T61String_tags) diff --git a/skeletons/TeletexString.c b/skeletons/TeletexString.c index b96cb3bb..81e646bd 100644 --- a/skeletons/TeletexString.c +++ b/skeletons/TeletexString.c @@ -22,7 +22,8 @@ asn_TYPE_descriptor_t asn_DEF_TeletexString = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_hex, OCTET_STRING_encode_xer, - 0, 0, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, 0, /* Use generic outmost tag fetcher */ asn_DEF_TeletexString_tags, sizeof(asn_DEF_TeletexString_tags) diff --git a/skeletons/UTCTime.c b/skeletons/UTCTime.c index 2a27718b..41a31dde 100644 --- a/skeletons/UTCTime.c +++ b/skeletons/UTCTime.c @@ -23,6 +23,11 @@ static ber_tlv_tag_t asn_DEF_UTCTime_tags[] = { (ASN_TAG_CLASS_UNIVERSAL | (26 << 2)), /* [UNIVERSAL 26] IMPLICIT ...*/ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */ }; +static asn_per_constraints_t asn_DEF_UTCTime_constraints = { + { APC_CONSTRAINED, 7, 7, 0x20, 0x7e }, /* Value */ + { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */ + 0, 0 +}; asn_TYPE_descriptor_t asn_DEF_UTCTime = { "UTCTime", "UTCTime", @@ -33,7 +38,8 @@ asn_TYPE_descriptor_t asn_DEF_UTCTime = { OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */ OCTET_STRING_decode_xer_utf8, UTCTime_encode_xer, - 0, 0, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, 0, /* Use generic outmost tag fetcher */ asn_DEF_UTCTime_tags, sizeof(asn_DEF_UTCTime_tags) @@ -41,7 +47,7 @@ asn_TYPE_descriptor_t asn_DEF_UTCTime = { asn_DEF_UTCTime_tags, sizeof(asn_DEF_UTCTime_tags) / sizeof(asn_DEF_UTCTime_tags[0]), - 0, /* No PER visible constraints */ + &asn_DEF_UTCTime_constraints, 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/skeletons/UTF8String.c b/skeletons/UTF8String.c index e3f73881..1e848154 100644 --- a/skeletons/UTF8String.c +++ b/skeletons/UTF8String.c @@ -23,7 +23,8 @@ asn_TYPE_descriptor_t asn_DEF_UTF8String = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, - 0, 0, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, 0, /* Use generic outmost tag fetcher */ asn_DEF_UTF8String_tags, sizeof(asn_DEF_UTF8String_tags) diff --git a/skeletons/VideotexString.c b/skeletons/VideotexString.c index 5f5f33d6..df7233e5 100644 --- a/skeletons/VideotexString.c +++ b/skeletons/VideotexString.c @@ -22,7 +22,8 @@ asn_TYPE_descriptor_t asn_DEF_VideotexString = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_hex, OCTET_STRING_encode_xer, - 0, 0, + OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ + OCTET_STRING_encode_uper, 0, /* Use generic outmost tag fetcher */ asn_DEF_VideotexString_tags, sizeof(asn_DEF_VideotexString_tags) diff --git a/skeletons/VisibleString.c b/skeletons/VisibleString.c index 8796582d..49a94c10 100644 --- a/skeletons/VisibleString.c +++ b/skeletons/VisibleString.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Copyright (c) 2003, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #include <asn_internal.h> @@ -12,6 +12,11 @@ static ber_tlv_tag_t asn_DEF_VisibleString_tags[] = { (ASN_TAG_CLASS_UNIVERSAL | (26 << 2)), /* [UNIVERSAL 26] IMPLICIT ...*/ (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)) /* ... OCTET STRING */ }; +static asn_per_constraints_t asn_DEF_VisibleString_constraints = { + { APC_CONSTRAINED, 7, 7, 0x20, 0x7e }, /* Value */ + { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 }, /* Size */ + 0, 0 +}; asn_TYPE_descriptor_t asn_DEF_VisibleString = { "VisibleString", "VisibleString", @@ -22,7 +27,8 @@ asn_TYPE_descriptor_t asn_DEF_VisibleString = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, - 0, 0, + OCTET_STRING_decode_uper, + OCTET_STRING_encode_uper, 0, /* Use generic outmost tag fetcher */ asn_DEF_VisibleString_tags, sizeof(asn_DEF_VisibleString_tags) @@ -30,7 +36,7 @@ asn_TYPE_descriptor_t asn_DEF_VisibleString = { asn_DEF_VisibleString_tags, sizeof(asn_DEF_VisibleString_tags) / sizeof(asn_DEF_VisibleString_tags[0]), - 0, /* No PER visible constraints */ + &asn_DEF_VisibleString_constraints, 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/skeletons/constr_SET_OF.c b/skeletons/constr_SET_OF.c index 09f27db5..96d2ae89 100644 --- a/skeletons/constr_SET_OF.c +++ b/skeletons/constr_SET_OF.c @@ -921,7 +921,7 @@ SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ASN_DEBUG("Failed to add element into %s", td->name); /* Fall through */ - rv.code == RC_FAIL; + rv.code = RC_FAIL; } else { ASN_DEBUG("Failed decoding %s of %s (SET OF)", elm->type->name, td->name); diff --git a/skeletons/per_support.h b/skeletons/per_support.h index 420bb83c..2708724d 100644 --- a/skeletons/per_support.h +++ b/skeletons/per_support.h @@ -29,6 +29,8 @@ typedef struct asn_per_constraint_s { typedef struct asn_per_constraints_s { asn_per_constraint_t value; asn_per_constraint_t size; + int (*value2code)(unsigned int value); + int (*code2value)(unsigned int code); } asn_per_constraints_t; /* diff --git a/skeletons/tests/check-OIDs.c b/skeletons/tests/check-OIDs.c index 4d4c9b56..b7fafe0b 100644 --- a/skeletons/tests/check-OIDs.c +++ b/skeletons/tests/check-OIDs.c @@ -442,3 +442,7 @@ main() { return 0; } + +asn_dec_rval_t OCTET_STRING_decode_uper(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void **sptr, asn_per_data_t *pd) { asn_dec_rval_t rv = { 0, 0 }; (void)ctx; (void)td; (void)cts; (void)sptr; (void)pd; return rv; } + +asn_enc_rval_t OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void *sptr, asn_per_outp_t *po) { asn_enc_rval_t er = { 0, 0, 0 }; (void)td; (void)cts; (void)sptr; (void)po; return er; } diff --git a/skeletons/tests/check-REAL.c b/skeletons/tests/check-REAL.c index 641da2da..3a868aaf 100644 --- a/skeletons/tests/check-REAL.c +++ b/skeletons/tests/check-REAL.c @@ -286,3 +286,7 @@ main() { return 0; } + +asn_dec_rval_t OCTET_STRING_decode_uper(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void **sptr, asn_per_data_t *pd) { asn_dec_rval_t rv = { 0, 0 }; (void)ctx; (void)td; (void)cts; (void)sptr; (void)pd; return rv; } + +asn_enc_rval_t OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *cts, void *sptr, asn_per_outp_t *po) { asn_enc_rval_t er = { 0, 0, 0 }; (void)td; (void)cts; (void)sptr; (void)po; return er; } diff --git a/tests/119-per-strings-OK.asn1 b/tests/119-per-strings-OK.asn1 new file mode 100644 index 00000000..856b51be --- /dev/null +++ b/tests/119-per-strings-OK.asn1 @@ -0,0 +1,38 @@ + +-- OK: Everything is fine + +-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1) +-- .spelio.software.asn1c.test (9363.1.5.1) +-- .119 + +ModulePERStrings + { iso org(3) dod(6) internet (1) private(4) enterprise(1) + spelio(9363) software(1) asn1c(5) test(1) 119 } + DEFINITIONS AUTOMATIC TAGS ::= +BEGIN + + PDU ::= SEQUENCE { + many SEQUENCE OF PDU OPTIONAL, + ia5 IA5String OPTIONAL, + ia5-c IA5String (FROM("A".."Z")) OPTIONAL, + ia5-ce IA5String (FROM("A".."Z",...)) OPTIONAL, + ia5-ir IA5String (FROM("A".."B"|"X".."Z")) OPTIONAL, + vs VisibleString OPTIONAL, + vs-c VisibleString (FROM("A".."Z")) OPTIONAL, + vs-ce VisibleString (FROM("A".."Z",...)) OPTIONAL, + vs-ir VisibleString (FROM("A".."B"|"X".."Z")) OPTIONAL, + pr PrintableString OPTIONAL, + pr-c PrintableString (FROM("A".."Z")) OPTIONAL, + pr-ir PrintableString (FROM("A".."B"|"X".."Z")) OPTIONAL, + ns NumericString OPTIONAL, + ns-c NumericString (FROM("5".."9")) OPTIONAL, + ns-ce NumericString (FROM("5".."9",...)) OPTIONAL, + ns-ir NumericString (FROM("1"|"9")) OPTIONAL, + ut-c UTF8String (SIZE(6)) OPTIONAL, + ut-ce UTF8String (SIZE(6,...)) OPTIONAL, + ut-ir UTF8String (FROM("A"|"Z")) OPTIONAL, + real REAL OPTIONAL, + oid OBJECT IDENTIFIER OPTIONAL + } + +END diff --git a/tests/50-constraint-OK.asn1.-Pgen-PER b/tests/50-constraint-OK.asn1.-Pgen-PER index 3e2911df..bb8d0e53 100644 --- a/tests/50-constraint-OK.asn1.-Pgen-PER +++ b/tests/50-constraint-OK.asn1.-Pgen-PER @@ -272,15 +272,19 @@ Int2_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [Int2] >>> ***/ + +static asn_per_constraints_t asn_PER_Int2_constr_1 = { + { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 } /* (0..MAX) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [Int2] >>> ***/ static ber_tlv_tag_t asn_DEF_Int2_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_Int2_constr_1 = { - { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 } /* (0..MAX) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_Int2 = { "Int2", "Int2", @@ -441,15 +445,19 @@ Int3_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [Int3] >>> ***/ + +static asn_per_constraints_t asn_PER_Int3_constr_1 = { + { APC_CONSTRAINED, 4, 4, 0, 10 } /* (0..10) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [Int3] >>> ***/ static ber_tlv_tag_t asn_DEF_Int3_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_Int3_constr_1 = { - { APC_CONSTRAINED, 4, 4, 0, 10 } /* (0..10) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_Int3 = { "Int3", "Int3", @@ -610,15 +618,19 @@ Int4_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [Int4] >>> ***/ + +static asn_per_constraints_t asn_PER_Int4_constr_1 = { + { APC_CONSTRAINED | APC_EXTENSIBLE, 4, 4, 1, 10 } /* (1..10,...) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [Int4] >>> ***/ static ber_tlv_tag_t asn_DEF_Int4_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_Int4_constr_1 = { - { APC_CONSTRAINED | APC_EXTENSIBLE, 4, 4, 1, 10 } /* (1..10,...) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_Int4 = { "Int4", "Int4", @@ -779,15 +791,19 @@ Int5_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [Int5] >>> ***/ + +static asn_per_constraints_t asn_PER_Int5_constr_1 = { + { APC_CONSTRAINED, 0, 0, 5, 5 } /* (5..5) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [Int5] >>> ***/ static ber_tlv_tag_t asn_DEF_Int5_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_Int5_constr_1 = { - { APC_CONSTRAINED, 0, 0, 5, 5 } /* (5..5) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_Int5 = { "Int5", "Int5", @@ -948,15 +964,19 @@ ExtensibleExtensions_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [ExtensibleExtensions] >>> ***/ + +static asn_per_constraints_t asn_PER_ExtensibleExtensions_constr_1 = { + { APC_CONSTRAINED | APC_EXTENSIBLE, 8, 8, 1, 256 } /* (1..256,...) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [ExtensibleExtensions] >>> ***/ static ber_tlv_tag_t asn_DEF_ExtensibleExtensions_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_ExtensibleExtensions_constr_1 = { - { APC_CONSTRAINED | APC_EXTENSIBLE, 8, 8, 1, 256 } /* (1..256,...) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_ExtensibleExtensions = { "ExtensibleExtensions", "ExtensibleExtensions", @@ -1271,15 +1291,19 @@ Str2_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [Str2] >>> ***/ + +static asn_per_constraints_t asn_PER_Str2_constr_1 = { + { APC_CONSTRAINED, 7, 7, 0, 127 } /* (0..127) */, + { APC_CONSTRAINED, 5, 5, 0, 30 } /* (SIZE(0..30)) */, + 0, 0 /* No PER character map necessary */ +}; + /*** <<< STAT-DEFS [Str2] >>> ***/ static ber_tlv_tag_t asn_DEF_Str2_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (22 << 2)) }; -static asn_per_constraints_t asn_PER_Str2_constr_1 = { - { APC_CONSTRAINED, 7, 7, 0, 127 } /* (0..127) */, - { APC_CONSTRAINED, 5, 5, 0, 30 } /* (SIZE(0..30)) */ -}; asn_TYPE_descriptor_t asn_DEF_Str2 = { "Str2", "Str2", @@ -1385,6 +1409,16 @@ Str3_constraint(asn_TYPE_descriptor_t *td, const void *sptr, } } +static int asn_PER_MAP_Str3_1_v2c(unsigned int value) { + if(value >= sizeof(permitted_alphabet_table_1)/sizeof(permitted_alphabet_table_1[0])) + return -1; + return permitted_alphabet_table_1[value] - 1; +} +static int asn_PER_MAP_Str3_1_c2v(unsigned int code) { + if(code >= sizeof(permitted_alphabet_code2value_1)/sizeof(permitted_alphabet_code2value_1[0])) + return -1; + return permitted_alphabet_code2value_1[code]; +} /* * This type is implemented using Str2, * so here we adjust the DEF accordingly. @@ -1466,15 +1500,20 @@ Str3_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [Str3] >>> ***/ + +static asn_per_constraints_t asn_PER_Str3_constr_1 = { + { APC_CONSTRAINED, 3, 3, 65, 102 } /* (65..102) */, + { APC_CONSTRAINED, 5, 5, 10, 27 } /* (SIZE(10..27)) */, + asn_PER_MAP_Str3_1_v2c, /* Value to PER code map */ + asn_PER_MAP_Str3_1_c2v /* PER code to value map */ +}; + /*** <<< STAT-DEFS [Str3] >>> ***/ static ber_tlv_tag_t asn_DEF_Str3_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (22 << 2)) }; -static asn_per_constraints_t asn_PER_Str3_constr_1 = { - { APC_CONSTRAINED, 6, 6, 65, 102 } /* (65..102) */, - { APC_CONSTRAINED, 5, 5, 10, 27 } /* (SIZE(10..27)) */ -}; asn_TYPE_descriptor_t asn_DEF_Str3 = { "Str3", "Str3", @@ -1644,15 +1683,19 @@ Str4_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [Str4] >>> ***/ + +static asn_per_constraints_t asn_PER_Str4_constr_1 = { + { APC_CONSTRAINED, 7, 7, 0, 127 } /* (0..127) */, + { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 } /* (SIZE(0..MAX)) */, + 0, 0 /* No PER character map necessary */ +}; + /*** <<< STAT-DEFS [Str4] >>> ***/ static ber_tlv_tag_t asn_DEF_Str4_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (22 << 2)) }; -static asn_per_constraints_t asn_PER_Str4_constr_1 = { - { APC_CONSTRAINED, 7, 7, 0, 127 } /* (0..127) */, - { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 } /* (SIZE(0..MAX)) */ -}; asn_TYPE_descriptor_t asn_DEF_Str4 = { "Str4", "Str4", @@ -1822,15 +1865,19 @@ PER_Visible_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [PER-Visible] >>> ***/ + +static asn_per_constraints_t asn_PER_PER_Visible_constr_1 = { + { APC_CONSTRAINED, 3, 3, 65, 70 } /* (65..70) */, + { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 } /* (SIZE(0..MAX)) */, + 0, 0 /* No PER character map necessary */ +}; + /*** <<< STAT-DEFS [PER-Visible] >>> ***/ static ber_tlv_tag_t asn_DEF_PER_Visible_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (22 << 2)) }; -static asn_per_constraints_t asn_PER_PER_Visible_constr_1 = { - { APC_CONSTRAINED, 3, 3, 65, 70 } /* (65..70) */, - { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 } /* (SIZE(0..MAX)) */ -}; asn_TYPE_descriptor_t asn_DEF_PER_Visible = { "PER-Visible", "PER-Visible", @@ -2000,15 +2047,19 @@ PER_Visible_2_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [PER-Visible-2] >>> ***/ + +static asn_per_constraints_t asn_PER_PER_Visible_2_constr_1 = { + { APC_CONSTRAINED, 1, 1, 69, 70 } /* (69..70) */, + { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 } /* (SIZE(0..MAX)) */, + 0, 0 /* No PER character map necessary */ +}; + /*** <<< STAT-DEFS [PER-Visible-2] >>> ***/ static ber_tlv_tag_t asn_DEF_PER_Visible_2_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (22 << 2)) }; -static asn_per_constraints_t asn_PER_PER_Visible_2_constr_1 = { - { APC_CONSTRAINED, 1, 1, 69, 70 } /* (69..70) */, - { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 } /* (SIZE(0..MAX)) */ -}; asn_TYPE_descriptor_t asn_DEF_PER_Visible_2 = { "PER-Visible-2", "PER-Visible-2", @@ -2178,15 +2229,19 @@ Not_PER_Visible_1_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [Not-PER-Visible-1] >>> ***/ + +static asn_per_constraints_t asn_PER_Not_PER_Visible_1_constr_1 = { + { APC_CONSTRAINED, 3, 3, 65, 70 } /* (65..70) */, + { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 } /* (SIZE(0..MAX)) */, + 0, 0 /* No PER character map necessary */ +}; + /*** <<< STAT-DEFS [Not-PER-Visible-1] >>> ***/ static ber_tlv_tag_t asn_DEF_Not_PER_Visible_1_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (22 << 2)) }; -static asn_per_constraints_t asn_PER_Not_PER_Visible_1_constr_1 = { - { APC_CONSTRAINED, 3, 3, 65, 70 } /* (65..70) */, - { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 } /* (SIZE(0..MAX)) */ -}; asn_TYPE_descriptor_t asn_DEF_Not_PER_Visible_1 = { "Not-PER-Visible-1", "Not-PER-Visible-1", @@ -2356,15 +2411,19 @@ Not_PER_Visible_2_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [Not-PER-Visible-2] >>> ***/ + +static asn_per_constraints_t asn_PER_Not_PER_Visible_2_constr_1 = { + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 } /* (SIZE(0..MAX)) */, + 0, 0 /* No PER character map necessary */ +}; + /*** <<< STAT-DEFS [Not-PER-Visible-2] >>> ***/ static ber_tlv_tag_t asn_DEF_Not_PER_Visible_2_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (22 << 2)) }; -static asn_per_constraints_t asn_PER_Not_PER_Visible_2_constr_1 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 } /* (SIZE(0..MAX)) */ -}; asn_TYPE_descriptor_t asn_DEF_Not_PER_Visible_2 = { "Not-PER-Visible-2", "Not-PER-Visible-2", @@ -2534,15 +2593,19 @@ Not_PER_Visible_3_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [Not-PER-Visible-3] >>> ***/ + +static asn_per_constraints_t asn_PER_Not_PER_Visible_3_constr_1 = { + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 } /* (SIZE(0..MAX)) */, + 0, 0 /* No PER character map necessary */ +}; + /*** <<< STAT-DEFS [Not-PER-Visible-3] >>> ***/ static ber_tlv_tag_t asn_DEF_Not_PER_Visible_3_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (22 << 2)) }; -static asn_per_constraints_t asn_PER_Not_PER_Visible_3_constr_1 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 } /* (SIZE(0..MAX)) */ -}; asn_TYPE_descriptor_t asn_DEF_Not_PER_Visible_3 = { "Not-PER-Visible-3", "Not-PER-Visible-3", @@ -2715,15 +2778,19 @@ SIZE_but_not_FROM_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [SIZE-but-not-FROM] >>> ***/ + +static asn_per_constraints_t asn_PER_SIZE_but_not_FROM_constr_1 = { + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + { APC_CONSTRAINED, 2, 2, 1, 4 } /* (SIZE(1..4)) */, + 0, 0 /* No PER character map necessary */ +}; + /*** <<< STAT-DEFS [SIZE-but-not-FROM] >>> ***/ static ber_tlv_tag_t asn_DEF_SIZE_but_not_FROM_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (22 << 2)) }; -static asn_per_constraints_t asn_PER_SIZE_but_not_FROM_constr_1 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 2, 2, 1, 4 } /* (SIZE(1..4)) */ -}; asn_TYPE_descriptor_t asn_DEF_SIZE_but_not_FROM = { "SIZE-but-not-FROM", "SIZE-but-not-FROM", @@ -2896,15 +2963,19 @@ SIZE_and_FROM_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [SIZE-and-FROM] >>> ***/ + +static asn_per_constraints_t asn_PER_SIZE_and_FROM_constr_1 = { + { APC_CONSTRAINED, 2, 2, 65, 68 } /* (65..68) */, + { APC_CONSTRAINED, 2, 2, 1, 4 } /* (SIZE(1..4)) */, + 0, 0 /* No PER character map necessary */ +}; + /*** <<< STAT-DEFS [SIZE-and-FROM] >>> ***/ static ber_tlv_tag_t asn_DEF_SIZE_and_FROM_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (22 << 2)) }; -static asn_per_constraints_t asn_PER_SIZE_and_FROM_constr_1 = { - { APC_CONSTRAINED, 2, 2, 65, 68 } /* (65..68) */, - { APC_CONSTRAINED, 2, 2, 1, 4 } /* (SIZE(1..4)) */ -}; asn_TYPE_descriptor_t asn_DEF_SIZE_and_FROM = { "SIZE-and-FROM", "SIZE-and-FROM", @@ -3074,15 +3145,19 @@ Neither_SIZE_nor_FROM_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [Neither-SIZE-nor-FROM] >>> ***/ + +static asn_per_constraints_t asn_PER_Neither_SIZE_nor_FROM_constr_1 = { + { APC_CONSTRAINED, 3, 3, 65, 70 } /* (65..70) */, + { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 } /* (SIZE(0..MAX)) */, + 0, 0 /* No PER character map necessary */ +}; + /*** <<< STAT-DEFS [Neither-SIZE-nor-FROM] >>> ***/ static ber_tlv_tag_t asn_DEF_Neither_SIZE_nor_FROM_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (22 << 2)) }; -static asn_per_constraints_t asn_PER_Neither_SIZE_nor_FROM_constr_1 = { - { APC_CONSTRAINED, 3, 3, 65, 70 } /* (65..70) */, - { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 } /* (SIZE(0..MAX)) */ -}; asn_TYPE_descriptor_t asn_DEF_Neither_SIZE_nor_FROM = { "Neither-SIZE-nor-FROM", "Neither-SIZE-nor-FROM", @@ -3246,15 +3321,19 @@ Utf8_4_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [Utf8-4] >>> ***/ + +static asn_per_constraints_t asn_PER_Utf8_4_constr_1 = { + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [Utf8-4] >>> ***/ static ber_tlv_tag_t asn_DEF_Utf8_4_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (12 << 2)) }; -static asn_per_constraints_t asn_PER_Utf8_4_constr_1 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_Utf8_4 = { "Utf8-4", "Utf8-4", @@ -3313,12 +3392,6 @@ static int permitted_alphabet_table_1[128] = { 0,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41, /* abcdefghijklmno */ 42,43,44,45,46,47,48,49,50,51,52, 0, 0, 0, 0, 0, /* pqrstuvwxyz */ }; -static int permitted_alphabet_code2value_1[52] = { -65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80, -81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102, -103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118, -119,120,121,122,}; - static int check_permitted_alphabet_1(const void *sptr) { int *table = permitted_alphabet_table_1; @@ -3452,15 +3525,19 @@ Utf8_3_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [Utf8-3] >>> ***/ + +static asn_per_constraints_t asn_PER_Utf8_3_constr_1 = { + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [Utf8-3] >>> ***/ static ber_tlv_tag_t asn_DEF_Utf8_3_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (12 << 2)) }; -static asn_per_constraints_t asn_PER_Utf8_3_constr_1 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_Utf8_3 = { "Utf8-3", "Utf8-3", @@ -3622,15 +3699,19 @@ Utf8_2_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [Utf8-2] >>> ***/ + +static asn_per_constraints_t asn_PER_Utf8_2_constr_1 = { + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [Utf8-2] >>> ***/ static ber_tlv_tag_t asn_DEF_Utf8_2_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (12 << 2)) }; -static asn_per_constraints_t asn_PER_Utf8_2_constr_1 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_Utf8_2 = { "Utf8-2", "Utf8-2", @@ -4223,6 +4304,29 @@ memb_int5_c_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, } +/*** <<< CTDEFS [Sequence] >>> ***/ + +static asn_per_constraints_t asn_PER_enum_c_constr_6 = { + { APC_CONSTRAINED | APC_EXTENSIBLE, 1, 1, 0, 1 } /* (0..1,...) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; +static asn_per_constraints_t asn_PER_int1_c_constr_2 = { + { APC_SEMI_CONSTRAINED, -1, -1, -2, 0 } /* (-2..MAX) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; +static asn_per_constraints_t asn_PER_int4_c_constr_4 = { + { APC_CONSTRAINED, 2, 2, 5, 7 } /* (5..7) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; +static asn_per_constraints_t asn_PER_int5_c_constr_13 = { + { APC_CONSTRAINED, 0, 0, 5, 5 } /* (5..5) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [Sequence] >>> ***/ static int asn_DFL_2_set_3(int set_value, void **sptr) { @@ -4285,10 +4389,6 @@ static asn_INTEGER_specifics_t asn_SPC_enum_c_specs_6 = { static ber_tlv_tag_t asn_DEF_enum_c_tags_6[] = { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)) }; -static asn_per_constraints_t asn_PER_enum_c_constr_6 = { - { APC_CONSTRAINED | APC_EXTENSIBLE, 1, 1, 0, 1 } /* (0..1,...) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; static /* Use -fall-defs-global to expose */ asn_TYPE_descriptor_t asn_DEF_enum_c_6 = { "enum-c", @@ -4314,29 +4414,13 @@ asn_TYPE_descriptor_t asn_DEF_enum_c_6 = { &asn_SPC_enum_c_specs_6 /* Additional specs */ }; -static asn_per_constraints_t asn_PER_memb_int1_c_constr_2 = { - { APC_SEMI_CONSTRAINED, -1, -1, -2, 0 } /* (-2..MAX) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; -static asn_per_constraints_t asn_PER_memb_int4_c_constr_4 = { - { APC_CONSTRAINED, 2, 2, 5, 7 } /* (5..7) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; -static asn_per_constraints_t asn_PER_memb_enum_c_constr_6 = { - { APC_CONSTRAINED | APC_EXTENSIBLE, 1, 1, 0, 1 } /* (0..1,...) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; -static asn_per_constraints_t asn_PER_memb_int5_c_constr_13 = { - { APC_CONSTRAINED, 0, 0, 5, 5 } /* (5..5) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; static asn_TYPE_member_t asn_MBR_Sequence_1[] = { { ATF_POINTER, 1, offsetof(struct Sequence, int1_c), .tag = (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), .tag_mode = 0, .type = &asn_DEF_Int1, .memb_constraints = memb_int1_c_constraint_1, - .per_constraints = &asn_PER_memb_int1_c_constr_2, + .per_constraints = &asn_PER_int1_c_constr_2, .default_value = asn_DFL_2_set_3, /* DEFAULT 3 */ .name = "int1-c" }, @@ -4354,7 +4438,7 @@ static asn_TYPE_member_t asn_MBR_Sequence_1[] = { .tag_mode = 0, .type = &asn_DEF_Int4, .memb_constraints = memb_int4_c_constraint_1, - .per_constraints = &asn_PER_memb_int4_c_constr_4, + .per_constraints = &asn_PER_int4_c_constr_4, .default_value = 0, .name = "int4-c" }, @@ -4372,7 +4456,7 @@ static asn_TYPE_member_t asn_MBR_Sequence_1[] = { .tag_mode = 0, .type = &asn_DEF_enum_c_6, .memb_constraints = 0, /* Defer constraints checking to the member type */ - .per_constraints = &asn_PER_memb_enum_c_constr_6, + .per_constraints = &asn_PER_enum_c_constr_6, .default_value = 0, .name = "enum-c" }, @@ -4390,7 +4474,7 @@ static asn_TYPE_member_t asn_MBR_Sequence_1[] = { .tag_mode = 0, .type = &asn_DEF_Int5, .memb_constraints = memb_int5_c_constraint_1, - .per_constraints = &asn_PER_memb_int5_c_constr_13, + .per_constraints = &asn_PER_int5_c_constr_13, .default_value = 0, .name = "int5-c" }, @@ -4470,6 +4554,14 @@ extern asn_TYPE_descriptor_t asn_DEF_SequenceOf; #include "Sequence.h" +/*** <<< CTDEFS [SequenceOf] >>> ***/ + +static asn_per_constraints_t asn_PER_SequenceOf_constr_1 = { + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + { APC_CONSTRAINED, 1, 1, 1, 2 } /* (SIZE(1..2)) */, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [SequenceOf] >>> ***/ static asn_TYPE_member_t asn_MBR_SequenceOf_1[] = { @@ -4491,10 +4583,6 @@ static asn_SET_OF_specifics_t asn_SPC_SequenceOf_specs_1 = { offsetof(struct SequenceOf, _asn_ctx), 0, /* XER encoding is XMLDelimitedItemList */ }; -static asn_per_constraints_t asn_PER_SequenceOf_constr_1 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_CONSTRAINED, 1, 1, 1, 2 } /* (SIZE(1..2)) */ -}; asn_TYPE_descriptor_t asn_DEF_SequenceOf = { "SequenceOf", "SequenceOf", @@ -4640,6 +4728,14 @@ Enum0_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [Enum0] >>> ***/ + +static asn_per_constraints_t asn_PER_Enum0_constr_1 = { + { APC_CONSTRAINED, 1, 1, 0, 1 } /* (0..1) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [Enum0] >>> ***/ static asn_INTEGER_enum_map_t asn_MAP_Enum0_value2enum_1[] = { @@ -4660,10 +4756,6 @@ static asn_INTEGER_specifics_t asn_SPC_Enum0_specs_1 = { static ber_tlv_tag_t asn_DEF_Enum0_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)) }; -static asn_per_constraints_t asn_PER_Enum0_constr_1 = { - { APC_CONSTRAINED, 1, 1, 0, 1 } /* (0..1) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_Enum0 = { "Enum0", "Enum0", @@ -4825,6 +4917,14 @@ Enum1_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [Enum1] >>> ***/ + +static asn_per_constraints_t asn_PER_Enum1_constr_1 = { + { APC_CONSTRAINED, 1, 1, 0, 1 } /* (0..1) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [Enum1] >>> ***/ static asn_INTEGER_enum_map_t asn_MAP_Enum1_value2enum_1[] = { @@ -4845,10 +4945,6 @@ static asn_INTEGER_specifics_t asn_SPC_Enum1_specs_1 = { static ber_tlv_tag_t asn_DEF_Enum1_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)) }; -static asn_per_constraints_t asn_PER_Enum1_constr_1 = { - { APC_CONSTRAINED, 1, 1, 0, 1 } /* (0..1) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_Enum1 = { "Enum1", "Enum1", @@ -4959,6 +5055,16 @@ Identifier_constraint(asn_TYPE_descriptor_t *td, const void *sptr, } } +static int asn_PER_MAP_Identifier_1_v2c(unsigned int value) { + if(value >= sizeof(permitted_alphabet_table_1)/sizeof(permitted_alphabet_table_1[0])) + return -1; + return permitted_alphabet_table_1[value] - 1; +} +static int asn_PER_MAP_Identifier_1_c2v(unsigned int code) { + if(code >= sizeof(permitted_alphabet_code2value_1)/sizeof(permitted_alphabet_code2value_1[0])) + return -1; + return permitted_alphabet_code2value_1[code]; +} /* * This type is implemented using VisibleString, * so here we adjust the DEF accordingly. @@ -5040,15 +5146,20 @@ Identifier_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [Identifier] >>> ***/ + +static asn_per_constraints_t asn_PER_Identifier_constr_1 = { + { APC_CONSTRAINED, 6, 6, 36, 122 } /* (36..122) */, + { APC_CONSTRAINED, 5, 5, 1, 32 } /* (SIZE(1..32)) */, + asn_PER_MAP_Identifier_1_v2c, /* Value to PER code map */ + asn_PER_MAP_Identifier_1_c2v /* PER code to value map */ +}; + /*** <<< STAT-DEFS [Identifier] >>> ***/ static ber_tlv_tag_t asn_DEF_Identifier_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (26 << 2)) }; -static asn_per_constraints_t asn_PER_Identifier_constr_1 = { - { APC_CONSTRAINED, 7, 7, 36, 122 } /* (36..122) */, - { APC_CONSTRAINED, 5, 5, 1, 32 } /* (SIZE(1..32)) */ -}; asn_TYPE_descriptor_t asn_DEF_Identifier = { "Identifier", "Identifier", diff --git a/tests/90-cond-int-type-OK.asn1.-Pgen-PER b/tests/90-cond-int-type-OK.asn1.-Pgen-PER index bd2f6e99..6fac7642 100644 --- a/tests/90-cond-int-type-OK.asn1.-Pgen-PER +++ b/tests/90-cond-int-type-OK.asn1.-Pgen-PER @@ -267,15 +267,19 @@ CN_IntegerMinMax_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [CN-IntegerMinMax] >>> ***/ + +static asn_per_constraints_t asn_PER_CN_IntegerMinMax_constr_1 = { + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [CN-IntegerMinMax] >>> ***/ static ber_tlv_tag_t asn_DEF_CN_IntegerMinMax_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_CN_IntegerMinMax_constr_1 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 }, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_CN_IntegerMinMax = { "CN-IntegerMinMax", "CN-IntegerMinMax", @@ -436,15 +440,19 @@ CN_IntegerMinLow_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [CN-IntegerMinLow] >>> ***/ + +static asn_per_constraints_t asn_PER_CN_IntegerMinLow_constr_1 = { + { APC_UNCONSTRAINED, -1, -1, 0, 0 } /* (MIN..1) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [CN-IntegerMinLow] >>> ***/ static ber_tlv_tag_t asn_DEF_CN_IntegerMinLow_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_CN_IntegerMinLow_constr_1 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 } /* (MIN..1) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_CN_IntegerMinLow = { "CN-IntegerMinLow", "CN-IntegerMinLow", @@ -605,15 +613,19 @@ NO_IntegerMinHigh_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [NO-IntegerMinHigh] >>> ***/ + +static asn_per_constraints_t asn_PER_NO_IntegerMinHigh_constr_1 = { + { APC_UNCONSTRAINED, -1, -1, 0, 0 } /* (MIN..3000000000) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [NO-IntegerMinHigh] >>> ***/ static ber_tlv_tag_t asn_DEF_NO_IntegerMinHigh_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_NO_IntegerMinHigh_constr_1 = { - { APC_UNCONSTRAINED, -1, -1, 0, 0 } /* (MIN..3000000000) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_NO_IntegerMinHigh = { "NO-IntegerMinHigh", "NO-IntegerMinHigh", @@ -774,15 +786,19 @@ NO_IntegerLowHigh_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [NO-IntegerLowHigh] >>> ***/ + +static asn_per_constraints_t asn_PER_NO_IntegerLowHigh_constr_1 = { + { APC_CONSTRAINED, 32, -1, 1, 3000000000 } /* (1..3000000000) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [NO-IntegerLowHigh] >>> ***/ static ber_tlv_tag_t asn_DEF_NO_IntegerLowHigh_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_NO_IntegerLowHigh_constr_1 = { - { APC_CONSTRAINED, 32, -1, 1, 3000000000 } /* (1..3000000000) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_NO_IntegerLowHigh = { "NO-IntegerLowHigh", "NO-IntegerLowHigh", @@ -943,15 +959,19 @@ CN_IntegerLowMax_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [CN-IntegerLowMax] >>> ***/ + +static asn_per_constraints_t asn_PER_CN_IntegerLowMax_constr_1 = { + { APC_SEMI_CONSTRAINED, -1, -1, 1, 0 } /* (1..MAX) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [CN-IntegerLowMax] >>> ***/ static ber_tlv_tag_t asn_DEF_CN_IntegerLowMax_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_CN_IntegerLowMax_constr_1 = { - { APC_SEMI_CONSTRAINED, -1, -1, 1, 0 } /* (1..MAX) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_CN_IntegerLowMax = { "CN-IntegerLowMax", "CN-IntegerLowMax", @@ -1112,15 +1132,19 @@ NO_IntegerHighMax_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [NO-IntegerHighMax] >>> ***/ + +static asn_per_constraints_t asn_PER_NO_IntegerHighMax_constr_1 = { + { APC_SEMI_CONSTRAINED, -1, -1, 3000000000, 0 } /* (3000000000..MAX) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [NO-IntegerHighMax] >>> ***/ static ber_tlv_tag_t asn_DEF_NO_IntegerHighMax_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_NO_IntegerHighMax_constr_1 = { - { APC_SEMI_CONSTRAINED, -1, -1, 3000000000, 0 } /* (3000000000..MAX) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_NO_IntegerHighMax = { "NO-IntegerHighMax", "NO-IntegerHighMax", @@ -1281,15 +1305,19 @@ NO_IntegerLowestMax_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [NO-IntegerLowestMax] >>> ***/ + +static asn_per_constraints_t asn_PER_NO_IntegerLowestMax_constr_1 = { + { APC_SEMI_CONSTRAINED, -1, -1, -3000000000, 0 } /* (-3000000000..MAX) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [NO-IntegerLowestMax] >>> ***/ static ber_tlv_tag_t asn_DEF_NO_IntegerLowestMax_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_NO_IntegerLowestMax_constr_1 = { - { APC_SEMI_CONSTRAINED, -1, -1, -3000000000, 0 } /* (-3000000000..MAX) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_NO_IntegerLowestMax = { "NO-IntegerLowestMax", "NO-IntegerLowestMax", @@ -1450,15 +1478,19 @@ NO_IntegerOutRange_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [NO-IntegerOutRange] >>> ***/ + +static asn_per_constraints_t asn_PER_NO_IntegerOutRange_constr_1 = { + { APC_CONSTRAINED, 1, -1, 3000000000, 3000000001 } /* (3000000000..3000000001) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [NO-IntegerOutRange] >>> ***/ static ber_tlv_tag_t asn_DEF_NO_IntegerOutRange_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_NO_IntegerOutRange_constr_1 = { - { APC_CONSTRAINED, 1, -1, 3000000000, 3000000001 } /* (3000000000..3000000001) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_NO_IntegerOutRange = { "NO-IntegerOutRange", "NO-IntegerOutRange", @@ -1619,15 +1651,19 @@ NO_IntegerOutValue_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [NO-IntegerOutValue] >>> ***/ + +static asn_per_constraints_t asn_PER_NO_IntegerOutValue_constr_1 = { + { APC_CONSTRAINED, 0, -1, 3000000000, 3000000000 } /* (3000000000..3000000000) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [NO-IntegerOutValue] >>> ***/ static ber_tlv_tag_t asn_DEF_NO_IntegerOutValue_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_NO_IntegerOutValue_constr_1 = { - { APC_CONSTRAINED, 0, -1, 3000000000, 3000000000 } /* (3000000000..3000000000) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_NO_IntegerOutValue = { "NO-IntegerOutValue", "NO-IntegerOutValue", @@ -1782,15 +1818,19 @@ OK_IntegerInRange1_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [OK-IntegerInRange1] >>> ***/ + +static asn_per_constraints_t asn_PER_OK_IntegerInRange1_constr_1 = { + { APC_CONSTRAINED, 8, 8, -100, 100 } /* (-100..100) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [OK-IntegerInRange1] >>> ***/ static ber_tlv_tag_t asn_DEF_OK_IntegerInRange1_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_OK_IntegerInRange1_constr_1 = { - { APC_CONSTRAINED, 8, 8, -100, 100 } /* (-100..100) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_OK_IntegerInRange1 = { "OK-IntegerInRange1", "OK-IntegerInRange1", @@ -1945,15 +1985,19 @@ OK_IntegerInRange2_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [OK-IntegerInRange2] >>> ***/ + +static asn_per_constraints_t asn_PER_OK_IntegerInRange2_constr_1 = { + { APC_CONSTRAINED, 8, 8, -100, 100 } /* (-100..100) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [OK-IntegerInRange2] >>> ***/ static ber_tlv_tag_t asn_DEF_OK_IntegerInRange2_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_OK_IntegerInRange2_constr_1 = { - { APC_CONSTRAINED, 8, 8, -100, 100 } /* (-100..100) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_OK_IntegerInRange2 = { "OK-IntegerInRange2", "OK-IntegerInRange2", @@ -2108,15 +2152,19 @@ OK_IntegerInRange3_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [OK-IntegerInRange3] >>> ***/ + +static asn_per_constraints_t asn_PER_OK_IntegerInRange3_constr_1 = { + { APC_CONSTRAINED, 32, -1, -2147483648, 2147483647 } /* (-2147483648..2147483647) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [OK-IntegerInRange3] >>> ***/ static ber_tlv_tag_t asn_DEF_OK_IntegerInRange3_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_OK_IntegerInRange3_constr_1 = { - { APC_CONSTRAINED, 32, -1, -2147483648, 2147483647 } /* (-2147483648..2147483647) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_OK_IntegerInRange3 = { "OK-IntegerInRange3", "OK-IntegerInRange3", @@ -2271,15 +2319,19 @@ OK_IntegerInRange4_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [OK-IntegerInRange4] >>> ***/ + +static asn_per_constraints_t asn_PER_OK_IntegerInRange4_constr_1 = { + { APC_CONSTRAINED, 32, -1, -2147483648, 2147483647 } /* (-2147483648..2147483647) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [OK-IntegerInRange4] >>> ***/ static ber_tlv_tag_t asn_DEF_OK_IntegerInRange4_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_OK_IntegerInRange4_constr_1 = { - { APC_CONSTRAINED, 32, -1, -2147483648, 2147483647 } /* (-2147483648..2147483647) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_OK_IntegerInRange4 = { "OK-IntegerInRange4", "OK-IntegerInRange4", @@ -2440,15 +2492,19 @@ OK_IntegerInRange5_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [OK-IntegerInRange5] >>> ***/ + +static asn_per_constraints_t asn_PER_OK_IntegerInRange5_constr_1 = { + { APC_CONSTRAINED | APC_EXTENSIBLE, 32, -1, -2147483648, 2147483647 } /* (-2147483648..2147483647,...) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [OK-IntegerInRange5] >>> ***/ static ber_tlv_tag_t asn_DEF_OK_IntegerInRange5_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_OK_IntegerInRange5_constr_1 = { - { APC_CONSTRAINED | APC_EXTENSIBLE, 32, -1, -2147483648, 2147483647 } /* (-2147483648..2147483647,...) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_OK_IntegerInRange5 = { "OK-IntegerInRange5", "OK-IntegerInRange5", @@ -2609,15 +2665,19 @@ NO_IntegerInRange6_encode_uper(asn_TYPE_descriptor_t *td, } +/*** <<< CTDEFS [NO-IntegerInRange6] >>> ***/ + +static asn_per_constraints_t asn_PER_NO_IntegerInRange6_constr_1 = { + { APC_CONSTRAINED, 32, -1, 0, 4294967295 } /* (0..4294967295) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [NO-IntegerInRange6] >>> ***/ static ber_tlv_tag_t asn_DEF_NO_IntegerInRange6_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)) }; -static asn_per_constraints_t asn_PER_NO_IntegerInRange6_constr_1 = { - { APC_CONSTRAINED, 32, -1, 0, 4294967295 } /* (0..4294967295) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_NO_IntegerInRange6 = { "NO-IntegerInRange6", "NO-IntegerInRange6", diff --git a/tests/95-choice-per-order-OK.asn1.-Pgen-PER b/tests/95-choice-per-order-OK.asn1.-Pgen-PER index 2256b5b7..b5429769 100644 --- a/tests/95-choice-per-order-OK.asn1.-Pgen-PER +++ b/tests/95-choice-per-order-OK.asn1.-Pgen-PER @@ -56,6 +56,19 @@ typedef struct Choice { extern asn_TYPE_descriptor_t asn_DEF_Choice; +/*** <<< CTDEFS [Choice] >>> ***/ + +static asn_per_constraints_t asn_PER_ch_constr_4 = { + { APC_CONSTRAINED, 1, 1, 0, 1 } /* (0..1) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; +static asn_per_constraints_t asn_PER_Choice_constr_1 = { + { APC_CONSTRAINED | APC_EXTENSIBLE, 2, 2, 0, 2 } /* (0..2,...) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [Choice] >>> ***/ static asn_TYPE_member_t asn_MBR_ch_4[] = { @@ -93,10 +106,6 @@ static asn_CHOICE_specifics_t asn_SPC_ch_specs_4 = { .canonical_order = asn_MAP_ch_cmap_4, /* Canonically sorted */ .ext_start = -1 /* Extensions start */ }; -static asn_per_constraints_t asn_PER_ch_constr_4 = { - { APC_CONSTRAINED, 1, 1, 0, 1 } /* (0..1) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; static /* Use -fall-defs-global to expose */ asn_TYPE_descriptor_t asn_DEF_ch_4 = { "ch", @@ -121,10 +130,6 @@ asn_TYPE_descriptor_t asn_DEF_ch_4 = { &asn_SPC_ch_specs_4 /* Additional specs */ }; -static asn_per_constraints_t asn_PER_memb_ch_constr_4 = { - { APC_CONSTRAINED, 1, 1, 0, 1 } /* (0..1) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; static asn_TYPE_member_t asn_MBR_Choice_1[] = { { ATF_NOFLAGS, 0, offsetof(struct Choice, choice.roid), .tag = (ASN_TAG_CLASS_UNIVERSAL | (13 << 2)), @@ -149,7 +154,7 @@ static asn_TYPE_member_t asn_MBR_Choice_1[] = { .tag_mode = 0, .type = &asn_DEF_ch_4, .memb_constraints = 0, /* Defer constraints checking to the member type */ - .per_constraints = &asn_PER_memb_ch_constr_4, + .per_constraints = &asn_PER_ch_constr_4, .default_value = 0, .name = "ch" }, @@ -181,10 +186,6 @@ static asn_CHOICE_specifics_t asn_SPC_Choice_specs_1 = { .canonical_order = asn_MAP_Choice_cmap_1, /* Canonically sorted */ .ext_start = 3 /* Extensions start */ }; -static asn_per_constraints_t asn_PER_Choice_constr_1 = { - { APC_CONSTRAINED | APC_EXTENSIBLE, 2, 2, 0, 2 } /* (0..2,...) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_Choice = { "Choice", "Choice", @@ -240,6 +241,14 @@ typedef struct Choice2 { extern asn_TYPE_descriptor_t asn_DEF_Choice2; +/*** <<< CTDEFS [Choice2] >>> ***/ + +static asn_per_constraints_t asn_PER_Choice2_constr_1 = { + { APC_CONSTRAINED, 1, 1, 0, 1 } /* (0..1) */, + { APC_UNCONSTRAINED, -1, -1, 0, 0 }, + 0, 0 /* No PER value map */ +}; + /*** <<< STAT-DEFS [Choice2] >>> ***/ static asn_TYPE_member_t asn_MBR_Choice2_1[] = { @@ -276,10 +285,6 @@ static asn_CHOICE_specifics_t asn_SPC_Choice2_specs_1 = { .canonical_order = 0, .ext_start = -1 /* Extensions start */ }; -static asn_per_constraints_t asn_PER_Choice2_constr_1 = { - { APC_CONSTRAINED, 1, 1, 0, 1 } /* (0..1) */, - { APC_UNCONSTRAINED, -1, -1, 0, 0 } -}; asn_TYPE_descriptor_t asn_DEF_Choice2 = { "Choice2", "Choice2", |