aboutsummaryrefslogtreecommitdiffstats
path: root/skeletons
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2005-11-26 11:25:14 +0000
committerLev Walkin <vlm@lionet.info>2005-11-26 11:25:14 +0000
commit59b176ee355b3e82e6a8649b164c187c7a17a28f (patch)
tree6d864f02cd16eb75f4ae6e40199d1879d8363152 /skeletons
parent708530582f5ba965fb596c3e189eec23c52337d9 (diff)
upgrade: PER related changes
Diffstat (limited to 'skeletons')
-rw-r--r--skeletons/ANY.c2
-rw-r--r--skeletons/BIT_STRING.c6
-rw-r--r--skeletons/BMPString.c4
-rw-r--r--skeletons/BOOLEAN.c38
-rw-r--r--skeletons/BOOLEAN.h1
-rw-r--r--skeletons/ENUMERATED.c24
-rw-r--r--skeletons/ENUMERATED.h4
-rw-r--r--skeletons/GeneralString.c2
-rw-r--r--skeletons/GeneralizedTime.c2
-rw-r--r--skeletons/GraphicString.c2
-rw-r--r--skeletons/IA5String.c2
-rw-r--r--skeletons/INTEGER.c101
-rw-r--r--skeletons/INTEGER.h3
-rw-r--r--skeletons/ISO646String.c2
-rw-r--r--skeletons/NULL.c37
-rw-r--r--skeletons/NULL.h1
-rw-r--r--skeletons/NativeEnumerated.c58
-rw-r--r--skeletons/NativeEnumerated.h1
-rw-r--r--skeletons/NativeInteger.c75
-rw-r--r--skeletons/NativeInteger.h1
-rw-r--r--skeletons/NativeReal.c4
-rw-r--r--skeletons/NumericString.c2
-rw-r--r--skeletons/OBJECT_IDENTIFIER.c6
-rw-r--r--skeletons/OCTET_STRING.c131
-rw-r--r--skeletons/OCTET_STRING.h1
-rw-r--r--skeletons/ObjectDescriptor.c2
-rw-r--r--skeletons/PrintableString.c2
-rw-r--r--skeletons/README10
-rw-r--r--skeletons/REAL.c6
-rw-r--r--skeletons/RELATIVE-OID.c6
-rw-r--r--skeletons/T61String.c2
-rw-r--r--skeletons/TeletexString.c2
-rw-r--r--skeletons/UTCTime.c2
-rw-r--r--skeletons/UTF8String.c2
-rw-r--r--skeletons/UniversalString.c4
-rw-r--r--skeletons/VideotexString.c2
-rw-r--r--skeletons/VisibleString.c2
-rw-r--r--skeletons/asn-decoder-template.c63
-rw-r--r--skeletons/asn_codecs.h14
-rw-r--r--skeletons/asn_codecs_prim.c4
-rw-r--r--skeletons/constr_CHOICE.c95
-rw-r--r--skeletons/constr_CHOICE.h9
-rw-r--r--skeletons/constr_SEQUENCE.c138
-rw-r--r--skeletons/constr_SEQUENCE.h13
-rw-r--r--skeletons/constr_SEQUENCE_OF.c6
-rw-r--r--skeletons/constr_SEQUENCE_OF.h1
-rw-r--r--skeletons/constr_SET.c6
-rw-r--r--skeletons/constr_SET_OF.c94
-rw-r--r--skeletons/constr_SET_OF.h1
-rw-r--r--skeletons/constr_TYPE.h9
-rw-r--r--skeletons/file-dependencies8
-rw-r--r--skeletons/per_decoder.c2
-rw-r--r--skeletons/per_decoder.h55
-rw-r--r--skeletons/per_support.c148
-rw-r--r--skeletons/per_support.h54
-rw-r--r--skeletons/tests/Makefile.am3
-rw-r--r--skeletons/tests/Makefile.in23
-rw-r--r--skeletons/tests/check-INTEGER.c1
-rw-r--r--skeletons/tests/check-OCTET_STRING.c1
-rw-r--r--skeletons/tests/check-PER.c105
-rw-r--r--skeletons/tests/check-UTF8String.c1
-rw-r--r--skeletons/tests/check-length.c1
-rw-r--r--skeletons/xer_encoder.c4
-rw-r--r--skeletons/xer_support.c6
64 files changed, 1268 insertions, 149 deletions
diff --git a/skeletons/ANY.c b/skeletons/ANY.c
index 73702444..b1e35bf0 100644
--- a/skeletons/ANY.c
+++ b/skeletons/ANY.c
@@ -21,8 +21,10 @@ asn_TYPE_descriptor_t asn_DEF_ANY = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_hex,
ANY_encode_xer,
+ 0,
0, /* Use generic outmost tag fetcher */
0, 0, 0, 0,
+ 0, /* No PER visible constraints */
0, 0, /* No members */
&asn_DEF_ANY_specs,
};
diff --git a/skeletons/BIT_STRING.c b/skeletons/BIT_STRING.c
index 8c83d689..900f41db 100644
--- a/skeletons/BIT_STRING.c
+++ b/skeletons/BIT_STRING.c
@@ -27,6 +27,7 @@ asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
OCTET_STRING_decode_xer_binary,
BIT_STRING_encode_xer,
+ OCTET_STRING_decode_uper, /* Unaligned PER decoder */
0, /* Use generic outmost tag fetcher */
asn_DEF_BIT_STRING_tags,
sizeof(asn_DEF_BIT_STRING_tags)
@@ -34,6 +35,7 @@ asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
asn_DEF_BIT_STRING_tags, /* Same as above */
sizeof(asn_DEF_BIT_STRING_tags)
/ sizeof(asn_DEF_BIT_STRING_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
&asn_DEF_BIT_STRING_specs
};
@@ -124,9 +126,7 @@ BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
- er.structure_ptr = 0;
- er.failed_type = 0;
- return er;
+ _ASN_ENCODED_OK(er);
cb_failed:
_ASN_ENCODE_FAILED;
}
diff --git a/skeletons/BMPString.c b/skeletons/BMPString.c
index f3308bf7..10fd05e0 100644
--- a/skeletons/BMPString.c
+++ b/skeletons/BMPString.c
@@ -23,6 +23,7 @@ asn_TYPE_descriptor_t asn_DEF_BMPString = {
OCTET_STRING_encode_der,
BMPString_decode_xer, /* Convert from UTF-8 */
BMPString_encode_xer, /* Convert to UTF-8 */
+ 0,
0, /* Use generic outmost tag fetcher */
asn_DEF_BMPString_tags,
sizeof(asn_DEF_BMPString_tags)
@@ -30,6 +31,7 @@ asn_TYPE_descriptor_t asn_DEF_BMPString = {
asn_DEF_BMPString_tags,
sizeof(asn_DEF_BMPString_tags)
/ sizeof(asn_DEF_BMPString_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
@@ -156,7 +158,7 @@ BMPString_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
er.encoded = BMPString__dump(st, cb, app_key);
if(er.encoded < 0) _ASN_ENCODE_FAILED;
- return er;
+ _ASN_ENCODED_OK(er);
}
int
diff --git a/skeletons/BOOLEAN.c b/skeletons/BOOLEAN.c
index 360b6643..84e57858 100644
--- a/skeletons/BOOLEAN.c
+++ b/skeletons/BOOLEAN.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
@@ -22,11 +22,13 @@ asn_TYPE_descriptor_t asn_DEF_BOOLEAN = {
BOOLEAN_encode_der,
BOOLEAN_decode_xer,
BOOLEAN_encode_xer,
+ BOOLEAN_decode_uper, /* Unaligned PER decoder */
0, /* Use generic outmost tag fetcher */
asn_DEF_BOOLEAN_tags,
sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]),
asn_DEF_BOOLEAN_tags, /* Same as above */
sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
@@ -126,7 +128,7 @@ BOOLEAN_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
erval.encoded += 1;
- return erval;
+ _ASN_ENCODED_OK(erval);
}
@@ -196,7 +198,7 @@ BOOLEAN_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
er.encoded = 8;
}
- return er;
+ _ASN_ENCODED_OK(er);
cb_failed:
_ASN_ENCODE_FAILED;
}
@@ -234,3 +236,33 @@ BOOLEAN_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
}
}
+asn_dec_rval_t
+BOOLEAN_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+ asn_dec_rval_t rv;
+ BOOLEAN_t *st = (BOOLEAN_t *)*sptr;
+
+ (void)opt_codec_ctx;
+ (void)constraints;
+
+ if(!st) {
+ st = (BOOLEAN_t *)(*sptr = MALLOC(sizeof(*st)));
+ if(!st) _ASN_DECODE_FAILED;
+ }
+
+ /*
+ * Extract a single bit
+ */
+ switch(per_get_few_bits(pd, 1)) {
+ case 1: *st = 1; break;
+ case 0: *st = 0; break;
+ case -1: default: _ASN_DECODE_FAILED;
+ }
+
+ ASN_DEBUG("%s decoded as %s", td->name, *st ? "TRUE" : "FALSE");
+
+ rv.code = RC_OK;
+ rv.consumed = 1;
+ return rv;
+}
+
diff --git a/skeletons/BOOLEAN.h b/skeletons/BOOLEAN.h
index ec4dbac8..1cf19803 100644
--- a/skeletons/BOOLEAN.h
+++ b/skeletons/BOOLEAN.h
@@ -26,6 +26,7 @@ ber_type_decoder_f BOOLEAN_decode_ber;
der_type_encoder_f BOOLEAN_encode_der;
xer_type_decoder_f BOOLEAN_decode_xer;
xer_type_encoder_f BOOLEAN_encode_xer;
+per_type_decoder_f BOOLEAN_decode_uper;
#ifdef __cplusplus
}
diff --git a/skeletons/ENUMERATED.c b/skeletons/ENUMERATED.c
index 12d4f6eb..c51f9265 100644
--- a/skeletons/ENUMERATED.c
+++ b/skeletons/ENUMERATED.c
@@ -1,9 +1,10 @@
/*-
- * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
#include <ENUMERATED.h>
+#include <NativeEnumerated.h>
#include <asn_codecs_prim.h> /* Encoder and decoder of a primitive type */
/*
@@ -22,12 +23,33 @@ asn_TYPE_descriptor_t asn_DEF_ENUMERATED = {
INTEGER_encode_der, /* Implemented in terms of INTEGER */
INTEGER_decode_xer, /* This is temporary! */
INTEGER_encode_xer,
+ ENUMERATED_decode_uper, /* Unaligned PER decoder */
0, /* Use generic outmost tag fetcher */
asn_DEF_ENUMERATED_tags,
sizeof(asn_DEF_ENUMERATED_tags) / sizeof(asn_DEF_ENUMERATED_tags[0]),
asn_DEF_ENUMERATED_tags, /* Same as above */
sizeof(asn_DEF_ENUMERATED_tags) / sizeof(asn_DEF_ENUMERATED_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
+asn_dec_rval_t
+ENUMERATED_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+ asn_dec_rval_t rval;
+ ENUMERATED_t *st = (ENUMERATED_t *)*sptr;
+ long value, *vptr = &value;
+
+ if(!st) {
+ st = (ENUMERATED_t *)(*sptr = CALLOC(1, sizeof(*st)));
+ if(!st) _ASN_DECODE_FAILED;
+ }
+
+ rval = NativeEnumerated_decode_uper(opt_codec_ctx, td, constraints,
+ (void **)&vptr, pd);
+ if(rval.code == RC_OK)
+ if(asn_long2INTEGER(st, value))
+ rval.code = RC_FAIL;
+ return rval;
+}
diff --git a/skeletons/ENUMERATED.h b/skeletons/ENUMERATED.h
index 53cc273e..e65a15af 100644
--- a/skeletons/ENUMERATED.h
+++ b/skeletons/ENUMERATED.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#ifndef _ENUMERATED_H_
@@ -15,6 +15,8 @@ typedef INTEGER_t ENUMERATED_t; /* Implemented via INTEGER */
extern asn_TYPE_descriptor_t asn_DEF_ENUMERATED;
+per_type_decoder_f ENUMERATED_decode_uper;
+
#ifdef __cplusplus
}
#endif
diff --git a/skeletons/GeneralString.c b/skeletons/GeneralString.c
index e4ea6f8a..c1a8823e 100644
--- a/skeletons/GeneralString.c
+++ b/skeletons/GeneralString.c
@@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_GeneralString = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_hex,
OCTET_STRING_encode_xer,
+ 0,
0, /* Use generic outmost tag fetcher */
asn_DEF_GeneralString_tags,
sizeof(asn_DEF_GeneralString_tags)
@@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_GeneralString = {
asn_DEF_GeneralString_tags,
sizeof(asn_DEF_GeneralString_tags)
/ sizeof(asn_DEF_GeneralString_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/GeneralizedTime.c b/skeletons/GeneralizedTime.c
index 9103455d..aabe66d6 100644
--- a/skeletons/GeneralizedTime.c
+++ b/skeletons/GeneralizedTime.c
@@ -128,6 +128,7 @@ asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = {
GeneralizedTime_encode_der,
OCTET_STRING_decode_xer_utf8,
GeneralizedTime_encode_xer,
+ 0,
0, /* Use generic outmost tag fetcher */
asn_DEF_GeneralizedTime_tags,
sizeof(asn_DEF_GeneralizedTime_tags)
@@ -135,6 +136,7 @@ asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = {
asn_DEF_GeneralizedTime_tags,
sizeof(asn_DEF_GeneralizedTime_tags)
/ sizeof(asn_DEF_GeneralizedTime_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/GraphicString.c b/skeletons/GraphicString.c
index c5d4a30b..0c3ad47c 100644
--- a/skeletons/GraphicString.c
+++ b/skeletons/GraphicString.c
@@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_GraphicString = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_hex,
OCTET_STRING_encode_xer, /* Can't expect it to be ASCII/UTF8 */
+ 0,
0, /* Use generic outmost tag fetcher */
asn_DEF_GraphicString_tags,
sizeof(asn_DEF_GraphicString_tags)
@@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_GraphicString = {
asn_DEF_GraphicString_tags,
sizeof(asn_DEF_GraphicString_tags)
/ sizeof(asn_DEF_GraphicString_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/IA5String.c b/skeletons/IA5String.c
index c4da875a..a4d7ff84 100644
--- a/skeletons/IA5String.c
+++ b/skeletons/IA5String.c
@@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_IA5String = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
+ 0,
0, /* Use generic outmost tag fetcher */
asn_DEF_IA5String_tags,
sizeof(asn_DEF_IA5String_tags)
@@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_IA5String = {
asn_DEF_IA5String_tags,
sizeof(asn_DEF_IA5String_tags)
/ sizeof(asn_DEF_IA5String_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/INTEGER.c b/skeletons/INTEGER.c
index d2a66b5d..dbb14859 100644
--- a/skeletons/INTEGER.c
+++ b/skeletons/INTEGER.c
@@ -24,11 +24,13 @@ asn_TYPE_descriptor_t asn_DEF_INTEGER = {
INTEGER_encode_der,
INTEGER_decode_xer,
INTEGER_encode_xer,
+ INTEGER_decode_uper, /* Unaligned PER decoder */
0, /* Use generic outmost tag fetcher */
asn_DEF_INTEGER_tags,
sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]),
asn_DEF_INTEGER_tags, /* Same as above */
sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
@@ -430,9 +432,102 @@ INTEGER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
er.encoded = INTEGER__dump(td, st, cb, app_key, 1);
if(er.encoded < 0) _ASN_ENCODE_FAILED;
- er.structure_ptr = 0;
- er.failed_type = 0;
- return er;
+ _ASN_ENCODED_OK(er);
+}
+
+asn_dec_rval_t
+INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+ asn_dec_rval_t rval = { RC_OK, 0 };
+ INTEGER_t *st = (INTEGER_t *)*sptr;
+ asn_per_constraint_t *ct;
+ int repeat;
+
+ (void)opt_codec_ctx;
+
+ if(!st) {
+ st = (INTEGER_t *)(*sptr = CALLOC(1, sizeof(*st)));
+ if(!st) _ASN_DECODE_FAILED;
+ }
+
+ if(!constraints) constraints = td->per_constraints;
+ ct = constraints ? &constraints->value : 0;
+
+ if(ct && ct->flags & APC_EXTENSIBLE) {
+ int inext = per_get_few_bits(pd, 1);
+ if(inext < 0) _ASN_DECODE_FAILED;
+ if(inext) ct = 0;
+ }
+
+ FREEMEM(st->buf);
+ if(ct) {
+ if(ct->flags & APC_SEMI_CONSTRAINED) {
+ st->buf = (uint8_t *)CALLOC(1, 2);
+ if(!st->buf) _ASN_DECODE_FAILED;
+ st->size = 1;
+ } else if(ct->flags & APC_CONSTRAINED && ct->range_bits >= 0) {
+ size_t size = (ct->range_bits + 7) >> 3;
+ st->buf = (uint8_t *)MALLOC(1 + size + 1);
+ if(!st->buf) _ASN_DECODE_FAILED;
+ st->size = size;
+ } else {
+ st->size = 0;
+ }
+ } else {
+ st->size = 0;
+ }
+
+ /* X.691, #12.2.2 */
+ if(ct && ct->flags != APC_UNCONSTRAINED) {
+ /* #10.5.6 */
+ ASN_DEBUG("Integer with range %d bits", ct->range_bits);
+ if(ct->range_bits >= 0) {
+ long value = per_get_few_bits(pd, ct->range_bits);
+ if(value < 0) _ASN_DECODE_FAILED;
+ ASN_DEBUG("Got value %ld + low %ld",
+ value, ct->lower_bound);
+ value += ct->lower_bound;
+ if(asn_long2INTEGER(st, value))
+ _ASN_DECODE_FAILED;
+ return rval;
+ }
+ } else {
+ ASN_DEBUG("Decoding unconstrained integer %s", td->name);
+ }
+
+ /* X.691, #12.2.3, #12.2.4 */
+ do {
+ ssize_t len;
+ void *p;
+ int ret;
+
+ /* Get the PER length */
+ len = uper_get_length(pd, -1, &repeat);
+ if(len < 0) _ASN_DECODE_FAILED;
+
+ p = REALLOC(st->buf, st->size + len + 1);
+ if(!p) _ASN_DECODE_FAILED;
+ st->buf = (uint8_t *)p;
+
+ ret = per_get_many_bits(pd, &st->buf[st->size], 0, 8 * len);
+ if(ret < 0) _ASN_DECODE_FAILED;
+ st->size += len;
+ } while(repeat);
+ st->buf[st->size] = 0; /* JIC */
+
+ /* #12.2.3 */
+ if(ct && ct->lower_bound) {
+ /*
+ * TODO: replace by in-place arithmetics.
+ */
+ long value;
+ if(asn_INTEGER2long(st, &value))
+ _ASN_DECODE_FAILED;
+ if(asn_long2INTEGER(st, value + ct->lower_bound))
+ _ASN_DECODE_FAILED;
+ }
+
+ return rval;
}
int
diff --git a/skeletons/INTEGER.h b/skeletons/INTEGER.h
index 165c055f..410fbe90 100644
--- a/skeletons/INTEGER.h
+++ b/skeletons/INTEGER.h
@@ -28,7 +28,7 @@ typedef struct asn_INTEGER_specifics_s {
asn_INTEGER_enum_map_t *value2enum; /* N -> "tag"; sorted by N */
unsigned int *enum2value; /* "tag" => N; sorted by tag */
int map_count; /* Elements in either map */
- int extensible; /* This map is extensible */
+ int extension; /* This map is extensible */
int strict_enumeration; /* Enumeration set is fixed */
} asn_INTEGER_specifics_t;
@@ -37,6 +37,7 @@ ber_type_decoder_f INTEGER_decode_ber;
der_type_encoder_f INTEGER_encode_der;
xer_type_decoder_f INTEGER_decode_xer;
xer_type_encoder_f INTEGER_encode_xer;
+per_type_decoder_f INTEGER_decode_uper;
/***********************************
* Some handy conversion routines. *
diff --git a/skeletons/ISO646String.c b/skeletons/ISO646String.c
index 035734b5..829af328 100644
--- a/skeletons/ISO646String.c
+++ b/skeletons/ISO646String.c
@@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_ISO646String = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
+ 0,
0, /* Use generic outmost tag fetcher */
asn_DEF_ISO646String_tags,
sizeof(asn_DEF_ISO646String_tags)
@@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_ISO646String = {
asn_DEF_ISO646String_tags,
sizeof(asn_DEF_ISO646String_tags)
/ sizeof(asn_DEF_ISO646String_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/NULL.c b/skeletons/NULL.c
index 5b0351e3..504be954 100644
--- a/skeletons/NULL.c
+++ b/skeletons/NULL.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
@@ -23,11 +23,13 @@ asn_TYPE_descriptor_t asn_DEF_NULL = {
NULL_encode_der, /* Special handling of DER encoding */
NULL_decode_xer,
NULL_encode_xer,
+ NULL_decode_uper, /* Unaligned PER decoder */
0, /* Use generic outmost tag fetcher */
asn_DEF_NULL_tags,
sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]),
asn_DEF_NULL_tags, /* Same as above */
sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
@@ -44,7 +46,7 @@ NULL_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
erval.structure_ptr = ptr;
}
- return erval;
+ _ASN_ENCODED_OK(erval);
}
asn_enc_rval_t
@@ -62,8 +64,7 @@ NULL_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
/* XMLNullValue is empty */
er.encoded = 0;
-
- return er;
+ _ASN_ENCODED_OK(er);
}
@@ -101,3 +102,31 @@ NULL_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
}
}
+
+asn_dec_rval_t
+NULL_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+ asn_dec_rval_t rv;
+
+ (void)opt_codec_ctx;
+ (void)td;
+ (void)constraints;
+ (void)pd;
+
+ if(!*sptr) {
+ *sptr = MALLOC(sizeof(NULL_t));
+ if(*sptr) {
+ *(NULL_t *)*sptr = 0;
+ } else {
+ _ASN_DECODE_FAILED;
+ }
+ }
+
+ /*
+ * NULL type does not have content octets.
+ */
+
+ rv.code = RC_OK;
+ rv.consumed = 0;
+ return rv;
+}
diff --git a/skeletons/NULL.h b/skeletons/NULL.h
index 28a3630e..7126e1df 100644
--- a/skeletons/NULL.h
+++ b/skeletons/NULL.h
@@ -23,6 +23,7 @@ asn_struct_print_f NULL_print;
der_type_encoder_f NULL_encode_der;
xer_type_decoder_f NULL_decode_xer;
xer_type_encoder_f NULL_encode_xer;
+per_type_decoder_f NULL_decode_uper;
#ifdef __cplusplus
}
diff --git a/skeletons/NativeEnumerated.c b/skeletons/NativeEnumerated.c
index fb77e06d..e130749f 100644
--- a/skeletons/NativeEnumerated.c
+++ b/skeletons/NativeEnumerated.c
@@ -28,11 +28,13 @@ asn_TYPE_descriptor_t asn_DEF_NativeEnumerated = {
NativeInteger_encode_der,
NativeInteger_decode_xer,
NativeEnumerated_encode_xer,
+ NativeEnumerated_decode_uper,
0, /* Use generic outmost tag fetcher */
asn_DEF_NativeEnumerated_tags,
sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
asn_DEF_NativeEnumerated_tags, /* Same as above */
sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
@@ -59,13 +61,65 @@ NativeEnumerated_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
er.encoded = snprintf(src, srcsize, "<%s/>", el->enum_name);
assert(er.encoded > 0 && (size_t)er.encoded < srcsize);
if(cb(src, er.encoded, app_key) < 0) _ASN_ENCODE_FAILED;
- return er;
+ _ASN_ENCODED_OK(er);
} else {
ASN_DEBUG("ASN.1 forbids dealing with "
"unknown value of ENUMERATED type");
_ASN_ENCODE_FAILED;
}
+}
+
+asn_dec_rval_t
+NativeEnumerated_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+ asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics;
+ asn_dec_rval_t rval = { RC_OK, 0 };
+ long *native = (long *)*sptr;
+ asn_per_constraint_t *ct;
+ long value;
+
+ (void)opt_codec_ctx;
+
+ if(constraints) ct = &constraints->value;
+ else if(td->per_constraints) ct = &td->per_constraints->value;
+ else _ASN_DECODE_FAILED; /* Mandatory! */
+ if(!specs) _ASN_DECODE_FAILED;
+
+ if(!native) {
+ native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
+ if(!native) _ASN_DECODE_FAILED;
+ }
+
+ ASN_DEBUG("Decoding %s as NativeEnumerated", td->name);
+
+ if(ct->flags & APC_EXTENSIBLE) {
+ int inext = per_get_few_bits(pd, 1);
+ if(inext < 0) _ASN_DECODE_FAILED;
+ if(inext) ct = 0;
+ }
+
+ if(ct && ct->range_bits >= 0) {
+ value = per_get_few_bits(pd, ct->range_bits);
+ if(value < 0) _ASN_DECODE_FAILED;
+ if(value >= (specs->extension
+ ? specs->extension - 1 : specs->map_count))
+ _ASN_DECODE_FAILED;
+ } else {
+ if(!specs->extension)
+ _ASN_DECODE_FAILED;
+ /*
+ * X.691, #10.6: normally small non-negative whole number;
+ */
+ value = uper_get_nsnnwn(pd);
+ if(value < 0) _ASN_DECODE_FAILED;
+ value += specs->extension - 1;
+ if(value >= specs->map_count)
+ _ASN_DECODE_FAILED;
+ }
+
+ *native = specs->value2enum[value].nat_value;
+ ASN_DEBUG("Decoded %s = %ld", td->name, *native);
- return er;
+ return rval;
}
diff --git a/skeletons/NativeEnumerated.h b/skeletons/NativeEnumerated.h
index 7e2bb1b9..5792beed 100644
--- a/skeletons/NativeEnumerated.h
+++ b/skeletons/NativeEnumerated.h
@@ -21,6 +21,7 @@ extern "C" {
extern asn_TYPE_descriptor_t asn_DEF_NativeEnumerated;
xer_type_encoder_f NativeEnumerated_encode_xer;
+per_type_decoder_f NativeEnumerated_decode_uper;
#ifdef __cplusplus
}
diff --git a/skeletons/NativeInteger.c b/skeletons/NativeInteger.c
index 96c78756..2e44eaa6 100644
--- a/skeletons/NativeInteger.c
+++ b/skeletons/NativeInteger.c
@@ -28,11 +28,13 @@ asn_TYPE_descriptor_t asn_DEF_NativeInteger = {
NativeInteger_encode_der,
NativeInteger_decode_xer,
NativeInteger_encode_xer,
+ NativeInteger_decode_uper, /* Unaligned PER decoder */
0, /* Use generic outmost tag fetcher */
asn_DEF_NativeInteger_tags,
sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
asn_DEF_NativeInteger_tags, /* Same as above */
sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
@@ -108,18 +110,6 @@ NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
}
*native = l;
-
- /*
- * Note that native integer size might be other than long.
- * This expression hopefully will be optimized away
- * by compiler.
- */
- if(sizeof(*native) != sizeof(long) && ((long)*native != l)) {
- *native = 0; /* Safe value */
- rval.code = RC_FAIL;
- rval.consumed = 0;
- return rval;
- }
}
rval.code = RC_OK;
@@ -176,38 +166,25 @@ NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname,
const void *buf_ptr, size_t size) {
asn_dec_rval_t rval;
- INTEGER_t *st = 0;
+ INTEGER_t st;
void *st_ptr = (void *)&st;
long *native = (long *)*sptr;
if(!native) {
- *sptr = CALLOC(1, sizeof(int));
- native = (long *)*sptr;
- if(!native) {
- rval.code = RC_FAIL;
- rval.consumed = 0;
- return rval;
- }
+ native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
+ if(!native) _ASN_DECODE_FAILED;
}
- rval = INTEGER_decode_xer(opt_codec_ctx, td, (void **)st_ptr,
+ memset(&st, 0, sizeof(st));
+ rval = INTEGER_decode_xer(opt_codec_ctx, td, &st_ptr,
opt_mname, buf_ptr, size);
if(rval.code == RC_OK) {
long l;
- if(asn_INTEGER2long(st, &l)) {
+ if(asn_INTEGER2long(&st, &l)) {
rval.code = RC_FAIL;
rval.consumed = 0;
} else {
*native = l;
-
- /* Native type might be shorter than long */
- if(sizeof(*native) != sizeof(long)
- && ((long)*native != l)) {
- *native = 0; /* Safe value */
- rval.code = RC_FAIL;
- rval.consumed = 0;
- return rval;
- }
}
} else {
/*
@@ -217,7 +194,7 @@ NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
*/
rval.consumed = 0;
}
- asn_DEF_INTEGER.free_struct(&asn_DEF_INTEGER, st, 0);
+ asn_DEF_INTEGER.free_struct(&asn_DEF_INTEGER, &st, 1);
return rval;
}
@@ -240,7 +217,39 @@ NativeInteger_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|| cb(scratch, er.encoded, app_key) < 0)
_ASN_ENCODE_FAILED;
- return er;
+ _ASN_ENCODED_OK(er);
+}
+
+asn_dec_rval_t
+NativeInteger_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+
+ asn_dec_rval_t rval;
+ long *native = (long *)*sptr;
+ INTEGER_t tmpint;
+ void *tmpintptr = &tmpint;
+
+ (void)opt_codec_ctx;
+ ASN_DEBUG("Decoding NativeInteger %s (UPER)", td->name);
+
+ if(!native) {
+ native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
+ if(!native) _ASN_DECODE_FAILED;
+ }
+
+ memset(&tmpint, 0, sizeof tmpint);
+ rval = INTEGER_decode_uper(opt_codec_ctx, td, constraints,
+ &tmpintptr, pd);
+ if(rval.code == RC_OK)
+ if(asn_INTEGER2long(&tmpint, native))
+ rval.code = RC_FAIL;
+ else
+ ASN_DEBUG("NativeInteger %s got value %ld",
+ td->name, *native);
+ asn_DEF_INTEGER.free_struct(&asn_DEF_INTEGER, &tmpint, 1);
+
+ return rval;
}
/*
diff --git a/skeletons/NativeInteger.h b/skeletons/NativeInteger.h
index f38fd477..e2ce22e9 100644
--- a/skeletons/NativeInteger.h
+++ b/skeletons/NativeInteger.h
@@ -27,6 +27,7 @@ ber_type_decoder_f NativeInteger_decode_ber;
der_type_encoder_f NativeInteger_encode_der;
xer_type_decoder_f NativeInteger_decode_xer;
xer_type_encoder_f NativeInteger_encode_xer;
+per_type_decoder_f NativeInteger_decode_uper;
#ifdef __cplusplus
}
diff --git a/skeletons/NativeReal.c b/skeletons/NativeReal.c
index f7755db1..9b303681 100644
--- a/skeletons/NativeReal.c
+++ b/skeletons/NativeReal.c
@@ -29,11 +29,13 @@ asn_TYPE_descriptor_t asn_DEF_NativeReal = {
NativeReal_encode_der,
NativeReal_decode_xer,
NativeReal_encode_xer,
+ 0,
0, /* Use generic outmost tag fetcher */
asn_DEF_NativeReal_tags,
sizeof(asn_DEF_NativeReal_tags) / sizeof(asn_DEF_NativeReal_tags[0]),
asn_DEF_NativeReal_tags, /* Same as above */
sizeof(asn_DEF_NativeReal_tags) / sizeof(asn_DEF_NativeReal_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
@@ -206,7 +208,7 @@ NativeReal_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
er.encoded = REAL__dump(*Dbl, flags & XER_F_CANONICAL, cb, app_key);
if(er.encoded < 0) _ASN_ENCODE_FAILED;
- return er;
+ _ASN_ENCODED_OK(er);
}
/*
diff --git a/skeletons/NumericString.c b/skeletons/NumericString.c
index 39404c25..e3302c6a 100644
--- a/skeletons/NumericString.c
+++ b/skeletons/NumericString.c
@@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_NumericString = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
+ 0,
0, /* Use generic outmost tag fetcher */
asn_DEF_NumericString_tags,
sizeof(asn_DEF_NumericString_tags)
@@ -29,6 +30,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 */
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/OBJECT_IDENTIFIER.c b/skeletons/OBJECT_IDENTIFIER.c
index e815d480..0c45e4d9 100644
--- a/skeletons/OBJECT_IDENTIFIER.c
+++ b/skeletons/OBJECT_IDENTIFIER.c
@@ -23,6 +23,7 @@ asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = {
der_encode_primitive,
OBJECT_IDENTIFIER_decode_xer,
OBJECT_IDENTIFIER_encode_xer,
+ 0,
0, /* Use generic outmost tag fetcher */
asn_DEF_OBJECT_IDENTIFIER_tags,
sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
@@ -30,6 +31,7 @@ asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = {
asn_DEF_OBJECT_IDENTIFIER_tags, /* Same as above */
sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
/ sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
@@ -332,9 +334,7 @@ OBJECT_IDENTIFIER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
er.encoded = OBJECT_IDENTIFIER__dump_body(st, cb, app_key);
if(er.encoded < 0) _ASN_ENCODE_FAILED;
- er.structure_ptr = 0;
- er.failed_type = 0;
- return er;
+ _ASN_ENCODED_OK(er);
}
int
diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c
index 447b2425..fe29f83f 100644
--- a/skeletons/OCTET_STRING.c
+++ b/skeletons/OCTET_STRING.c
@@ -19,6 +19,9 @@ static asn_OCTET_STRING_specifics_t asn_DEF_OCTET_STRING_specs = {
offsetof(OCTET_STRING_t, _asn_ctx),
0
};
+static asn_per_constraint_t asn_DEF_OCTET_STRING_constraint = {
+ APC_SEMI_CONSTRAINED, -1, 0, 0, 0
+};
asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = {
"OCTET STRING", /* Canonical name */
"OCTET_STRING", /* XML tag name */
@@ -29,6 +32,7 @@ asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_hex,
OCTET_STRING_encode_xer,
+ OCTET_STRING_decode_uper, /* Unaligned PER decoder */
0, /* Use generic outmost tag fetcher */
asn_DEF_OCTET_STRING_tags,
sizeof(asn_DEF_OCTET_STRING_tags)
@@ -36,6 +40,7 @@ asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = {
asn_DEF_OCTET_STRING_tags, /* Same as above */
sizeof(asn_DEF_OCTET_STRING_tags)
/ sizeof(asn_DEF_OCTET_STRING_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
&asn_DEF_OCTET_STRING_specs
};
@@ -61,9 +66,10 @@ asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = {
#undef RETURN
#define RETURN(_code) do { \
- rval.code = _code; \
- rval.consumed = consumed_myself; \
- return rval; \
+ asn_dec_rval_t tmprval; \
+ tmprval.code = _code; \
+ tmprval.consumed = consumed_myself; \
+ return tmprval; \
} while(0)
#undef APPEND
@@ -167,11 +173,11 @@ _new_stack() {
asn_dec_rval_t
OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
asn_TYPE_descriptor_t *td,
- void **os_structure, const void *buf_ptr, size_t size, int tag_mode) {
+ void **sptr, const void *buf_ptr, size_t size, int tag_mode) {
asn_OCTET_STRING_specifics_t *specs = td->specifics
? (asn_OCTET_STRING_specifics_t *)td->specifics
: &asn_DEF_OCTET_STRING_specs;
- BIT_STRING_t *st = (BIT_STRING_t *)*os_structure;
+ BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
asn_dec_rval_t rval;
asn_struct_ctx_t *ctx;
ssize_t consumed_myself = 0;
@@ -190,10 +196,8 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
* Create the string if does not exist.
*/
if(st == NULL) {
- *os_structure = CALLOC(1, specs->struct_size);
- st = (BIT_STRING_t *)*os_structure;
- if(st == NULL)
- RETURN(RC_FAIL);
+ st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
+ if(st == NULL) RETURN(RC_FAIL);
}
/* Restore parsing context */
@@ -549,9 +553,7 @@ OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
if(!cb) {
er.encoded += (type_variant == _TT_BIT_STRING) + st->size;
- er.structure_ptr = 0;
- er.failed_type = 0;
- return er;
+ _ASN_ENCODED_OK(er);
}
/*
@@ -574,9 +576,7 @@ OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
}
er.encoded += st->size;
- er.structure_ptr = 0;
- er.failed_type = 0;
- return er;
+ _ASN_ENCODED_OK(er);
cb_failed:
_ASN_ENCODE_FAILED;
}
@@ -639,9 +639,7 @@ OCTET_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
}
}
- er.structure_ptr = 0;
- er.failed_type = 0;
- return er;
+ _ASN_ENCODED_OK(er);
cb_failed:
_ASN_ENCODE_FAILED;
}
@@ -781,9 +779,7 @@ OCTET_STRING_encode_xer_utf8(asn_TYPE_descriptor_t *td, void *sptr,
_ASN_ENCODE_FAILED;
er.encoded = encoded_len;
- er.structure_ptr = 0;
- er.failed_type = 0;
- return er;
+ _ASN_ENCODED_OK(er);
}
/*
@@ -1200,6 +1196,99 @@ OCTET_STRING_decode_xer_utf8(asn_codec_ctx_t *opt_codec_ctx,
OCTET_STRING__convert_entrefs);
}
+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,
+ void **sptr, asn_per_data_t *pd) {
+
+ 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_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;
+
+ (void)opt_codec_ctx;
+
+ /*
+ * Allocate the string.
+ */
+ if(!st) {
+ st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
+ if(!st) RETURN(RC_FAIL);
+ }
+
+ if(ct->flags & APC_EXTENSIBLE) {
+ int inext = per_get_few_bits(pd, 1);
+ if(inext < 0) RETURN(RC_FAIL);
+ if(inext) ct = &asn_DEF_OCTET_STRING_constraint;
+ consumed_myself = 0;
+ }
+
+ if(ct->effective_bits >= 0
+ && (!st->buf || st->size < ct->upper_bound)) {
+ FREEMEM(st->buf);
+ if(unit_bits == 1) {
+ st->size = (ct->upper_bound + 7) >> 3;
+ } else {
+ st->size = ct->upper_bound;
+ }
+ st->buf = (uint8_t *)MALLOC(st->size + 1);
+ if(!st->buf) { st->size = 0; RETURN(RC_FAIL); }
+ }
+
+ /* X.691, #16.5: zero-length encoding */
+ /* 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,
+ unit_bits * ct->upper_bound);
+ if(ret < 0) RETURN(RC_FAIL);
+ consumed_myself += unit_bits * ct->upper_bound;
+ st->buf[st->size] = 0;
+ if(unit_bits == 1 && (ct->upper_bound & 0x7))
+ st->bits_unused = 8 - (ct->upper_bound & 0x7);
+ RETURN(RC_OK);
+ }
+
+ st->size = 0;
+ do {
+ ssize_t len_bytes;
+ ssize_t len_bits;
+ void *p;
+ int ret;
+
+ /* Get the PER length */
+ len_bits = uper_get_length(pd, ct->effective_bits, &repeat);
+ if(len_bits < 0) RETURN(RC_FAIL);
+
+ if(unit_bits == 1) {
+ len_bytes = (len_bits + 7) >> 3;
+ if(len_bits & 0x7)
+ st->bits_unused = 8 - (len_bits & 0x7);
+ /* len_bits be multiple of 16K if repeat is set */
+ } else {
+ len_bytes = len_bits;
+ len_bits = len_bytes << 3;
+ }
+ p = REALLOC(st->buf, st->size + len_bytes + 1);
+ if(!p) RETURN(RC_FAIL);
+ st->buf = (uint8_t *)p;
+
+ ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
+ if(ret < 0) RETURN(RC_FAIL);
+ st->size += len_bytes;
+ } while(repeat);
+ st->buf[st->size] = 0; /* nul-terminate */
+
+ return rval;
+}
int
OCTET_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
diff --git a/skeletons/OCTET_STRING.h b/skeletons/OCTET_STRING.h
index 94c19a0b..22bd6272 100644
--- a/skeletons/OCTET_STRING.h
+++ b/skeletons/OCTET_STRING.h
@@ -30,6 +30,7 @@ xer_type_decoder_f OCTET_STRING_decode_xer_binary; /* 01010111010 */
xer_type_decoder_f OCTET_STRING_decode_xer_utf8; /* ASCII/UTF-8 */
xer_type_encoder_f OCTET_STRING_encode_xer;
xer_type_encoder_f OCTET_STRING_encode_xer_utf8;
+per_type_decoder_f OCTET_STRING_decode_uper;
/******************************
* Handy conversion routines. *
diff --git a/skeletons/ObjectDescriptor.c b/skeletons/ObjectDescriptor.c
index 9f52147e..37f51e8c 100644
--- a/skeletons/ObjectDescriptor.c
+++ b/skeletons/ObjectDescriptor.c
@@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_ObjectDescriptor = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
+ 0,
0, /* Use generic outmost tag fetcher */
asn_DEF_ObjectDescriptor_tags,
sizeof(asn_DEF_ObjectDescriptor_tags)
@@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_ObjectDescriptor = {
asn_DEF_ObjectDescriptor_tags,
sizeof(asn_DEF_ObjectDescriptor_tags)
/ sizeof(asn_DEF_ObjectDescriptor_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/PrintableString.c b/skeletons/PrintableString.c
index bc48c0f8..57f65731 100644
--- a/skeletons/PrintableString.c
+++ b/skeletons/PrintableString.c
@@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_PrintableString = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
+ 0,
0, /* Use generic outmost tag fetcher */
asn_DEF_PrintableString_tags,
sizeof(asn_DEF_PrintableString_tags)
@@ -29,6 +30,7 @@ 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 */
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/README b/skeletons/README
index 29dbae63..92201ed9 100644
--- a/skeletons/README
+++ b/skeletons/README
@@ -1,6 +1,4 @@
-
-Here are the canonical encoder/decoder algorithms that work with the tables
-constructed by the compiler. The compiler itself does not generate code,
-it just creates those tables and then copies (links) over these files
-which contain generic algorithms.
-
+This directory contains encoder/decoder code for various encoding rules
+(PER, DER, BER, XER) that work with the tables constructed by the compiler.
+The compiler itself does not generate much code. It creates parsing tables
+and then copies (links) over these files which contain generic codecs.
diff --git a/skeletons/REAL.c b/skeletons/REAL.c
index c4801538..689b05ec 100644
--- a/skeletons/REAL.c
+++ b/skeletons/REAL.c
@@ -42,11 +42,13 @@ asn_TYPE_descriptor_t asn_DEF_REAL = {
der_encode_primitive,
REAL_decode_xer,
REAL_encode_xer,
+ 0,
0, /* Use generic outmost tag fetcher */
asn_DEF_REAL_tags,
sizeof(asn_DEF_REAL_tags) / sizeof(asn_DEF_REAL_tags[0]),
asn_DEF_REAL_tags, /* Same as above */
sizeof(asn_DEF_REAL_tags) / sizeof(asn_DEF_REAL_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
@@ -257,9 +259,7 @@ REAL_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
er.encoded = REAL__dump(d, flags & XER_F_CANONICAL, cb, app_key);
if(er.encoded < 0) _ASN_ENCODE_FAILED;
- er.structure_ptr = 0;
- er.failed_type = 0;
- return er;
+ _ASN_ENCODED_OK(er);
}
diff --git a/skeletons/RELATIVE-OID.c b/skeletons/RELATIVE-OID.c
index 2b32315e..74511b7b 100644
--- a/skeletons/RELATIVE-OID.c
+++ b/skeletons/RELATIVE-OID.c
@@ -25,6 +25,7 @@ asn_TYPE_descriptor_t asn_DEF_RELATIVE_OID = {
der_encode_primitive,
RELATIVE_OID_decode_xer,
RELATIVE_OID_encode_xer,
+ 0,
0, /* Use generic outmost tag fetcher */
asn_DEF_RELATIVE_OID_tags,
sizeof(asn_DEF_RELATIVE_OID_tags)
@@ -32,6 +33,7 @@ asn_TYPE_descriptor_t asn_DEF_RELATIVE_OID = {
asn_DEF_RELATIVE_OID_tags, /* Same as above */
sizeof(asn_DEF_RELATIVE_OID_tags)
/ sizeof(asn_DEF_RELATIVE_OID_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
@@ -156,9 +158,7 @@ RELATIVE_OID_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
er.encoded = RELATIVE_OID__dump_body(st, cb, app_key);
if(er.encoded < 0) _ASN_ENCODE_FAILED;
- er.structure_ptr = 0;
- er.failed_type = 0;
- return er;
+ _ASN_ENCODED_OK(er);
}
int
diff --git a/skeletons/T61String.c b/skeletons/T61String.c
index a37c176e..4157a6b2 100644
--- a/skeletons/T61String.c
+++ b/skeletons/T61String.c
@@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_T61String = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_hex,
OCTET_STRING_encode_xer,
+ 0,
0, /* Use generic outmost tag fetcher */
asn_DEF_T61String_tags,
sizeof(asn_DEF_T61String_tags)
@@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_T61String = {
asn_DEF_T61String_tags,
sizeof(asn_DEF_T61String_tags)
/ sizeof(asn_DEF_T61String_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/TeletexString.c b/skeletons/TeletexString.c
index 47aad419..11f57033 100644
--- a/skeletons/TeletexString.c
+++ b/skeletons/TeletexString.c
@@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_TeletexString = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_hex,
OCTET_STRING_encode_xer,
+ 0,
0, /* Use generic outmost tag fetcher */
asn_DEF_TeletexString_tags,
sizeof(asn_DEF_TeletexString_tags)
@@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_TeletexString = {
asn_DEF_TeletexString_tags,
sizeof(asn_DEF_TeletexString_tags)
/ sizeof(asn_DEF_TeletexString_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/UTCTime.c b/skeletons/UTCTime.c
index c2079fbd..9032dbd6 100644
--- a/skeletons/UTCTime.c
+++ b/skeletons/UTCTime.c
@@ -28,6 +28,7 @@ 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, /* Use generic outmost tag fetcher */
asn_DEF_UTCTime_tags,
sizeof(asn_DEF_UTCTime_tags)
@@ -35,6 +36,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 */
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/UTF8String.c b/skeletons/UTF8String.c
index 64b3a712..5d0334f9 100644
--- a/skeletons/UTF8String.c
+++ b/skeletons/UTF8String.c
@@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_UTF8String = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
+ 0,
0, /* Use generic outmost tag fetcher */
asn_DEF_UTF8String_tags,
sizeof(asn_DEF_UTF8String_tags)
@@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_UTF8String = {
asn_DEF_UTF8String_tags,
sizeof(asn_DEF_UTF8String_tags)
/ sizeof(asn_DEF_UTF8String_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/UniversalString.c b/skeletons/UniversalString.c
index 938bf07b..0fab915f 100644
--- a/skeletons/UniversalString.c
+++ b/skeletons/UniversalString.c
@@ -23,6 +23,7 @@ asn_TYPE_descriptor_t asn_DEF_UniversalString = {
OCTET_STRING_encode_der,
UniversalString_decode_xer, /* Convert from UTF-8 */
UniversalString_encode_xer, /* Convert into UTF-8 */
+ 0,
0, /* Use generic outmost tag fetcher */
asn_DEF_UniversalString_tags,
sizeof(asn_DEF_UniversalString_tags)
@@ -30,6 +31,7 @@ asn_TYPE_descriptor_t asn_DEF_UniversalString = {
asn_DEF_UniversalString_tags,
sizeof(asn_DEF_UniversalString_tags)
/ sizeof(asn_DEF_UniversalString_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
@@ -167,7 +169,7 @@ UniversalString_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
er.encoded = UniversalString__dump(st, cb, app_key);
if(er.encoded < 0) _ASN_ENCODE_FAILED;
- return er;
+ _ASN_ENCODED_OK(er);
}
int
diff --git a/skeletons/VideotexString.c b/skeletons/VideotexString.c
index 2a2baa81..c51c31aa 100644
--- a/skeletons/VideotexString.c
+++ b/skeletons/VideotexString.c
@@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_VideotexString = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_hex,
OCTET_STRING_encode_xer,
+ 0,
0, /* Use generic outmost tag fetcher */
asn_DEF_VideotexString_tags,
sizeof(asn_DEF_VideotexString_tags)
@@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_VideotexString = {
asn_DEF_VideotexString_tags,
sizeof(asn_DEF_VideotexString_tags)
/ sizeof(asn_DEF_VideotexString_tags[0]),
+ 0, /* No PER visible constraints */
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/VisibleString.c b/skeletons/VisibleString.c
index 30f29455..2a88169d 100644
--- a/skeletons/VisibleString.c
+++ b/skeletons/VisibleString.c
@@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_VisibleString = {
OCTET_STRING_encode_der,
OCTET_STRING_decode_xer_utf8,
OCTET_STRING_encode_xer_utf8,
+ 0,
0, /* Use generic outmost tag fetcher */
asn_DEF_VisibleString_tags,
sizeof(asn_DEF_VisibleString_tags)
@@ -29,6 +30,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 */
0, 0, /* No members */
0 /* No specifics */
};
diff --git a/skeletons/asn-decoder-template.c b/skeletons/asn-decoder-template.c
index 348c3731..c50d8b9c 100644
--- a/skeletons/asn-decoder-template.c
+++ b/skeletons/asn-decoder-template.c
@@ -21,7 +21,9 @@
#include <asn_application.h>
extern asn_TYPE_descriptor_t asn_DEF; /* ASN.1 type to be decoded */
-static asn_TYPE_descriptor_t *pduType = &asn_DEF;
+#ifdef ASN_PDU_COLLECTION /* Generated by asn1c: -pdu=... */
+extern asn_TYPE_descriptor_t *asn_pdu_collection[];
+#endif
/*
* Open file and parse its contens.
@@ -37,7 +39,8 @@ static int opt_stack; /* -s */
/* Input data format selector */
static enum input_format {
INP_BER, /* -iber: BER input */
- INP_XER /* -ixer: XER input */
+ INP_XER, /* -ixer: XER input */
+ INP_PER /* -iper: Unaligned PER input */
} iform; /* -i<format> */
/* Output data format selector */
@@ -56,19 +59,26 @@ static enum output_format {
int
main(int ac, char **av) {
+ static asn_TYPE_descriptor_t *pduType = &asn_DEF;
ssize_t suggested_bufsize = 8192; /* close or equal to stdio buffer */
int number_of_iterations = 1;
int num;
int ch;
+ /* Figure out if Unaligned PER needs to be default */
+ if(pduType->uper_decoder)
+ iform = INP_PER;
+
/*
* Pocess the command-line argments.
*/
- while((ch = getopt(ac, av, "i:o:b:cdn:hs:")) != -1)
+ while((ch = getopt(ac, av, "i:o:b:cdn:p:hs:")) != -1)
switch(ch) {
case 'i':
if(optarg[0] == 'b') { iform = INP_BER; break; }
if(optarg[0] == 'x') { iform = INP_XER; break; }
+ if(pduType->uper_decoder
+ && optarg[0] == 'p') { iform = INP_PER; break; }
fprintf(stderr, "-i<format>: '%s': improper format selector",
optarg);
exit(EX_UNAVAILABLE);
@@ -80,6 +90,21 @@ main(int ac, char **av) {
fprintf(stderr, "-o<format>: '%s': improper format selector",
optarg);
exit(EX_UNAVAILABLE);
+ case 'p':
+#ifdef ASN_PDU_COLLECTION
+ {
+ asn_TYPE_descriptor_t **pdu = asn_pdu_collection;
+ if(optarg[0] < 'A' || optarg[0] > 'Z') {
+ fprintf(stderr, "Available PDU types:\n");
+ for(; *pdu; pdu++) printf("%s\n", (*pdu)->name);
+ exit(0);
+ }
+ while(*pdu && strcmp((*pdu)->name, optarg)) pdu++;
+ if(*pdu) { pduType = *pdu; break; }
+ }
+#endif /* ASN_PDU_COLLECTION */
+ fprintf(stderr, "-p %s: Unrecognized PDU\n", optarg);
+ exit(EX_UNAVAILABLE);
case 'b':
suggested_bufsize = atoi(optarg);
if(suggested_bufsize < 1
@@ -115,21 +140,32 @@ main(int ac, char **av) {
break;
case 'h':
default:
+ fprintf(stderr, "Usage: %s [options] <data.ber> ...\n", av[0]);
+ fprintf(stderr, "Where options are:\n");
+ if(pduType->uper_decoder)
+ fprintf(stderr,
+ " -iper (I) Input is in Unaligned PER (Packed Encoding Rules)\n");
+ fprintf(stderr,
+ " -iber %s Input is in BER (Basic Encoding Rules)\n",
+ iform == INP_PER ? " " : "(I)");
fprintf(stderr,
- "Usage: %s [options] <data.ber> ...\n"
- "Where options are:\n"
- " -iber (I) Input is in BER (Basic Encoding Rules)\n"
" -ixer Input is in XER (XML Encoding Rules)\n"
" -oder Output in DER (Distinguished Encoding Rules)\n"
" -oxer (O) Output in XER (XML Encoding Rules)\n"
" -otext Output in plain semi-structured text (dump)\n"
- " -onull Verify (decode) input, but do not output\n"
+ " -onull Verify (decode) input, but do not output\n");
+#ifdef ASN_PDU_COLLECTION
+ fprintf(stderr,
+ " -p <PDU> Specify PDU type to decode\n"
+ " -p list List available PDUs\n");
+#endif /* ASN_PDU_COLLECTION */
+ fprintf(stderr,
" -b <size> Set the i/o buffer size (default is %ld)\n"
" -c Check ASN.1 constraints after decoding\n"
" -d Enable debugging (-dd is even better)\n"
" -n <num> Process files <num> times\n"
" -s <size> Set the stack usage limit\n"
- , av[0], (long)suggested_bufsize);
+ , (long)suggested_bufsize);
exit(EX_USAGE);
}
@@ -210,7 +246,8 @@ main(int ac, char **av) {
/* Dump the buffer */
static int write_out(const void *buffer, size_t size, void *key) {
- return (fwrite(buffer, 1, size, key) == size) ? 0 : -1;
+ FILE *fp = (FILE *)key;
+ return (fwrite(buffer, 1, size, fp) == size) ? 0 : -1;
}
static char *buffer;
@@ -302,6 +339,7 @@ static void *data_decode_from_file(asn_TYPE_descriptor_t *pduType, const char *f
rval.consumed = 0;
while((rd = fread(fbuf, 1, fbuf_size, fp)) || !feof(fp)) {
+ asn_per_data_t pd;
char *i_bptr;
size_t i_size;
@@ -330,6 +368,13 @@ static void *data_decode_from_file(asn_TYPE_descriptor_t *pduType, const char *f
rval = xer_decode(opt_codec_ctx, pduType,
(void **)&structure, i_bptr, i_size);
break;
+ case INP_PER:
+ pd.buffer = (uint8_t *)i_bptr;
+ pd.nboff = 0;
+ pd.nbits = i_size * 8;
+ rval = pduType->uper_decoder(opt_codec_ctx, pduType, 0,
+ (void **)&structure, &pd);
+ break;
}
DEBUG("decode(%ld) consumed %ld, code %d",
(long)buf_len, (long)rval.consumed, rval.code);
diff --git a/skeletons/asn_codecs.h b/skeletons/asn_codecs.h
index 9250adab..f25a7975 100644
--- a/skeletons/asn_codecs.h
+++ b/skeletons/asn_codecs.h
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#ifndef _ASN_CODECS_H_
@@ -61,6 +62,11 @@ typedef struct asn_enc_rval_s {
tmp_error.structure_ptr = sptr; \
return tmp_error; \
} while(0)
+#define _ASN_ENCODED_OK(rval) do { \
+ rval.structure_ptr = 0; \
+ rval.failed_type = 0; \
+ return rval; \
+} while(0)
/*
* Type of the return value of the decoding functions (ber_decode, xer_decode)
@@ -79,6 +85,12 @@ typedef struct asn_dec_rval_s {
enum asn_dec_rval_code_e code; /* Result code */
size_t consumed; /* Number of bytes consumed */
} asn_dec_rval_t;
+#define _ASN_DECODE_FAILED do { \
+ asn_dec_rval_t tmp_error; \
+ tmp_error.code = RC_FAIL; \
+ tmp_error.consumed = 0; \
+ return tmp_error; \
+} while(0)
#ifdef __cplusplus
}
diff --git a/skeletons/asn_codecs_prim.c b/skeletons/asn_codecs_prim.c
index b599bdfa..97dc22af 100644
--- a/skeletons/asn_codecs_prim.c
+++ b/skeletons/asn_codecs_prim.c
@@ -119,9 +119,7 @@ der_encode_primitive(asn_TYPE_descriptor_t *td, void *sptr,
}
erval.encoded += st->size;
- erval.structure_ptr = 0;
- erval.failed_type = 0;
- return erval;
+ _ASN_ENCODED_OK(erval);
}
void
diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c
index 6ab4a0bd..d3738df3 100644
--- a/skeletons/constr_CHOICE.c
+++ b/skeletons/constr_CHOICE.c
@@ -118,7 +118,7 @@ CHOICE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
ASN_DEBUG("Decoding %s as CHOICE", td->name);
-
+
/*
* Create the target structure if it is not present already.
*/
@@ -196,7 +196,7 @@ CHOICE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
NEXT_PHASE(ctx);
ctx->step = t2m->el_no;
break;
- } else if(specs->extensible == 0) {
+ } else if(specs->ext_start == -1) {
ASN_DEBUG("Unexpected tag %s "
"in non-extensible CHOICE %s",
ber_tlv_tag_string(tlv_tag), td->name);
@@ -252,16 +252,16 @@ CHOICE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
memb_ptr = (char *)st + elm->memb_offset;
memb_ptr2 = &memb_ptr;
}
+ /* Set presence to be able to free it properly at any time */
+ _set_present_idx(st, specs->pres_offset,
+ specs->pres_size, ctx->step + 1);
/*
* Invoke the member fetch routine according to member's type
*/
rval = elm->type->ber_decoder(opt_codec_ctx, elm->type,
- memb_ptr2, ptr, LEFT,
- elm->tag_mode);
+ memb_ptr2, ptr, LEFT, elm->tag_mode);
switch(rval.code) {
case RC_OK:
- _set_present_idx(st, specs->pres_offset,
- specs->pres_size, ctx->step + 1);
break;
case RC_WMORE: /* More data expected */
if(!SIZE_VIOLATION) {
@@ -377,7 +377,7 @@ CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
if(present == 0 && td->elements_count == 0) {
/* The CHOICE is empty?! */
erval.encoded = 0;
- return erval;
+ _ASN_ENCODED_OK(erval);
}
_ASN_ENCODE_FAILED;
}
@@ -391,7 +391,7 @@ CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
if(memb_ptr == 0) {
if(elm->optional) {
erval.encoded = 0;
- return erval;
+ _ASN_ENCODED_OK(erval);
}
/* Mandatory element absent */
_ASN_ENCODE_FAILED;
@@ -729,7 +729,7 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
continue;
/* It is expected extension */
- if(specs->extensible) {
+ if(specs->ext_start != -1) {
ASN_DEBUG("Got anticipated extension");
/*
* Check for (XCT_BOTH or XCT_UNKNOWN_BO)
@@ -810,11 +810,86 @@ CHOICE_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
if(!(flags & XER_F_CANONICAL)) _i_ASN_TEXT_INDENT(1, ilevel - 1);
- return er;
+ _ASN_ENCODED_OK(er);
cb_failed:
_ASN_ENCODE_FAILED;
}
+asn_dec_rval_t
+CHOICE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+ asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
+ asn_dec_rval_t rv;
+ asn_per_constraint_t *ct;
+ asn_TYPE_member_t *elm; /* CHOICE's element */
+ void *memb_ptr;
+ void **memb_ptr2;
+ void *st = *sptr;
+ int value;
+
+ /*
+ * Create the target structure if it is not present already.
+ */
+ if(!st) {
+ st = *sptr = CALLOC(1, specs->struct_size);
+ if(!st) _ASN_DECODE_FAILED;
+ }
+
+ if(constraints) ct = &constraints->value;
+ else if(td->per_constraints) ct = &td->per_constraints->value;
+ else ct = 0;
+
+ if(ct && ct->flags & APC_EXTENSIBLE) {
+ value = per_get_few_bits(pd, 1);
+ if(value < 0) _ASN_DECODE_FAILED;
+ if(value) ct = 0; /* Not restricted */
+ }
+
+ if(ct && ct->range_bits >= 0) {
+ value = per_get_few_bits(pd, ct->range_bits);
+ if(value < 0) _ASN_DECODE_FAILED;
+ if(value > ct->upper_bound)
+ _ASN_DECODE_FAILED;
+ ASN_DEBUG("CHOICE %s got index %d in range %d",
+ td->name, value, ct->range_bits);
+ } else {
+ if(specs->ext_start == -1)
+ _ASN_DECODE_FAILED;
+ value = uper_get_nsnnwn(pd);
+ if(value < 0) _ASN_DECODE_FAILED;
+ value += specs->ext_start;
+ if(value >= td->elements_count)
+ _ASN_DECODE_FAILED;
+ ASN_DEBUG("NOT IMPLEMENTED YET");
+ _ASN_DECODE_FAILED;
+ }
+
+ /* Adjust if canonical order is different from natural order */
+ if(specs->canonical_order)
+ value = specs->canonical_order[value];
+
+ /* Set presence to be able to free it later */
+ _set_present_idx(st, specs->pres_offset, specs->pres_size, value + 1);
+
+ elm = &td->elements[value];
+ if(elm->flags & ATF_POINTER) {
+ /* Member is a pointer to another structure */
+ memb_ptr2 = (void **)((char *)st + elm->memb_offset);
+ } else {
+ memb_ptr = (char *)st + elm->memb_offset;
+ memb_ptr2 = &memb_ptr;
+ }
+ ASN_DEBUG("Discovered CHOICE %s encodes %s", td->name, elm->name);
+
+ rv = elm->type->uper_decoder(opt_codec_ctx, elm->type,
+ elm->per_constraints, memb_ptr2, pd);
+ if(rv.code != RC_OK)
+ ASN_DEBUG("Failed to decode %s in %s (CHOICE)",
+ elm->name, td->name);
+ return rv;
+}
+
+
int
CHOICE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
asn_app_consume_bytes_f *cb, void *app_key) {
diff --git a/skeletons/constr_CHOICE.h b/skeletons/constr_CHOICE.h
index 859c5329..6276d7e4 100644
--- a/skeletons/constr_CHOICE.h
+++ b/skeletons/constr_CHOICE.h
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#ifndef _CONSTR_CHOICE_H_
@@ -26,10 +27,13 @@ typedef struct asn_CHOICE_specifics_s {
asn_TYPE_tag2member_t *tag2el;
int tag2el_count;
+ /* Canonical ordering of CHOICE elements, for PER */
+ int *canonical_order;
+
/*
* Extensions-related stuff.
*/
- int extensible; /* Whether CHOICE is extensible */
+ int ext_start; /* First member of extensions, or -1 */
} asn_CHOICE_specifics_t;
/*
@@ -42,6 +46,7 @@ ber_type_decoder_f CHOICE_decode_ber;
der_type_encoder_f CHOICE_encode_der;
xer_type_decoder_f CHOICE_decode_xer;
xer_type_encoder_f CHOICE_encode_xer;
+per_type_decoder_f CHOICE_decode_uper;
asn_outmost_tag_f CHOICE_outmost_tag;
#ifdef __cplusplus
diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c
index 7dcb5da1..e3dfd1d4 100644
--- a/skeletons/constr_SEQUENCE.c
+++ b/skeletons/constr_SEQUENCE.c
@@ -551,7 +551,7 @@ SEQUENCE_encode_der(asn_TYPE_descriptor_t *td,
_ASN_ENCODE_FAILED;
erval.encoded = computed_size + ret;
- if(!cb) return erval;
+ if(!cb) _ASN_ENCODED_OK(erval);
/*
* Encode all members.
@@ -583,7 +583,7 @@ SEQUENCE_encode_der(asn_TYPE_descriptor_t *td,
*/
_ASN_ENCODE_FAILED;
- return erval;
+ _ASN_ENCODED_OK(erval);
}
@@ -883,7 +883,7 @@ SEQUENCE_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
- return er;
+ _ASN_ENCODED_OK(er);
cb_failed:
_ASN_ENCODE_FAILED;
}
@@ -1014,3 +1014,135 @@ SEQUENCE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
return 0;
}
+
+asn_dec_rval_t
+SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+ asn_SEQUENCE_specifics_t *specs = (asn_SEQUENCE_specifics_t *)td->specifics;
+ void *st = *sptr; /* Target structure. */
+ int extpresent = 0; /* Extension additions are present */
+ uint8_t *opres; /* Presence of optional root members */
+ asn_per_data_t opmd;
+ asn_dec_rval_t rv;
+ int edx;
+
+ (void)constraints;
+
+ if(!st) {
+ st = *sptr = CALLOC(1, specs->struct_size);
+ if(!st) _ASN_DECODE_FAILED;
+ }
+
+ ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name);
+
+ /* Handle extensions */
+ if(specs->ext_before >= 0) {
+ extpresent = per_get_few_bits(pd, 1);
+ if(extpresent < 0) _ASN_DECODE_FAILED;
+ }
+
+ /* Prepare a place and read-in the presence bitmap */
+ if(specs->roms_count) {
+ opres = (uint8_t *)MALLOC(((specs->roms_count + 7) >> 3) + 1);
+ if(!opres) _ASN_DECODE_FAILED;
+ /* Get the presence map */
+ if(per_get_many_bits(pd, opres, 0, specs->roms_count)) {
+ FREEMEM(opres);
+ _ASN_DECODE_FAILED;
+ }
+ opmd.buffer = opres;
+ opmd.nboff = 0;
+ opmd.nbits = specs->roms_count;
+ ASN_DEBUG("Read in presence bitmap for %s of %d bits (%x..)",
+ td->name, specs->roms_count, *opres);
+ } else {
+ opres = 0;
+ memset(&opmd, 0, sizeof opmd);
+ }
+
+ /*
+ * Get the sequence ROOT elements.
+ */
+ for(edx = 0; edx < ((specs->ext_before < 0)
+ ? td->elements_count : specs->ext_before + 1); edx++) {
+ asn_TYPE_member_t *elm = &td->elements[edx];
+ void *memb_ptr; /* Pointer to the member */
+ void **memb_ptr2; /* Pointer to that pointer */
+
+ /* Fetch the pointer to this member */
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr2 = (void **)((char *)st + elm->memb_offset);
+ } else {
+ memb_ptr = (char *)st + elm->memb_offset;
+ memb_ptr2 = &memb_ptr;
+ }
+
+ /* Deal with optionality */
+ if(elm->optional) {
+ int present = per_get_few_bits(&opmd, 1);
+ ASN_DEBUG("Member %s->%s is optional, p=%d (%d->%d)",
+ td->name, elm->name, present,
+ (int)opmd.nboff, (int)opmd.nbits);
+ if(present == 0) {
+ /* This element is not present */
+ if(elm->default_value) {
+ /* Fill-in DEFAULT */
+ if(elm->default_value(memb_ptr2)) {
+ FREEMEM(opres);
+ _ASN_DECODE_FAILED;
+ }
+ }
+ /* The member is just not present */
+ continue;
+ }
+ /* Fall through */
+ }
+
+ /* Fetch the member from the stream */
+ ASN_DEBUG("Decoding member %s in %s", elm->name, td->name);
+ rv = elm->type->uper_decoder(opt_codec_ctx, elm->type,
+ elm->per_constraints, memb_ptr2, pd);
+ if(rv.code != RC_OK) {
+ ASN_DEBUG("Failed decode %s in %s",
+ elm->name, td->name);
+ FREEMEM(opres);
+ return rv;
+ }
+ }
+
+ /*
+ * Deal with extensions.
+ */
+ if(extpresent) {
+ ASN_DEBUG("Extensibility for %s: NOT IMPLEMENTED", td->name);
+ _ASN_DECODE_FAILED;
+ } else {
+ for(edx = specs->roms_count; edx < specs->roms_count
+ + specs->aoms_count; edx++) {
+ asn_TYPE_member_t *elm = &td->elements[edx];
+ void *memb_ptr; /* Pointer to the member */
+ void **memb_ptr2; /* Pointer to that pointer */
+
+ if(!elm->default_value) continue;
+
+ /* Fetch the pointer to this member */
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr2 = (void **)((char *)st + elm->memb_offset);
+ } else {
+ memb_ptr = (char *)st + elm->memb_offset;
+ memb_ptr2 = &memb_ptr;
+ }
+
+ /* Set default value */
+ if(elm->default_value(memb_ptr2)) {
+ FREEMEM(opres);
+ _ASN_DECODE_FAILED;
+ }
+ }
+ }
+
+ rv.consumed = 0;
+ rv.code = RC_OK;
+ return rv;
+}
+
diff --git a/skeletons/constr_SEQUENCE.h b/skeletons/constr_SEQUENCE.h
index ab8a8ec1..b4ee47f9 100644
--- a/skeletons/constr_SEQUENCE.h
+++ b/skeletons/constr_SEQUENCE.h
@@ -25,10 +25,18 @@ typedef struct asn_SEQUENCE_specifics_s {
int tag2el_count;
/*
+ * Optional members of the extensions root (roms) or additions (aoms).
+ * Meaningful for PER.
+ */
+ int *oms; /* Optional MemberS */
+ int roms_count; /* Root optional members count */
+ int aoms_count; /* Additions optional members count */
+
+ /*
* Description of an extensions group.
*/
- int ext_after; /* Extensions start after this member */
- int ext_before; /* Extensions stop before this member */
+ int ext_after; /* Extensions start after this member */
+ int ext_before; /* Extensions stop before this member */
} asn_SEQUENCE_specifics_t;
@@ -42,6 +50,7 @@ ber_type_decoder_f SEQUENCE_decode_ber;
der_type_encoder_f SEQUENCE_encode_der;
xer_type_decoder_f SEQUENCE_decode_xer;
xer_type_encoder_f SEQUENCE_encode_xer;
+per_type_decoder_f SEQUENCE_decode_uper;
#ifdef __cplusplus
}
diff --git a/skeletons/constr_SEQUENCE_OF.c b/skeletons/constr_SEQUENCE_OF.c
index 12233a6c..3ddd5a39 100644
--- a/skeletons/constr_SEQUENCE_OF.c
+++ b/skeletons/constr_SEQUENCE_OF.c
@@ -51,9 +51,7 @@ SEQUENCE_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
computed_size += encoding_size;
if(!cb) {
erval.encoded = computed_size;
- erval.structure_ptr = 0;
- erval.failed_type = 0;
- return erval;
+ _ASN_ENCODED_OK(erval);
}
ASN_DEBUG("Encoding members of SEQUENCE OF %s", td->name);
@@ -136,7 +134,7 @@ SEQUENCE_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
- return er;
+ _ASN_ENCODED_OK(er);
cb_failed:
_ASN_ENCODE_FAILED;
}
diff --git a/skeletons/constr_SEQUENCE_OF.h b/skeletons/constr_SEQUENCE_OF.h
index 94b04cdc..32078cb3 100644
--- a/skeletons/constr_SEQUENCE_OF.h
+++ b/skeletons/constr_SEQUENCE_OF.h
@@ -21,6 +21,7 @@ extern "C" {
#define SEQUENCE_OF_constraint SET_OF_constraint
#define SEQUENCE_OF_decode_ber SET_OF_decode_ber
#define SEQUENCE_OF_decode_xer SET_OF_decode_xer
+#define SEQUENCE_OF_decode_uper SET_OF_decode_uper
der_type_encoder_f SEQUENCE_OF_encode_der;
xer_type_encoder_f SEQUENCE_OF_encode_xer;
diff --git a/skeletons/constr_SET.c b/skeletons/constr_SET.c
index f99d66f4..e83abd78 100644
--- a/skeletons/constr_SET.c
+++ b/skeletons/constr_SET.c
@@ -536,7 +536,7 @@ SET_encode_der(asn_TYPE_descriptor_t *td,
if(ret == -1) _ASN_ENCODE_FAILED;
er.encoded = computed_size + ret;
- if(!cb) return er;
+ if(!cb) _ASN_ENCODED_OK(er);
/*
* Encode all members.
@@ -570,7 +570,7 @@ SET_encode_der(asn_TYPE_descriptor_t *td,
_ASN_ENCODE_FAILED;
}
- return er;
+ _ASN_ENCODED_OK(er);
}
#undef XER_ADVANCE
@@ -857,7 +857,7 @@ SET_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
- return er;
+ _ASN_ENCODED_OK(er);
cb_failed:
_ASN_ENCODE_FAILED;
}
diff --git a/skeletons/constr_SET_OF.c b/skeletons/constr_SET_OF.c
index bd25b3d8..251da390 100644
--- a/skeletons/constr_SET_OF.c
+++ b/skeletons/constr_SET_OF.c
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
@@ -356,7 +357,7 @@ SET_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
if(!cb) {
erval.encoded = computed_size;
- return erval;
+ _ASN_ENCODED_OK(erval);
}
/*
@@ -448,7 +449,7 @@ SET_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
erval.encoded = computed_size;
}
- return erval;
+ _ASN_ENCODED_OK(erval);
}
#undef XER_ADVANCE
@@ -748,7 +749,7 @@ cleanup:
}
free(encs);
}
- return er;
+ _ASN_ENCODED_OK(er);
}
int
@@ -850,3 +851,88 @@ SET_OF_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
return 0;
}
+
+asn_dec_rval_t
+SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+ asn_dec_rval_t rv;
+ asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
+ asn_TYPE_member_t *elm = td->elements; /* Single one */
+ void *st = *sptr;
+ asn_anonymous_set_ *list;
+ asn_per_constraint_t *ct;
+ int repeat = 0;
+ ssize_t nelems;
+
+ /*
+ * Create the target structure if it is not present already.
+ */
+ if(!st) {
+ st = *sptr = CALLOC(1, specs->struct_size);
+ if(!st) _ASN_DECODE_FAILED;
+ }
+ list = _A_SET_FROM_VOID(st);
+
+ /* Figure out which constraints to use */
+ if(constraints) ct = &constraints->size;
+ else if(td->per_constraints) ct = &td->per_constraints->size;
+ else ct = 0;
+
+ if(ct && ct->flags & APC_EXTENSIBLE) {
+ int value = per_get_few_bits(pd, 1);
+ if(value < 0) _ASN_DECODE_FAILED;
+ if(value) ct = 0; /* Not restricted! */
+ }
+
+ if(ct && ct->effective_bits >= 0) {
+ /* X.691, #19.5: No length determinant */
+ nelems = per_get_few_bits(pd, ct->effective_bits);
+ ASN_DEBUG("Preparing to fetch %ld+%ld elements from %s",
+ (long)nelems, ct->lower_bound, td->name);
+ if(nelems < 0) _ASN_DECODE_FAILED;
+ nelems += ct->lower_bound;
+ } else {
+ nelems = -1;
+ }
+
+ do {
+ int i;
+ if(nelems < 0) {
+ nelems = uper_get_length(pd,
+ ct ? ct->effective_bits : -1, &repeat);
+ ASN_DEBUG("Got to decode %d elements (eff %d)",
+ nelems, ct ? ct->effective_bits : -1);
+ if(nelems < 0) _ASN_DECODE_FAILED;
+ }
+
+ for(i = 0; i < nelems; i++) {
+ void *ptr = 0;
+ ASN_DEBUG("SET OF %s decoding", elm->type->name);
+ rv = elm->type->uper_decoder(opt_codec_ctx, elm->type,
+ elm->per_constraints, &ptr, pd);
+ ASN_DEBUG("%s SET OF %s decoded %d, %p",
+ td->name, elm->type->name, rv.code, ptr);
+ if(rv.code == RC_OK) {
+ if(ASN_SET_ADD(list, ptr) == 0)
+ continue;
+ ASN_DEBUG("Failed to add element into %s",
+ td->name);
+ /* Fall through */
+ } else {
+ ASN_DEBUG("Failed decoding %s of %s (SET OF)",
+ elm->type->name, td->name);
+ }
+ if(ptr) elm->type->free_struct(elm->type, ptr, 0);
+ _ASN_DECODE_FAILED;
+ }
+
+ nelems = -1; /* Allow uper_get_length() */
+ } while(repeat);
+
+ ASN_DEBUG("Decoded %s as SET OF", td->name);
+
+ rv.code = RC_OK;
+ rv.consumed = 0;
+ return rv;
+}
+
diff --git a/skeletons/constr_SET_OF.h b/skeletons/constr_SET_OF.h
index 410be26b..14209316 100644
--- a/skeletons/constr_SET_OF.h
+++ b/skeletons/constr_SET_OF.h
@@ -32,6 +32,7 @@ ber_type_decoder_f SET_OF_decode_ber;
der_type_encoder_f SET_OF_encode_der;
xer_type_decoder_f SET_OF_decode_xer;
xer_type_encoder_f SET_OF_encode_xer;
+per_type_decoder_f SET_OF_decode_uper;
#ifdef __cplusplus
}
diff --git a/skeletons/constr_TYPE.h b/skeletons/constr_TYPE.h
index 90b6578c..37d21f6d 100644
--- a/skeletons/constr_TYPE.h
+++ b/skeletons/constr_TYPE.h
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
/*
@@ -38,6 +39,7 @@ typedef struct asn_struct_ctx_s {
#include <der_encoder.h> /* Distinguished Encoding Rules encoder */
#include <xer_decoder.h> /* Decoder of XER (XML, text) */
#include <xer_encoder.h> /* Encoder into XER (XML, text) */
+#include <per_decoder.h> /* Packet Encoding Rules decoder */
#include <constraints.h> /* Subtype constraints support */
/*
@@ -91,6 +93,7 @@ typedef struct asn_TYPE_descriptor_s {
der_type_encoder_f *der_encoder; /* Canonical DER encoder */
xer_type_decoder_f *xer_decoder; /* Generic XER decoder */
xer_type_encoder_f *xer_encoder; /* [Canonical] XER encoder */
+ per_type_decoder_f *uper_decoder; /* Unaligned PER decoder */
/***********************************************************************
* Internally useful members. Not to be used by applications directly. *
@@ -105,6 +108,8 @@ typedef struct asn_TYPE_descriptor_s {
ber_tlv_tag_t *all_tags;/* Every tag for BER/containment */
int all_tags_count; /* Number of tags */
+ asn_per_constraints_t *per_constraints; /* PER compiled constraints */
+
/*
* An ASN.1 production type members (members of SEQUENCE, SET, CHOICE).
*/
@@ -135,6 +140,8 @@ typedef struct asn_TYPE_member_s {
int tag_mode; /* IMPLICIT/no/EXPLICIT tag at current level */
asn_TYPE_descriptor_t *type; /* Member type descriptor */
asn_constr_check_f *memb_constraints; /* Constraints validator */
+ asn_per_constraints_t *per_constraints; /* PER compiled constraints */
+ int (*default_value)(void **sptr); /* DEFAULT <value> */
char *name; /* ASN.1 identifier of the element */
} asn_TYPE_member_t;
diff --git a/skeletons/file-dependencies b/skeletons/file-dependencies
index ce9c0010..87e96098 100644
--- a/skeletons/file-dependencies
+++ b/skeletons/file-dependencies
@@ -9,7 +9,7 @@
ANY.h ANY.c
BMPString.h BMPString.c UTF8String.h
BOOLEAN.h BOOLEAN.c
-ENUMERATED.h ENUMERATED.c INTEGER.h
+ENUMERATED.h ENUMERATED.c INTEGER.h NativeEnumerated.h
GeneralString.h GeneralString.c
GeneralizedTime.h GeneralizedTime.c
GraphicString.h GraphicString.c
@@ -58,4 +58,10 @@ constraints.h constraints.c # Subtype constraints support
xer_support.h xer_support.c # XML parsing
xer_decoder.h xer_decoder.c # XER decoding support
xer_encoder.h xer_encoder.c # XER encoding support
+per_decoder.h per_support.h # PER declarations, just in case
#asn-decoder-template.c # Template for quick decoder creation
+
+CODEC-PER: # THIS IS A SPECIAL SECTION
+per_support.h per_support.c # PER parsing
+per_decoder.h per_decoder.c # PER decoding support
+
diff --git a/skeletons/per_decoder.c b/skeletons/per_decoder.c
new file mode 100644
index 00000000..55c04cb5
--- /dev/null
+++ b/skeletons/per_decoder.c
@@ -0,0 +1,2 @@
+#include <asn_application.h>
+#include <per_decoder.h>
diff --git a/skeletons/per_decoder.h b/skeletons/per_decoder.h
new file mode 100644
index 00000000..6303b3cf
--- /dev/null
+++ b/skeletons/per_decoder.h
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _PER_DECODER_H_
+#define _PER_DECODER_H_
+
+#include <asn_application.h>
+#include <per_support.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * Pre-computed PER constraints.
+ */
+ enum asn_per_constraint_flags {
+ APC_UNCONSTRAINED = 0x0, /* No PER visible constraints */
+ APC_SEMI_CONSTRAINED = 0x1, /* Constrained at "lb" */
+ APC_CONSTRAINED = 0x2, /* Fully constrained */
+ APC_EXTENSIBLE = 0x4 /* May have extension */
+ };
+typedef struct asn_per_constraint_s {
+
+ enum asn_per_constraint_flags flags;
+ int range_bits; /* Full number of bits in the range */
+ int effective_bits; /* Effective bits */
+ long lower_bound; /* "lb" value */
+ long upper_bound; /* "ub" value */
+} asn_per_constraint_t;
+typedef struct asn_per_constraints_s {
+ asn_per_constraint_t value;
+ asn_per_constraint_t size;
+} asn_per_constraints_t;
+
+
+struct asn_TYPE_descriptor_s; /* Forward declaration */
+
+/*
+ * Type of the type-specific PER decoder function.
+ */
+typedef asn_dec_rval_t (per_type_decoder_f)(asn_codec_ctx_t *opt_codec_ctx,
+ struct asn_TYPE_descriptor_s *type_descriptor,
+ asn_per_constraints_t *constraints,
+ void **struct_ptr,
+ asn_per_data_t *per_data
+ );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PER_DECODER_H_ */
diff --git a/skeletons/per_support.c b/skeletons/per_support.c
new file mode 100644
index 00000000..506ca780
--- /dev/null
+++ b/skeletons/per_support.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_system.h>
+#include <per_support.h>
+
+/*
+ * Extract a small number of bits (<= 24) from the specified PER data pointer.
+ */
+int32_t
+per_get_few_bits(asn_per_data_t *pd, int nbits) {
+ size_t off; /* Next after last bit offset */
+ uint32_t accum;
+ uint8_t *buf;
+
+ if(nbits < 0 || pd->nboff + nbits > pd->nbits)
+ return -1;
+ if(nbits == 0)
+ return 0;
+
+ /*
+ * Normalize position indicator.
+ */
+ if(pd->nboff >= 8) {
+ pd->buffer += (pd->nboff >> 3);
+ pd->nbits -= (pd->nboff & ~0x07);
+ pd->nboff &= 0x07;
+ }
+ off = (pd->nboff += nbits);
+ buf = pd->buffer;
+
+ /*
+ * Extract specified number of bits.
+ */
+ if(off <= 8)
+ accum = (buf[0]) >> (8 - off);
+ else if(off <= 16)
+ accum = ((buf[0] << 8) + buf[1]) >> (16 - off);
+ else if(off <= 24)
+ accum = ((buf[0] << 16) + (buf[1] << 8) + buf[2]) >> (24 - off);
+ else if(off <= 31)
+ accum = ((buf[0] << 24) + (buf[1] << 16)
+ + (buf[2] << 8) + (buf[3])) >> (32 - off);
+ else {
+ pd->nboff -= nbits; /* Oops, revert back */
+ return -1;
+ }
+
+ return (accum & ((1 << nbits) - 1));
+}
+
+/*
+ * Extract a large number of bits from the specified PER data pointer.
+ */
+int
+per_get_many_bits(asn_per_data_t *pd, uint8_t *dst, int alright, int nbits) {
+ int32_t value;
+
+ if(alright && (nbits & 7)) {
+ /* Perform right alignment of a first few bits */
+ value = per_get_few_bits(pd, nbits & 0x07);
+ if(value < 0) return -1;
+ *dst++ = value; /* value is already right-aligned */
+ nbits &= ~7;
+ }
+
+ while(nbits) {
+ if(nbits >= 24) {
+ value = per_get_few_bits(pd, 24);
+ if(value < 0) return -1;
+ *(dst++) = value >> 16;
+ *(dst++) = value >> 8;
+ *(dst++) = value;
+ nbits -= 24;
+ } else {
+ value = per_get_few_bits(pd, nbits);
+ if(value < 0) return -1;
+ if(nbits & 7) { /* implies alright */
+ value <<= 8 - (nbits & 7),
+ nbits += 8 - (nbits & 7);
+ if(nbits > 24)
+ *dst++ = value >> 24;
+ }
+ if(nbits > 16)
+ *dst++ = value >> 16;
+ if(nbits > 8)
+ *dst++ = value >> 8;
+ *dst++ = value;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Get the length "n" from the stream.
+ */
+ssize_t
+uper_get_length(asn_per_data_t *pd, int ebits, int *repeat) {
+ ssize_t value;
+
+ *repeat = 0;
+
+ if(ebits >= 0) return per_get_few_bits(pd, ebits);
+
+ value = per_get_few_bits(pd, 8);
+ if(value < 0) return -1;
+ if((value & 128) == 0) /* #10.9.3.6 */
+ return (value & 0x7F);
+ if((value & 64) == 0) { /* #10.9.3.7 */
+ value = ((value & 63) << 8) | per_get_few_bits(pd, 8);
+ if(value < 0) return -1;
+ return value;
+ }
+ value &= 63; /* this is "m" from X.691, #10.9.3.8 */
+ if(value < 1 || value > 4)
+ return -1;
+ *repeat = 1;
+ return (16384 * value);
+}
+
+/*
+ * Get the normally small non-negative whole number.
+ * X.691, #10.6
+ */
+ssize_t
+uper_get_nsnnwn(asn_per_data_t *pd) {
+ ssize_t value;
+
+ value = per_get_few_bits(pd, 7);
+ if(value & 64) { /* implicit (value < 0) */
+ value &= 63;
+ value <<= 2;
+ value |= per_get_few_bits(pd, 2);
+ if(value & 128) /* implicit (value < 0) */
+ return -1;
+ if(value == 0)
+ return 0;
+ if(value >= 3)
+ return -1;
+ value = per_get_few_bits(pd, 8 * value);
+ return value;
+ }
+
+ return value;
+}
diff --git a/skeletons/per_support.h b/skeletons/per_support.h
new file mode 100644
index 00000000..25c92566
--- /dev/null
+++ b/skeletons/per_support.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _PER_SUPPORT_H_
+#define _PER_SUPPORT_H_
+
+#include <asn_system.h> /* Platform-specific types */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This structure describes a position inside a PER bit stream.
+ */
+typedef struct asn_per_data_s {
+ uint8_t *buffer; /* Pointer to the octet stream */
+ size_t nboff; /* Bit offset to the meaningful bit */
+ size_t nbits; /* Number of bits in the stream */
+} asn_per_data_t;
+
+/*
+ * Extract a small number of bits (<= 24) from the specified PER data pointer.
+ * This function returns -1 if the specified number of bits could not be
+ * extracted due to EOD or other conditions.
+ */
+int32_t per_get_few_bits(asn_per_data_t *per_data, int get_nbits);
+
+/*
+ * Extract a large number of bits from the specified PER data pointer.
+ * This function returns -1 if the specified number of bits could not be
+ * extracted due to EOD or other conditions.
+ */
+int per_get_many_bits(asn_per_data_t *pd, uint8_t *dst, int right_align,
+ int get_nbits);
+
+/*
+ * Get the length "n" from the Unaligned PER stream.
+ */
+ssize_t uper_get_length(asn_per_data_t *pd,
+ int effective_bound_bits,
+ int *repeat);
+
+/*
+ * Get the normally small non-negative whole number.
+ */
+ssize_t uper_get_nsnnwn(asn_per_data_t *pd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PER_SUPPORT_H_ */
diff --git a/skeletons/tests/Makefile.am b/skeletons/tests/Makefile.am
index c374438d..a664a6f6 100644
--- a/skeletons/tests/Makefile.am
+++ b/skeletons/tests/Makefile.am
@@ -10,7 +10,8 @@ check_PROGRAMS = \
check-UTCTime \
check-INTEGER \
check-REAL \
- check-XER
+ check-XER \
+ check-PER
LDADD = -lm
diff --git a/skeletons/tests/Makefile.in b/skeletons/tests/Makefile.in
index f5a3c689..d0f980f2 100644
--- a/skeletons/tests/Makefile.in
+++ b/skeletons/tests/Makefile.in
@@ -13,7 +13,7 @@
# PARTICULAR PURPOSE.
@SET_MAKE@
-SOURCES = check-GeneralizedTime.c check-INTEGER.c check-OCTET_STRING.c check-OIDs.c check-REAL.c check-UTCTime.c check-UTF8String.c check-XER.c check-ber_tlv_tag.c check-length.c
+SOURCES = check-GeneralizedTime.c check-INTEGER.c check-OCTET_STRING.c check-OIDs.c check-PER.c check-REAL.c check-UTCTime.c check-UTF8String.c check-XER.c check-ber_tlv_tag.c check-length.c
srcdir = @srcdir@
top_srcdir = @top_srcdir@
@@ -40,7 +40,7 @@ check_PROGRAMS = check-ber_tlv_tag$(EXEEXT) check-length$(EXEEXT) \
check-OIDs$(EXEEXT) check-GeneralizedTime$(EXEEXT) \
check-OCTET_STRING$(EXEEXT) check-UTF8String$(EXEEXT) \
check-UTCTime$(EXEEXT) check-INTEGER$(EXEEXT) \
- check-REAL$(EXEEXT) check-XER$(EXEEXT)
+ check-REAL$(EXEEXT) check-XER$(EXEEXT) check-PER$(EXEEXT)
subdir = skeletons/tests
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -66,6 +66,10 @@ check_OIDs_SOURCES = check-OIDs.c
check_OIDs_OBJECTS = check-OIDs.$(OBJEXT)
check_OIDs_LDADD = $(LDADD)
check_OIDs_DEPENDENCIES =
+check_PER_SOURCES = check-PER.c
+check_PER_OBJECTS = check-PER.$(OBJEXT)
+check_PER_LDADD = $(LDADD)
+check_PER_DEPENDENCIES =
check_REAL_SOURCES = check-REAL.c
check_REAL_OBJECTS = check-REAL.$(OBJEXT)
check_REAL_LDADD = $(LDADD)
@@ -96,7 +100,7 @@ am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/check-GeneralizedTime.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/check-INTEGER.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/check-OCTET_STRING.Po \
-@AMDEP_TRUE@ ./$(DEPDIR)/check-OIDs.Po \
+@AMDEP_TRUE@ ./$(DEPDIR)/check-OIDs.Po ./$(DEPDIR)/check-PER.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/check-REAL.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/check-UTCTime.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/check-UTF8String.Po \
@@ -112,12 +116,13 @@ CCLD = $(CC)
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = check-GeneralizedTime.c check-INTEGER.c check-OCTET_STRING.c \
- check-OIDs.c check-REAL.c check-UTCTime.c check-UTF8String.c \
- check-XER.c check-ber_tlv_tag.c check-length.c
-DIST_SOURCES = check-GeneralizedTime.c check-INTEGER.c \
- check-OCTET_STRING.c check-OIDs.c check-REAL.c check-UTCTime.c \
+ check-OIDs.c check-PER.c check-REAL.c check-UTCTime.c \
check-UTF8String.c check-XER.c check-ber_tlv_tag.c \
check-length.c
+DIST_SOURCES = check-GeneralizedTime.c check-INTEGER.c \
+ check-OCTET_STRING.c check-OIDs.c check-PER.c check-REAL.c \
+ check-UTCTime.c check-UTF8String.c check-XER.c \
+ check-ber_tlv_tag.c check-length.c
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -285,6 +290,9 @@ check-OCTET_STRING$(EXEEXT): $(check_OCTET_STRING_OBJECTS) $(check_OCTET_STRING_
check-OIDs$(EXEEXT): $(check_OIDs_OBJECTS) $(check_OIDs_DEPENDENCIES)
@rm -f check-OIDs$(EXEEXT)
$(LINK) $(check_OIDs_LDFLAGS) $(check_OIDs_OBJECTS) $(check_OIDs_LDADD) $(LIBS)
+check-PER$(EXEEXT): $(check_PER_OBJECTS) $(check_PER_DEPENDENCIES)
+ @rm -f check-PER$(EXEEXT)
+ $(LINK) $(check_PER_LDFLAGS) $(check_PER_OBJECTS) $(check_PER_LDADD) $(LIBS)
check-REAL$(EXEEXT): $(check_REAL_OBJECTS) $(check_REAL_DEPENDENCIES)
@rm -f check-REAL$(EXEEXT)
$(LINK) $(check_REAL_LDFLAGS) $(check_REAL_OBJECTS) $(check_REAL_LDADD) $(LIBS)
@@ -314,6 +322,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-INTEGER.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-OCTET_STRING.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-OIDs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-PER.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-REAL.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-UTCTime.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-UTF8String.Po@am__quote@
diff --git a/skeletons/tests/check-INTEGER.c b/skeletons/tests/check-INTEGER.c
index bb692c50..fccce287 100644
--- a/skeletons/tests/check-INTEGER.c
+++ b/skeletons/tests/check-INTEGER.c
@@ -6,6 +6,7 @@
#include <der_encoder.c>
#include <xer_decoder.c>
#include <xer_support.c>
+#include <per_support.c>
#include <constraints.c>
static char *shared_scratch_start;
diff --git a/skeletons/tests/check-OCTET_STRING.c b/skeletons/tests/check-OCTET_STRING.c
index 51f6eb3b..b3e298f1 100644
--- a/skeletons/tests/check-OCTET_STRING.c
+++ b/skeletons/tests/check-OCTET_STRING.c
@@ -3,6 +3,7 @@
#include <BIT_STRING.c>
#include <xer_decoder.c>
#include <xer_support.c>
+#include <per_support.c>
#include <ber_decoder.c>
#include <ber_tlv_length.c>
#include <ber_tlv_tag.c>
diff --git a/skeletons/tests/check-PER.c b/skeletons/tests/check-PER.c
new file mode 100644
index 00000000..94f5fe42
--- /dev/null
+++ b/skeletons/tests/check-PER.c
@@ -0,0 +1,105 @@
+#include <per_support.c>
+#include <assert.h>
+
+int
+main() {
+ uint8_t buf[] = { 0xB7, 0x19, 0x2F, 0xEE, 0xAD };
+ uint8_t tmpbuf[10];
+ int32_t z;
+ asn_per_data_t pos;
+
+ pos.buffer = buf;
+ pos.nboff = 0;
+ pos.nbits = sizeof(buf) * 8;
+
+ z = per_get_few_bits(&pos, 32);
+ assert(z == -1);
+
+ z = per_get_few_bits(&pos, 0);
+ assert(z == 0);
+ assert(pos.nboff == 0);
+
+ z = per_get_few_bits(&pos, 1);
+ assert(z == 1);
+ assert(pos.nboff == 1);
+
+ z = per_get_few_bits(&pos, 2);
+ assert(z == 1);
+ assert(pos.nboff == 3);
+
+ z = per_get_few_bits(&pos, 2);
+ assert(z == 2);
+ assert(pos.nboff == 5);
+
+ z = per_get_few_bits(&pos, 3);
+ assert(z == 7);
+ assert(pos.nboff == 8);
+ assert(pos.nbits == sizeof(buf) * 8);
+
+ z = per_get_few_bits(&pos, 8);
+ assert(z == 0x19);
+ assert(pos.nboff == 8);
+ assert(pos.nbits == (sizeof(buf) - 1) * 8);
+
+ z = per_get_few_bits(&pos, 1);
+ assert(z == 0);
+ assert(pos.nboff == 1);
+ assert(pos.nbits == (sizeof(buf) - 2) * 8);
+
+ z = per_get_few_bits(&pos, 3);
+ assert(z == 2);
+ assert(pos.nboff == 4);
+ assert(pos.nbits == (sizeof(buf) - 2) * 8);
+
+ z = per_get_few_bits(&pos, 8);
+ assert(z == 254);
+ assert(pos.nboff == 12);
+
+ pos.buffer = buf;
+ pos.nboff = 2;
+ pos.nbits = sizeof(buf) * 8;
+ z = per_get_few_bits(&pos, 24);
+ assert(z == 14443711);
+
+ pos.buffer = buf;
+ pos.nboff = 0;
+ pos.nbits = sizeof(buf) * 8;
+ z = per_get_many_bits(&pos, tmpbuf, 0, sizeof(buf) * 8);
+ assert(z == 0);
+ assert(buf[0] == tmpbuf[0]);
+ assert(buf[1] == tmpbuf[1]);
+ assert(buf[2] == tmpbuf[2]);
+ assert(buf[3] == tmpbuf[3]);
+ assert(buf[4] == tmpbuf[4]);
+
+ pos.buffer = buf;
+ pos.nboff = 1;
+ pos.nbits = sizeof(buf) * 8;
+ z = per_get_many_bits(&pos, tmpbuf, 0, sizeof(buf) * 8);
+ assert(z == -1);
+
+ pos.buffer = buf;
+ pos.nboff = 1;
+ pos.nbits = sizeof(buf) * 8;
+ z = per_get_many_bits(&pos, tmpbuf, 0, sizeof(buf) * 8 - 1);
+ assert(z == 0);
+ assert(tmpbuf[0] == 110);
+ assert(tmpbuf[1] == 50);
+ assert(tmpbuf[2] == 95);
+ assert(tmpbuf[3] == 221);
+ assert(tmpbuf[4] == 90);
+
+ pos.buffer = buf;
+ pos.nboff = 1;
+ pos.nbits = sizeof(buf) * 8;
+ z = per_get_many_bits(&pos, tmpbuf, 1, sizeof(buf) * 8 - 1);
+ assert(z == 0);
+ assert(tmpbuf[0] == 55);
+ assert(tmpbuf[0] != buf[0]);
+ assert(tmpbuf[1] == buf[1]);
+ assert(tmpbuf[2] == buf[2]);
+ assert(tmpbuf[3] == buf[3]);
+ assert(tmpbuf[4] == buf[4]);
+
+ return 0;
+}
diff --git a/skeletons/tests/check-UTF8String.c b/skeletons/tests/check-UTF8String.c
index 10592a19..8a90b242 100644
--- a/skeletons/tests/check-UTF8String.c
+++ b/skeletons/tests/check-UTF8String.c
@@ -6,6 +6,7 @@
#include <der_encoder.c>
#include <xer_decoder.c>
#include <xer_support.c>
+#include <per_support.c>
#include <constraints.c>
#include <sys/time.h>
diff --git a/skeletons/tests/check-length.c b/skeletons/tests/check-length.c
index 9a6d8d67..cf104050 100644
--- a/skeletons/tests/check-length.c
+++ b/skeletons/tests/check-length.c
@@ -4,6 +4,7 @@
#include <der_encoder.c>
#include <xer_decoder.c>
#include <xer_support.c>
+#include <per_support.c>
#include <constraints.c>
#undef ADVANCE
#undef RETURN
diff --git a/skeletons/xer_encoder.c b/skeletons/xer_encoder.c
index 3ee62cb8..aa7cf040 100644
--- a/skeletons/xer_encoder.c
+++ b/skeletons/xer_encoder.c
@@ -32,9 +32,7 @@ xer_encode(asn_TYPE_descriptor_t *td, void *sptr,
er.encoded = 4 + xcan + (2 * mlen) + tmper.encoded;
- er.structure_ptr = 0;
- er.failed_type = 0;
- return er;
+ _ASN_ENCODED_OK(er);
cb_failed:
_ASN_ENCODE_FAILED;
}
diff --git a/skeletons/xer_support.c b/skeletons/xer_support.c
index 1d0b42c5..9e34e692 100644
--- a/skeletons/xer_support.c
+++ b/skeletons/xer_support.c
@@ -4,11 +4,7 @@
* All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-
+#include <asn_system.h>
#include <xer_support.h>
/* Parser states */