BIT STRING decode for OER
diff --git a/examples/sample.source.1609.2/Makefile b/examples/sample.source.1609.2/Makefile
index b57dc68..43b9620 100644
--- a/examples/sample.source.1609.2/Makefile
+++ b/examples/sample.source.1609.2/Makefile
@@ -288,6 +288,7 @@
ASN_MODULE_SOURCES+=constr_SEQUENCE_oer.c
ASN_MODULE_SOURCES+=constr_CHOICE_oer.c
ASN_MODULE_SOURCES+=constr_SET_OF_oer.c
+ASN_MODULE_SOURCES+=BIT_STRING_oer.c
ASN_CONVERTER_SOURCES+=pdu_collection.c
diff --git a/skeletons/BIT_STRING.c b/skeletons/BIT_STRING.c
index 7e9b82c..3eabf0c 100644
--- a/skeletons/BIT_STRING.c
+++ b/skeletons/BIT_STRING.c
@@ -30,8 +30,8 @@
0,
0,
#else
- 0,
- 0,
+ BIT_STRING_decode_oer,
+ BIT_STRING_encode_oer,
#endif /* ASN_DISABLE_OER_SUPPORT */
#ifdef ASN_DISABLE_PER_SUPPORT
0,
diff --git a/skeletons/BIT_STRING.h b/skeletons/BIT_STRING.h
index ed3d108..2b19584 100644
--- a/skeletons/BIT_STRING.h
+++ b/skeletons/BIT_STRING.h
@@ -28,6 +28,8 @@
asn_struct_compare_f BIT_STRING_compare;
asn_constr_check_f BIT_STRING_constraint;
xer_type_encoder_f BIT_STRING_encode_xer;
+oer_type_decoder_f BIT_STRING_decode_oer;
+oer_type_encoder_f BIT_STRING_encode_oer;
#define BIT_STRING_free OCTET_STRING_free
#define BIT_STRING_decode_ber OCTET_STRING_decode_ber
diff --git a/skeletons/BIT_STRING_oer.c b/skeletons/BIT_STRING_oer.c
new file mode 100644
index 0000000..55cee4a
--- /dev/null
+++ b/skeletons/BIT_STRING_oer.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef ASN_DISABLE_OER_SUPPORT
+
+#include <asn_internal.h>
+#include <BIT_STRING.h>
+#include <errno.h>
+
+asn_dec_rval_t
+BIT_STRING_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ const asn_oer_constraints_t *constraints, void **sptr,
+ const void *ptr, size_t size) {
+ BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
+ const asn_oer_constraints_t *cts =
+ constraints ? constraints : td->oer_constraints;
+ ssize_t ct_size = cts ? cts->size : -1;
+ asn_dec_rval_t rval = {RC_OK, 0};
+ size_t expected_length = 0;
+
+ (void)opt_codec_ctx;
+
+ if(!st) {
+ st = (BIT_STRING_t *)(*sptr = CALLOC(1, sizeof(*st)));
+ if(!st) ASN__DECODE_FAILED;
+ }
+
+ if(ct_size >= 0) {
+ expected_length = (ct_size + 7) >> 3;
+ st->bits_unused = (8 - (ct_size & 7)) & 7;
+ } else {
+ /*
+ * X.696 (08/2015) #13.3.1
+ * Encode length determinant as _number of octets_, but only
+ * if upper bound is not equal to lower bound.
+ */
+ ssize_t len_len = oer_fetch_length(ptr, size, &expected_length);
+ if(len_len > 0) {
+ ptr = (const char *)ptr + len_len;
+ size -= len_len;
+ } else if(len_len == 0) {
+ ASN__DECODE_STARVED;
+ } else if(len_len < 0) {
+ ASN__DECODE_FAILED;
+ }
+
+ if(expected_length < 1) {
+ ASN__DECODE_STARVED;
+ }
+
+ st->bits_unused = ((const uint8_t *)ptr)[0];
+ if(st->bits_unused & ~7) {
+ ASN_DEBUG("%s: unused bits outside of 0..7 range", td->name);
+ ASN__DECODE_FAILED;
+ }
+ ptr = (const char *)ptr + 1;
+ size--;
+ expected_length--;
+ rval.consumed = len_len + 1;
+ }
+
+ if(size < expected_length) {
+ ASN__DECODE_STARVED;
+ } else {
+ uint8_t *buf = MALLOC(expected_length + 1);
+ if(buf == NULL) {
+ ASN__DECODE_FAILED;
+ } else {
+ memcpy(buf, ptr, expected_length);
+ buf[expected_length] = '\0';
+ }
+ FREEMEM(st->buf);
+ st->buf = buf;
+ st->size = expected_length;
+ if(expected_length > 0) {
+ buf[expected_length - 1] &= (0xff << st->bits_unused);
+ }
+
+ rval.consumed += expected_length;
+ return rval;
+ }
+}
+
+/*
+ * Encode as Canonical OER.
+ */
+asn_enc_rval_t
+BIT_STRING_encode_oer(asn_TYPE_descriptor_t *td,
+ const asn_oer_constraints_t *constraints, void *sptr,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t er = {-1,td,sptr};
+ (void)constraints;
+ (void)cb;
+ (void)app_key;
+ return er;
+}
+
+
+#endif /* ASN_DISABLE_OER_SUPPORT */
diff --git a/skeletons/Makefile.am b/skeletons/Makefile.am
index 4b36622..d61c66c 100644
--- a/skeletons/Makefile.am
+++ b/skeletons/Makefile.am
@@ -24,6 +24,7 @@
libasn1cskeletons_la_SOURCES = \
ANY.c ANY.h \
BIT_STRING.c BIT_STRING.h \
+ BIT_STRING_oer.c \
BMPString.c BMPString.h \
BOOLEAN.c BOOLEAN.h \
ENUMERATED.c ENUMERATED.h \
diff --git a/skeletons/constr_SEQUENCE_oer.c b/skeletons/constr_SEQUENCE_oer.c
index 85566a3..5b2a0bd 100644
--- a/skeletons/constr_SEQUENCE_oer.c
+++ b/skeletons/constr_SEQUENCE_oer.c
@@ -54,10 +54,16 @@
/*
* Return pointer to a member.
*/
-static void **element_ptrptr(void *struct_ptr, asn_TYPE_member_t *elm) {
- assert(elm->flags & ATF_POINTER);
- /* Member is a pointer to another structure */
- return (void **)((char *)struct_ptr + elm->memb_offset);
+static void **
+element_ptrptr(void *struct_ptr, asn_TYPE_member_t *elm, void **tmp_save_ptr) {
+ if(elm->flags & ATF_POINTER) {
+ /* Member is a pointer to another structure */
+ return (void **)((char *)struct_ptr + elm->memb_offset);
+ } else {
+ assert(tmp_save_ptr);
+ *tmp_save_ptr = (void *)((char *)struct_ptr + elm->memb_offset);
+ return tmp_save_ptr;
+ }
}
static void *element_ptr(void *struct_ptr, asn_TYPE_member_t *elm) {
@@ -172,7 +178,9 @@
} else if(present == 0) {
if(elm->default_value) {
/* Fill-in DEFAULT */
- if(elm->default_value(1, element_ptrptr(st, elm))) {
+ void *tmp;
+ if(elm->default_value(1,
+ element_ptrptr(st, elm, &tmp))) {
RETURN(RC_FAIL);
}
}
@@ -306,7 +314,7 @@
asn_bit_data_t *extadds = ctx->ptr;
size_t edx = ctx->step;
asn_TYPE_member_t *elm = &td->elements[edx];
- void **memb_ptr2 = element_ptrptr(st, elm);
+ void **memb_ptr2 = element_ptrptr(st, elm, 0);
switch(asn_get_few_bits(extadds, 1)) {
case -1:
diff --git a/skeletons/file-dependencies b/skeletons/file-dependencies
index 6a9e135..8814d68 100644
--- a/skeletons/file-dependencies
+++ b/skeletons/file-dependencies
@@ -79,5 +79,6 @@
constr_SEQUENCE_oer.c
constr_CHOICE_oer.c
constr_SET_OF_oer.c constr_SET_OF.h asn_SET_OF.h asn_SET_OF.c
+BIT_STRING_oer.c
CODEC-PER: # THIS IS A SPECIAL SECTION