git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7886 818b1a75-f10b-46b9-bf7c-635c3b92a50f
5083 lines
146 KiB
Plaintext
5083 lines
146 KiB
Plaintext
Index: asn1c/unber.c
|
|
===================================================================
|
|
--- asn1c/unber.c (revision 1516)
|
|
+++ asn1c/unber.c (working copy)
|
|
@@ -775,4 +775,8 @@
|
|
|
|
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; }
|
|
|
|
+asn_dec_rval_t OCTET_STRING_decode_aper(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_aper(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; }
|
|
+
|
|
size_t xer_whitespace_span(const void *chunk_buf, size_t chunk_size) { (void)chunk_buf; (void)chunk_size; return 0; }
|
|
Index: asn1c/asn1c.c
|
|
===================================================================
|
|
--- asn1c/asn1c.c (revision 1516)
|
|
+++ asn1c/asn1c.c (working copy)
|
|
@@ -111,6 +111,8 @@
|
|
asn1_compiler_flags &= ~A1C_LINK_SKELETONS;
|
|
} else if(strcmp(optarg, "link-skeletons") == 0) {
|
|
asn1_compiler_flags |= A1C_LINK_SKELETONS;
|
|
+ } else if(strcmp(optarg, "have_native64") == 0) {
|
|
+ asn1_compiler_flags |= A1C_HAVE_NATIVE_64;
|
|
} else {
|
|
fprintf(stderr, "-f%s: Invalid argument\n", optarg);
|
|
exit(EX_USAGE);
|
|
@@ -471,6 +473,7 @@
|
|
" -fno-include-deps Do not generate courtesy #includes for dependencies\n"
|
|
" -funnamed-unions Enable unnamed unions in structures\n"
|
|
" -fwide-types Use INTEGER_t instead of \"long\" by default, etc.\n"
|
|
+" -fhave_native64 Use int64_t/uint64_t for target platform\n"
|
|
"\n"
|
|
|
|
" -gen-PER Generate PER support code\n"
|
|
Index: examples/README
|
|
===================================================================
|
|
--- examples/README (revision 1516)
|
|
+++ examples/README (working copy)
|
|
@@ -25,6 +25,8 @@
|
|
UserPlane Location Protocol decoder. Before trying to compile, read the
|
|
README file in that directory.
|
|
|
|
+The clyx2asn1.pl script can be used to extract ASN.1 data from LyX editor files.
|
|
+
|
|
The crfc2asn1.pl script can be used to extract ASN.1 data from RFC texts.
|
|
For instance, it is used to extract X.509, MEGACO, and LDAPv3 ASN.1 modules
|
|
from the corresponding RFC texts (rfc3280.txt, rfc3525.txt, rfc4211.txt).
|
|
Index: skeletons/UTF8String.c
|
|
===================================================================
|
|
--- skeletons/UTF8String.c (revision 1516)
|
|
+++ skeletons/UTF8String.c (working copy)
|
|
@@ -25,6 +25,8 @@
|
|
OCTET_STRING_encode_xer_utf8,
|
|
OCTET_STRING_decode_uper,
|
|
OCTET_STRING_encode_uper,
|
|
+ OCTET_STRING_decode_aper,
|
|
+ OCTET_STRING_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_UTF8String_tags,
|
|
sizeof(asn_DEF_UTF8String_tags)
|
|
Index: skeletons/constr_TYPE.h
|
|
===================================================================
|
|
--- skeletons/constr_TYPE.h (revision 1516)
|
|
+++ skeletons/constr_TYPE.h (working copy)
|
|
@@ -99,6 +99,8 @@
|
|
xer_type_encoder_f *xer_encoder; /* [Canonical] XER encoder */
|
|
per_type_decoder_f *uper_decoder; /* Unaligned PER decoder */
|
|
per_type_encoder_f *uper_encoder; /* Unaligned PER encoder */
|
|
+ per_type_decoder_f *aper_decoder; /* Aligned PER decoder */
|
|
+ per_type_encoder_f *aper_encoder; /* Aligned PER encoder */
|
|
|
|
/***********************************************************************
|
|
* Internally useful members. Not to be used by applications directly. *
|
|
Index: skeletons/RELATIVE-OID.c
|
|
===================================================================
|
|
--- skeletons/RELATIVE-OID.c (revision 1516)
|
|
+++ skeletons/RELATIVE-OID.c (working copy)
|
|
@@ -28,6 +28,8 @@
|
|
RELATIVE_OID_encode_xer,
|
|
OCTET_STRING_decode_uper,
|
|
OCTET_STRING_encode_uper,
|
|
+ OCTET_STRING_decode_aper,
|
|
+ OCTET_STRING_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_RELATIVE_OID_tags,
|
|
sizeof(asn_DEF_RELATIVE_OID_tags)
|
|
Index: skeletons/per_encoder.c
|
|
===================================================================
|
|
--- skeletons/per_encoder.c (revision 1516)
|
|
+++ skeletons/per_encoder.c (working copy)
|
|
@@ -4,6 +4,7 @@
|
|
|
|
static asn_enc_rval_t uper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *, void *sptr, asn_app_consume_bytes_f *cb, void *app_key);
|
|
|
|
+static asn_enc_rval_t aper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *, void *sptr, asn_app_consume_bytes_f *cb, void *app_key);
|
|
asn_enc_rval_t
|
|
uper_encode(asn_TYPE_descriptor_t *td, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) {
|
|
return uper_encode_internal(td, 0, sptr, cb, app_key);
|
|
@@ -41,6 +42,18 @@
|
|
return uper_encode_internal(td, 0, sptr, encode_to_buffer_cb, &key);
|
|
}
|
|
|
|
+asn_enc_rval_t
|
|
+aper_encode_to_buffer(asn_TYPE_descriptor_t *td, void *sptr, void *buffer, size_t buffer_size) {
|
|
+ enc_to_buf_arg key;
|
|
+
|
|
+ key.buffer = buffer;
|
|
+ key.left = buffer_size;
|
|
+
|
|
+ if(td) ASN_DEBUG("Encoding \"%s\" using ALIGNED PER", td->name);
|
|
+
|
|
+ return aper_encode_internal(td, 0, sptr, encode_to_buffer_cb, &key);
|
|
+}
|
|
+
|
|
typedef struct enc_dyn_arg {
|
|
void *buffer;
|
|
size_t length;
|
|
@@ -93,6 +106,35 @@
|
|
}
|
|
}
|
|
|
|
+ssize_t
|
|
+aper_encode_to_new_buffer(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, void **buffer_r) {
|
|
+ asn_enc_rval_t er;
|
|
+ enc_dyn_arg key;
|
|
+
|
|
+ memset(&key, 0, sizeof(key));
|
|
+
|
|
+ er = aper_encode_internal(td, constraints, sptr, encode_dyn_cb, &key);
|
|
+ switch(er.encoded) {
|
|
+ case -1:
|
|
+ FREEMEM(key.buffer);
|
|
+ return -1;
|
|
+ case 0:
|
|
+ FREEMEM(key.buffer);
|
|
+ key.buffer = MALLOC(1);
|
|
+ if(key.buffer) {
|
|
+ *(char *)key.buffer = '\0';
|
|
+ *buffer_r = key.buffer;
|
|
+ return 1;
|
|
+ } else {
|
|
+ return -1;
|
|
+ }
|
|
+ default:
|
|
+ *buffer_r = key.buffer;
|
|
+ ASN_DEBUG("Complete encoded in %ld bits", (long)er.encoded);
|
|
+ return ((er.encoded + 7) >> 3);
|
|
+ }
|
|
+}
|
|
+
|
|
/*
|
|
* Internally useful functions.
|
|
*/
|
|
@@ -115,6 +157,23 @@
|
|
return po->outper(po->tmpspace, buf - po->tmpspace, po->op_key);
|
|
}
|
|
|
|
+static int
|
|
+_aper_encode_flush_outp(asn_per_outp_t *po) {
|
|
+ uint8_t *buf;
|
|
+
|
|
+ if(po->nboff == 0 && po->buffer == po->tmpspace)
|
|
+ return 0;
|
|
+
|
|
+ buf = po->buffer + (po->nboff >> 3);
|
|
+ /* Make sure we account for the last, partially filled */
|
|
+ if(po->nboff & 0x07) {
|
|
+ buf[0] &= 0xff << (8 - (po->nboff & 0x07));
|
|
+ buf++;
|
|
+ }
|
|
+
|
|
+ return po->outper(po->tmpspace, buf - po->tmpspace, po->op_key);
|
|
+}
|
|
+
|
|
static asn_enc_rval_t
|
|
uper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) {
|
|
asn_per_outp_t po;
|
|
@@ -149,3 +208,37 @@
|
|
return er;
|
|
}
|
|
|
|
+static asn_enc_rval_t
|
|
+aper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) {
|
|
+ asn_per_outp_t po;
|
|
+ asn_enc_rval_t er;
|
|
+
|
|
+ /*
|
|
+ * Invoke type-specific encoder.
|
|
+ */
|
|
+ if(!td || !td->aper_encoder)
|
|
+ _ASN_ENCODE_FAILED; /* PER is not compiled in */
|
|
+
|
|
+ po.buffer = po.tmpspace;
|
|
+ po.nboff = 0;
|
|
+ po.nbits = 8 * sizeof(po.tmpspace);
|
|
+ po.outper = cb;
|
|
+ po.op_key = app_key;
|
|
+ po.flushed_bytes = 0;
|
|
+
|
|
+ er = td->aper_encoder(td, constraints, sptr, &po);
|
|
+ if(er.encoded != -1) {
|
|
+ size_t bits_to_flush;
|
|
+
|
|
+ bits_to_flush = ((po.buffer - po.tmpspace) << 3) + po.nboff;
|
|
+
|
|
+ /* Set number of bits encoded to a firm value */
|
|
+ er.encoded = (po.flushed_bytes << 3) + bits_to_flush;
|
|
+
|
|
+ if(_aper_encode_flush_outp(&po))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+
|
|
+ return er;
|
|
+}
|
|
+
|
|
Index: skeletons/NumericString.c
|
|
===================================================================
|
|
--- skeletons/NumericString.c (revision 1516)
|
|
+++ skeletons/NumericString.c (working copy)
|
|
@@ -49,6 +49,8 @@
|
|
OCTET_STRING_encode_xer_utf8,
|
|
OCTET_STRING_decode_uper,
|
|
OCTET_STRING_encode_uper,
|
|
+ OCTET_STRING_decode_aper,
|
|
+ OCTET_STRING_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_NumericString_tags,
|
|
sizeof(asn_DEF_NumericString_tags)
|
|
Index: skeletons/per_encoder.h
|
|
===================================================================
|
|
--- skeletons/per_encoder.h (revision 1516)
|
|
+++ skeletons/per_encoder.h (working copy)
|
|
@@ -38,6 +38,12 @@
|
|
size_t buffer_size /* Initial buffer size (max) */
|
|
);
|
|
|
|
+asn_enc_rval_t aper_encode_to_buffer(
|
|
+ struct asn_TYPE_descriptor_s *type_descriptor,
|
|
+ void *struct_ptr, /* Structure to be encoded */
|
|
+ void *buffer, /* Pre-allocated buffer */
|
|
+ size_t buffer_size /* Initial buffer size (max) */
|
|
+);
|
|
/*
|
|
* A variant of uper_encode_to_buffer() which allocates buffer itself.
|
|
* Returns the number of bytes in the buffer or -1 in case of failure.
|
|
@@ -52,6 +58,11 @@
|
|
void **buffer_r /* Buffer allocated and returned */
|
|
);
|
|
|
|
+ssize_t
|
|
+aper_encode_to_new_buffer(struct asn_TYPE_descriptor_s *td,
|
|
+ asn_per_constraints_t *constraints,
|
|
+ void *sptr,
|
|
+ void **buffer_r);
|
|
/*
|
|
* Type of the generic PER encoder function.
|
|
*/
|
|
Index: skeletons/T61String.c
|
|
===================================================================
|
|
--- skeletons/T61String.c (revision 1516)
|
|
+++ skeletons/T61String.c (working copy)
|
|
@@ -24,6 +24,8 @@
|
|
OCTET_STRING_encode_xer,
|
|
OCTET_STRING_decode_uper,
|
|
OCTET_STRING_encode_uper,
|
|
+ OCTET_STRING_decode_aper,
|
|
+ OCTET_STRING_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_T61String_tags,
|
|
sizeof(asn_DEF_T61String_tags)
|
|
Index: skeletons/TeletexString.c
|
|
===================================================================
|
|
--- skeletons/TeletexString.c (revision 1516)
|
|
+++ skeletons/TeletexString.c (working copy)
|
|
@@ -24,6 +24,8 @@
|
|
OCTET_STRING_encode_xer,
|
|
OCTET_STRING_decode_uper,
|
|
OCTET_STRING_encode_uper,
|
|
+ OCTET_STRING_decode_aper,
|
|
+ OCTET_STRING_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_TeletexString_tags,
|
|
sizeof(asn_DEF_TeletexString_tags)
|
|
Index: skeletons/BMPString.c
|
|
===================================================================
|
|
--- skeletons/BMPString.c (revision 1516)
|
|
+++ skeletons/BMPString.c (working copy)
|
|
@@ -35,6 +35,8 @@
|
|
BMPString_encode_xer, /* Convert to UTF-8 */
|
|
OCTET_STRING_decode_uper,
|
|
OCTET_STRING_encode_uper,
|
|
+ OCTET_STRING_decode_aper, /* Aligned PER decoder */
|
|
+ OCTET_STRING_encode_aper, /* Aligned PER encoder */
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_BMPString_tags,
|
|
sizeof(asn_DEF_BMPString_tags)
|
|
Index: skeletons/ObjectDescriptor.c
|
|
===================================================================
|
|
--- skeletons/ObjectDescriptor.c (revision 1516)
|
|
+++ skeletons/ObjectDescriptor.c (working copy)
|
|
@@ -24,6 +24,8 @@
|
|
OCTET_STRING_encode_xer_utf8,
|
|
OCTET_STRING_decode_uper,
|
|
OCTET_STRING_encode_uper,
|
|
+ OCTET_STRING_decode_aper,
|
|
+ OCTET_STRING_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_ObjectDescriptor_tags,
|
|
sizeof(asn_DEF_ObjectDescriptor_tags)
|
|
Index: skeletons/PrintableString.c
|
|
===================================================================
|
|
--- skeletons/PrintableString.c (revision 1516)
|
|
+++ skeletons/PrintableString.c (working copy)
|
|
@@ -59,6 +59,8 @@
|
|
OCTET_STRING_encode_xer_utf8,
|
|
OCTET_STRING_decode_uper,
|
|
OCTET_STRING_encode_uper,
|
|
+ OCTET_STRING_decode_aper,
|
|
+ OCTET_STRING_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_PrintableString_tags,
|
|
sizeof(asn_DEF_PrintableString_tags)
|
|
Index: skeletons/constr_SET_OF.c
|
|
===================================================================
|
|
--- skeletons/constr_SET_OF.c (revision 1516)
|
|
+++ skeletons/constr_SET_OF.c (working copy)
|
|
@@ -34,7 +34,7 @@
|
|
#undef ADVANCE
|
|
#define ADVANCE(num_bytes) do { \
|
|
size_t num = num_bytes; \
|
|
- ptr = ((const void *)ptr) + num;\
|
|
+ ptr = ((const char *)ptr) + num;\
|
|
size -= num; \
|
|
if(ctx->left >= 0) \
|
|
ctx->left -= num; \
|
|
@@ -100,7 +100,7 @@
|
|
/*
|
|
* Restore parsing context.
|
|
*/
|
|
- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset);
|
|
+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
|
|
|
|
/*
|
|
* Start to parse where left previously
|
|
@@ -457,7 +457,7 @@
|
|
#undef XER_ADVANCE
|
|
#define XER_ADVANCE(num_bytes) do { \
|
|
size_t num = num_bytes; \
|
|
- buf_ptr = ((const void *)buf_ptr) + num;\
|
|
+ buf_ptr = ((const char *)buf_ptr) + num;\
|
|
size -= num; \
|
|
consumed_myself += num; \
|
|
} while(0)
|
|
@@ -505,7 +505,7 @@
|
|
/*
|
|
* Restore parsing context.
|
|
*/
|
|
- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset);
|
|
+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
|
|
|
|
/*
|
|
* Phases of XER/XML processing:
|
|
@@ -627,7 +627,7 @@
|
|
t->buffer = p;
|
|
t->size = newsize;
|
|
}
|
|
- memcpy((void *)t->buffer + t->offset, buffer, size);
|
|
+ memcpy((char *)t->buffer + t->offset, buffer, size);
|
|
t->offset += size;
|
|
return 0;
|
|
}
|
|
@@ -809,7 +809,7 @@
|
|
asn_set_empty(list); /* Remove (list->array) */
|
|
|
|
specs = (asn_SET_OF_specifics_t *)td->specifics;
|
|
- ctx = (asn_struct_ctx_t *)((void *)ptr + specs->ctx_offset);
|
|
+ ctx = (asn_struct_ctx_t *)((char *)ptr + specs->ctx_offset);
|
|
if(ctx->ptr) {
|
|
ASN_STRUCT_FREE(*elm->type, ctx->ptr);
|
|
ctx->ptr = 0;
|
|
@@ -884,7 +884,7 @@
|
|
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 */
|
|
@@ -901,7 +901,7 @@
|
|
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",
|
|
+ ASN_DEBUG("Preparing to fetch %ld+%"PRIdMAX" elements from %s",
|
|
(long)nelems, ct->lower_bound, td->name);
|
|
if(nelems < 0) _ASN_DECODE_STARVED;
|
|
nelems += ct->lower_bound;
|
|
@@ -951,3 +951,91 @@
|
|
return rv;
|
|
}
|
|
|
|
+asn_dec_rval_t
|
|
+SET_OF_decode_aper(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;
|
|
+
|
|
+ if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
|
|
+ _ASN_DECODE_FAILED;
|
|
+
|
|
+ /*
|
|
+ * 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_STARVED;
|
|
+ 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);
|
|
+ nelems = aper_get_nsnnwn(pd, ct->upper_bound - ct->lower_bound);
|
|
+ ASN_DEBUG("Preparing to fetch %ld+%"PRIdMAX" elements from %s",
|
|
+ (long)nelems, ct->lower_bound, td->name);
|
|
+ if(nelems < 0) _ASN_DECODE_STARVED;
|
|
+ nelems += ct->lower_bound;
|
|
+ } else {
|
|
+ nelems = -1;
|
|
+ }
|
|
+
|
|
+ do {
|
|
+ int i;
|
|
+ if(nelems < 0) {
|
|
+ nelems = aper_get_length(pd, ct ? ct->upper_bound - ct->lower_bound + 1 : -1,
|
|
+ ct ? ct->effective_bits : -1, &repeat);
|
|
+ ASN_DEBUG("Got to decode %d elements (eff %d)",
|
|
+ (int)nelems, (int)ct ? ct->effective_bits : -1);
|
|
+ if(nelems < 0) _ASN_DECODE_STARVED;
|
|
+ }
|
|
+
|
|
+ for(i = 0; i < nelems; i++) {
|
|
+ void *ptr = 0;
|
|
+ ASN_DEBUG("SET OF %s decoding", elm->type->name);
|
|
+ rv = elm->type->aper_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 */
|
|
+ rv.code = RC_FAIL;
|
|
+ } else {
|
|
+ ASN_DEBUG("Failed decoding %s of %s (SET OF)",
|
|
+ elm->type->name, td->name);
|
|
+ }
|
|
+ if(ptr) ASN_STRUCT_FREE(*elm->type, ptr);
|
|
+ return rv;
|
|
+ }
|
|
+
|
|
+ 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;
|
|
+}
|
|
Index: skeletons/NULL.c
|
|
===================================================================
|
|
--- skeletons/NULL.c (revision 1516)
|
|
+++ skeletons/NULL.c (working copy)
|
|
@@ -25,6 +25,8 @@
|
|
NULL_encode_xer,
|
|
NULL_decode_uper, /* Unaligned PER decoder */
|
|
NULL_encode_uper, /* Unaligned PER encoder */
|
|
+ NULL_decode_aper, /* Aligned PER decoder */
|
|
+ NULL_encode_aper, /* Aligned PER encoder */
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_NULL_tags,
|
|
sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]),
|
|
@@ -135,6 +137,34 @@
|
|
return rv;
|
|
}
|
|
|
|
+asn_dec_rval_t
|
|
+NULL_decode_aper(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;
|
|
+}
|
|
+
|
|
asn_enc_rval_t
|
|
NULL_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints,
|
|
void *sptr, asn_per_outp_t *po) {
|
|
@@ -148,3 +178,17 @@
|
|
er.encoded = 0;
|
|
_ASN_ENCODED_OK(er);
|
|
}
|
|
+
|
|
+asn_enc_rval_t
|
|
+NULL_encode_aper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints,
|
|
+ void *sptr, asn_per_outp_t *po) {
|
|
+ asn_enc_rval_t er;
|
|
+
|
|
+ (void)td;
|
|
+ (void)constraints;
|
|
+ (void)sptr;
|
|
+ (void)po;
|
|
+
|
|
+ er.encoded = 0;
|
|
+ _ASN_ENCODED_OK(er);
|
|
+}
|
|
Index: skeletons/per_decoder.c
|
|
===================================================================
|
|
--- skeletons/per_decoder.c (revision 1516)
|
|
+++ skeletons/per_decoder.c (working copy)
|
|
@@ -37,6 +37,35 @@
|
|
}
|
|
|
|
asn_dec_rval_t
|
|
+aper_decode_complete(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size) {
|
|
+ asn_dec_rval_t rval;
|
|
+
|
|
+ rval = aper_decode(opt_codec_ctx, td, sptr, buffer, size, 0, 0);
|
|
+ if(rval.consumed) {
|
|
+ /*
|
|
+ * We've always given 8-aligned data,
|
|
+ * so convert bits to integral bytes.
|
|
+ */
|
|
+ rval.consumed += 7;
|
|
+ rval.consumed >>= 3;
|
|
+ } else if(rval.code == RC_OK) {
|
|
+ if(size) {
|
|
+ if(((const uint8_t *)buffer)[0] == 0) {
|
|
+ rval.consumed = 1; /* 1 byte */
|
|
+ } else {
|
|
+ ASN_DEBUG("Expecting single zeroed byte");
|
|
+ rval.code = RC_FAIL;
|
|
+ }
|
|
+ } else {
|
|
+ /* Must contain at least 8 bits. */
|
|
+ rval.code = RC_WMORE;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return rval;
|
|
+}
|
|
+
|
|
+asn_dec_rval_t
|
|
uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size, int skip_bits, int unused_bits) {
|
|
asn_codec_ctx_t s_codec_ctx;
|
|
asn_dec_rval_t rval;
|
|
@@ -91,3 +120,57 @@
|
|
return rval;
|
|
}
|
|
|
|
+asn_dec_rval_t
|
|
+aper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size, int skip_bits, int unused_bits) {
|
|
+ asn_codec_ctx_t s_codec_ctx;
|
|
+ asn_dec_rval_t rval;
|
|
+ asn_per_data_t pd;
|
|
+
|
|
+ if(skip_bits < 0 || skip_bits > 7
|
|
+ || unused_bits < 0 || unused_bits > 7
|
|
+ || (unused_bits > 0 && !size))
|
|
+ _ASN_DECODE_FAILED;
|
|
+
|
|
+ /*
|
|
+ * Stack checker requires that the codec context
|
|
+ * must be allocated on the stack.
|
|
+ */
|
|
+ if(opt_codec_ctx) {
|
|
+ if(opt_codec_ctx->max_stack_size) {
|
|
+ s_codec_ctx = *opt_codec_ctx;
|
|
+ opt_codec_ctx = &s_codec_ctx;
|
|
+ }
|
|
+ } else {
|
|
+ /* If context is not given, be security-conscious anyway */
|
|
+ memset(&s_codec_ctx, 0, sizeof(s_codec_ctx));
|
|
+ s_codec_ctx.max_stack_size = _ASN_DEFAULT_STACK_MAX;
|
|
+ opt_codec_ctx = &s_codec_ctx;
|
|
+ }
|
|
+
|
|
+ /* Fill in the position indicator */
|
|
+ memset(&pd, 0, sizeof(pd));
|
|
+ pd.buffer = (const uint8_t *)buffer;
|
|
+ pd.nboff = skip_bits;
|
|
+ pd.nbits = 8 * size - unused_bits; /* 8 is CHAR_BIT from <limits.h> */
|
|
+ if(pd.nboff > pd.nbits)
|
|
+ _ASN_DECODE_FAILED;
|
|
+
|
|
+ /*
|
|
+ * Invoke type-specific decoder.
|
|
+ */
|
|
+ if(!td->aper_decoder)
|
|
+ _ASN_DECODE_FAILED; /* PER is not compiled in */
|
|
+ rval = td->aper_decoder(opt_codec_ctx, td, 0, sptr, &pd);
|
|
+ if(rval.code == RC_OK) {
|
|
+ /* Return the number of consumed bits */
|
|
+ rval.consumed = ((pd.buffer - (const uint8_t *)buffer) << 3)
|
|
+ + pd.nboff - skip_bits;
|
|
+ ASN_DEBUG("PER decoding consumed %d, counted %d",
|
|
+ rval.consumed, pd.moved);
|
|
+ assert(rval.consumed == pd.moved);
|
|
+ } else {
|
|
+ /* PER codec is not a restartable */
|
|
+ rval.consumed = 0;
|
|
+ }
|
|
+ return rval;
|
|
+}
|
|
Index: skeletons/constr_SET_OF.h
|
|
===================================================================
|
|
--- skeletons/constr_SET_OF.h (revision 1516)
|
|
+++ skeletons/constr_SET_OF.h (working copy)
|
|
@@ -34,6 +34,8 @@
|
|
xer_type_encoder_f SET_OF_encode_xer;
|
|
per_type_decoder_f SET_OF_decode_uper;
|
|
per_type_encoder_f SET_OF_encode_uper;
|
|
+per_type_decoder_f SET_OF_decode_aper;
|
|
+per_type_encoder_f SET_OF_encode_aper;
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
Index: skeletons/NULL.h
|
|
===================================================================
|
|
--- skeletons/NULL.h (revision 1516)
|
|
+++ skeletons/NULL.h (working copy)
|
|
@@ -25,6 +25,8 @@
|
|
xer_type_encoder_f NULL_encode_xer;
|
|
per_type_decoder_f NULL_decode_uper;
|
|
per_type_encoder_f NULL_encode_uper;
|
|
+per_type_decoder_f NULL_decode_aper;
|
|
+per_type_encoder_f NULL_encode_aper;
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
Index: skeletons/per_decoder.h
|
|
===================================================================
|
|
--- skeletons/per_decoder.h (revision 1516)
|
|
+++ skeletons/per_decoder.h (working copy)
|
|
@@ -38,8 +38,30 @@
|
|
int unused_bits /* Number of unused tailing bits, 0..7 */
|
|
);
|
|
|
|
+/*
|
|
+ * Aligned PER decoder of a "complete encoding" as per X.691#10.1.
|
|
+ * On success, this call always returns (.consumed >= 1), as per X.691#10.1.3.
|
|
+ */
|
|
+asn_dec_rval_t aper_decode_complete(struct asn_codec_ctx_s *opt_codec_ctx,
|
|
+ struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
|
|
+ void **struct_ptr, /* Pointer to a target structure's pointer */
|
|
+ const void *buffer, /* Data to be decoded */
|
|
+ size_t size /* Size of data buffer */
|
|
+ );
|
|
|
|
/*
|
|
+ * Aligned PER decoder of any ASN.1 type. May be invoked by the application.
|
|
+ * WARNING: This call returns the number of BITS read from the stream. Beware.
|
|
+ */
|
|
+asn_dec_rval_t aper_decode(struct asn_codec_ctx_s *opt_codec_ctx,
|
|
+ struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
|
|
+ void **struct_ptr, /* Pointer to a target structure's pointer */
|
|
+ const void *buffer, /* Data to be decoded */
|
|
+ size_t size, /* Size of data buffer */
|
|
+ int skip_bits, /* Number of unused leading bits, 0..7 */
|
|
+ int unused_bits /* Number of unused tailing bits, 0..7 */
|
|
+ );
|
|
+/*
|
|
* Type of the type-specific PER decoder function.
|
|
*/
|
|
typedef asn_dec_rval_t (per_type_decoder_f)(asn_codec_ctx_t *opt_codec_ctx,
|
|
Index: skeletons/per_support.c
|
|
===================================================================
|
|
--- skeletons/per_support.c (revision 1516)
|
|
+++ skeletons/per_support.c (working copy)
|
|
@@ -31,6 +31,16 @@
|
|
}
|
|
}
|
|
|
|
+int32_t
|
|
+aper_get_align(asn_per_data_t *pd) {
|
|
+
|
|
+ if(pd->nboff & 0x7) {
|
|
+ ASN_DEBUG("Aligning %d bits", 8 - (pd->nboff & 0x7));
|
|
+ return per_get_few_bits(pd, 8 - (pd->nboff & 0x7));
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/*
|
|
* Extract a small number of bits (<= 31) from the specified PER data pointer.
|
|
*/
|
|
@@ -187,6 +197,36 @@
|
|
return (16384 * value);
|
|
}
|
|
|
|
+ssize_t
|
|
+aper_get_length(asn_per_data_t *pd, int range, int ebits, int *repeat) {
|
|
+ ssize_t value;
|
|
+
|
|
+ *repeat = 0;
|
|
+
|
|
+ if (range <= 65536 && range >= 0)
|
|
+ return aper_get_nsnnwn(pd, range);
|
|
+
|
|
+ if (aper_get_align(pd) < 0)
|
|
+ return -1;
|
|
+
|
|
+ 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 length "n".
|
|
* This procedure used to decode length of extensions bit-maps
|
|
@@ -211,6 +251,25 @@
|
|
}
|
|
}
|
|
|
|
+ssize_t
|
|
+aper_get_nslength(asn_per_data_t *pd) {
|
|
+ ssize_t length;
|
|
+
|
|
+ ASN_DEBUG("Getting normally small length");
|
|
+
|
|
+ if(per_get_few_bits(pd, 1) == 0) {
|
|
+ length = per_get_few_bits(pd, 6) + 1;
|
|
+ if(length <= 0) return -1;
|
|
+ ASN_DEBUG("l=%d", length);
|
|
+ return length;
|
|
+ } else {
|
|
+ int repeat;
|
|
+ length = aper_get_length(pd, -1, -1, &repeat);
|
|
+ if(length >= 0 && !repeat) return length;
|
|
+ return -1; /* Error, or do not support >16K extensions */
|
|
+ }
|
|
+}
|
|
+
|
|
/*
|
|
* Get the normally small non-negative whole number.
|
|
* X.691, #10.6
|
|
@@ -237,6 +296,40 @@
|
|
return value;
|
|
}
|
|
|
|
+ssize_t
|
|
+aper_get_nsnnwn(asn_per_data_t *pd, int range) {
|
|
+ ssize_t value;
|
|
+ int bytes = 0;
|
|
+
|
|
+ ASN_DEBUG("getting nsnnwn with range %d", range);
|
|
+
|
|
+ if(range <= 255) {
|
|
+ if (range < 0) return -1;
|
|
+ /* 1 -> 8 bits */
|
|
+ int i;
|
|
+ for (i = 1; i <= 8; i++) {
|
|
+ int upper = 1 << i;
|
|
+ if (upper >= range)
|
|
+ break;
|
|
+ }
|
|
+ value = per_get_few_bits(pd, i);
|
|
+ return value;
|
|
+ } else if (range == 256){
|
|
+ /* 1 byte */
|
|
+ bytes = 1;
|
|
+ return -1;
|
|
+ } else if (range <= 65536) {
|
|
+ /* 2 bytes */
|
|
+ bytes = 2;
|
|
+ } else {
|
|
+ return -1;
|
|
+ }
|
|
+ if (aper_get_align(pd) < 0)
|
|
+ return -1;
|
|
+ value = per_get_few_bits(pd, 8 * bytes);
|
|
+ return value;
|
|
+}
|
|
+
|
|
/*
|
|
* Put the normally small non-negative whole number.
|
|
* X.691, #10.6
|
|
@@ -263,7 +356,59 @@
|
|
return per_put_few_bits(po, n, 8 * bytes);
|
|
}
|
|
|
|
+int
|
|
+aper_put_nsnnwn(asn_per_outp_t *po, int range, int number) {
|
|
+ int bytes;
|
|
|
|
+ /* 10.5.7.1 X.691 */
|
|
+ if(range < 0) {
|
|
+ int i;
|
|
+ for (i = 1; ; i++) {
|
|
+ int bits = 1 << (8 * i);
|
|
+ if (number <= bits)
|
|
+ break;
|
|
+ }
|
|
+ bytes = i;
|
|
+ assert(i <= 4);
|
|
+ }
|
|
+ if(range <= 255) {
|
|
+ int i;
|
|
+ for (i = 1; i <= 8; i++) {
|
|
+ int bits = 1 << i;
|
|
+ if (range <= bits)
|
|
+ break;
|
|
+ }
|
|
+ return per_put_few_bits(po, number, i);
|
|
+ } else if(range == 256) {
|
|
+ bytes = 1;
|
|
+ } else if(range <= 65536) {
|
|
+ bytes = 2;
|
|
+ } else { /* Ranges > 64K */
|
|
+ int i;
|
|
+ for (i = 1; ; i++) {
|
|
+ int bits = 1 << (8 * i);
|
|
+ if (range <= bits)
|
|
+ break;
|
|
+ }
|
|
+ assert(i <= 4);
|
|
+ bytes = i;
|
|
+ }
|
|
+ if(aper_put_align(po) < 0) /* Aligning on octet */
|
|
+ return -1;
|
|
+
|
|
+ return per_put_few_bits(po, number, 8 * bytes);
|
|
+}
|
|
+
|
|
+int aper_put_align(asn_per_outp_t *po) {
|
|
+
|
|
+ if(po->nboff & 0x7) {
|
|
+ ASN_DEBUG("Aligning %d bits", 8 - (po->nboff & 0x7));
|
|
+ if(per_put_few_bits(po, 0x00, (8 - (po->nboff & 0x7))))
|
|
+ return -1;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/*
|
|
* Put a small number of bits (<= 31).
|
|
*/
|
|
@@ -392,6 +537,8 @@
|
|
ssize_t
|
|
uper_put_length(asn_per_outp_t *po, size_t length) {
|
|
|
|
+ ASN_DEBUG("UPER put length %d", length);
|
|
+
|
|
if(length <= 127) /* #10.9.3.6 */
|
|
return per_put_few_bits(po, length, 8)
|
|
? -1 : (ssize_t)length;
|
|
@@ -406,7 +553,34 @@
|
|
? -1 : (ssize_t)(length << 14);
|
|
}
|
|
|
|
+ssize_t
|
|
+aper_put_length(asn_per_outp_t *po, int range, size_t length) {
|
|
|
|
+ ASN_DEBUG("APER put length %d with range %d", length, range);
|
|
+
|
|
+ /* 10.9 X.691 Note 2 */
|
|
+ if (range <= 65536 && range >= 0)
|
|
+ return aper_put_nsnnwn(po, range, length);
|
|
+
|
|
+ if (aper_put_align(po) < 0)
|
|
+ return -1;
|
|
+
|
|
+ if(length <= 127) /* #10.9.3.6 */{
|
|
+ return per_put_few_bits(po, length, 8)
|
|
+ ? -1 : (ssize_t)length;
|
|
+ }
|
|
+ else if(length < 16384) /* #10.9.3.7 */
|
|
+ return per_put_few_bits(po, length|0x8000, 16)
|
|
+ ? -1 : (ssize_t)length;
|
|
+
|
|
+ length >>= 14;
|
|
+ if(length > 4) length = 4;
|
|
+
|
|
+ return per_put_few_bits(po, 0xC0 | length, 8)
|
|
+ ? -1 : (ssize_t)(length << 14);
|
|
+}
|
|
+
|
|
+
|
|
/*
|
|
* Put the normally small length "n" into the stream.
|
|
* This procedure used to encode length of extensions bit-maps
|
|
@@ -429,3 +603,19 @@
|
|
return 0;
|
|
}
|
|
|
|
+int
|
|
+aper_put_nslength(asn_per_outp_t *po, size_t length) {
|
|
+
|
|
+ if(length <= 64) {
|
|
+ /* #10.9.3.4 */
|
|
+ if(length == 0) return -1;
|
|
+ return per_put_few_bits(po, length-1, 7) ? -1 : 0;
|
|
+ } else {
|
|
+ if(aper_put_length(po, -1, length) != (ssize_t)length) {
|
|
+ /* This might happen in case of >16K extensions */
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
Index: skeletons/constr_SET.c
|
|
===================================================================
|
|
--- skeletons/constr_SET.c (revision 1516)
|
|
+++ skeletons/constr_SET.c (working copy)
|
|
@@ -36,7 +36,7 @@
|
|
#undef ADVANCE
|
|
#define ADVANCE(num_bytes) do { \
|
|
size_t num = num_bytes; \
|
|
- ptr = ((const void *)ptr) + num;\
|
|
+ ptr = ((const char *)ptr) + num;\
|
|
size -= num; \
|
|
if(ctx->left >= 0) \
|
|
ctx->left -= num; \
|
|
@@ -132,7 +132,7 @@
|
|
/*
|
|
* Restore parsing context.
|
|
*/
|
|
- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset);
|
|
+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
|
|
|
|
/*
|
|
* Start to parse where left previously
|
|
@@ -250,7 +250,7 @@
|
|
|
|
skip = ber_skip_length(opt_codec_ctx,
|
|
BER_TLV_CONSTRUCTED(ptr),
|
|
- (const void *)ptr + tag_len, LEFT - tag_len);
|
|
+ (const char *)ptr + tag_len, LEFT - tag_len);
|
|
|
|
switch(skip) {
|
|
case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
|
|
@@ -271,7 +271,7 @@
|
|
* Check for duplications: must not overwrite
|
|
* already decoded elements.
|
|
*/
|
|
- if(ASN_SET_ISPRESENT2((void *)st + specs->pres_offset, edx)) {
|
|
+ if(ASN_SET_ISPRESENT2((char *)st + specs->pres_offset, edx)) {
|
|
ASN_DEBUG("SET %s: Duplicate element %s (%d)",
|
|
td->name, elements[edx].name, edx);
|
|
RETURN(RC_FAIL);
|
|
@@ -284,13 +284,13 @@
|
|
*/
|
|
if(elements[edx].flags & ATF_POINTER) {
|
|
/* Member is a pointer to another structure */
|
|
- memb_ptr2 = (void **)((void *)st + elements[edx].memb_offset);
|
|
+ memb_ptr2 = (void **)((char *)st + elements[edx].memb_offset);
|
|
} else {
|
|
/*
|
|
* A pointer to a pointer
|
|
* holding the start of the structure
|
|
*/
|
|
- memb_ptr = (void *)st + elements[edx].memb_offset;
|
|
+ memb_ptr = (char *)st + elements[edx].memb_offset;
|
|
memb_ptr2 = &memb_ptr;
|
|
}
|
|
/*
|
|
@@ -302,7 +302,7 @@
|
|
elements[edx].tag_mode);
|
|
switch(rval.code) {
|
|
case RC_OK:
|
|
- ASN_SET_MKPRESENT((void *)st + specs->pres_offset, edx);
|
|
+ ASN_SET_MKPRESENT((char *)st + specs->pres_offset, edx);
|
|
break;
|
|
case RC_WMORE: /* More data expected */
|
|
if(!SIZE_VIOLATION) {
|
|
@@ -369,7 +369,7 @@
|
|
|
|
ll = ber_skip_length(opt_codec_ctx,
|
|
BER_TLV_CONSTRUCTED(ptr),
|
|
- (const void *)ptr + tl, LEFT - tl);
|
|
+ (const char *)ptr + tl, LEFT - tl);
|
|
switch(ll) {
|
|
case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
|
|
/* Fall through */
|
|
@@ -404,7 +404,7 @@
|
|
unsigned int midx, pres, must;
|
|
|
|
midx = edx/(8 * sizeof(specs->_mandatory_elements[0]));
|
|
- pres = ((unsigned int *)((void *)st+specs->pres_offset))[midx];
|
|
+ pres = ((unsigned int *)((char *)st+specs->pres_offset))[midx];
|
|
must = sys_ntohl(specs->_mandatory_elements[midx]);
|
|
|
|
if((pres & must) == must) {
|
|
@@ -473,7 +473,7 @@
|
|
* Compute the length of the encoding of this member.
|
|
*/
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr = *(void **)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
|
|
if(!memb_ptr) {
|
|
if(!elm->optional)
|
|
/* Mandatory elements missing */
|
|
@@ -486,7 +486,7 @@
|
|
continue;
|
|
}
|
|
} else {
|
|
- memb_ptr = (void *)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
|
}
|
|
tmper = elm->type->der_encoder(elm->type, memb_ptr,
|
|
elm->tag_mode, elm->tag,
|
|
@@ -547,10 +547,10 @@
|
|
elm = &td->elements[t2m[edx].el_no];
|
|
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr = *(void **)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
|
|
if(!memb_ptr) continue;
|
|
} else {
|
|
- memb_ptr = (void *)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
|
}
|
|
tmper = elm->type->der_encoder(elm->type, memb_ptr,
|
|
elm->tag_mode, elm->tag,
|
|
@@ -570,10 +570,185 @@
|
|
_ASN_ENCODED_OK(er);
|
|
}
|
|
|
|
+asn_enc_rval_t
|
|
+SET_encode_uper(asn_TYPE_descriptor_t *td,
|
|
+ asn_per_constraints_t *constraints,
|
|
+ void *sptr,
|
|
+ asn_per_outp_t *po) {
|
|
+}
|
|
+
|
|
+asn_dec_rval_t
|
|
+SET_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_enc_rval_t
|
|
+SET_encode_aper(asn_TYPE_descriptor_t *td,
|
|
+ asn_per_constraints_t *constraints,
|
|
+ void *sptr,
|
|
+ asn_per_outp_t *po) {
|
|
+ asn_SET_specifics_t *specs = (asn_SET_specifics_t *)td->specifics;
|
|
+ asn_enc_rval_t er;
|
|
+ int edx, i;
|
|
+ int t2m_build_own = (specs->tag2el_count != td->elements_count);
|
|
+ asn_TYPE_tag2member_t *t2m;
|
|
+ int t2m_count;
|
|
+
|
|
+ (void)constraints;
|
|
+
|
|
+ if(!sptr)
|
|
+ _ASN_ENCODE_FAILED;
|
|
+
|
|
+ er.encoded = 0;
|
|
+
|
|
+ ASN_DEBUG("Encoding %s as SET (APER) map %d", td->name, specs->_mandatory_elements[0]);
|
|
+
|
|
+ /*
|
|
+ * Use existing, or build our own tags map.
|
|
+ */
|
|
+ if(t2m_build_own) {
|
|
+ t2m = (asn_TYPE_tag2member_t *)alloca(
|
|
+ td->elements_count * sizeof(t2m[0]));
|
|
+ if(!t2m) _ASN_ENCODE_FAILED; /* There are such platforms */
|
|
+ t2m_count = 0;
|
|
+ } else {
|
|
+ /*
|
|
+ * There is no untagged CHOICE in this SET.
|
|
+ * Employ existing table.
|
|
+ */
|
|
+ t2m = specs->tag2el;
|
|
+ t2m_count = specs->tag2el_count;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Gather the length of the underlying members sequence.
|
|
+ */
|
|
+ for(edx = 0; edx < td->elements_count; edx++) {
|
|
+ asn_TYPE_member_t *elm = &td->elements[edx];
|
|
+ asn_enc_rval_t tmper;
|
|
+ void *memb_ptr;
|
|
+
|
|
+ /*
|
|
+ * Compute the length of the encoding of this member.
|
|
+ */
|
|
+ if(elm->flags & ATF_POINTER) {
|
|
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
|
|
+ if(!memb_ptr) {
|
|
+ if(!elm->optional)
|
|
+ /* Mandatory elements missing */
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ if(t2m_build_own) {
|
|
+ t2m[t2m_count].el_no = edx;
|
|
+ t2m[t2m_count].el_tag = 0;
|
|
+ t2m_count++;
|
|
+ }
|
|
+ continue;
|
|
+ }
|
|
+ } else {
|
|
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Remember the outmost tag of this member.
|
|
+ */
|
|
+ if(t2m_build_own) {
|
|
+ t2m[t2m_count].el_no = edx;
|
|
+ t2m[t2m_count].el_tag = asn_TYPE_outmost_tag(
|
|
+ elm->type, memb_ptr, elm->tag_mode, elm->tag);
|
|
+ t2m_count++;
|
|
+ } else {
|
|
+ /*
|
|
+ * No dynamic sorting is necessary.
|
|
+ */
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Finalize order of the components.
|
|
+ */
|
|
+ assert(t2m_count == td->elements_count);
|
|
+ if(t2m_build_own) {
|
|
+ /*
|
|
+ * Sort the underlying members according to their
|
|
+ * canonical tags order. DER encoding mandates it.
|
|
+ */
|
|
+ qsort(t2m, t2m_count, sizeof(specs->tag2el[0]), _t2e_cmp);
|
|
+ } else {
|
|
+ /*
|
|
+ * Tags are already sorted by the compiler.
|
|
+ */
|
|
+ }
|
|
+
|
|
+ for(edx = 0; edx < td->elements_count; edx++) {
|
|
+ asn_TYPE_member_t *elm = &td->elements[t2m[edx].el_no];
|
|
+ asn_enc_rval_t tmper;
|
|
+ void *memb_ptr; /* Pointer to the member */
|
|
+ void **memb_ptr2; /* Pointer to that pointer */
|
|
+ int present;
|
|
+
|
|
+ /* Fetch the pointer to this member */
|
|
+ if(elm->flags & ATF_POINTER) {
|
|
+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
|
|
+ present = (*memb_ptr2 != 0);
|
|
+ } else {
|
|
+// memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
|
+// memb_ptr2 = &memb_ptr;
|
|
+ present = 1;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+// /* Eliminate default values */
|
|
+// if(present && elm->default_value
|
|
+// && elm->default_value(0, memb_ptr2) == 1)
|
|
+// present = 0;
|
|
+
|
|
+ ASN_DEBUG("Element %s %s %s->%s is %s",
|
|
+ elm->flags & ATF_POINTER ? "ptr" : "inline",
|
|
+ elm->default_value ? "def" : "wtv",
|
|
+ td->name, elm->name, present ? "present" : "absent");
|
|
+ if(per_put_few_bits(po, present << 7, 8))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Encode all members.
|
|
+ */
|
|
+ for(edx = 0; edx < td->elements_count; edx++) {
|
|
+ asn_TYPE_member_t *elm = &td->elements[edx];
|
|
+ asn_enc_rval_t tmper;
|
|
+ void *memb_ptr; /* Pointer to the member */
|
|
+ void **memb_ptr2; /* Pointer to that pointer */
|
|
+
|
|
+ /* Encode according to the tag order */
|
|
+// elm = &td->elements[t2m[edx].el_no];
|
|
+
|
|
+ if(elm->flags & ATF_POINTER) {
|
|
+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
|
|
+ if(!*memb_ptr2) {
|
|
+ ASN_DEBUG("Element %s %d not present",
|
|
+ elm->name, edx);
|
|
+ if(elm->optional)
|
|
+ continue;
|
|
+ /* Mandatory element is missing */
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+ } else {
|
|
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
|
+ memb_ptr2 = &memb_ptr;
|
|
+ }
|
|
+ tmper = elm->type->aper_encoder(elm->type, elm->per_constraints,
|
|
+ *memb_ptr2, po);
|
|
+ if(tmper.encoded == -1)
|
|
+ return tmper;
|
|
+ }
|
|
+
|
|
+ _ASN_ENCODED_OK(er);
|
|
+}
|
|
+
|
|
#undef XER_ADVANCE
|
|
#define XER_ADVANCE(num_bytes) do { \
|
|
size_t num = num_bytes; \
|
|
- buf_ptr = ((const void *)buf_ptr) + num;\
|
|
+ buf_ptr = ((const char *)buf_ptr) + num;\
|
|
size -= num; \
|
|
consumed_myself += num; \
|
|
} while(0)
|
|
@@ -613,7 +788,7 @@
|
|
/*
|
|
* Restore parsing context.
|
|
*/
|
|
- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset);
|
|
+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
|
|
|
|
/*
|
|
* Phases of XER/XML processing:
|
|
@@ -637,7 +812,7 @@
|
|
void *memb_ptr; /* Pointer to the member */
|
|
void **memb_ptr2; /* Pointer to that pointer */
|
|
|
|
- if(ASN_SET_ISPRESENT2((void *)st + specs->pres_offset,
|
|
+ if(ASN_SET_ISPRESENT2((char *)st + specs->pres_offset,
|
|
edx)) {
|
|
ASN_DEBUG("SET %s: Duplicate element %s (%d)",
|
|
td->name, elements[edx].name, edx);
|
|
@@ -648,10 +823,10 @@
|
|
|
|
if(elm->flags & ATF_POINTER) {
|
|
/* Member is a pointer to another structure */
|
|
- memb_ptr2 = (void **)((void *)st
|
|
+ memb_ptr2 = (void **)((char *)st
|
|
+ elm->memb_offset);
|
|
} else {
|
|
- memb_ptr = (void *)st + elm->memb_offset;
|
|
+ memb_ptr = (char *)st + elm->memb_offset;
|
|
memb_ptr2 = &memb_ptr;
|
|
}
|
|
|
|
@@ -663,7 +838,7 @@
|
|
if(tmprval.code != RC_OK)
|
|
RETURN(tmprval.code);
|
|
ctx->phase = 1; /* Back to body processing */
|
|
- ASN_SET_MKPRESENT((void *)st + specs->pres_offset, edx);
|
|
+ ASN_SET_MKPRESENT((char *)st + specs->pres_offset, edx);
|
|
ASN_DEBUG("XER/SET phase => %d", ctx->phase);
|
|
/* Fall through */
|
|
}
|
|
@@ -827,7 +1002,7 @@
|
|
mlen = strlen(elm->name);
|
|
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr = *(void **)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
|
|
if(!memb_ptr) {
|
|
if(elm->optional)
|
|
continue;
|
|
@@ -835,7 +1010,7 @@
|
|
_ASN_ENCODE_FAILED;
|
|
}
|
|
} else {
|
|
- memb_ptr = (void *)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
|
}
|
|
|
|
if(!xcan)
|
|
@@ -877,14 +1052,14 @@
|
|
const void *memb_ptr;
|
|
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr = *(const void * const *)((const void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
|
|
if(!memb_ptr) {
|
|
if(elm->optional) continue;
|
|
/* Print <absent> line */
|
|
/* Fall through */
|
|
}
|
|
} else {
|
|
- memb_ptr = (const void *)((const void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
|
|
}
|
|
|
|
_i_INDENT(1);
|
|
@@ -919,11 +1094,11 @@
|
|
asn_TYPE_member_t *elm = &td->elements[edx];
|
|
void *memb_ptr;
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr = *(void **)((void *)ptr + elm->memb_offset);
|
|
+ memb_ptr = *(void **)((char *)ptr + elm->memb_offset);
|
|
if(memb_ptr)
|
|
ASN_STRUCT_FREE(*elm->type, memb_ptr);
|
|
} else {
|
|
- memb_ptr = (void *)((void *)ptr + elm->memb_offset);
|
|
+ memb_ptr = (void *)((char *)ptr + elm->memb_offset);
|
|
ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr);
|
|
}
|
|
}
|
|
@@ -953,7 +1128,7 @@
|
|
const void *memb_ptr;
|
|
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr = *(const void * const *)((const void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
|
|
if(!memb_ptr) {
|
|
if(elm->optional)
|
|
continue;
|
|
@@ -963,7 +1138,7 @@
|
|
return -1;
|
|
}
|
|
} else {
|
|
- memb_ptr = (const void *)((const void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
|
|
}
|
|
|
|
if(elm->memb_constraints) {
|
|
Index: skeletons/constr_SEQUENCE_OF.c
|
|
===================================================================
|
|
--- skeletons/constr_SEQUENCE_OF.c (revision 1516)
|
|
+++ skeletons/constr_SEQUENCE_OF.c (working copy)
|
|
@@ -164,7 +164,7 @@
|
|
if(ct) {
|
|
int not_in_root = (list->count < ct->lower_bound
|
|
|| list->count > ct->upper_bound);
|
|
- ASN_DEBUG("lb %ld ub %ld %s",
|
|
+ ASN_DEBUG("lb %"PRIdMAX" ub %"PRIdMAX" %s",
|
|
ct->lower_bound, ct->upper_bound,
|
|
ct->flags & APC_EXTENSIBLE ? "ext" : "fix");
|
|
if(ct->flags & APC_EXTENSIBLE) {
|
|
@@ -206,3 +206,70 @@
|
|
_ASN_ENCODED_OK(er);
|
|
}
|
|
|
|
+asn_enc_rval_t
|
|
+SEQUENCE_OF_encode_aper(asn_TYPE_descriptor_t *td,
|
|
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
|
+ asn_anonymous_sequence_ *list;
|
|
+ asn_per_constraint_t *ct;
|
|
+ asn_enc_rval_t er;
|
|
+ asn_TYPE_member_t *elm = td->elements;
|
|
+ int seq;
|
|
+
|
|
+ if(!sptr) _ASN_ENCODE_FAILED;
|
|
+ list = _A_SEQUENCE_FROM_VOID(sptr);
|
|
+
|
|
+ er.encoded = 0;
|
|
+
|
|
+ ASN_DEBUG("Encoding %s as SEQUENCE OF size (%d) using ALIGNED PER", td->name, list->count);
|
|
+
|
|
+ if(constraints) ct = &constraints->size;
|
|
+ else if(td->per_constraints) ct = &td->per_constraints->size;
|
|
+ else ct = 0;
|
|
+
|
|
+ /* If extensible constraint, check if size is in root */
|
|
+ if(ct) {
|
|
+ int not_in_root = (list->count < ct->lower_bound
|
|
+ || list->count > ct->upper_bound);
|
|
+ ASN_DEBUG("lb %"PRIdMAX" ub %"PRIdMAX" %s",
|
|
+ ct->lower_bound, ct->upper_bound,
|
|
+ ct->flags & APC_EXTENSIBLE ? "ext" : "fix");
|
|
+ if(ct->flags & APC_EXTENSIBLE) {
|
|
+ /* Declare whether size is in extension root */
|
|
+ if(per_put_few_bits(po, not_in_root, 1))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ if(not_in_root) ct = 0;
|
|
+ } else if(not_in_root && ct->effective_bits >= 0)
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+
|
|
+ if(ct && ct->effective_bits >= 0) {
|
|
+ /* X.691, #19.5: No length determinant */
|
|
+// if(per_put_few_bits(po, list->count - ct->lower_bound,
|
|
+// ct->effective_bits))
|
|
+// _ASN_ENCODE_FAILED;
|
|
+ if (aper_put_length(po, ct->upper_bound - ct->lower_bound + 1, list->count - ct->lower_bound) < 0)
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+
|
|
+ for(seq = -1; seq < list->count;) {
|
|
+ ssize_t mayEncode;
|
|
+ if(seq < 0) seq = 0;
|
|
+ if(ct && ct->effective_bits >= 0) {
|
|
+ mayEncode = list->count;
|
|
+ } else {
|
|
+ mayEncode = aper_put_length(po, -1, list->count - seq);
|
|
+ if(mayEncode < 0) _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+
|
|
+ while(mayEncode--) {
|
|
+ void *memb_ptr = list->array[seq++];
|
|
+ if(!memb_ptr) _ASN_ENCODE_FAILED;
|
|
+ er = elm->type->aper_encoder(elm->type,
|
|
+ elm->per_constraints, memb_ptr, po);
|
|
+ if(er.encoded == -1)
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ _ASN_ENCODED_OK(er);
|
|
+}
|
|
Index: skeletons/per_support.h
|
|
===================================================================
|
|
--- skeletons/per_support.h (revision 1516)
|
|
+++ skeletons/per_support.h (working copy)
|
|
@@ -24,8 +24,8 @@
|
|
} 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 */
|
|
+ int64_t lower_bound; /* "lb" value */
|
|
+ int64_t upper_bound; /* "ub" value */
|
|
} asn_per_constraint_t;
|
|
typedef struct asn_per_constraints_s {
|
|
asn_per_constraint_t value;
|
|
@@ -39,9 +39,9 @@
|
|
*/
|
|
typedef struct asn_per_data_s {
|
|
const 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 */
|
|
- size_t moved; /* Number of bits moved through this bit stream */
|
|
+ size_t nboff; /* Bit offset to the meaningful bit */
|
|
+ size_t nbits; /* Number of bits in the stream */
|
|
+ size_t moved; /* Number of bits moved through this bit stream */
|
|
int (*refill)(struct asn_per_data_s *);
|
|
void *refill_key;
|
|
} asn_per_data_t;
|
|
@@ -71,15 +71,22 @@
|
|
int effective_bound_bits,
|
|
int *repeat);
|
|
|
|
+ssize_t aper_get_length(asn_per_data_t *pd,
|
|
+ int range,
|
|
+ int effective_bound_bits,
|
|
+ int *repeat);
|
|
+
|
|
/*
|
|
* Get the normally small length "n".
|
|
*/
|
|
ssize_t uper_get_nslength(asn_per_data_t *pd);
|
|
+ssize_t aper_get_nslength(asn_per_data_t *pd);
|
|
|
|
/*
|
|
* Get the normally small non-negative whole number.
|
|
*/
|
|
ssize_t uper_get_nsnnwn(asn_per_data_t *pd);
|
|
+ssize_t aper_get_nsnnwn(asn_per_data_t *pd, int range);
|
|
|
|
/* Non-thread-safe debugging function, don't use it */
|
|
char *per_data_string(asn_per_data_t *pd);
|
|
@@ -103,6 +110,10 @@
|
|
/* Output a large number of bits */
|
|
int per_put_many_bits(asn_per_outp_t *po, const uint8_t *src, int put_nbits);
|
|
|
|
+/* Align the current bit position to octet bundary */
|
|
+int aper_put_align(asn_per_outp_t *po);
|
|
+int32_t aper_get_align(asn_per_data_t *pd);
|
|
+
|
|
/*
|
|
* Put the length "n" to the Unaligned PER stream.
|
|
* This function returns the number of units which may be flushed
|
|
@@ -110,17 +121,23 @@
|
|
*/
|
|
ssize_t uper_put_length(asn_per_outp_t *po, size_t whole_length);
|
|
|
|
+ssize_t aper_put_length(asn_per_outp_t *po, int range, size_t length);
|
|
+
|
|
/*
|
|
* Put the normally small length "n" to the Unaligned PER stream.
|
|
* Returns 0 or -1.
|
|
*/
|
|
int uper_put_nslength(asn_per_outp_t *po, size_t length);
|
|
|
|
+int aper_put_nslength(asn_per_outp_t *po, size_t length);
|
|
+
|
|
/*
|
|
* Put the normally small non-negative whole number.
|
|
*/
|
|
int uper_put_nsnnwn(asn_per_outp_t *po, int n);
|
|
|
|
+int aper_put_nsnnwn(asn_per_outp_t *po, int range, int number);
|
|
+
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
Index: skeletons/constr_SET.h
|
|
===================================================================
|
|
--- skeletons/constr_SET.h (revision 1516)
|
|
+++ skeletons/constr_SET.h (working copy)
|
|
@@ -53,7 +53,9 @@
|
|
xer_type_decoder_f SET_decode_xer;
|
|
xer_type_encoder_f SET_encode_xer;
|
|
per_type_decoder_f SET_decode_uper;
|
|
+per_type_decoder_f SET_decode_aper;
|
|
per_type_encoder_f SET_encode_uper;
|
|
+per_type_encoder_f SET_encode_aper;
|
|
|
|
/***********************
|
|
* Some handy helpers. *
|
|
Index: skeletons/constr_SEQUENCE_OF.h
|
|
===================================================================
|
|
--- skeletons/constr_SEQUENCE_OF.h (revision 1516)
|
|
+++ skeletons/constr_SEQUENCE_OF.h (working copy)
|
|
@@ -22,9 +22,11 @@
|
|
#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
|
|
+#define SEQUENCE_OF_decode_aper SET_OF_decode_aper
|
|
der_type_encoder_f SEQUENCE_OF_encode_der;
|
|
xer_type_encoder_f SEQUENCE_OF_encode_xer;
|
|
per_type_encoder_f SEQUENCE_OF_encode_uper;
|
|
+per_type_encoder_f SEQUENCE_OF_encode_aper;
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
Index: skeletons/ENUMERATED.c
|
|
===================================================================
|
|
--- skeletons/ENUMERATED.c (revision 1516)
|
|
+++ skeletons/ENUMERATED.c (working copy)
|
|
@@ -26,6 +26,8 @@
|
|
INTEGER_encode_xer,
|
|
ENUMERATED_decode_uper, /* Unaligned PER decoder */
|
|
ENUMERATED_encode_uper, /* Unaligned PER encoder */
|
|
+ ENUMERATED_decode_aper, /* Aligned PER decoder */
|
|
+ ENUMERATED_encode_aper, /* Aligned PER encoder */
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_ENUMERATED_tags,
|
|
sizeof(asn_DEF_ENUMERATED_tags) / sizeof(asn_DEF_ENUMERATED_tags[0]),
|
|
@@ -57,6 +59,27 @@
|
|
return rval;
|
|
}
|
|
|
|
+asn_dec_rval_t
|
|
+ENUMERATED_decode_aper(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;
|
|
+ void *vptr = &value;
|
|
+
|
|
+ if(!st) {
|
|
+ st = (ENUMERATED_t *)(*sptr = CALLOC(1, sizeof(*st)));
|
|
+ if(!st) _ASN_DECODE_FAILED;
|
|
+ }
|
|
+
|
|
+ rval = NativeEnumerated_decode_aper(opt_codec_ctx, td, constraints,
|
|
+ (void **)&vptr, pd);
|
|
+ if(rval.code == RC_OK)
|
|
+ if(asn_long2INTEGER(st, value))
|
|
+ rval.code = RC_FAIL;
|
|
+ return rval;
|
|
+}
|
|
+
|
|
asn_enc_rval_t
|
|
ENUMERATED_encode_uper(asn_TYPE_descriptor_t *td,
|
|
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
|
@@ -69,3 +92,14 @@
|
|
return NativeEnumerated_encode_uper(td, constraints, &value, po);
|
|
}
|
|
|
|
+asn_enc_rval_t
|
|
+ENUMERATED_encode_aper(asn_TYPE_descriptor_t *td,
|
|
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
|
+ ENUMERATED_t *st = (ENUMERATED_t *)sptr;
|
|
+ long value;
|
|
+
|
|
+ if(asn_INTEGER2long(st, &value))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+
|
|
+ return NativeEnumerated_encode_aper(td, constraints, &value, po);
|
|
+}
|
|
Index: skeletons/ENUMERATED.h
|
|
===================================================================
|
|
--- skeletons/ENUMERATED.h (revision 1516)
|
|
+++ skeletons/ENUMERATED.h (working copy)
|
|
@@ -17,6 +17,8 @@
|
|
|
|
per_type_decoder_f ENUMERATED_decode_uper;
|
|
per_type_encoder_f ENUMERATED_encode_uper;
|
|
+per_type_decoder_f ENUMERATED_decode_aper;
|
|
+per_type_encoder_f ENUMERATED_encode_aper;
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
Index: skeletons/NativeEnumerated.c
|
|
===================================================================
|
|
--- skeletons/NativeEnumerated.c (revision 1516)
|
|
+++ skeletons/NativeEnumerated.c (working copy)
|
|
@@ -30,6 +30,8 @@
|
|
NativeEnumerated_encode_xer,
|
|
NativeEnumerated_decode_uper,
|
|
NativeEnumerated_encode_uper,
|
|
+ NativeEnumerated_decode_aper,
|
|
+ NativeEnumerated_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_NativeEnumerated_tags,
|
|
sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
|
|
@@ -42,17 +44,17 @@
|
|
|
|
asn_enc_rval_t
|
|
NativeEnumerated_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
|
- int ilevel, enum xer_encoder_flags_e flags,
|
|
- asn_app_consume_bytes_f *cb, void *app_key) {
|
|
+ int ilevel, enum xer_encoder_flags_e flags,
|
|
+ asn_app_consume_bytes_f *cb, void *app_key) {
|
|
asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
|
|
- asn_enc_rval_t er;
|
|
- const long *native = (const long *)sptr;
|
|
+ asn_enc_rval_t er;
|
|
+ const long *native = (const long *)sptr;
|
|
const asn_INTEGER_enum_map_t *el;
|
|
|
|
- (void)ilevel;
|
|
- (void)flags;
|
|
+ (void)ilevel;
|
|
+ (void)flags;
|
|
|
|
- if(!native) _ASN_ENCODE_FAILED;
|
|
+ if(!native) _ASN_ENCODE_FAILED;
|
|
|
|
el = INTEGER_map_value2enum(specs, *native);
|
|
if(el) {
|
|
@@ -125,6 +127,66 @@
|
|
return rval;
|
|
}
|
|
|
|
+asn_dec_rval_t
|
|
+NativeEnumerated_decode_aper(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;
|
|
+ int freeme = 0;
|
|
+
|
|
+ (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)));
|
|
+ freeme = 1;
|
|
+ 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_STARVED;
|
|
+ if(inext) ct = 0;
|
|
+ }
|
|
+
|
|
+ if(ct && ct->range_bits >= 0) {
|
|
+ value = per_get_few_bits(pd, ct->range_bits);
|
|
+ if(value < 0) _ASN_DECODE_STARVED;
|
|
+ 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_STARVED;
|
|
+ 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);
|
|
+
|
|
+ if (freeme)
|
|
+ free(native);
|
|
+
|
|
+ return rval;
|
|
+}
|
|
+
|
|
static int
|
|
NativeEnumerated__compar_value2enum(const void *ap, const void *bp) {
|
|
const asn_INTEGER_enum_map_t *a = ap;
|
|
@@ -205,3 +267,71 @@
|
|
_ASN_ENCODED_OK(er);
|
|
}
|
|
|
|
+asn_enc_rval_t
|
|
+NativeEnumerated_encode_aper(asn_TYPE_descriptor_t *td,
|
|
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
|
+ asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics;
|
|
+ asn_enc_rval_t er;
|
|
+ long native, value;
|
|
+ asn_per_constraint_t *ct;
|
|
+ int inext = 0;
|
|
+ asn_INTEGER_enum_map_t key;
|
|
+ asn_INTEGER_enum_map_t *kf;
|
|
+
|
|
+ if(!sptr) _ASN_ENCODE_FAILED;
|
|
+ if(!specs) _ASN_ENCODE_FAILED;
|
|
+
|
|
+ if(constraints) ct = &constraints->value;
|
|
+ else if(td->per_constraints) ct = &td->per_constraints->value;
|
|
+ else _ASN_ENCODE_FAILED; /* Mandatory! */
|
|
+
|
|
+ ASN_DEBUG("Encoding %s as NativeEnumerated", td->name);
|
|
+
|
|
+ er.encoded = 0;
|
|
+
|
|
+ native = *(long *)sptr;
|
|
+ if(native < 0) _ASN_ENCODE_FAILED;
|
|
+
|
|
+ key.nat_value = native;
|
|
+ kf = bsearch(&key, specs->value2enum, specs->map_count,
|
|
+ sizeof(key), NativeEnumerated__compar_value2enum);
|
|
+ if(!kf) {
|
|
+ ASN_DEBUG("No element corresponds to %ld", native);
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+ value = kf - specs->value2enum;
|
|
+
|
|
+ if(ct->range_bits >= 0) {
|
|
+ int cmpWith = specs->extension
|
|
+ ? specs->extension - 1 : specs->map_count;
|
|
+ if(value >= cmpWith)
|
|
+ inext = 1;
|
|
+ }
|
|
+ if(ct->flags & APC_EXTENSIBLE) {
|
|
+ if(per_put_few_bits(po, inext, 1))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ if(inext) ct = 0;
|
|
+ } else if(inext) {
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+
|
|
+ if(ct && ct->range_bits >= 0) {
|
|
+ if(per_put_few_bits(po, value, ct->range_bits))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ _ASN_ENCODED_OK(er);
|
|
+ }
|
|
+
|
|
+ if(!specs->extension)
|
|
+ _ASN_ENCODE_FAILED;
|
|
+
|
|
+ /*
|
|
+ * X.691, #10.6: normally small non-negative whole number;
|
|
+ */
|
|
+ ASN_DEBUG("value = %ld, ext = %d, inext = %d, res = %ld",
|
|
+ value, specs->extension, inext,
|
|
+ value - (inext ? (specs->extension - 1) : 0));
|
|
+ if(uper_put_nsnnwn(po, value - (inext ? (specs->extension - 1) : 0)))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+
|
|
+ _ASN_ENCODED_OK(er);
|
|
+}
|
|
Index: skeletons/GeneralString.c
|
|
===================================================================
|
|
--- skeletons/GeneralString.c (revision 1516)
|
|
+++ skeletons/GeneralString.c (working copy)
|
|
@@ -24,6 +24,8 @@
|
|
OCTET_STRING_encode_xer,
|
|
OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */
|
|
OCTET_STRING_encode_uper,
|
|
+ OCTET_STRING_decode_aper,
|
|
+ OCTET_STRING_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_GeneralString_tags,
|
|
sizeof(asn_DEF_GeneralString_tags)
|
|
Index: skeletons/IA5String.c
|
|
===================================================================
|
|
--- skeletons/IA5String.c (revision 1516)
|
|
+++ skeletons/IA5String.c (working copy)
|
|
@@ -29,6 +29,8 @@
|
|
OCTET_STRING_encode_xer_utf8,
|
|
OCTET_STRING_decode_uper,
|
|
OCTET_STRING_encode_uper,
|
|
+ OCTET_STRING_decode_aper,
|
|
+ OCTET_STRING_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_IA5String_tags,
|
|
sizeof(asn_DEF_IA5String_tags)
|
|
Index: skeletons/NativeEnumerated.h
|
|
===================================================================
|
|
--- skeletons/NativeEnumerated.h (revision 1516)
|
|
+++ skeletons/NativeEnumerated.h (working copy)
|
|
@@ -24,6 +24,8 @@
|
|
xer_type_encoder_f NativeEnumerated_encode_xer;
|
|
per_type_decoder_f NativeEnumerated_decode_uper;
|
|
per_type_encoder_f NativeEnumerated_encode_uper;
|
|
+per_type_decoder_f NativeEnumerated_decode_aper;
|
|
+per_type_encoder_f NativeEnumerated_encode_aper;
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
Index: skeletons/OBJECT_IDENTIFIER.c
|
|
===================================================================
|
|
--- skeletons/OBJECT_IDENTIFIER.c (revision 1516)
|
|
+++ skeletons/OBJECT_IDENTIFIER.c (working copy)
|
|
@@ -27,6 +27,8 @@
|
|
OBJECT_IDENTIFIER_encode_xer,
|
|
OCTET_STRING_decode_uper,
|
|
OCTET_STRING_encode_uper,
|
|
+ OCTET_STRING_decode_aper,
|
|
+ OCTET_STRING_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_OBJECT_IDENTIFIER_tags,
|
|
sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
|
|
Index: skeletons/per_opentype.c
|
|
===================================================================
|
|
--- skeletons/per_opentype.c (revision 1516)
|
|
+++ skeletons/per_opentype.c (working copy)
|
|
@@ -53,6 +53,35 @@
|
|
return 0;
|
|
}
|
|
|
|
+int
|
|
+aper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
|
+ void *buf;
|
|
+ void *bptr;
|
|
+ ssize_t size;
|
|
+ size_t toGo;
|
|
+
|
|
+ ASN_DEBUG("Open type put %s ...", td->name);
|
|
+
|
|
+ size = aper_encode_to_new_buffer(td, constraints, sptr, &buf);
|
|
+ if(size <= 0) return -1;
|
|
+
|
|
+ for(bptr = buf, toGo = size; toGo;) {
|
|
+ ssize_t maySave = aper_put_length(po, -1, toGo);
|
|
+ if(maySave < 0) break;
|
|
+ if(per_put_many_bits(po, bptr, maySave * 8)) break;
|
|
+ bptr = (char *)bptr + maySave;
|
|
+ toGo -= maySave;
|
|
+ }
|
|
+
|
|
+ FREEMEM(buf);
|
|
+ if(toGo) return -1;
|
|
+
|
|
+ ASN_DEBUG("Open type put %s of length %ld + overhead (1byte?)",
|
|
+ td->name, (long)size);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static asn_dec_rval_t
|
|
uper_open_type_get_simple(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
|
|
asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
|
|
Index: skeletons/VideotexString.c
|
|
===================================================================
|
|
--- skeletons/VideotexString.c (revision 1516)
|
|
+++ skeletons/VideotexString.c (working copy)
|
|
@@ -24,6 +24,8 @@
|
|
OCTET_STRING_encode_xer,
|
|
OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */
|
|
OCTET_STRING_encode_uper,
|
|
+ OCTET_STRING_decode_aper,
|
|
+ OCTET_STRING_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_VideotexString_tags,
|
|
sizeof(asn_DEF_VideotexString_tags)
|
|
Index: skeletons/per_opentype.h
|
|
===================================================================
|
|
--- skeletons/per_opentype.h (revision 1516)
|
|
+++ skeletons/per_opentype.h (working copy)
|
|
@@ -15,6 +15,8 @@
|
|
|
|
int uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po);
|
|
|
|
+int aper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po);
|
|
+
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
Index: skeletons/BOOLEAN.c
|
|
===================================================================
|
|
--- skeletons/BOOLEAN.c (revision 1516)
|
|
+++ skeletons/BOOLEAN.c (working copy)
|
|
@@ -24,6 +24,8 @@
|
|
BOOLEAN_encode_xer,
|
|
BOOLEAN_decode_uper, /* Unaligned PER decoder */
|
|
BOOLEAN_encode_uper, /* Unaligned PER encoder */
|
|
+ BOOLEAN_decode_aper, /* Aligned PER decoder */
|
|
+ BOOLEAN_encode_aper, /* Aligned PER encoder */
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_BOOLEAN_tags,
|
|
sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]),
|
|
@@ -264,7 +266,36 @@
|
|
return rv;
|
|
}
|
|
|
|
+asn_dec_rval_t
|
|
+BOOLEAN_decode_aper(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_STARVED;
|
|
+ }
|
|
+
|
|
+ ASN_DEBUG("%s decoded as %s", td->name, *st ? "TRUE" : "FALSE");
|
|
+
|
|
+ rv.code = RC_OK;
|
|
+ rv.consumed = 1;
|
|
+ return rv;
|
|
+}
|
|
+
|
|
asn_enc_rval_t
|
|
BOOLEAN_encode_uper(asn_TYPE_descriptor_t *td,
|
|
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
|
@@ -280,3 +311,18 @@
|
|
|
|
_ASN_ENCODED_OK(er);
|
|
}
|
|
+
|
|
+asn_enc_rval_t
|
|
+BOOLEAN_encode_aper(asn_TYPE_descriptor_t *td,
|
|
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
|
+ const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
|
|
+ asn_enc_rval_t er;
|
|
+
|
|
+ (void)constraints;
|
|
+
|
|
+ if(!st) _ASN_ENCODE_FAILED;
|
|
+
|
|
+ per_put_few_bits(po, *st ? 1 : 0, 1);
|
|
+
|
|
+ _ASN_ENCODED_OK(er);
|
|
+}
|
|
Index: skeletons/ISO646String.c
|
|
===================================================================
|
|
--- skeletons/ISO646String.c (revision 1516)
|
|
+++ skeletons/ISO646String.c (working copy)
|
|
@@ -29,6 +29,8 @@
|
|
OCTET_STRING_encode_xer_utf8,
|
|
OCTET_STRING_decode_uper,
|
|
OCTET_STRING_encode_uper,
|
|
+ OCTET_STRING_decode_aper,
|
|
+ OCTET_STRING_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_ISO646String_tags,
|
|
sizeof(asn_DEF_ISO646String_tags)
|
|
Index: skeletons/constr_CHOICE.c
|
|
===================================================================
|
|
--- skeletons/constr_CHOICE.c (revision 1516)
|
|
+++ skeletons/constr_CHOICE.c (working copy)
|
|
@@ -34,7 +34,7 @@
|
|
#undef ADVANCE
|
|
#define ADVANCE(num_bytes) do { \
|
|
size_t num = num_bytes; \
|
|
- ptr = ((const void *)ptr) + num;\
|
|
+ ptr = ((const char *)ptr) + num;\
|
|
size -= num; \
|
|
if(ctx->left >= 0) \
|
|
ctx->left -= num; \
|
|
@@ -133,7 +133,7 @@
|
|
/*
|
|
* Restore parsing context.
|
|
*/
|
|
- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset);
|
|
+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
|
|
|
|
/*
|
|
* Start to parse where left previously
|
|
@@ -211,7 +211,7 @@
|
|
|
|
skip = ber_skip_length(opt_codec_ctx,
|
|
BER_TLV_CONSTRUCTED(ptr),
|
|
- (const void *)ptr + tag_len,
|
|
+ (const char *)ptr + tag_len,
|
|
LEFT - tag_len);
|
|
|
|
switch(skip) {
|
|
@@ -244,7 +244,7 @@
|
|
*/
|
|
if(elm->flags & ATF_POINTER) {
|
|
/* Member is a pointer to another structure */
|
|
- memb_ptr2 = (void **)((void *)st + elm->memb_offset);
|
|
+ memb_ptr2 = (void **)((char *)st + elm->memb_offset);
|
|
} else {
|
|
/*
|
|
* A pointer to a pointer
|
|
@@ -390,7 +390,7 @@
|
|
*/
|
|
elm = &td->elements[present-1];
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr = *(void **)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
|
|
if(memb_ptr == 0) {
|
|
if(elm->optional) {
|
|
erval.encoded = 0;
|
|
@@ -400,7 +400,7 @@
|
|
_ASN_ENCODE_FAILED;
|
|
}
|
|
} else {
|
|
- memb_ptr = (void *)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
|
}
|
|
|
|
/*
|
|
@@ -463,10 +463,10 @@
|
|
|
|
if(elm->flags & ATF_POINTER) {
|
|
memb_ptr = *(const void * const *)
|
|
- ((const void *)ptr + elm->memb_offset);
|
|
+ ((const char *)ptr + elm->memb_offset);
|
|
} else {
|
|
memb_ptr = (const void *)
|
|
- ((const void *)ptr + elm->memb_offset);
|
|
+ ((const char *)ptr + elm->memb_offset);
|
|
}
|
|
|
|
return asn_TYPE_outmost_tag(elm->type, memb_ptr,
|
|
@@ -498,7 +498,7 @@
|
|
const void *memb_ptr;
|
|
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr = *(const void * const *)((const void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
|
|
if(!memb_ptr) {
|
|
if(elm->optional)
|
|
return 0;
|
|
@@ -508,7 +508,7 @@
|
|
return -1;
|
|
}
|
|
} else {
|
|
- memb_ptr = (const void *)((const void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
|
|
}
|
|
|
|
if(elm->memb_constraints) {
|
|
@@ -535,7 +535,7 @@
|
|
#undef XER_ADVANCE
|
|
#define XER_ADVANCE(num_bytes) do { \
|
|
size_t num = num_bytes; \
|
|
- buf_ptr = ((const void *)buf_ptr) + num;\
|
|
+ buf_ptr = ((const char *)buf_ptr) + num;\
|
|
size -= num; \
|
|
consumed_myself += num; \
|
|
} while(0)
|
|
@@ -574,7 +574,7 @@
|
|
/*
|
|
* Restore parsing context.
|
|
*/
|
|
- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset);
|
|
+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
|
|
if(ctx->phase == 0 && !*xml_tag)
|
|
ctx->phase = 1; /* Skip the outer tag checking phase */
|
|
|
|
@@ -605,7 +605,7 @@
|
|
|
|
if(elm->flags & ATF_POINTER) {
|
|
/* Member is a pointer to another structure */
|
|
- memb_ptr2 = (void **)((void *)st
|
|
+ memb_ptr2 = (void **)((char *)st
|
|
+ elm->memb_offset);
|
|
} else {
|
|
memb_ptr = (char *)st + elm->memb_offset;
|
|
@@ -797,10 +797,10 @@
|
|
unsigned int mlen = strlen(mname);
|
|
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr = *(void **)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
|
|
if(!memb_ptr) _ASN_ENCODE_FAILED;
|
|
} else {
|
|
- memb_ptr = (void *)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
|
}
|
|
|
|
er.encoded = 0;
|
|
@@ -884,7 +884,7 @@
|
|
elm = &td->elements[value];
|
|
if(elm->flags & ATF_POINTER) {
|
|
/* Member is a pointer to another structure */
|
|
- memb_ptr2 = (void **)((void *)st + elm->memb_offset);
|
|
+ memb_ptr2 = (void **)((char *)st + elm->memb_offset);
|
|
} else {
|
|
memb_ptr = (char *)st + elm->memb_offset;
|
|
memb_ptr2 = &memb_ptr;
|
|
@@ -904,7 +904,88 @@
|
|
elm->name, td->name, rv.code);
|
|
return rv;
|
|
}
|
|
-
|
|
+
|
|
+asn_dec_rval_t
|
|
+CHOICE_decode_aper(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;
|
|
+
|
|
+ if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
|
|
+ _ASN_DECODE_FAILED;
|
|
+
|
|
+ /*
|
|
+ * 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_STARVED;
|
|
+ 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_STARVED;
|
|
+ ASN_DEBUG("CHOICE %s got index %d in range %d",
|
|
+ td->name, value, ct->range_bits);
|
|
+ if(value > ct->upper_bound)
|
|
+ _ASN_DECODE_FAILED;
|
|
+ } else {
|
|
+ if(specs->ext_start == -1)
|
|
+ _ASN_DECODE_FAILED;
|
|
+ value = uper_get_nsnnwn(pd);
|
|
+ if(value < 0) _ASN_DECODE_STARVED;
|
|
+ value += specs->ext_start;
|
|
+ if(value >= td->elements_count)
|
|
+ _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);
|
|
+
|
|
+ if(ct && ct->range_bits >= 0) {
|
|
+ rv = elm->type->aper_decoder(opt_codec_ctx, elm->type,
|
|
+ elm->per_constraints, memb_ptr2, pd);
|
|
+ } else {
|
|
+ rv = uper_open_type_get(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) %d",
|
|
+ elm->name, td->name, rv.code);
|
|
+ return rv;
|
|
+}
|
|
+
|
|
asn_enc_rval_t
|
|
CHOICE_encode_uper(asn_TYPE_descriptor_t *td,
|
|
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
|
@@ -917,7 +998,7 @@
|
|
|
|
if(!sptr) _ASN_ENCODE_FAILED;
|
|
|
|
- ASN_DEBUG("Encoding %s as CHOICE", td->name);
|
|
+ ASN_DEBUG("Encoding %s as CHOICE using UPER", td->name);
|
|
|
|
if(constraints) ct = &constraints->value;
|
|
else if(td->per_constraints) ct = &td->per_constraints->value;
|
|
@@ -962,7 +1043,7 @@
|
|
elm = &td->elements[present];
|
|
if(elm->flags & ATF_POINTER) {
|
|
/* Member is a pointer to another structure */
|
|
- memb_ptr = *(void **)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
|
|
if(!memb_ptr) _ASN_ENCODE_FAILED;
|
|
} else {
|
|
memb_ptr = (char *)sptr + elm->memb_offset;
|
|
@@ -987,8 +1068,88 @@
|
|
_ASN_ENCODED_OK(rval);
|
|
}
|
|
}
|
|
-
|
|
|
|
+asn_enc_rval_t
|
|
+CHOICE_encode_aper(asn_TYPE_descriptor_t *td,
|
|
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
|
+ asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
|
|
+ asn_TYPE_member_t *elm; /* CHOICE's element */
|
|
+ asn_per_constraint_t *ct;
|
|
+ void *memb_ptr;
|
|
+ int present;
|
|
+
|
|
+ if(!sptr) _ASN_ENCODE_FAILED;
|
|
+
|
|
+ ASN_DEBUG("Encoding %s as CHOICE using ALIGNED PER", td->name);
|
|
+
|
|
+ if(constraints) ct = &constraints->value;
|
|
+ else if(td->per_constraints) ct = &td->per_constraints->value;
|
|
+ else ct = 0;
|
|
+
|
|
+ present = _fetch_present_idx(sptr,
|
|
+ specs->pres_offset, specs->pres_size);
|
|
+
|
|
+ /*
|
|
+ * If the structure was not initialized properly, it cannot be encoded:
|
|
+ * can't deduce what to encode in the choice type.
|
|
+ */
|
|
+ if(present <= 0 || present > td->elements_count)
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ else
|
|
+ present--;
|
|
+
|
|
+ /* Adjust if canonical order is different from natural order */
|
|
+ if(specs->canonical_order)
|
|
+ present = specs->canonical_order[present];
|
|
+
|
|
+ ASN_DEBUG("Encoding %s CHOICE element %d", td->name, present);
|
|
+
|
|
+ if(ct && ct->range_bits >= 0) {
|
|
+ if(present < ct->lower_bound
|
|
+ || present > ct->upper_bound) {
|
|
+ if(ct->flags & APC_EXTENSIBLE) {
|
|
+ if(per_put_few_bits(po, 1, 1))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ } else {
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+ ct = 0;
|
|
+ }
|
|
+ }
|
|
+ if(ct && ct->flags & APC_EXTENSIBLE) {
|
|
+ if(per_put_few_bits(po, 0, 1))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+
|
|
+ elm = &td->elements[present];
|
|
+ if(elm->flags & ATF_POINTER) {
|
|
+ /* Member is a pointer to another structure */
|
|
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
|
|
+ if(!memb_ptr) _ASN_ENCODE_FAILED;
|
|
+ } else {
|
|
+ memb_ptr = (char *)sptr + elm->memb_offset;
|
|
+ }
|
|
+
|
|
+ if(ct && ct->range_bits >= 0) {
|
|
+ if(per_put_few_bits(po, present, ct->range_bits))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+
|
|
+ return elm->type->aper_encoder(elm->type, elm->per_constraints,
|
|
+ memb_ptr, po);
|
|
+ } else {
|
|
+ asn_enc_rval_t rval;
|
|
+ if(specs->ext_start == -1)
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ if(aper_put_nsnnwn(po, ct->range_bits, present - specs->ext_start))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ if(aper_open_type_put(elm->type, elm->per_constraints,
|
|
+ memb_ptr, po))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ rval.encoded = 0;
|
|
+ _ASN_ENCODED_OK(rval);
|
|
+ }
|
|
+}
|
|
+
|
|
int
|
|
CHOICE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
|
asn_app_consume_bytes_f *cb, void *app_key) {
|
|
@@ -1010,10 +1171,10 @@
|
|
const void *memb_ptr;
|
|
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr = *(const void * const *)((const void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
|
|
if(!memb_ptr) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
|
|
} else {
|
|
- memb_ptr = (const void *)((const void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
|
|
}
|
|
|
|
/* Print member's name and stuff */
|
|
@@ -1053,11 +1214,11 @@
|
|
void *memb_ptr;
|
|
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr = *(void **)((void *)ptr + elm->memb_offset);
|
|
+ memb_ptr = *(void **)((char *)ptr + elm->memb_offset);
|
|
if(memb_ptr)
|
|
ASN_STRUCT_FREE(*elm->type, memb_ptr);
|
|
} else {
|
|
- memb_ptr = (void *)((void *)ptr + elm->memb_offset);
|
|
+ memb_ptr = (void *)((char *)ptr + elm->memb_offset);
|
|
ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr);
|
|
}
|
|
}
|
|
@@ -1082,7 +1243,7 @@
|
|
const void *present_ptr;
|
|
int present;
|
|
|
|
- present_ptr = ((const void *)struct_ptr) + pres_offset;
|
|
+ present_ptr = ((const char *)struct_ptr) + pres_offset;
|
|
|
|
switch(pres_size) {
|
|
case sizeof(int): present = *(const int *)present_ptr; break;
|
|
@@ -1100,7 +1261,7 @@
|
|
static void
|
|
_set_present_idx(void *struct_ptr, int pres_offset, int pres_size, int present) {
|
|
void *present_ptr;
|
|
- present_ptr = ((void *)struct_ptr) + pres_offset;
|
|
+ present_ptr = ((char *)struct_ptr) + pres_offset;
|
|
|
|
switch(pres_size) {
|
|
case sizeof(int): *(int *)present_ptr = present; break;
|
|
Index: skeletons/asn_internal.h
|
|
===================================================================
|
|
--- skeletons/asn_internal.h (revision 1516)
|
|
+++ skeletons/asn_internal.h (working copy)
|
|
@@ -20,7 +20,7 @@
|
|
#endif
|
|
|
|
/* Environment version might be used to avoid running with the old library */
|
|
-#define ASN1C_ENVIRONMENT_VERSION 923 /* Compile-time version */
|
|
+#define ASN1C_ENVIRONMENT_VERSION 924 /* Compile-time version */
|
|
int get_asn1c_environment_version(void); /* Run-time version */
|
|
|
|
#define CALLOC(nmemb, size) calloc(nmemb, size)
|
|
@@ -48,18 +48,22 @@
|
|
#define ASN_DEBUG_INDENT_ADD(i) do { asn_debug_indent += i; } while(0)
|
|
#endif /* ASN_THREAD_SAFE */
|
|
#define ASN_DEBUG(fmt, args...) do { \
|
|
- int adi = asn_debug_indent; \
|
|
- while(adi--) fprintf(stderr, " "); \
|
|
- fprintf(stderr, fmt, ##args); \
|
|
- fprintf(stderr, " (%s:%d)\n", \
|
|
- __FILE__, __LINE__); \
|
|
- } while(0)
|
|
+ int adi = asn_debug_indent; \
|
|
+ while(adi--) fprintf(stderr, " "); \
|
|
+ fprintf(stderr, fmt, ##args); \
|
|
+ fprintf(stderr, " (%s:%d)\n", \
|
|
+ __FILE__, __LINE__); \
|
|
+} while(0)
|
|
#else /* !__GNUC__ */
|
|
void ASN_DEBUG_f(const char *fmt, ...);
|
|
#define ASN_DEBUG ASN_DEBUG_f
|
|
#endif /* __GNUC__ */
|
|
#else /* EMIT_ASN_DEBUG != 1 */
|
|
+# ifdef EMIT_ASN_DEBUG_EXTERN
|
|
+extern inline void ASN_DEBUG(const char *fmt, ...);
|
|
+# else
|
|
static inline void ASN_DEBUG(const char *fmt, ...) { (void)fmt; }
|
|
+# endif
|
|
#endif /* EMIT_ASN_DEBUG */
|
|
#endif /* ASN_DEBUG */
|
|
|
|
Index: skeletons/BOOLEAN.h
|
|
===================================================================
|
|
--- skeletons/BOOLEAN.h (revision 1516)
|
|
+++ skeletons/BOOLEAN.h (working copy)
|
|
@@ -28,6 +28,8 @@
|
|
xer_type_encoder_f BOOLEAN_encode_xer;
|
|
per_type_decoder_f BOOLEAN_decode_uper;
|
|
per_type_encoder_f BOOLEAN_encode_uper;
|
|
+per_type_decoder_f BOOLEAN_decode_aper;
|
|
+per_type_encoder_f BOOLEAN_encode_aper;
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
Index: skeletons/constr_CHOICE.h
|
|
===================================================================
|
|
--- skeletons/constr_CHOICE.h (revision 1516)
|
|
+++ skeletons/constr_CHOICE.h (working copy)
|
|
@@ -48,6 +48,8 @@
|
|
xer_type_encoder_f CHOICE_encode_xer;
|
|
per_type_decoder_f CHOICE_decode_uper;
|
|
per_type_encoder_f CHOICE_encode_uper;
|
|
+per_type_decoder_f CHOICE_decode_aper;
|
|
+per_type_encoder_f CHOICE_encode_aper;
|
|
asn_outmost_tag_f CHOICE_outmost_tag;
|
|
|
|
#ifdef __cplusplus
|
|
Index: skeletons/INTEGER.c
|
|
===================================================================
|
|
--- skeletons/INTEGER.c (revision 1516)
|
|
+++ skeletons/INTEGER.c (working copy)
|
|
@@ -27,9 +27,13 @@
|
|
#ifdef ASN_DISABLE_PER_SUPPORT
|
|
0,
|
|
0,
|
|
+ 0,
|
|
+ 0,
|
|
#else
|
|
INTEGER_decode_uper, /* Unaligned PER decoder */
|
|
INTEGER_encode_uper, /* Unaligned PER encoder */
|
|
+ INTEGER_decode_aper,
|
|
+ INTEGER_encode_aper,
|
|
#endif /* ASN_DISABLE_PER_SUPPORT */
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_INTEGER_tags,
|
|
@@ -612,7 +616,7 @@
|
|
value = per_get_few_bits(pd, ct->range_bits);
|
|
if(value < 0) _ASN_DECODE_STARVED;
|
|
}
|
|
- ASN_DEBUG("Got value %ld + low %ld",
|
|
+ ASN_DEBUG("Got value %ld + low %"PRIdMAX,
|
|
value, ct->lower_bound);
|
|
value += ct->lower_bound;
|
|
if((specs && specs->field_unsigned)
|
|
@@ -660,6 +664,158 @@
|
|
return rval;
|
|
}
|
|
|
|
+asn_dec_rval_t
|
|
+INTEGER_decode_aper(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 };
|
|
+ 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_STARVED;
|
|
+ if(inext) ct = 0;
|
|
+ }
|
|
+
|
|
+ FREEMEM(st->buf);
|
|
+ st->buf = 0;
|
|
+ st->size = 0;
|
|
+ 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;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* 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) {
|
|
+ if (ct->range_bits > 16) {
|
|
+ int max_range_bytes = (ct->range_bits >> 3) +
|
|
+ (((ct->range_bits % 8) > 0) ? 1 : 0);
|
|
+ int length = 0, i;
|
|
+ int64_t value = 0;
|
|
+
|
|
+ for (i = 1; ; i++) {
|
|
+ int upper = 1 << i;
|
|
+ if (upper >= max_range_bytes)
|
|
+ break;
|
|
+ }
|
|
+ ASN_DEBUG("Can encode %d (%d bytes) in %d bits", ct->range_bits,
|
|
+ max_range_bytes, i);
|
|
+
|
|
+ if ((length = per_get_few_bits(pd, i)) < 0)
|
|
+ _ASN_DECODE_FAILED;
|
|
+
|
|
+ /* X.691 #12.2.6 length determinant + lb (1) */
|
|
+ length += 1;
|
|
+ ASN_DEBUG("Got length %d", length);
|
|
+
|
|
+ if (aper_get_align(pd) != 0)
|
|
+ _ASN_DECODE_STARVED;
|
|
+
|
|
+ while (length--) {
|
|
+ int buf = per_get_few_bits(pd, 8);
|
|
+ if (buf < 0)
|
|
+ _ASN_DECODE_STARVED;
|
|
+ value += (((int64_t)buf) << (8 * length));
|
|
+ }
|
|
+
|
|
+ value += ct->lower_bound;
|
|
+ if((specs && specs->field_unsigned)
|
|
+ ? asn_uint642INTEGER(st, value)
|
|
+ : asn_int642INTEGER(st, value))
|
|
+ _ASN_DECODE_FAILED;
|
|
+ ASN_DEBUG("Got value %lld + low %lld",
|
|
+ value, ct->lower_bound);
|
|
+ } else {
|
|
+ long value = 0;
|
|
+ if (ct->range_bits < 8) {
|
|
+ value = per_get_few_bits(pd, ct->range_bits);
|
|
+ if(value < 0) _ASN_DECODE_STARVED;
|
|
+ } else if (ct->range_bits == 8) {
|
|
+ if (aper_get_align(pd) < 0)
|
|
+ _ASN_DECODE_FAILED;
|
|
+ value = per_get_few_bits(pd, ct->range_bits);
|
|
+ if(value < 0) _ASN_DECODE_STARVED;
|
|
+ } else {
|
|
+ /* Align */
|
|
+ if (aper_get_align(pd) < 0)
|
|
+ _ASN_DECODE_FAILED;
|
|
+ value = per_get_few_bits(pd, 16);
|
|
+ if(value < 0) _ASN_DECODE_STARVED;
|
|
+ }
|
|
+ value += ct->lower_bound;
|
|
+ if((specs && specs->field_unsigned)
|
|
+ ? asn_ulong2INTEGER(st, value)
|
|
+ : asn_long2INTEGER(st, value))
|
|
+ _ASN_DECODE_FAILED;
|
|
+ ASN_DEBUG("Got value %ld + low %lld",
|
|
+ value, ct->lower_bound);
|
|
+ }
|
|
+ return rval;
|
|
+ } else {
|
|
+ _ASN_DECODE_FAILED;
|
|
+ }
|
|
+ } 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 = aper_get_length(pd, -1, -1, &repeat);
|
|
+ if(len < 0) _ASN_DECODE_STARVED;
|
|
+
|
|
+ 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_STARVED;
|
|
+ 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;
|
|
+}
|
|
+
|
|
asn_enc_rval_t
|
|
INTEGER_encode_uper(asn_TYPE_descriptor_t *td,
|
|
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
|
@@ -693,7 +849,7 @@
|
|
|| uval > (unsigned long)ct->upper_bound)
|
|
inext = 1;
|
|
}
|
|
- ASN_DEBUG("Value %lu (%02x/%d) lb %lu ub %lu %s",
|
|
+ ASN_DEBUG("Value %lu (%02x/%d) lb %"PRIuMAX" ub %"PRIuMAX" %s",
|
|
uval, st->buf[0], st->size,
|
|
ct->lower_bound, ct->upper_bound,
|
|
inext ? "ext" : "fix");
|
|
@@ -710,7 +866,7 @@
|
|
|| value > ct->upper_bound)
|
|
inext = 1;
|
|
}
|
|
- ASN_DEBUG("Value %ld (%02x/%d) lb %ld ub %ld %s",
|
|
+ ASN_DEBUG("Value %ld (%02x/%d) lb %"PRIdMAX" ub %"PRIdMAX" %s",
|
|
value, st->buf[0], st->size,
|
|
ct->lower_bound, ct->upper_bound,
|
|
inext ? "ext" : "fix");
|
|
@@ -745,7 +901,7 @@
|
|
}
|
|
|
|
if(ct && ct->lower_bound) {
|
|
- ASN_DEBUG("Adjust lower bound to %ld", ct->lower_bound);
|
|
+ ASN_DEBUG("Adjust lower bound to %"PRIdMAX"\n", ct->lower_bound);
|
|
/* TODO: adjust lower bound */
|
|
_ASN_ENCODE_FAILED;
|
|
}
|
|
@@ -762,6 +918,153 @@
|
|
_ASN_ENCODED_OK(er);
|
|
}
|
|
|
|
+asn_enc_rval_t
|
|
+INTEGER_encode_aper(asn_TYPE_descriptor_t *td,
|
|
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
|
+ asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
|
|
+ asn_enc_rval_t er;
|
|
+ INTEGER_t *st = (INTEGER_t *)sptr;
|
|
+ const uint8_t *buf;
|
|
+ const uint8_t *end;
|
|
+ asn_per_constraint_t *ct;
|
|
+ int64_t value = 0;
|
|
+
|
|
+ if(!st || st->size == 0) _ASN_ENCODE_FAILED;
|
|
+
|
|
+ if(!constraints) constraints = td->per_constraints;
|
|
+ ct = constraints ? &constraints->value : 0;
|
|
+
|
|
+ er.encoded = 0;
|
|
+
|
|
+ if(ct) {
|
|
+ int inext = 0;
|
|
+ if(specs && specs->field_unsigned) {
|
|
+ uint64_t uval;
|
|
+ if(asn_INTEGER2uint64(st, &uval))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ /* Check proper range */
|
|
+ if(ct->flags & APC_SEMI_CONSTRAINED) {
|
|
+ if(uval < ct->lower_bound)
|
|
+ inext = 1;
|
|
+ } else if(ct->range_bits >= 0) {
|
|
+ if(uval < ct->lower_bound
|
|
+ || uval > ct->upper_bound)
|
|
+ inext = 1;
|
|
+ }
|
|
+ ASN_DEBUG("Value %llu (%02x/%d) lb %llu ub %llu %s",
|
|
+ uval, st->buf[0], st->size,
|
|
+ ct->lower_bound, ct->upper_bound,
|
|
+ inext ? "ext" : "fix");
|
|
+ value = uval;
|
|
+ } else {
|
|
+ if(asn_INTEGER2int64(st, &value)) _ASN_ENCODE_FAILED;
|
|
+ /* Check proper range */
|
|
+ if(ct->flags & APC_SEMI_CONSTRAINED) {
|
|
+ if(value < ct->lower_bound)
|
|
+ inext = 1;
|
|
+ } else if(ct->range_bits >= 0) {
|
|
+ if(value < ct->lower_bound
|
|
+ || value > ct->upper_bound)
|
|
+ inext = 1;
|
|
+ }
|
|
+ ASN_DEBUG("Value %lld (%02x/%d) lb %lld ub %lld %s",
|
|
+ value, st->buf[0], st->size,
|
|
+ ct->lower_bound, ct->upper_bound,
|
|
+ inext ? "ext" : "fix");
|
|
+ }
|
|
+ if(ct->flags & APC_EXTENSIBLE) {
|
|
+ if(per_put_few_bits(po, inext, 1))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ if(inext) ct = 0;
|
|
+ } else if(inext) {
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* X.691, #12.2.2 */
|
|
+ if(ct && ct->range_bits >= 0) {
|
|
+ /* #10.5.6 */
|
|
+ ASN_DEBUG("Encoding integer with range %d bits",
|
|
+ ct->range_bits);
|
|
+
|
|
+ value -= ct->lower_bound;
|
|
+
|
|
+ /* #12 <= 8 -> alignment ? */
|
|
+ if (ct->range_bits < 8) {
|
|
+ /* Bit field case -> no alignment*/
|
|
+ if(per_put_few_bits(po, 0x00 | value, ct->range_bits))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ } else if (ct->range_bits == 8) {
|
|
+ if(aper_put_align(po) < 0)
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ if(per_put_few_bits(po, 0x00 | value, ct->range_bits))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ } else if (ct->range_bits <= 16) {
|
|
+ // Consume the bytes to align on octet
|
|
+ if(aper_put_align(po) < 0)
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ if(per_put_few_bits(po, 0x0000 | value,
|
|
+ 16))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ } else {
|
|
+ /* TODO: extend to >64 bits */
|
|
+ int64_t v = value;
|
|
+ int i, j;
|
|
+ int max_range_bytes = (ct->range_bits >> 3) +
|
|
+ (((ct->range_bits % 8) > 0) ? 1 : 0);
|
|
+
|
|
+ for (i = 1; ; i++) {
|
|
+ int upper = 1 << i;
|
|
+ if (upper >= max_range_bytes)
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ for(j = sizeof(int64_t) - 1; j != 0; j--) {
|
|
+ uint8_t val;
|
|
+ val = v >> (j * 8);
|
|
+ if (val != 0) {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ ASN_DEBUG("Putting n - lb (%"PRIdMAX") with range %d bytes (real size - lb (1)) %d in %d bits",
|
|
+ v, max_range_bytes, j, i);
|
|
+
|
|
+ /* Putting length in the minimum number of bits ex: 5 = 3bits */
|
|
+ if (per_put_few_bits(po, j, i))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+
|
|
+ // Consume the bits to align on octet
|
|
+ if (aper_put_align(po) < 0)
|
|
+ _ASN_ENCODE_FAILED;
|
|
+
|
|
+ /* Put the value */
|
|
+ for (i = 0; i <= j; i++) {
|
|
+ if(per_put_few_bits(po, (v >> (8 * (j - i))) & 0xff, 8))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+ }
|
|
+ _ASN_ENCODED_OK(er);
|
|
+ }
|
|
+
|
|
+ if(ct && ct->lower_bound) {
|
|
+ ASN_DEBUG("Adjust lower bound to %"PRIdMAX, ct->lower_bound);
|
|
+ /* TODO: adjust lower bound */
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+
|
|
+ for(buf = st->buf, end = st->buf + st->size; buf < end;) {
|
|
+ ssize_t mayEncode = aper_put_length(po, -1, end - buf);
|
|
+ if(mayEncode < 0)
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ if(per_put_many_bits(po, buf, 8 * mayEncode))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ buf += mayEncode;
|
|
+ }
|
|
+
|
|
+ _ASN_ENCODED_OK(er);
|
|
+}
|
|
+
|
|
#endif /* ASN_DISABLE_PER_SUPPORT */
|
|
|
|
int
|
|
@@ -825,6 +1128,66 @@
|
|
}
|
|
|
|
int
|
|
+asn_INTEGER2int64(const INTEGER_t *iptr, int64_t *lptr) {
|
|
+ uint8_t *b, *end;
|
|
+ size_t size;
|
|
+ int64_t l;
|
|
+
|
|
+ /* Sanity checking */
|
|
+ if(!iptr || !iptr->buf || !lptr) {
|
|
+ errno = EINVAL;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /* Cache the begin/end of the buffer */
|
|
+ b = iptr->buf; /* Start of the INTEGER buffer */
|
|
+ size = iptr->size;
|
|
+ end = b + size; /* Where to stop */
|
|
+
|
|
+ if(size > sizeof(int64_t)) {
|
|
+ uint8_t *end1 = end - 1;
|
|
+ /*
|
|
+ * Slightly more advanced processing,
|
|
+ * able to >sizeof(int64_t) bytes,
|
|
+ * when the actual value is small
|
|
+ * (0x0000000000abcdef would yield a fine 0x00abcdef)
|
|
+ */
|
|
+ /* Skip out the insignificant leading bytes */
|
|
+ for(; b < end1; b++) {
|
|
+ switch(*b) {
|
|
+ case 0x00: if((b[1] & 0x80) == 0) continue; break;
|
|
+ case 0xff: if((b[1] & 0x80) != 0) continue; break;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ size = end - b;
|
|
+ if(size > sizeof(int64_t)) {
|
|
+ /* Still cannot fit the int64_t */
|
|
+ errno = ERANGE;
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* Shortcut processing of a corner case */
|
|
+ if(end == b) {
|
|
+ *lptr = 0;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ /* Perform the sign initialization */
|
|
+ /* Actually l = -(*b >> 7); gains nothing, yet unreadable! */
|
|
+ if((*b >> 7)) l = -1; else l = 0;
|
|
+
|
|
+ /* Conversion engine */
|
|
+ for(; b < end; b++)
|
|
+ l = (l << 8) | *b;
|
|
+
|
|
+ *lptr = l;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
asn_INTEGER2ulong(const INTEGER_t *iptr, unsigned long *lptr) {
|
|
uint8_t *b, *end;
|
|
unsigned long l;
|
|
@@ -857,6 +1220,38 @@
|
|
}
|
|
|
|
int
|
|
+asn_INTEGER2uint64(const INTEGER_t *iptr, uint64_t *lptr) {
|
|
+ uint8_t *b, *end;
|
|
+ uint64_t l;
|
|
+ size_t size;
|
|
+
|
|
+ if(!iptr || !iptr->buf || !lptr) {
|
|
+ errno = EINVAL;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ b = iptr->buf;
|
|
+ size = iptr->size;
|
|
+ end = b + size;
|
|
+
|
|
+ /* If all extra leading bytes are zeroes, ignore them */
|
|
+ for(; size > sizeof(uint64_t); b++, size--) {
|
|
+ if(*b) {
|
|
+ /* Value won't fit unsigned long */
|
|
+ errno = ERANGE;
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* Conversion engine */
|
|
+ for(l = 0; b < end; b++)
|
|
+ l = (l << 8) | *b;
|
|
+
|
|
+ *lptr = l;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
asn_ulong2INTEGER(INTEGER_t *st, unsigned long value) {
|
|
uint8_t *buf;
|
|
uint8_t *end;
|
|
@@ -871,7 +1266,7 @@
|
|
|
|
end = buf + (sizeof(value) + 1);
|
|
buf[0] = 0;
|
|
- for(b = buf + 1, shr = (sizeof(long)-1)*8; b < end; shr -= 8, b++)
|
|
+ for(b = buf + 1, shr = (sizeof(unsigned long)-1)*8; b < end; shr -= 8, b++)
|
|
*b = (uint8_t)(value >> shr);
|
|
|
|
if(st->buf) FREEMEM(st->buf);
|
|
@@ -882,6 +1277,31 @@
|
|
}
|
|
|
|
int
|
|
+asn_uint642INTEGER(INTEGER_t *st, uint64_t value) {
|
|
+ uint8_t *buf;
|
|
+ uint8_t *end;
|
|
+ uint8_t *b;
|
|
+ int shr;
|
|
+
|
|
+ if(value <= INT64_MAX)
|
|
+ return asn_int642INTEGER(st, value);
|
|
+
|
|
+ buf = (uint8_t *)MALLOC(1 + sizeof(value));
|
|
+ if(!buf) return -1;
|
|
+
|
|
+ end = buf + (sizeof(value) + 1);
|
|
+ buf[0] = 0;
|
|
+ for(b = buf + 1, shr = (sizeof(value)-1)*8; b < end; shr -= 8, b++)
|
|
+ *b = (uint8_t)(value >> shr);
|
|
+
|
|
+ if(st->buf) FREEMEM(st->buf);
|
|
+ st->buf = buf;
|
|
+ st->size = 1 + sizeof(value);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
asn_long2INTEGER(INTEGER_t *st, long value) {
|
|
uint8_t *buf, *bp;
|
|
uint8_t *p;
|
|
@@ -1024,3 +1444,60 @@
|
|
return ASN_STRTOL_OK;
|
|
}
|
|
|
|
+
|
|
+int
|
|
+asn_int642INTEGER(INTEGER_t *st, int64_t value) {
|
|
+ uint8_t *buf, *bp;
|
|
+ uint8_t *p;
|
|
+ uint8_t *pstart;
|
|
+ uint8_t *pend1;
|
|
+ int littleEndian = 1; /* Run-time detection */
|
|
+ int add;
|
|
+
|
|
+ if(!st) {
|
|
+ errno = EINVAL;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ buf = (uint8_t *)MALLOC(sizeof(value));
|
|
+ if(!buf) return -1;
|
|
+
|
|
+ if(*(char *)&littleEndian) {
|
|
+ pstart = (uint8_t *)&value + sizeof(value) - 1;
|
|
+ pend1 = (uint8_t *)&value;
|
|
+ add = -1;
|
|
+ } else {
|
|
+ pstart = (uint8_t *)&value;
|
|
+ pend1 = pstart + sizeof(value) - 1;
|
|
+ add = 1;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * If the contents octet consists of more than one octet,
|
|
+ * then bits of the first octet and bit 8 of the second octet:
|
|
+ * a) shall not all be ones; and
|
|
+ * b) shall not all be zero.
|
|
+ */
|
|
+ for(p = pstart; p != pend1; p += add) {
|
|
+ switch(*p) {
|
|
+ case 0x00: if((*(p+add) & 0x80) == 0)
|
|
+ continue;
|
|
+ break;
|
|
+ case 0xff: if((*(p+add) & 0x80))
|
|
+ continue;
|
|
+ break;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ /* Copy the integer body */
|
|
+ for(pstart = p, bp = buf, pend1 += add; p != pend1; p += add)
|
|
+ *bp++ = *p;
|
|
+
|
|
+ if(st->buf) FREEMEM(st->buf);
|
|
+ st->buf = buf;
|
|
+ st->size = bp - buf;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
Index: skeletons/constr_SEQUENCE.c
|
|
===================================================================
|
|
--- skeletons/constr_SEQUENCE.c (revision 1516)
|
|
+++ skeletons/constr_SEQUENCE.c (working copy)
|
|
@@ -34,7 +34,7 @@
|
|
#undef ADVANCE
|
|
#define ADVANCE(num_bytes) do { \
|
|
size_t num = num_bytes; \
|
|
- ptr = ((const void *)ptr) + num;\
|
|
+ ptr = ((const char *)ptr) + num;\
|
|
size -= num; \
|
|
if(ctx->left >= 0) \
|
|
ctx->left -= num; \
|
|
@@ -144,7 +144,7 @@
|
|
/*
|
|
* Restore parsing context.
|
|
*/
|
|
- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset);
|
|
+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
|
|
|
|
/*
|
|
* Start to parse where left previously
|
|
@@ -366,7 +366,7 @@
|
|
ber_tlv_tag_string(tlv_tag), edx);
|
|
skip = ber_skip_length(opt_codec_ctx,
|
|
BER_TLV_CONSTRUCTED(ptr),
|
|
- (const void *)ptr + tag_len,
|
|
+ (const char *)ptr + tag_len,
|
|
LEFT - tag_len);
|
|
ASN_DEBUG("Skip length %d in %s",
|
|
(int)skip, td->name);
|
|
@@ -397,13 +397,13 @@
|
|
*/
|
|
if(elements[edx].flags & ATF_POINTER) {
|
|
/* Member is a pointer to another structure */
|
|
- memb_ptr2 = (void **)((void *)st + elements[edx].memb_offset);
|
|
+ memb_ptr2 = (void **)((char *)st + elements[edx].memb_offset);
|
|
} else {
|
|
/*
|
|
* A pointer to a pointer
|
|
* holding the start of the structure
|
|
*/
|
|
- memb_ptr = (void *)st + elements[edx].memb_offset;
|
|
+ memb_ptr = (char *)st + elements[edx].memb_offset;
|
|
memb_ptr2 = &memb_ptr;
|
|
}
|
|
/*
|
|
@@ -489,7 +489,7 @@
|
|
|
|
ll = ber_skip_length(opt_codec_ctx,
|
|
BER_TLV_CONSTRUCTED(ptr),
|
|
- (const void *)ptr + tl, LEFT - tl);
|
|
+ (const char *)ptr + tl, LEFT - tl);
|
|
switch(ll) {
|
|
case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
|
|
/* Fall through */
|
|
@@ -528,14 +528,14 @@
|
|
asn_TYPE_member_t *elm = &td->elements[edx];
|
|
void *memb_ptr;
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr = *(void **)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
|
|
if(!memb_ptr) {
|
|
if(elm->optional) continue;
|
|
/* Mandatory element is missing */
|
|
_ASN_ENCODE_FAILED;
|
|
}
|
|
} else {
|
|
- memb_ptr = (void *)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
|
}
|
|
erval = elm->type->der_encoder(elm->type, memb_ptr,
|
|
elm->tag_mode, elm->tag,
|
|
@@ -567,10 +567,10 @@
|
|
void *memb_ptr;
|
|
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr = *(void **)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
|
|
if(!memb_ptr) continue;
|
|
} else {
|
|
- memb_ptr = (void *)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
|
}
|
|
tmperval = elm->type->der_encoder(elm->type, memb_ptr,
|
|
elm->tag_mode, elm->tag,
|
|
@@ -595,7 +595,7 @@
|
|
#undef XER_ADVANCE
|
|
#define XER_ADVANCE(num_bytes) do { \
|
|
size_t num = num_bytes; \
|
|
- buf_ptr = ((const void *)buf_ptr) + num;\
|
|
+ buf_ptr = ((const char *)buf_ptr) + num;\
|
|
size -= num; \
|
|
consumed_myself += num; \
|
|
} while(0)
|
|
@@ -637,7 +637,7 @@
|
|
/*
|
|
* Restore parsing context.
|
|
*/
|
|
- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset);
|
|
+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
|
|
|
|
|
|
/*
|
|
@@ -667,9 +667,10 @@
|
|
|
|
if(elm->flags & ATF_POINTER) {
|
|
/* Member is a pointer to another structure */
|
|
- memb_ptr2 = (void **)((void *)st + elm->memb_offset);
|
|
+ memb_ptr2 = (void **)((char *)st
|
|
+ + elm->memb_offset);
|
|
} else {
|
|
- memb_ptr = (void *)st + elm->memb_offset;
|
|
+ memb_ptr = (char *)st + elm->memb_offset;
|
|
memb_ptr2 = &memb_ptr;
|
|
}
|
|
|
|
@@ -739,7 +740,7 @@
|
|
if(edx >= td->elements_count
|
|
||
|
|
/* Explicit OPTIONAL specs reaches the end */
|
|
- (edx + elements[edx].optional
|
|
+ (edx + elements[edx].optional
|
|
== td->elements_count)
|
|
||
|
|
/* All extensions are optional */
|
|
@@ -869,7 +870,7 @@
|
|
unsigned int mlen = strlen(mname);
|
|
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr = *(void **)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
|
|
if(!memb_ptr) {
|
|
if(elm->optional)
|
|
continue;
|
|
@@ -877,7 +878,7 @@
|
|
_ASN_ENCODE_FAILED;
|
|
}
|
|
} else {
|
|
- memb_ptr = (void *)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
|
}
|
|
|
|
if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel);
|
|
@@ -917,14 +918,14 @@
|
|
const void *memb_ptr;
|
|
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr = *(const void * const *)((const void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
|
|
if(!memb_ptr) {
|
|
if(elm->optional) continue;
|
|
/* Print <absent> line */
|
|
/* Fall through */
|
|
}
|
|
} else {
|
|
- memb_ptr = (const void *)((const void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
|
|
}
|
|
|
|
/* Indentation */
|
|
@@ -960,11 +961,11 @@
|
|
asn_TYPE_member_t *elm = &td->elements[edx];
|
|
void *memb_ptr;
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr = *(void **)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
|
|
if(memb_ptr)
|
|
ASN_STRUCT_FREE(*elm->type, memb_ptr);
|
|
} else {
|
|
- memb_ptr = (void *)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
|
ASN_STRUCT_FREE_CONTENTS_ONLY(*elm->type, memb_ptr);
|
|
}
|
|
}
|
|
@@ -994,7 +995,7 @@
|
|
const void *memb_ptr;
|
|
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr = *(const void * const *)((const void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = *(const void * const *)((const char *)sptr + elm->memb_offset);
|
|
if(!memb_ptr) {
|
|
if(elm->optional)
|
|
continue;
|
|
@@ -1004,7 +1005,7 @@
|
|
return -1;
|
|
}
|
|
} else {
|
|
- memb_ptr = (const void *)((const void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
|
|
}
|
|
|
|
if(elm->memb_constraints) {
|
|
@@ -1088,9 +1089,9 @@
|
|
|
|
/* Fetch the pointer to this member */
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr2 = (void **)((void *)st + elm->memb_offset);
|
|
+ memb_ptr2 = (void **)((char *)st + elm->memb_offset);
|
|
} else {
|
|
- memb_ptr = (void *)st + elm->memb_offset;
|
|
+ memb_ptr = (char *)st + elm->memb_offset;
|
|
memb_ptr2 = &memb_ptr;
|
|
}
|
|
|
|
@@ -1154,11 +1155,224 @@
|
|
memset(&epmd, 0, sizeof(epmd));
|
|
epmd.buffer = epres;
|
|
epmd.nbits = bmlength;
|
|
+ ASN_DEBUG("Read in extensions bitmap for %s of %d bits (%x..)",
|
|
+ td->name, bmlength, *epres);
|
|
+
|
|
+ /* Go over extensions and read them in */
|
|
+ for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) {
|
|
+ asn_TYPE_member_t *elm = &td->elements[edx];
|
|
+ void *memb_ptr; /* Pointer to the member */
|
|
+ void **memb_ptr2; /* Pointer to that pointer */
|
|
+ int present;
|
|
+
|
|
+ if(!IN_EXTENSION_GROUP(specs, edx)) {
|
|
+ ASN_DEBUG("%d is not extension", edx);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ /* Fetch the pointer to this member */
|
|
+ if(elm->flags & ATF_POINTER) {
|
|
+ memb_ptr2 = (void **)((char *)st + elm->memb_offset);
|
|
+ } else {
|
|
+ memb_ptr = (void *)((char *)st + elm->memb_offset);
|
|
+ memb_ptr2 = &memb_ptr;
|
|
+ }
|
|
+
|
|
+ present = per_get_few_bits(&epmd, 1);
|
|
+ if(present <= 0) {
|
|
+ if(present < 0) break; /* No more extensions */
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name, *memb_ptr2);
|
|
+ rv = uper_open_type_get(opt_codec_ctx, elm->type,
|
|
+ elm->per_constraints, memb_ptr2, pd);
|
|
+ if(rv.code != RC_OK) {
|
|
+ FREEMEM(epres);
|
|
+ return rv;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* Skip over overflow extensions which aren't present
|
|
+ * in this system's version of the protocol */
|
|
+ for(;;) {
|
|
+ ASN_DEBUG("Getting overflow extensions");
|
|
+ switch(per_get_few_bits(&epmd, 1)) {
|
|
+ case -1: break;
|
|
+ case 0: continue;
|
|
+ default:
|
|
+ if(uper_open_type_skip(opt_codec_ctx, pd)) {
|
|
+ FREEMEM(epres);
|
|
+ _ASN_DECODE_STARVED;
|
|
+ }
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ FREEMEM(epres);
|
|
+ }
|
|
+
|
|
+ /* Fill DEFAULT members in extensions */
|
|
+ for(edx = specs->roms_count; edx < specs->roms_count
|
|
+ + specs->aoms_count; edx++) {
|
|
+ asn_TYPE_member_t *elm = &td->elements[edx];
|
|
+ void **memb_ptr2; /* Pointer to member 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);
|
|
+ if(*memb_ptr2) continue;
|
|
+ } else {
|
|
+ continue; /* Extensions are all optionals */
|
|
+ }
|
|
+
|
|
+ /* Set default value */
|
|
+ if(elm->default_value(1, memb_ptr2)) {
|
|
+ _ASN_DECODE_FAILED;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ rv.consumed = 0;
|
|
+ rv.code = RC_OK;
|
|
+ return rv;
|
|
+}
|
|
+
|
|
+asn_dec_rval_t
|
|
+SEQUENCE_decode_aper(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; /* 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(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
|
|
+ _ASN_DECODE_FAILED;
|
|
+
|
|
+ if(!st) {
|
|
+ st = *sptr = CALLOC(1, specs->struct_size);
|
|
+ if(!st) _ASN_DECODE_FAILED;
|
|
+ }
|
|
+
|
|
+ ASN_DEBUG("Decoding %s as SEQUENCE (APER)", td->name);
|
|
+
|
|
+ /* Handle extensions */
|
|
+ if(specs->ext_before >= 0) {
|
|
+ extpresent = per_get_few_bits(pd, 1);
|
|
+ if(extpresent < 0) _ASN_DECODE_STARVED;
|
|
+ } else {
|
|
+ extpresent = 0;
|
|
+ }
|
|
+
|
|
+ /* Prepare a place and read-in the presence bitmap */
|
|
+ memset(&opmd, 0, sizeof(opmd));
|
|
+ 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_STARVED;
|
|
+ }
|
|
+ opmd.buffer = opres;
|
|
+ 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;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Get the sequence ROOT elements.
|
|
+ */
|
|
+ for(edx = 0; edx < td->elements_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(IN_EXTENSION_GROUP(specs, edx))
|
|
+ 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;
|
|
+ }
|
|
+
|
|
+ /* 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(1, memb_ptr2)) {
|
|
+ FREEMEM(opres);
|
|
+ _ASN_DECODE_FAILED;
|
|
+ }
|
|
+ ASN_DEBUG("Filled-in default");
|
|
+ }
|
|
+ /* 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->aper_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;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* Optionality map is not needed anymore */
|
|
+ FREEMEM(opres);
|
|
+
|
|
+ /*
|
|
+ * Deal with extensions.
|
|
+ */
|
|
+ if(extpresent) {
|
|
+ ssize_t bmlength;
|
|
+ uint8_t *epres; /* Presence of extension members */
|
|
+ asn_per_data_t epmd;
|
|
+
|
|
+ bmlength = uper_get_nslength(pd);
|
|
+ if(bmlength < 0) _ASN_DECODE_STARVED;
|
|
+
|
|
+ ASN_DEBUG("Extensions %d present in %s", bmlength, td->name);
|
|
+
|
|
+ epres = (uint8_t *)MALLOC((bmlength + 15) >> 3);
|
|
+ if(!epres) _ASN_DECODE_STARVED;
|
|
+
|
|
+ /* Get the extensions map */
|
|
+ if(per_get_many_bits(pd, epres, 0, bmlength))
|
|
+ _ASN_DECODE_STARVED;
|
|
+
|
|
+ memset(&epmd, 0, sizeof(epmd));
|
|
+ epmd.buffer = epres;
|
|
+ epmd.nbits = bmlength;
|
|
ASN_DEBUG("Read in extensions bitmap for %s of %ld bits (%x..)",
|
|
td->name, (long)bmlength, *epres);
|
|
|
|
- /* Go over extensions and read them in */
|
|
- for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) {
|
|
+ /* Go over extensions and read them in */
|
|
+ for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) {
|
|
asn_TYPE_member_t *elm = &td->elements[edx];
|
|
void *memb_ptr; /* Pointer to the member */
|
|
void **memb_ptr2; /* Pointer to that pointer */
|
|
@@ -1171,9 +1385,9 @@
|
|
|
|
/* Fetch the pointer to this member */
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr2 = (void **)((void *)st + elm->memb_offset);
|
|
+ memb_ptr2 = (void **)((char *)st + elm->memb_offset);
|
|
} else {
|
|
- memb_ptr = (void *)((void *)st + elm->memb_offset);
|
|
+ memb_ptr = (void *)((char *)st + elm->memb_offset);
|
|
memb_ptr2 = &memb_ptr;
|
|
}
|
|
|
|
@@ -1190,7 +1404,7 @@
|
|
FREEMEM(epres);
|
|
return rv;
|
|
}
|
|
- }
|
|
+ }
|
|
|
|
/* Skip over overflow extensions which aren't present
|
|
* in this system's version of the protocol */
|
|
@@ -1221,7 +1435,7 @@
|
|
|
|
/* Fetch the pointer to this member */
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr2 = (void **)((void *)st
|
|
+ memb_ptr2 = (void **)((char *)st
|
|
+ elm->memb_offset);
|
|
if(*memb_ptr2) continue;
|
|
} else {
|
|
@@ -1265,10 +1479,10 @@
|
|
|
|
/* Fetch the pointer to this member */
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr2 = (void **)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
|
|
present = (*memb_ptr2 != 0);
|
|
} else {
|
|
- memb_ptr = (void *)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
|
memb_ptr2 = &memb_ptr;
|
|
present = 1;
|
|
}
|
|
@@ -1334,10 +1548,10 @@
|
|
|
|
/* Fetch the pointer to this member */
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr2 = (void **)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
|
|
present = (*memb_ptr2 != 0);
|
|
} else {
|
|
- memb_ptr = (void *)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
|
memb_ptr2 = &memb_ptr;
|
|
present = 1;
|
|
}
|
|
@@ -1373,7 +1587,7 @@
|
|
|
|
/* Fetch the pointer to this member */
|
|
if(elm->flags & ATF_POINTER) {
|
|
- memb_ptr2 = (void **)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
|
|
if(!*memb_ptr2) {
|
|
ASN_DEBUG("Element %s %d not present",
|
|
elm->name, edx);
|
|
@@ -1383,7 +1597,7 @@
|
|
_ASN_ENCODE_FAILED;
|
|
}
|
|
} else {
|
|
- memb_ptr = (void *)((void *)sptr + elm->memb_offset);
|
|
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
|
memb_ptr2 = &memb_ptr;
|
|
}
|
|
|
|
@@ -1420,3 +1634,130 @@
|
|
_ASN_ENCODED_OK(er);
|
|
}
|
|
|
|
+asn_enc_rval_t
|
|
+SEQUENCE_encode_aper(asn_TYPE_descriptor_t *td,
|
|
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
|
+ asn_SEQUENCE_specifics_t *specs
|
|
+ = (asn_SEQUENCE_specifics_t *)td->specifics;
|
|
+ asn_enc_rval_t er;
|
|
+ int n_extensions;
|
|
+ int edx;
|
|
+ int i;
|
|
+
|
|
+ (void)constraints;
|
|
+
|
|
+ if(!sptr)
|
|
+ _ASN_ENCODE_FAILED;
|
|
+
|
|
+ er.encoded = 0;
|
|
+
|
|
+ ASN_DEBUG("Encoding %s as SEQUENCE (APER)", td->name);
|
|
+
|
|
+ /*
|
|
+ * X.691#18.1 Whether structure is extensible
|
|
+ * and whether to encode extensions
|
|
+ */
|
|
+ if(specs->ext_before >= 0) {
|
|
+ n_extensions = SEQUENCE_handle_extensions(td, sptr, 0, 0);
|
|
+ per_put_few_bits(po, n_extensions ? 1 : 0, 1);
|
|
+ } else {
|
|
+ n_extensions = 0; /* There are no extensions to encode */
|
|
+ }
|
|
+
|
|
+ /* Encode a presence bitmap */
|
|
+ for(i = 0; i < specs->roms_count; i++) {
|
|
+ asn_TYPE_member_t *elm;
|
|
+ void *memb_ptr; /* Pointer to the member */
|
|
+ void **memb_ptr2; /* Pointer to that pointer */
|
|
+ int present;
|
|
+
|
|
+ edx = specs->oms[i];
|
|
+ elm = &td->elements[edx];
|
|
+
|
|
+ /* Fetch the pointer to this member */
|
|
+ if(elm->flags & ATF_POINTER) {
|
|
+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
|
|
+ present = (*memb_ptr2 != 0);
|
|
+ } else {
|
|
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
|
+ memb_ptr2 = &memb_ptr;
|
|
+ present = 1;
|
|
+ }
|
|
+
|
|
+ /* Eliminate default values */
|
|
+ if(present && elm->default_value
|
|
+ && elm->default_value(0, memb_ptr2) == 1)
|
|
+ present = 0;
|
|
+
|
|
+ ASN_DEBUG("Element %s %s %s->%s is %s",
|
|
+ elm->flags & ATF_POINTER ? "ptr" : "inline",
|
|
+ elm->default_value ? "def" : "wtv",
|
|
+ td->name, elm->name, present ? "present" : "absent");
|
|
+ if(per_put_few_bits(po, present, 1))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Encode the sequence ROOT elements.
|
|
+ */
|
|
+ ASN_DEBUG("ext_after = %d, ec = %d, eb = %d", specs->ext_after, td->elements_count, specs->ext_before);
|
|
+ for(edx = 0; edx < ((specs->ext_after < 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 */
|
|
+
|
|
+ if(IN_EXTENSION_GROUP(specs, edx))
|
|
+ continue;
|
|
+
|
|
+ ASN_DEBUG("About to encode %s", elm->type->name);
|
|
+
|
|
+ /* Fetch the pointer to this member */
|
|
+ if(elm->flags & ATF_POINTER) {
|
|
+ memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
|
|
+ if(!*memb_ptr2) {
|
|
+ ASN_DEBUG("Element %s %d not present",
|
|
+ elm->name, edx);
|
|
+ if(elm->optional)
|
|
+ continue;
|
|
+ /* Mandatory element is missing */
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+ } else {
|
|
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
|
+ memb_ptr2 = &memb_ptr;
|
|
+ }
|
|
+
|
|
+ /* Eliminate default values */
|
|
+ if(elm->default_value && elm->default_value(0, memb_ptr2) == 1)
|
|
+ continue;
|
|
+
|
|
+ ASN_DEBUG("Encoding %s->%s", td->name, elm->name);
|
|
+ er = elm->type->aper_encoder(elm->type, elm->per_constraints,
|
|
+ *memb_ptr2, po);
|
|
+ if(er.encoded == -1)
|
|
+ return er;
|
|
+ }
|
|
+
|
|
+ /* No extensions to encode */
|
|
+ if(!n_extensions) _ASN_ENCODED_OK(er);
|
|
+
|
|
+ ASN_DEBUG("Length of %d bit-map", n_extensions);
|
|
+ /* #18.8. Write down the presence bit-map length. */
|
|
+ if(aper_put_nslength(po, n_extensions))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+
|
|
+ ASN_DEBUG("Bit-map of %d elements", n_extensions);
|
|
+ /* #18.7. Encoding the extensions presence bit-map. */
|
|
+ /* TODO: act upon NOTE in #18.7 for canonical PER */
|
|
+ if(SEQUENCE_handle_extensions(td, sptr, po, 0) != n_extensions)
|
|
+ _ASN_ENCODE_FAILED;
|
|
+
|
|
+ ASN_DEBUG("Writing %d extensions", n_extensions);
|
|
+ /* #18.9. Encode extensions as open type fields. */
|
|
+ if(SEQUENCE_handle_extensions(td, sptr, 0, po) != n_extensions)
|
|
+ _ASN_ENCODE_FAILED;
|
|
+
|
|
+ _ASN_ENCODED_OK(er);
|
|
+}
|
|
Index: skeletons/INTEGER.h
|
|
===================================================================
|
|
--- skeletons/INTEGER.h (revision 1516)
|
|
+++ skeletons/INTEGER.h (working copy)
|
|
@@ -41,6 +41,8 @@
|
|
xer_type_encoder_f INTEGER_encode_xer;
|
|
per_type_decoder_f INTEGER_decode_uper;
|
|
per_type_encoder_f INTEGER_encode_uper;
|
|
+per_type_decoder_f INTEGER_decode_aper;
|
|
+per_type_encoder_f INTEGER_encode_aper;
|
|
|
|
/***********************************
|
|
* Some handy conversion routines. *
|
|
@@ -52,8 +54,12 @@
|
|
* -1/ERANGE: Value encoded is out of range for long representation
|
|
* -1/ENOMEM: Memory allocation failed (in asn_long2INTEGER()).
|
|
*/
|
|
+int asn_INTEGER2int64(const INTEGER_t *i, int64_t *l);
|
|
+int asn_INTEGER2uint64(const INTEGER_t *i, uint64_t *l);
|
|
int asn_INTEGER2long(const INTEGER_t *i, long *l);
|
|
int asn_INTEGER2ulong(const INTEGER_t *i, unsigned long *l);
|
|
+int asn_int642INTEGER(INTEGER_t *i, int64_t l);
|
|
+int asn_uint642INTEGER(INTEGER_t *i, uint64_t l);
|
|
int asn_long2INTEGER(INTEGER_t *i, long l);
|
|
int asn_ulong2INTEGER(INTEGER_t *i, unsigned long l);
|
|
|
|
Index: skeletons/OCTET_STRING.c
|
|
===================================================================
|
|
--- skeletons/OCTET_STRING.c (revision 1516)
|
|
+++ skeletons/OCTET_STRING.c (working copy)
|
|
@@ -36,6 +36,8 @@
|
|
OCTET_STRING_encode_xer,
|
|
OCTET_STRING_decode_uper, /* Unaligned PER decoder */
|
|
OCTET_STRING_encode_uper, /* Unaligned PER encoder */
|
|
+ OCTET_STRING_decode_aper, /* Aligned PER decoder */
|
|
+ OCTET_STRING_encode_aper, /* Aligned PER encoder */
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_OCTET_STRING_tags,
|
|
sizeof(asn_DEF_OCTET_STRING_tags)
|
|
@@ -86,7 +88,7 @@
|
|
void *ptr; \
|
|
/* Be nice and round to the memory allocator */ \
|
|
do { _ns = _ns ? _ns << 1 : 16; } \
|
|
- while(_ns <= _es); \
|
|
+ while(_ns <= _es); \
|
|
/* int is really a typeof(st->size): */ \
|
|
if((int)_ns < 0) RETURN(RC_FAIL); \
|
|
ptr = REALLOC(st->buf, _ns); \
|
|
@@ -195,7 +197,7 @@
|
|
}
|
|
|
|
/* Restore parsing context */
|
|
- ctx = (asn_struct_ctx_t *)((void *)st + specs->ctx_offset);
|
|
+ ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
|
|
|
|
switch(ctx->phase) {
|
|
case 0:
|
|
@@ -416,7 +418,7 @@
|
|
ASN_DEBUG("Phase 2: Need %ld bytes, size=%ld, alrg=%ld, wn=%d",
|
|
(long)sel->left, (long)size, (long)sel->got,
|
|
sel->want_nulls);
|
|
- {
|
|
+ {
|
|
ber_tlv_len_t len;
|
|
|
|
assert(sel->left >= 0);
|
|
@@ -446,7 +448,7 @@
|
|
|
|
PREV_PHASE(ctx);
|
|
goto phase1;
|
|
- }
|
|
+ }
|
|
break;
|
|
case 3:
|
|
phase3:
|
|
@@ -1143,7 +1145,7 @@
|
|
}
|
|
|
|
/* Restore parsing context */
|
|
- ctx = (asn_struct_ctx_t *)(((void *)*sptr) + specs->ctx_offset);
|
|
+ ctx = (asn_struct_ctx_t *)(((char *)*sptr) + specs->ctx_offset);
|
|
|
|
return xer_decode_general(opt_codec_ctx, ctx, *sptr, xml_tag,
|
|
buf_ptr, size, opt_unexpected_tag_decoder, body_receiver);
|
|
@@ -1392,7 +1394,7 @@
|
|
if(!st) RETURN(RC_FAIL);
|
|
}
|
|
|
|
- ASN_DEBUG("PER Decoding %s size %ld .. %ld bits %d",
|
|
+ ASN_DEBUG("PER Decoding %s size %"PRIdMAX" .. %"PRIdMAX" bits %d",
|
|
csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible",
|
|
csiz->lower_bound, csiz->upper_bound, csiz->effective_bits);
|
|
|
|
@@ -1423,17 +1425,17 @@
|
|
if(csiz->effective_bits == 0) {
|
|
int ret;
|
|
if(bpc) {
|
|
- ASN_DEBUG("Encoding OCTET STRING size %ld",
|
|
+ ASN_DEBUG("Encoding OCTET STRING size %"PRIdMAX,
|
|
csiz->upper_bound);
|
|
ret = OCTET_STRING_per_get_characters(pd, st->buf,
|
|
csiz->upper_bound, bpc, unit_bits,
|
|
cval->lower_bound, cval->upper_bound, pc);
|
|
if(ret > 0) RETURN(RC_FAIL);
|
|
} else {
|
|
- ASN_DEBUG("Encoding BIT STRING size %ld",
|
|
+ ASN_DEBUG("Encoding BIT STRING size %"PRIdMAX,
|
|
csiz->upper_bound);
|
|
ret = per_get_many_bits(pd, st->buf, 0,
|
|
- unit_bits * csiz->upper_bound);
|
|
+ unit_bits * csiz->upper_bound);
|
|
}
|
|
if(ret < 0) RETURN(RC_WMORE);
|
|
consumed_myself += unit_bits * csiz->upper_bound;
|
|
@@ -1492,9 +1494,197 @@
|
|
return rval;
|
|
}
|
|
|
|
+asn_dec_rval_t
|
|
+OCTET_STRING_decode_aper(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_constraints_t *pc = constraints ? constraints
|
|
+ : td->per_constraints;
|
|
+ asn_per_constraint_t *cval;
|
|
+ asn_per_constraint_t *csiz;
|
|
+ asn_dec_rval_t rval = { RC_OK, 0 };
|
|
+ BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
|
|
+ ssize_t consumed_myself = 0;
|
|
+ int repeat;
|
|
+ enum {
|
|
+ OS__BPC_BIT = 0,
|
|
+ OS__BPC_CHAR = 1,
|
|
+ OS__BPC_U16 = 2,
|
|
+ OS__BPC_U32 = 4
|
|
+ } bpc; /* Bytes per character */
|
|
+ unsigned int unit_bits;
|
|
+ unsigned int canonical_unit_bits;
|
|
+
|
|
+ (void)opt_codec_ctx;
|
|
+
|
|
+ if(pc) {
|
|
+ cval = &pc->value;
|
|
+ csiz = &pc->size;
|
|
+ } else {
|
|
+ cval = &asn_DEF_OCTET_STRING_constraints.value;
|
|
+ csiz = &asn_DEF_OCTET_STRING_constraints.size;
|
|
+ }
|
|
+
|
|
+ switch(specs->subvariant) {
|
|
+ default:
|
|
+// case ASN_OSUBV_ANY:
|
|
+// ASN_DEBUG("Unrecognized subvariant %d", specs->subvariant);
|
|
+// RETURN(RC_FAIL);
|
|
+ case ASN_OSUBV_BIT:
|
|
+ canonical_unit_bits = unit_bits = 1;
|
|
+ bpc = OS__BPC_BIT;
|
|
+ break;
|
|
+ case ASN_OSUBV_ANY:
|
|
+ case ASN_OSUBV_STR:
|
|
+ canonical_unit_bits = unit_bits = 8;
|
|
+// if(cval->flags & APC_CONSTRAINED)
|
|
+// unit_bits = cval->range_bits;
|
|
+ bpc = OS__BPC_CHAR;
|
|
+ break;
|
|
+ case ASN_OSUBV_U16:
|
|
+ canonical_unit_bits = unit_bits = 16;
|
|
+ if(cval->flags & APC_CONSTRAINED)
|
|
+ unit_bits = cval->range_bits;
|
|
+ bpc = OS__BPC_U16;
|
|
+ break;
|
|
+ case ASN_OSUBV_U32:
|
|
+ canonical_unit_bits = unit_bits = 32;
|
|
+ if(cval->flags & APC_CONSTRAINED)
|
|
+ unit_bits = cval->range_bits;
|
|
+ bpc = OS__BPC_U32;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Allocate the string.
|
|
+ */
|
|
+ if(!st) {
|
|
+ st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
|
|
+ if(!st) RETURN(RC_FAIL);
|
|
+ }
|
|
+
|
|
+ ASN_DEBUG("PER Decoding %s size %"PRIdMAX" .. %"PRIdMAX" bits %d",
|
|
+ csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible",
|
|
+ csiz->lower_bound, csiz->upper_bound, csiz->effective_bits);
|
|
+
|
|
+ if(csiz->flags & APC_EXTENSIBLE) {
|
|
+ int inext = per_get_few_bits(pd, 1);
|
|
+ if(inext < 0) RETURN(RC_WMORE);
|
|
+ if(inext) {
|
|
+ csiz = &asn_DEF_OCTET_STRING_constraints.size;
|
|
+ cval = &asn_DEF_OCTET_STRING_constraints.value;
|
|
+ unit_bits = canonical_unit_bits;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if(csiz->effective_bits >= 0) {
|
|
+ FREEMEM(st->buf);
|
|
+ if(bpc) {
|
|
+ st->size = csiz->upper_bound * bpc;
|
|
+ } else {
|
|
+ st->size = (csiz->upper_bound + 7) >> 3;
|
|
+ }
|
|
+ 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(csiz->effective_bits == 0) {
|
|
+ int ret;
|
|
+ if (st->size > 2) { /* X.691 #16 NOTE 1 */
|
|
+ if (aper_get_align(pd) < 0)
|
|
+ RETURN(RC_FAIL);
|
|
+ }
|
|
+ if(bpc) {
|
|
+ ASN_DEBUG("Decoding OCTET STRING size %"PRIdMAX,
|
|
+ csiz->upper_bound);
|
|
+ ret = OCTET_STRING_per_get_characters(pd, st->buf,
|
|
+ csiz->upper_bound, bpc, unit_bits,
|
|
+ cval->lower_bound, cval->upper_bound, pc);
|
|
+ if(ret > 0) RETURN(RC_FAIL);
|
|
+ } else {
|
|
+ ASN_DEBUG("Decoding BIT STRING size %"PRIdMAX,
|
|
+ csiz->upper_bound);
|
|
+ ret = per_get_many_bits(pd, st->buf, 0,
|
|
+ unit_bits * csiz->upper_bound);
|
|
+ }
|
|
+ if(ret < 0) RETURN(RC_WMORE);
|
|
+ consumed_myself += unit_bits * csiz->upper_bound;
|
|
+ st->buf[st->size] = 0;
|
|
+ if(bpc == 0) {
|
|
+ int ubs = (csiz->upper_bound & 0x7);
|
|
+ st->bits_unused = ubs ? 8 - ubs : 0;
|
|
+ }
|
|
+ RETURN(RC_OK);
|
|
+ }
|
|
+
|
|
+ st->size = 0;
|
|
+ do {
|
|
+ ssize_t raw_len;
|
|
+ ssize_t len_bytes;
|
|
+ ssize_t len_bits;
|
|
+ void *p;
|
|
+ int ret;
|
|
+
|
|
+ /* Get the PER length */
|
|
+ if (csiz->upper_bound - csiz->lower_bound == 0)
|
|
+ // Indefinite length case
|
|
+ raw_len = aper_get_length(pd, -1, csiz->effective_bits, &repeat);
|
|
+ else
|
|
+ raw_len = aper_get_length(pd, csiz->upper_bound - csiz->lower_bound + 1, csiz->effective_bits, &repeat);
|
|
+ repeat = 0;
|
|
+ if(raw_len < 0) RETURN(RC_WMORE);
|
|
+ raw_len += csiz->lower_bound;
|
|
+
|
|
+ ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)",
|
|
+ (long)csiz->effective_bits, (long)raw_len,
|
|
+ repeat ? "repeat" : "once", td->name);
|
|
+
|
|
+ if (raw_len > 2) { /* X.691 #16 NOTE 1 */
|
|
+ if (aper_get_align(pd) < 0)
|
|
+ RETURN(RC_FAIL);
|
|
+ }
|
|
+
|
|
+ if(bpc) {
|
|
+ len_bytes = raw_len * bpc;
|
|
+ len_bits = len_bytes * unit_bits;
|
|
+ } else {
|
|
+ len_bits = raw_len;
|
|
+ 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 */
|
|
+ }
|
|
+ p = REALLOC(st->buf, st->size + len_bytes + 1);
|
|
+ if(!p) RETURN(RC_FAIL);
|
|
+ st->buf = (uint8_t *)p;
|
|
+
|
|
+ if(bpc) {
|
|
+ ret = OCTET_STRING_per_get_characters(pd,
|
|
+ &st->buf[st->size], raw_len, bpc, unit_bits,
|
|
+ cval->lower_bound, cval->upper_bound, pc);
|
|
+ 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);
|
|
+ st->buf[st->size] = 0; /* nul-terminate */
|
|
+
|
|
+ return rval;
|
|
+}
|
|
+
|
|
asn_enc_rval_t
|
|
OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
|
|
- asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
|
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
|
|
|
asn_OCTET_STRING_specifics_t *specs = td->specifics
|
|
? (asn_OCTET_STRING_specifics_t *)td->specifics
|
|
@@ -1566,7 +1756,7 @@
|
|
}
|
|
|
|
ASN_DEBUG("Encoding %s into %d units of %d bits"
|
|
- " (%ld..%ld, effective %d)%s",
|
|
+ " (%"PRIdMAX"..%"PRIdMAX", effective %d)%s",
|
|
td->name, sizeinunits, unit_bits,
|
|
csiz->lower_bound, csiz->upper_bound,
|
|
csiz->effective_bits, ct_extensible ? " EXT" : "");
|
|
@@ -1598,7 +1788,7 @@
|
|
/* 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(csiz->effective_bits >= 0) {
|
|
- ASN_DEBUG("Encoding %d bytes (%ld), length in %d bits",
|
|
+ ASN_DEBUG("Encoding %d bytes (%"PRIdMAX"), length in %d bits",
|
|
st->size, sizeinunits - csiz->lower_bound,
|
|
csiz->effective_bits);
|
|
ret = per_put_few_bits(po, sizeinunits - csiz->lower_bound,
|
|
@@ -1652,6 +1842,173 @@
|
|
_ASN_ENCODED_OK(er);
|
|
}
|
|
|
|
+asn_enc_rval_t
|
|
+OCTET_STRING_encode_aper(asn_TYPE_descriptor_t *td,
|
|
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
|
+
|
|
+ asn_OCTET_STRING_specifics_t *specs = td->specifics
|
|
+ ? (asn_OCTET_STRING_specifics_t *)td->specifics
|
|
+ : &asn_DEF_OCTET_STRING_specs;
|
|
+ asn_per_constraints_t *pc = constraints ? constraints
|
|
+ : td->per_constraints;
|
|
+ asn_per_constraint_t *cval;
|
|
+ asn_per_constraint_t *csiz;
|
|
+ const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
|
|
+ asn_enc_rval_t er = { 0, 0, 0 };
|
|
+ int inext = 0; /* Lies not within extension root */
|
|
+ unsigned int unit_bits;
|
|
+ unsigned int canonical_unit_bits;
|
|
+ unsigned int sizeinunits;
|
|
+ const uint8_t *buf;
|
|
+ int ret;
|
|
+ enum {
|
|
+ OS__BPC_BIT = 0,
|
|
+ OS__BPC_CHAR = 1,
|
|
+ OS__BPC_U16 = 2,
|
|
+ OS__BPC_U32 = 4
|
|
+ } bpc; /* Bytes per character */
|
|
+ int ct_extensible;
|
|
+
|
|
+ if(!st || (!st->buf && st->size))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+
|
|
+ if(pc) {
|
|
+ cval = &pc->value;
|
|
+ csiz = &pc->size;
|
|
+ } else {
|
|
+ cval = &asn_DEF_OCTET_STRING_constraints.value;
|
|
+ csiz = &asn_DEF_OCTET_STRING_constraints.size;
|
|
+ }
|
|
+ ct_extensible = csiz->flags & APC_EXTENSIBLE;
|
|
+
|
|
+ switch(specs->subvariant) {
|
|
+ default:
|
|
+// case ASN_OSUBV_ANY:
|
|
+// _ASN_ENCODE_FAILED;
|
|
+ case ASN_OSUBV_BIT:
|
|
+ canonical_unit_bits = unit_bits = 1;
|
|
+ bpc = OS__BPC_BIT;
|
|
+ sizeinunits = st->size * 8 - (st->bits_unused & 0x07);
|
|
+ ASN_DEBUG("BIT STRING of %d bits",
|
|
+ sizeinunits);
|
|
+ break;
|
|
+ case ASN_OSUBV_ANY:
|
|
+ case ASN_OSUBV_STR:
|
|
+ canonical_unit_bits = unit_bits = 8;
|
|
+// if(cval->flags & APC_CONSTRAINED)
|
|
+// unit_bits = 8;
|
|
+ bpc = OS__BPC_CHAR;
|
|
+ sizeinunits = st->size;
|
|
+ break;
|
|
+ case ASN_OSUBV_U16:
|
|
+ canonical_unit_bits = unit_bits = 16;
|
|
+ if(cval->flags & APC_CONSTRAINED)
|
|
+ unit_bits = cval->range_bits;
|
|
+ bpc = OS__BPC_U16;
|
|
+ sizeinunits = st->size / 2;
|
|
+ break;
|
|
+ case ASN_OSUBV_U32:
|
|
+ canonical_unit_bits = unit_bits = 32;
|
|
+ if(cval->flags & APC_CONSTRAINED)
|
|
+ unit_bits = cval->range_bits;
|
|
+ bpc = OS__BPC_U32;
|
|
+ sizeinunits = st->size / 4;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ ASN_DEBUG("Encoding %s into %d units of %d bits"
|
|
+ " (%"PRIdMAX"..%"PRIdMAX", effective %d)%s",
|
|
+ td->name, sizeinunits, unit_bits,
|
|
+ csiz->lower_bound, csiz->upper_bound,
|
|
+ csiz->effective_bits, ct_extensible ? " EXT" : "");
|
|
+
|
|
+ /* Figure out wheter size lies within PER visible constraint */
|
|
+
|
|
+ if(csiz->effective_bits >= 0) {
|
|
+ if((int)sizeinunits < csiz->lower_bound
|
|
+ || (int)sizeinunits > csiz->upper_bound) {
|
|
+ if(ct_extensible) {
|
|
+ cval = &asn_DEF_OCTET_STRING_constraints.value;
|
|
+ csiz = &asn_DEF_OCTET_STRING_constraints.size;
|
|
+ unit_bits = canonical_unit_bits;
|
|
+ inext = 1;
|
|
+ } else
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+ } else {
|
|
+ inext = 0;
|
|
+ }
|
|
+
|
|
+
|
|
+ if(ct_extensible) {
|
|
+ /* Declare whether length is [not] within extension root */
|
|
+ if(per_put_few_bits(po, inext, 1))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+
|
|
+ /* 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(csiz->effective_bits >= 0) {
|
|
+ ASN_DEBUG("Encoding %d bytes (%"PRIdMAX"), length in %d bits",
|
|
+ st->size, sizeinunits - csiz->lower_bound,
|
|
+ csiz->effective_bits);
|
|
+ ret = per_put_few_bits(po, sizeinunits - csiz->lower_bound,
|
|
+ csiz->effective_bits);
|
|
+ if(ret) _ASN_ENCODE_FAILED;
|
|
+ if (st->size > 2) { /* X.691 #16 NOTE 1 */
|
|
+ if (aper_put_align(po) < 0)
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+ if(bpc) {
|
|
+ ret = OCTET_STRING_per_put_characters(po, st->buf,
|
|
+ sizeinunits, bpc, unit_bits,
|
|
+ cval->lower_bound, cval->upper_bound, pc);
|
|
+ } else {
|
|
+ ret = per_put_many_bits(po, st->buf,
|
|
+ sizeinunits * unit_bits);
|
|
+ }
|
|
+ if(ret) _ASN_ENCODE_FAILED;
|
|
+ _ASN_ENCODED_OK(er);
|
|
+ }
|
|
+
|
|
+ ASN_DEBUG("Encoding %d bytes", st->size);
|
|
+
|
|
+ if(sizeinunits == 0) {
|
|
+ if(aper_put_length(po, -1, 0))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ _ASN_ENCODED_OK(er);
|
|
+ }
|
|
+
|
|
+ buf = st->buf;
|
|
+ while(sizeinunits) {
|
|
+ ssize_t maySave = aper_put_length(po, -1, sizeinunits);
|
|
+
|
|
+ if(maySave < 0) _ASN_ENCODE_FAILED;
|
|
+
|
|
+ ASN_DEBUG("Encoding %ld of %ld",
|
|
+ (long)maySave, (long)sizeinunits);
|
|
+
|
|
+ if(bpc) {
|
|
+ ret = OCTET_STRING_per_put_characters(po, buf,
|
|
+ maySave, bpc, unit_bits,
|
|
+ cval->lower_bound, cval->upper_bound, pc);
|
|
+ } else {
|
|
+ ret = per_put_many_bits(po, buf, maySave * unit_bits);
|
|
+ }
|
|
+ if(ret) _ASN_ENCODE_FAILED;
|
|
+
|
|
+ if(bpc)
|
|
+ buf += maySave * bpc;
|
|
+ else
|
|
+ buf += maySave >> 3;
|
|
+ sizeinunits -= maySave;
|
|
+ assert(!(maySave & 0x07) || !sizeinunits);
|
|
+ }
|
|
+
|
|
+ _ASN_ENCODED_OK(er);
|
|
+}
|
|
+
|
|
int
|
|
OCTET_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
|
asn_app_consume_bytes_f *cb, void *app_key) {
|
|
@@ -1716,7 +2073,7 @@
|
|
? (asn_OCTET_STRING_specifics_t *)td->specifics
|
|
: &asn_DEF_OCTET_STRING_specs;
|
|
asn_struct_ctx_t *ctx = (asn_struct_ctx_t *)
|
|
- ((void *)st + specs->ctx_offset);
|
|
+ ((char *)st + specs->ctx_offset);
|
|
struct _stack *stck;
|
|
|
|
if(!td || !st)
|
|
Index: skeletons/BIT_STRING.c
|
|
===================================================================
|
|
--- skeletons/BIT_STRING.c (revision 1516)
|
|
+++ skeletons/BIT_STRING.c (working copy)
|
|
@@ -29,6 +29,8 @@
|
|
BIT_STRING_encode_xer,
|
|
OCTET_STRING_decode_uper, /* Unaligned PER decoder */
|
|
OCTET_STRING_encode_uper, /* Unaligned PER encoder */
|
|
+ OCTET_STRING_decode_aper, /* Aligned PER decoder */
|
|
+ OCTET_STRING_encode_aper, /* Aligned PER encoder */
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_BIT_STRING_tags,
|
|
sizeof(asn_DEF_BIT_STRING_tags)
|
|
Index: skeletons/NativeInteger.c
|
|
===================================================================
|
|
--- skeletons/NativeInteger.c (revision 1516)
|
|
+++ skeletons/NativeInteger.c (working copy)
|
|
@@ -31,6 +31,8 @@
|
|
NativeInteger_encode_xer,
|
|
NativeInteger_decode_uper, /* Unaligned PER decoder */
|
|
NativeInteger_encode_uper, /* Unaligned PER encoder */
|
|
+ NativeInteger_decode_aper, /* Aligned PER decoder */
|
|
+ NativeInteger_encode_aper, /* Aligned PER encoder */
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_NativeInteger_tags,
|
|
sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
|
|
@@ -267,6 +269,46 @@
|
|
return rval;
|
|
}
|
|
|
|
+asn_dec_rval_t
|
|
+NativeInteger_decode_aper(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;
|
|
+ long *native = (long *)*sptr;
|
|
+ INTEGER_t tmpint;
|
|
+ void *tmpintptr = &tmpint;
|
|
+ int dynamic = 0;
|
|
+
|
|
+ (void)opt_codec_ctx;
|
|
+ ASN_DEBUG("Decoding NativeInteger %s (APER)", td->name);
|
|
+
|
|
+ if(!native) {
|
|
+ native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
|
|
+ dynamic = 1;
|
|
+ if(!native) _ASN_DECODE_FAILED;
|
|
+ }
|
|
+
|
|
+ memset(&tmpint, 0, sizeof tmpint);
|
|
+ rval = INTEGER_decode_aper(opt_codec_ctx, td, constraints,
|
|
+ &tmpintptr, pd);
|
|
+ if(rval.code == RC_OK) {
|
|
+ if((specs&&specs->field_unsigned)
|
|
+ ? asn_INTEGER2ulong(&tmpint, (unsigned long *)native)
|
|
+ : asn_INTEGER2long(&tmpint, native))
|
|
+ rval.code = RC_FAIL;
|
|
+ else
|
|
+ ASN_DEBUG("NativeInteger %s got value %ld",
|
|
+ td->name, *native);
|
|
+ }
|
|
+ ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
|
|
+ //if (dynamic)
|
|
+ // free(native);
|
|
+
|
|
+ return rval;
|
|
+}
|
|
+
|
|
asn_enc_rval_t
|
|
NativeInteger_encode_uper(asn_TYPE_descriptor_t *td,
|
|
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
|
@@ -291,6 +333,44 @@
|
|
return er;
|
|
}
|
|
|
|
+asn_enc_rval_t
|
|
+NativeInteger_encode_aper(
|
|
+ asn_TYPE_descriptor_t *td,
|
|
+ asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
|
+
|
|
+ asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
|
|
+ asn_enc_rval_t er;
|
|
+ INTEGER_t tmpint;
|
|
+
|
|
+ if(!sptr) _ASN_ENCODE_FAILED;
|
|
+ memset(&tmpint, 0, sizeof(tmpint));
|
|
+
|
|
+ if(specs&&specs->field_unsigned) {
|
|
+ unsigned long native;
|
|
+ native = *(unsigned long *)sptr;
|
|
+
|
|
+ ASN_DEBUG("Encoding NativeInteger %s %lu (APER) (unsigned)", td->name, native);
|
|
+
|
|
+ if(asn_ulong2INTEGER(&tmpint, native))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ } else {
|
|
+ long native;
|
|
+ native = *(long *)sptr;
|
|
+
|
|
+ ASN_DEBUG("Encoding NativeInteger %s %ld (APER) (unsigned)", td->name, native);
|
|
+ if(asn_long2INTEGER(&tmpint, native))
|
|
+ _ASN_ENCODE_FAILED;
|
|
+ }
|
|
+
|
|
+// if((specs&&specs->field_unsigned)
|
|
+// ? asn_ulong2INTEGER(&tmpint, native)
|
|
+// : asn_long2INTEGER(&tmpint, native))
|
|
+// _ASN_ENCODE_FAILED;
|
|
+ er = INTEGER_encode_aper(td, constraints, &tmpint, po);
|
|
+ ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
|
|
+ return er;
|
|
+}
|
|
+
|
|
/*
|
|
* INTEGER specific human-readable output.
|
|
*/
|
|
Index: skeletons/constr_SEQUENCE.h
|
|
===================================================================
|
|
--- skeletons/constr_SEQUENCE.h (revision 1516)
|
|
+++ skeletons/constr_SEQUENCE.h (working copy)
|
|
@@ -52,6 +52,8 @@
|
|
xer_type_encoder_f SEQUENCE_encode_xer;
|
|
per_type_decoder_f SEQUENCE_decode_uper;
|
|
per_type_encoder_f SEQUENCE_encode_uper;
|
|
+per_type_decoder_f SEQUENCE_decode_aper;
|
|
+per_type_encoder_f SEQUENCE_encode_aper;
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
Index: skeletons/NativeInteger.h
|
|
===================================================================
|
|
--- skeletons/NativeInteger.h (revision 1516)
|
|
+++ skeletons/NativeInteger.h (working copy)
|
|
@@ -29,6 +29,8 @@
|
|
xer_type_encoder_f NativeInteger_encode_xer;
|
|
per_type_decoder_f NativeInteger_decode_uper;
|
|
per_type_encoder_f NativeInteger_encode_uper;
|
|
+per_type_decoder_f NativeInteger_decode_aper;
|
|
+per_type_encoder_f NativeInteger_encode_aper;
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
Index: skeletons/OCTET_STRING.h
|
|
===================================================================
|
|
--- skeletons/OCTET_STRING.h (revision 1516)
|
|
+++ skeletons/OCTET_STRING.h (working copy)
|
|
@@ -32,6 +32,8 @@
|
|
xer_type_encoder_f OCTET_STRING_encode_xer_utf8;
|
|
per_type_decoder_f OCTET_STRING_decode_uper;
|
|
per_type_encoder_f OCTET_STRING_encode_uper;
|
|
+per_type_decoder_f OCTET_STRING_decode_aper;
|
|
+per_type_encoder_f OCTET_STRING_encode_aper;
|
|
|
|
/******************************
|
|
* Handy conversion routines. *
|
|
Index: skeletons/UTCTime.c
|
|
===================================================================
|
|
--- skeletons/UTCTime.c (revision 1516)
|
|
+++ skeletons/UTCTime.c (working copy)
|
|
@@ -40,6 +40,8 @@
|
|
UTCTime_encode_xer,
|
|
OCTET_STRING_decode_uper,
|
|
OCTET_STRING_encode_uper,
|
|
+ OCTET_STRING_decode_aper,
|
|
+ OCTET_STRING_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_UTCTime_tags,
|
|
sizeof(asn_DEF_UTCTime_tags)
|
|
Index: skeletons/REAL.c
|
|
===================================================================
|
|
--- skeletons/REAL.c (revision 1516)
|
|
+++ skeletons/REAL.c (working copy)
|
|
@@ -45,6 +45,8 @@
|
|
REAL_encode_xer,
|
|
REAL_decode_uper,
|
|
REAL_encode_uper,
|
|
+ REAL_decode_aper,
|
|
+ REAL_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_REAL_tags,
|
|
sizeof(asn_DEF_REAL_tags) / sizeof(asn_DEF_REAL_tags[0]),
|
|
@@ -361,6 +363,21 @@
|
|
return OCTET_STRING_encode_uper(td, 0, sptr, po);
|
|
}
|
|
|
|
+asn_dec_rval_t
|
|
+REAL_decode_aper(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_aper(opt_codec_ctx, td, 0, sptr, pd);
|
|
+}
|
|
+
|
|
+asn_enc_rval_t
|
|
+REAL_encode_aper(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_aper(td, 0, sptr, po);
|
|
+}
|
|
+
|
|
int
|
|
asn_REAL2double(const REAL_t *st, double *dbl_value) {
|
|
unsigned int octv;
|
|
Index: skeletons/VisibleString.c
|
|
===================================================================
|
|
--- skeletons/VisibleString.c (revision 1516)
|
|
+++ skeletons/VisibleString.c (working copy)
|
|
@@ -29,6 +29,8 @@
|
|
OCTET_STRING_encode_xer_utf8,
|
|
OCTET_STRING_decode_uper,
|
|
OCTET_STRING_encode_uper,
|
|
+ OCTET_STRING_decode_aper,
|
|
+ OCTET_STRING_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_VisibleString_tags,
|
|
sizeof(asn_DEF_VisibleString_tags)
|
|
Index: skeletons/ANY.c
|
|
===================================================================
|
|
--- skeletons/ANY.c (revision 1516)
|
|
+++ skeletons/ANY.c (working copy)
|
|
@@ -21,7 +21,10 @@
|
|
OCTET_STRING_encode_der,
|
|
OCTET_STRING_decode_xer_hex,
|
|
ANY_encode_xer,
|
|
- 0, 0,
|
|
+ OCTET_STRING_decode_uper,
|
|
+ OCTET_STRING_encode_uper,
|
|
+ OCTET_STRING_decode_aper,
|
|
+ OCTET_STRING_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
0, 0, 0, 0,
|
|
0, /* No PER visible constraints */
|
|
@@ -87,6 +90,37 @@
|
|
return 0;
|
|
}
|
|
|
|
+int
|
|
+ANY_fromType_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr) {
|
|
+ uint8_t *buffer = NULL;
|
|
+ ssize_t erval;
|
|
+
|
|
+ if(!st || !td) {
|
|
+ errno = EINVAL;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if(!sptr) {
|
|
+ if(st->buf) FREEMEM(st->buf);
|
|
+ st->size = 0;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ erval = aper_encode_to_new_buffer(td, td->per_constraints, sptr, (void**)&buffer);
|
|
+
|
|
+ if(erval == -1) {
|
|
+ if(buffer) FREEMEM(buffer);
|
|
+ return -1;
|
|
+ }
|
|
+ assert((size_t)erval > 0);
|
|
+
|
|
+ if(st->buf) FREEMEM(st->buf);
|
|
+ st->buf = buffer;
|
|
+ st->size = erval;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
ANY_t *
|
|
ANY_new_fromType(asn_TYPE_descriptor_t *td, void *sptr) {
|
|
ANY_t tmp;
|
|
@@ -111,6 +145,30 @@
|
|
}
|
|
}
|
|
|
|
+ANY_t *
|
|
+ANY_new_fromType_aper(asn_TYPE_descriptor_t *td, void *sptr) {
|
|
+ ANY_t tmp;
|
|
+ ANY_t *st;
|
|
+
|
|
+ if(!td || !sptr) {
|
|
+ errno = EINVAL;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ memset(&tmp, 0, sizeof(tmp));
|
|
+
|
|
+ if(ANY_fromType_aper(&tmp, td, sptr)) return 0;
|
|
+
|
|
+ st = (ANY_t *)CALLOC(1, sizeof(ANY_t));
|
|
+ if(st) {
|
|
+ *st = tmp;
|
|
+ return st;
|
|
+ } else {
|
|
+ FREEMEM(tmp.buf);
|
|
+ return 0;
|
|
+ }
|
|
+}
|
|
+
|
|
int
|
|
ANY_to_type(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
|
|
asn_dec_rval_t rval;
|
|
@@ -138,6 +196,33 @@
|
|
}
|
|
}
|
|
|
|
+int
|
|
+ANY_to_type_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
|
|
+ asn_dec_rval_t rval;
|
|
+ void *newst = 0;
|
|
+
|
|
+ if(!st || !td || !struct_ptr) {
|
|
+ errno = EINVAL;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if(st->buf == 0) {
|
|
+ /* Nothing to convert, make it empty. */
|
|
+ *struct_ptr = (void *)0;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ rval = aper_decode(0, td, (void **)&newst, st->buf, st->size, 0, 0);
|
|
+ if(rval.code == RC_OK) {
|
|
+ *struct_ptr = newst;
|
|
+ return 0;
|
|
+ } else {
|
|
+ /* Remove possibly partially decoded data. */
|
|
+ ASN_STRUCT_FREE(*td, newst);
|
|
+ return -1;
|
|
+ }
|
|
+}
|
|
+
|
|
static int ANY__consume_bytes(const void *buffer, size_t size, void *key) {
|
|
struct _callback_arg *arg = (struct _callback_arg *)key;
|
|
|
|
Index: skeletons/REAL.h
|
|
===================================================================
|
|
--- skeletons/REAL.h (revision 1516)
|
|
+++ skeletons/REAL.h (working copy)
|
|
@@ -21,6 +21,8 @@
|
|
xer_type_encoder_f REAL_encode_xer;
|
|
per_type_decoder_f REAL_decode_uper;
|
|
per_type_encoder_f REAL_encode_uper;
|
|
+per_type_decoder_f REAL_decode_aper;
|
|
+per_type_encoder_f REAL_encode_aper;
|
|
|
|
/***********************************
|
|
* Some handy conversion routines. *
|
|
Index: skeletons/NativeReal.c
|
|
===================================================================
|
|
--- skeletons/NativeReal.c (revision 1516)
|
|
+++ skeletons/NativeReal.c (working copy)
|
|
@@ -32,6 +32,8 @@
|
|
NativeReal_encode_xer,
|
|
NativeReal_decode_uper,
|
|
NativeReal_encode_uper,
|
|
+ NativeReal_decode_aper,
|
|
+ NativeReal_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_NativeReal_tags,
|
|
sizeof(asn_DEF_NativeReal_tags) / sizeof(asn_DEF_NativeReal_tags[0]),
|
|
@@ -123,11 +125,11 @@
|
|
tmp.size = length;
|
|
memcpy(tmp.buf, buf_ptr, length);
|
|
tmp.buf[tmp.size] = '\0';
|
|
- if(asn_REAL2double(&tmp, &d)) {
|
|
- rval.code = RC_FAIL;
|
|
- rval.consumed = 0;
|
|
- return rval;
|
|
- }
|
|
+ if(asn_REAL2double(&tmp, &d)) {
|
|
+ rval.code = RC_FAIL;
|
|
+ rval.consumed = 0;
|
|
+ return rval;
|
|
+ }
|
|
} else {
|
|
/* This should probably never happen: impractically long value */
|
|
tmp.buf = CALLOC(1, length + 1);
|
|
@@ -228,6 +230,43 @@
|
|
return rval;
|
|
}
|
|
|
|
+asn_dec_rval_t
|
|
+NativeReal_decode_aper(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_aper(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.
|
|
*/
|
|
@@ -257,6 +296,32 @@
|
|
return erval;
|
|
}
|
|
|
|
+asn_enc_rval_t
|
|
+NativeReal_encode_aper(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_aper(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.
|
|
*/
|
|
Index: skeletons/asn_system.h
|
|
===================================================================
|
|
--- skeletons/asn_system.h (revision 1516)
|
|
+++ skeletons/asn_system.h (working copy)
|
|
@@ -21,6 +21,11 @@
|
|
#include <stdarg.h> /* For va_start */
|
|
#include <stddef.h> /* for offsetof and ptrdiff_t */
|
|
|
|
+#if HAVE_STDINT_H
|
|
+# include <stdint.h>
|
|
+# include <inttypes.h>
|
|
+#endif
|
|
+
|
|
#ifdef _WIN32
|
|
|
|
#include <malloc.h>
|
|
Index: skeletons/ANY.h
|
|
===================================================================
|
|
--- skeletons/ANY.h (revision 1516)
|
|
+++ skeletons/ANY.h (working copy)
|
|
@@ -32,10 +32,13 @@
|
|
|
|
/* Convert another ASN.1 type into the ANY. This implies DER encoding. */
|
|
int ANY_fromType(ANY_t *, asn_TYPE_descriptor_t *td, void *struct_ptr);
|
|
+int ANY_fromType_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr);
|
|
ANY_t *ANY_new_fromType(asn_TYPE_descriptor_t *td, void *struct_ptr);
|
|
+ANY_t *ANY_new_fromType_aper(asn_TYPE_descriptor_t *td, void *sptr);
|
|
|
|
/* Convert the contents of the ANY type into the specified type. */
|
|
int ANY_to_type(ANY_t *, asn_TYPE_descriptor_t *td, void **struct_ptr);
|
|
+int ANY_to_type_aper(ANY_t *, asn_TYPE_descriptor_t *td, void **struct_ptr);
|
|
|
|
#define ANY_fromBuf(s, buf, size) OCTET_STRING_fromBuf((s), (buf), (size))
|
|
#define ANY_new_fromBuf(buf, size) OCTET_STRING_new_fromBuf( \
|
|
Index: skeletons/NativeReal.h
|
|
===================================================================
|
|
--- skeletons/NativeReal.h (revision 1516)
|
|
+++ skeletons/NativeReal.h (working copy)
|
|
@@ -27,6 +27,8 @@
|
|
xer_type_encoder_f NativeReal_encode_xer;
|
|
per_type_decoder_f NativeReal_decode_uper;
|
|
per_type_encoder_f NativeReal_encode_uper;
|
|
+per_type_decoder_f NativeReal_decode_aper;
|
|
+per_type_encoder_f NativeReal_encode_aper;
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
Index: skeletons/UniversalString.c
|
|
===================================================================
|
|
--- skeletons/UniversalString.c (revision 1516)
|
|
+++ skeletons/UniversalString.c (working copy)
|
|
@@ -35,6 +35,8 @@
|
|
UniversalString_encode_xer, /* Convert into UTF-8 */
|
|
OCTET_STRING_decode_uper,
|
|
OCTET_STRING_encode_uper,
|
|
+ OCTET_STRING_decode_aper,
|
|
+ OCTET_STRING_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_UniversalString_tags,
|
|
sizeof(asn_DEF_UniversalString_tags)
|
|
Index: skeletons/GraphicString.c
|
|
===================================================================
|
|
--- skeletons/GraphicString.c (revision 1516)
|
|
+++ skeletons/GraphicString.c (working copy)
|
|
@@ -24,6 +24,8 @@
|
|
OCTET_STRING_encode_xer, /* Can't expect it to be ASCII/UTF8 */
|
|
OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */
|
|
OCTET_STRING_encode_uper,
|
|
+ OCTET_STRING_decode_aper,
|
|
+ OCTET_STRING_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_GraphicString_tags,
|
|
sizeof(asn_DEF_GraphicString_tags)
|
|
Index: skeletons/GeneralizedTime.c
|
|
===================================================================
|
|
--- skeletons/GeneralizedTime.c (revision 1516)
|
|
+++ skeletons/GeneralizedTime.c (working copy)
|
|
@@ -167,6 +167,8 @@
|
|
GeneralizedTime_encode_xer,
|
|
OCTET_STRING_decode_uper,
|
|
OCTET_STRING_encode_uper,
|
|
+ OCTET_STRING_decode_aper,
|
|
+ OCTET_STRING_encode_aper,
|
|
0, /* Use generic outmost tag fetcher */
|
|
asn_DEF_GeneralizedTime_tags,
|
|
sizeof(asn_DEF_GeneralizedTime_tags)
|
|
Index: libasn1compiler/asn1c_out.h
|
|
===================================================================
|
|
--- libasn1compiler/asn1c_out.h (revision 1516)
|
|
+++ libasn1compiler/asn1c_out.h (working copy)
|
|
@@ -117,16 +117,24 @@
|
|
* Format LONG_MIN according to C90 rules.
|
|
*/
|
|
#define OINT(iv) do { \
|
|
- if(iv == (-2147483647L - 1)) \
|
|
+ if(iv > 4294967295U) \
|
|
+ OUT("%" PRIdASN"ULL", iv); \
|
|
+ else if(iv > 2147483647L) \
|
|
+ OUT("%" PRIdASN"U", iv); \
|
|
+ else if(iv == (-2147483647L - 1)) \
|
|
OUT("(-2147483647L - 1)"); \
|
|
- else \
|
|
+ else \
|
|
OUT("%" PRIdASN, iv); \
|
|
} while(0)
|
|
|
|
#define OINTS(iv) do { \
|
|
- if(iv == (-2147483647L - 1)) \
|
|
+ if(iv > 4294967295U) \
|
|
+ OUT("%" PRIdASN"ULL", iv); \
|
|
+ else if(iv > 2147483647L) \
|
|
+ OUT("%" PRIdASN"U", iv); \
|
|
+ else if(iv == (-2147483647L - 1)) \
|
|
OUT("(-2147483647L - 1)"); \
|
|
- else \
|
|
+ else \
|
|
OUT("% " PRIdASN, iv); \
|
|
} while(0)
|
|
|
|
Index: libasn1compiler/asn1compiler.h
|
|
===================================================================
|
|
--- libasn1compiler/asn1compiler.h (revision 1516)
|
|
+++ libasn1compiler/asn1compiler.h (working copy)
|
|
@@ -77,7 +77,14 @@
|
|
* -fline-refs
|
|
* Include ASN.1 module's line numbers in comments.
|
|
*/
|
|
- A1C_LINE_REFS = 0x20000
|
|
+ A1C_LINE_REFS = 0x20000,
|
|
+ /*
|
|
+ * -fhave_native64
|
|
+ * Assume target platform has native 64bits support and generate types using
|
|
+ * int64_t or uint64_t whereas possible
|
|
+ */
|
|
+ A1C_HAVE_NATIVE_64 = 0x40000
|
|
+
|
|
};
|
|
|
|
/*
|
|
Index: libasn1compiler/asn1c_C.c
|
|
===================================================================
|
|
--- libasn1compiler/asn1c_C.c (revision 1516)
|
|
+++ libasn1compiler/asn1c_C.c (working copy)
|
|
@@ -1242,6 +1242,8 @@
|
|
OUT("td->xer_encoder = asn_DEF_%s.xer_encoder;\n", type_name);
|
|
OUT("td->uper_decoder = asn_DEF_%s.uper_decoder;\n", type_name);
|
|
OUT("td->uper_encoder = asn_DEF_%s.uper_encoder;\n", type_name);
|
|
+ OUT("td->aper_decoder = asn_DEF_%s.aper_decoder;\n", type_name);
|
|
+ OUT("td->aper_encoder = asn_DEF_%s.aper_encoder;\n", type_name);
|
|
if(!terminal && !tags_count) {
|
|
OUT("/* The next four lines are here because of -fknown-extern-type */\n");
|
|
OUT("td->tags = asn_DEF_%s.tags;\n", type_name);
|
|
@@ -1394,6 +1396,38 @@
|
|
);
|
|
OUT("}\n");
|
|
OUT("\n");
|
|
+
|
|
+ p = MKID(expr);
|
|
+ if(HIDE_INNER_DEFS) OUT("static ");
|
|
+ OUT("asn_enc_rval_t\n");
|
|
+ OUT("%s", p);
|
|
+ if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index);
|
|
+ OUT("_encode_aper(asn_TYPE_descriptor_t *td,\n");
|
|
+ INDENTED(
|
|
+ OUT("\tasn_per_constraints_t *constraints,\n");
|
|
+ OUT("\tvoid *structure, asn_per_outp_t *per_out) {\n");
|
|
+ OUT("%s_%d_inherit_TYPE_descriptor(td);\n",
|
|
+ p, expr->_type_unique_index);
|
|
+ OUT("return td->aper_encoder(td, constraints, structure, per_out);\n");
|
|
+ );
|
|
+ OUT("}\n");
|
|
+ OUT("\n");
|
|
+
|
|
+ p = MKID(expr);
|
|
+
|
|
+ if(HIDE_INNER_DEFS) OUT("static ");
|
|
+ OUT("asn_dec_rval_t\n");
|
|
+ OUT("%s", p);
|
|
+ if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index);
|
|
+ OUT("_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,\n");
|
|
+ INDENTED(
|
|
+ OUT("\tasn_per_constraints_t *constraints, void **structure, asn_per_data_t *per_data) {\n");
|
|
+ OUT("%s_%d_inherit_TYPE_descriptor(td);\n",
|
|
+ p, expr->_type_unique_index);
|
|
+ OUT("return td->aper_decoder(opt_codec_ctx, td, constraints, structure, per_data);\n");
|
|
+ );
|
|
+ OUT("}\n");
|
|
+ OUT("\n");
|
|
}
|
|
|
|
REDIR(OT_FUNC_DECLS);
|
|
@@ -1415,6 +1449,8 @@
|
|
if(arg->flags & A1C_GEN_PER) {
|
|
OUT("per_type_decoder_f %s_decode_uper;\n", p);
|
|
OUT("per_type_encoder_f %s_encode_uper;\n", p);
|
|
+ OUT("per_type_decoder_f %s_decode_aper;\n", p);
|
|
+ OUT("per_type_encoder_f %s_encode_aper;\n", p);
|
|
}
|
|
}
|
|
|
|
@@ -1670,12 +1706,11 @@
|
|
OUT("%d, ", tag2el[i].el_no);
|
|
OUT("%d, ", tag2el[i].toff_first);
|
|
OUT("%d ", tag2el[i].toff_last);
|
|
- OUT("}%s /* %s",
|
|
+ OUT("}%s /* %s at %d */\n",
|
|
(i + 1 < tag2el_count) ? "," : "",
|
|
- tag2el[i].from_expr->Identifier);
|
|
- if(arg->flags & A1C_LINE_REFS)
|
|
- OUT("at %d", tag2el[i].from_expr->_lineno);
|
|
- OUT(" */\n");
|
|
+ tag2el[i].from_expr->Identifier,
|
|
+ tag2el[i].from_expr->_lineno
|
|
+ );
|
|
}
|
|
OUT("};\n");
|
|
|
|
@@ -2111,19 +2146,22 @@
|
|
try_inline_default(arg_t *arg, asn1p_expr_t *expr, int out) {
|
|
int save_target = arg->target->target;
|
|
asn1p_expr_type_e etype = expr_get_type(arg, expr);
|
|
- int fits_long = 0;
|
|
+// int fits_long = 0;
|
|
+ enum asn1c_fitslong_e fits = FL_NOTFIT;
|
|
|
|
switch(etype) {
|
|
case ASN_BASIC_BOOLEAN:
|
|
- fits_long = 1;
|
|
+// fits_long = 1;
|
|
+ fits = FL_FITS_SIGNED;
|
|
case ASN_BASIC_INTEGER:
|
|
case ASN_BASIC_ENUMERATED:
|
|
if(expr->marker.default_value == NULL
|
|
|| expr->marker.default_value->type != ATV_INTEGER)
|
|
break;
|
|
- if(!fits_long)
|
|
- fits_long = asn1c_type_fits_long(arg, expr)!=FL_NOTFIT;
|
|
- if(fits_long && !expr->marker.default_value->value.v_integer)
|
|
+ if(fits == FL_NOTFIT)
|
|
+// fits_long = asn1c_type_fits_long(arg, expr)!=FL_NOTFIT;
|
|
+ fits = asn1c_type_fits_long(arg, expr);
|
|
+ if(fits != FL_NOTFIT && !expr->marker.default_value->value.v_integer)
|
|
expr->marker.flags &= ~EM_INDIRECT;
|
|
if(!out) {
|
|
OUT("asn_DFL_%d_set_%" PRIdASN
|
|
@@ -2150,7 +2188,7 @@
|
|
INDENT(+1);
|
|
OUT("/* Install default value %" PRIdASN " */\n",
|
|
expr->marker.default_value->value.v_integer);
|
|
- if(fits_long) {
|
|
+ if(fits != FL_NOTFIT) {
|
|
OUT("*st = ");
|
|
OINT(expr->marker.default_value->value.v_integer);
|
|
OUT(";\n");
|
|
@@ -2165,7 +2203,7 @@
|
|
INDENT(+1);
|
|
OUT("/* Test default value %" PRIdASN " */\n",
|
|
expr->marker.default_value->value.v_integer);
|
|
- if(fits_long) {
|
|
+ if(fits != FL_NOTFIT) {
|
|
OUT("return (*st == %" PRIdASN ");\n",
|
|
expr->marker.default_value->value.v_integer);
|
|
} else {
|
|
@@ -2455,9 +2493,13 @@
|
|
if(arg->flags & A1C_GEN_PER) {
|
|
FUNCREF(decode_uper);
|
|
FUNCREF(encode_uper);
|
|
+ FUNCREF(decode_aper);
|
|
+ FUNCREF(encode_aper);
|
|
} else {
|
|
- OUT("0, 0,\t/* No PER support, "
|
|
+ OUT("0, 0,\t/* No UPER support, "
|
|
"use \"-gen-PER\" to enable */\n");
|
|
+ OUT("0, 0,\t/* No APER support, "
|
|
+ "use \"-gen-PER\" to enable */\n");
|
|
}
|
|
|
|
if(!terminal || terminal->expr_type == ASN_CONSTR_CHOICE) {
|
|
Index: libasn1compiler/asn1c_constraint.c
|
|
===================================================================
|
|
--- libasn1compiler/asn1c_constraint.c (revision 1516)
|
|
+++ libasn1compiler/asn1c_constraint.c (working copy)
|
|
@@ -35,6 +35,7 @@
|
|
int alphabet_table_compiled;
|
|
int produce_st = 0;
|
|
int ulong_optimize = 0;
|
|
+ enum asn1c_fitslong_e fits = FL_NOTFIT;
|
|
|
|
ct = expr->combined_constraints;
|
|
if(ct == NULL)
|
|
@@ -74,7 +75,8 @@
|
|
switch(etype) {
|
|
case ASN_BASIC_INTEGER:
|
|
case ASN_BASIC_ENUMERATED:
|
|
- if(asn1c_type_fits_long(arg, arg->expr) == FL_NOTFIT)
|
|
+ fits = asn1c_type_fits_long(arg, arg->expr);
|
|
+ if(fits == FL_NOTFIT)
|
|
produce_st = 1;
|
|
break;
|
|
case ASN_BASIC_REAL:
|
|
@@ -103,13 +105,19 @@
|
|
switch(etype) {
|
|
case ASN_BASIC_INTEGER:
|
|
case ASN_BASIC_ENUMERATED:
|
|
- if(native_long_sign(r_value) >= 0) {
|
|
- ulong_optimize = ulong_optimization(etype, r_size, r_value);
|
|
- if(!ulong_optimize) {
|
|
- OUT("unsigned long value;\n");
|
|
+ if(fits == FL_FITS_INT64) {
|
|
+ OUT("int64_t value;\n");
|
|
+ } else if(fits == FL_FITS_UINT64) {
|
|
+ OUT("uint64_t value;\n");
|
|
+ } else {
|
|
+ if(native_long_sign(r_value) >= 0) {
|
|
+ ulong_optimize = ulong_optimization(etype, r_size, r_value);
|
|
+ if(!ulong_optimize) {
|
|
+ OUT("unsigned long value;\n");
|
|
+ }
|
|
+ } else {
|
|
+ OUT("long value;\n");
|
|
}
|
|
- } else {
|
|
- OUT("long value;\n");
|
|
}
|
|
break;
|
|
case ASN_BASIC_REAL:
|
|
@@ -603,13 +611,19 @@
|
|
|
|
static int
|
|
emit_value_determination_code(arg_t *arg, asn1p_expr_type_e etype, asn1cnst_range_t *r_value) {
|
|
+ enum asn1c_fitslong_e fits = FL_NOTFIT;
|
|
|
|
switch(etype) {
|
|
case ASN_BASIC_INTEGER:
|
|
case ASN_BASIC_ENUMERATED:
|
|
- if(asn1c_type_fits_long(arg, arg->expr) == FL_FITS_UNSIGN) {
|
|
+ fits = asn1c_type_fits_long(arg, arg->expr);
|
|
+ if(fits == FL_FITS_INT64) {
|
|
+ OUT("value = *(const int64_t *)sptr;\n");
|
|
+ } else if(fits == FL_FITS_UINT64) {
|
|
+ OUT("value = *(const uint64_t *)sptr;\n");
|
|
+ } else if(fits == FL_FITS_UNSIGN) {
|
|
OUT("value = *(const unsigned long *)sptr;\n");
|
|
- } else if(asn1c_type_fits_long(arg, arg->expr) != FL_NOTFIT) {
|
|
+ } else if(fits != FL_NOTFIT) {
|
|
OUT("value = *(const long *)sptr;\n");
|
|
} else {
|
|
/*
|
|
Index: libasn1compiler/asn1c_misc.c
|
|
===================================================================
|
|
--- libasn1compiler/asn1c_misc.c (revision 1516)
|
|
+++ libasn1compiler/asn1c_misc.c (working copy)
|
|
@@ -158,6 +158,7 @@
|
|
asn1p_expr_t *terminal;
|
|
int stdname = 0;
|
|
char *typename;
|
|
+ enum asn1c_fitslong_e fits;
|
|
|
|
/* Rewind to the topmost parent expression */
|
|
if((top_parent = expr->parent_expr))
|
|
@@ -213,15 +214,20 @@
|
|
case ASN_BASIC_INTEGER:
|
|
case ASN_BASIC_ENUMERATED:
|
|
case ASN_BASIC_REAL:
|
|
+ fits = asn1c_type_fits_long(arg, expr);
|
|
if((expr->expr_type == ASN_BASIC_REAL
|
|
&& !(arg->flags & A1C_USE_WIDE_TYPES))
|
|
- || asn1c_type_fits_long(arg, expr)) {
|
|
+ || (fits != FL_NOTFIT)) {
|
|
switch(_format) {
|
|
case TNF_CTYPE:
|
|
case TNF_RSAFE:
|
|
if(expr->expr_type == ASN_BASIC_REAL)
|
|
return "double";
|
|
- else if(asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN)
|
|
+ else if (fits == FL_FITS_INT64)
|
|
+ return "int64_t";
|
|
+ else if (fits == FL_FITS_UINT64)
|
|
+ return "uint64_t";
|
|
+ else if(fits == FL_FITS_UNSIGN)
|
|
return "unsigned long";
|
|
else
|
|
return "long";
|
|
@@ -377,11 +383,33 @@
|
|
/* Special case for unsigned */
|
|
if(left.type == ARE_VALUE
|
|
&& left.value >= 0
|
|
- && right.type == ARE_VALUE
|
|
+ && right.type == ARE_VALUE
|
|
&& right.value > 2147483647
|
|
&& right.value <= 4294967295UL)
|
|
return FL_FITS_UNSIGN;
|
|
-
|
|
+ /* Special for native 64 bits integer option */
|
|
+ if (arg->flags & A1C_HAVE_NATIVE_64) {
|
|
+// printf("left.value %lld right.value %lld\n", left.value, right.value);
|
|
+ if(left.type == ARE_VALUE
|
|
+ && left.value >= 0
|
|
+ && right.type == ARE_VALUE
|
|
+ && right.value > 9223372036854775807LL
|
|
+ && right.value <= 18446744073709551615ULL)
|
|
+ return FL_FITS_UINT64;
|
|
+ if(left.type == ARE_VALUE
|
|
+ && left.value < -2147483648
|
|
+ && left.value >= -9223372036854775808LL
|
|
+ && right.type == ARE_VALUE
|
|
+ && right.value > 2147483647
|
|
+ && right.value <= 9223372036854775807LL)
|
|
+ return FL_FITS_INT64;
|
|
+ if(left.type == ARE_VALUE
|
|
+ && left.value >= 0
|
|
+ && right.type == ARE_VALUE
|
|
+ && right.value > 4294967295UL
|
|
+ && right.value <= 9223372036854775807LL)
|
|
+ return FL_FITS_INT64;
|
|
+ }
|
|
|
|
/* If some fixed value is outside of target range, not fit */
|
|
if(left.type == ARE_VALUE
|
|
Index: libasn1compiler/asn1c_misc.h
|
|
===================================================================
|
|
--- libasn1compiler/asn1c_misc.h (revision 1516)
|
|
+++ libasn1compiler/asn1c_misc.h (working copy)
|
|
@@ -36,6 +36,8 @@
|
|
*/
|
|
enum asn1c_fitslong_e {
|
|
FL_NOTFIT,
|
|
+ FL_FITS_INT64,
|
|
+ FL_FITS_UINT64,
|
|
FL_FITS_SIGNED,
|
|
FL_FITS_UNSIGN,
|
|
FL_PRESUMED,
|