OBJECT IDENTIFIER and RELATIVE-OID API simplified
diff --git a/skeletons/RELATIVE-OID.c b/skeletons/RELATIVE-OID.c
index 33bfd4a..3eb2276 100644
--- a/skeletons/RELATIVE-OID.c
+++ b/skeletons/RELATIVE-OID.c
@@ -58,31 +58,38 @@
static ssize_t
RELATIVE_OID__dump_body(const RELATIVE_OID_t *st, asn_app_consume_bytes_f *cb, void *app_key) {
- ssize_t wrote = 0;
- ssize_t ret;
- size_t startn;
- size_t i;
+ char scratch[32];
+ size_t produced = 0;
+ size_t off = 0;
- for(i = 0, startn = 0; i < st->size; i++) {
- uint8_t b = st->buf[i];
- if((b & 0x80)) /* Continuation expected */
- continue;
- if(startn) {
- /* Separate arcs */
- if(cb(".", 1, app_key) < 0)
- return -1;
- wrote++;
- }
+ for(;;) {
+ asn_oid_arc_t arc;
+ ssize_t rd = OBJECT_IDENTIFIER_get_single_arc(st->buf + off,
+ st->size - off, &arc);
+ if(rd < 0) {
+ return -1;
+ } else if(rd == 0) {
+ /* No more arcs. */
+ break;
+ } else {
+ int ret = snprintf(scratch, sizeof(scratch), "%s%" PRIu32,
+ off ? "." : "", arc);
+ if(ret >= (ssize_t)sizeof(scratch)) {
+ return -1;
+ }
+ produced += ret;
+ off += rd;
+ assert(off <= st->size);
+ if(cb(scratch, ret, app_key) < 0) return -1;
+ }
+ }
- ret = OBJECT_IDENTIFIER__dump_arc(&st->buf[startn],
- i - startn + 1, 0, cb, app_key);
- if(ret < 0) return -1;
- wrote += ret;
+ if(off != st->size) {
+ ASN_DEBUG("Could not scan to the end of Object Identifier");
+ return -1;
+ }
- startn = i + 1;
- }
-
- return wrote;
+ return produced;
}
int
@@ -111,41 +118,41 @@
RELATIVE_OID_t *st = (RELATIVE_OID_t *)sptr;
const char *chunk_end = (const char *)chunk_buf + chunk_size;
const char *endptr;
- long s_arcs[6];
- long *arcs = s_arcs;
- int arcs_count;
+ asn_oid_arc_t s_arcs[6];
+ asn_oid_arc_t *arcs = s_arcs;
+ ssize_t num_arcs;
int ret;
(void)td;
- arcs_count = OBJECT_IDENTIFIER_parse_arcs(
- (const char *)chunk_buf, chunk_size,
- arcs, sizeof(s_arcs)/sizeof(s_arcs[0]), &endptr);
- if(arcs_count < 0) {
- /* Expecting at least one arc arcs */
- return XPBD_BROKEN_ENCODING;
- } else if(arcs_count == 0) {
- return XPBD_NOT_BODY_IGNORE;
- }
- assert(endptr == chunk_end);
+ num_arcs = OBJECT_IDENTIFIER_parse_arcs(
+ (const char *)chunk_buf, chunk_size, arcs,
+ sizeof(s_arcs) / sizeof(s_arcs[0]), &endptr);
+ if(num_arcs < 0) {
+ /* Expecting at least one arc arcs */
+ return XPBD_BROKEN_ENCODING;
+ } else if(num_arcs == 0) {
+ return XPBD_NOT_BODY_IGNORE;
+ }
+ assert(endptr == chunk_end);
- if((size_t)arcs_count > sizeof(s_arcs)/sizeof(s_arcs[0])) {
- arcs = (long *)MALLOC(arcs_count * sizeof(long));
- if(!arcs) return XPBD_SYSTEM_FAILURE;
- ret = OBJECT_IDENTIFIER_parse_arcs(
- (const char *)chunk_buf, chunk_size,
- arcs, arcs_count, &endptr);
- if(ret != arcs_count)
- return XPBD_SYSTEM_FAILURE; /* assert?.. */
- }
+ if((size_t)num_arcs > sizeof(s_arcs) / sizeof(s_arcs[0])) {
+ arcs = (asn_oid_arc_t *)MALLOC(num_arcs * sizeof(arcs[0]));
+ if(!arcs) return XPBD_SYSTEM_FAILURE;
+ ret = OBJECT_IDENTIFIER_parse_arcs((const char *)chunk_buf, chunk_size,
+ arcs, num_arcs, &endptr);
+ if(ret != num_arcs) {
+ return XPBD_SYSTEM_FAILURE; /* assert?.. */
+ }
+ }
- /*
- * Convert arcs into BER representation.
- */
- ret = RELATIVE_OID_set_arcs(st, arcs, sizeof(*arcs), arcs_count);
- if(arcs != s_arcs) FREEMEM(arcs);
+ /*
+ * Convert arcs into BER representation.
+ */
+ ret = RELATIVE_OID_set_arcs(st, arcs, num_arcs);
+ if(arcs != s_arcs) FREEMEM(arcs);
- return ret ? XPBD_SYSTEM_FAILURE : XPBD_BODY_CONSUMED;
+ return ret ? XPBD_SYSTEM_FAILURE : XPBD_BODY_CONSUMED;
}
asn_dec_rval_t
@@ -177,48 +184,51 @@
ASN__ENCODED_OK(er);
}
-int
-RELATIVE_OID_get_arcs(const RELATIVE_OID_t *roid,
- void *arcs, unsigned int arc_type_size, unsigned int arc_slots) {
- void *arcs_end = (char *)arcs + (arc_slots * arc_type_size);
- int num_arcs = 0;
- size_t startn = 0;
- size_t i;
+ssize_t
+RELATIVE_OID_get_arcs(const RELATIVE_OID_t *st, asn_oid_arc_t *arcs,
+ size_t arcs_count) {
+ size_t num_arcs = 0;
+ size_t off;
- if(!roid || !roid->buf) {
- errno = EINVAL;
- return -1;
- }
+ if(!st || !st->buf) {
+ errno = EINVAL;
+ return -1;
+ }
- for(i = 0; i < roid->size; i++) {
- uint8_t b = roid->buf[i];
- if((b & 0x80)) /* Continuation expected */
- continue;
+ for(off = 0;;) {
+ asn_oid_arc_t arc;
+ ssize_t rd = OBJECT_IDENTIFIER_get_single_arc(st->buf + off,
+ st->size - off, &arc);
+ if(rd < 0) {
+ return -1;
+ } else if(rd == 0) {
+ /* No more arcs. */
+ break;
+ } else {
+ off += rd;
+ if(num_arcs < arcs_count) {
+ arcs[num_arcs] = arc;
+ }
+ num_arcs++;
+ }
+ }
- if(arcs < arcs_end) {
- if(OBJECT_IDENTIFIER_get_single_arc(
- &roid->buf[startn],
- i - startn + 1, 0,
- arcs, arc_type_size))
- return -1;
- arcs = ((char *)arcs) + arc_type_size;
- num_arcs++;
- }
-
- startn = i + 1;
- }
+ if(off != st->size) {
+ return -1;
+ }
return num_arcs;
}
int
-RELATIVE_OID_set_arcs(RELATIVE_OID_t *roid, void *arcs, unsigned int arc_type_size, unsigned int arcs_slots) {
- uint8_t *buf;
+RELATIVE_OID_set_arcs(RELATIVE_OID_t *st, const asn_oid_arc_t *arcs,
+ size_t arcs_count) {
+ uint8_t *buf;
uint8_t *bp;
- unsigned int size;
- unsigned int i;
+ size_t size;
+ size_t i;
- if(roid == NULL || arcs == NULL || arc_type_size < 1) {
+ if(!st || !arcs) {
errno = EINVAL;
return -1;
}
@@ -226,8 +236,8 @@
/*
* Roughly estimate the maximum size necessary to encode these arcs.
*/
- size = ((arc_type_size * CHAR_BIT + 6) / 7) * arcs_slots;
- bp = buf = (uint8_t *)MALLOC(size + 1);
+ size = ((sizeof(asn_oid_arc_t) * CHAR_BIT + 6) / 7) * arcs_count;
+ bp = buf = (uint8_t *)MALLOC(size + 1);
if(!buf) {
/* ENOMEM */
return -1;
@@ -236,19 +246,26 @@
/*
* Encode the arcs.
*/
- for(i = 0; i < arcs_slots; i++, arcs = ((char *)arcs) + arc_type_size) {
- bp += OBJECT_IDENTIFIER_set_single_arc(bp,
- arcs, arc_type_size, 0);
- }
+ for(i = 0; i < arcs_count; i++) {
+ ssize_t wrote = OBJECT_IDENTIFIER_set_single_arc(bp, size, arcs[i]);
+ if(wrote <= 0) {
+ FREEMEM(buf);
+ return -1;
+ }
+ assert((size_t)wrote <= size);
+ bp += wrote;
+ size -= wrote;
+ }
- assert((unsigned)(bp - buf) <= size);
+ assert(size >= 0);
/*
* Replace buffer.
*/
- roid->size = (int)(bp - buf);
- bp = roid->buf;
- roid->buf = buf;
+ st->size = bp - buf;
+ bp = st->buf;
+ st->buf = buf;
+ st->buf[st->size] = '\0';
if(bp) FREEMEM(bp);
return 0;
@@ -258,7 +275,7 @@
/*
* Generate values from the list of interesting values, or just a random value.
*/
-static uint32_t
+static asn_oid_arc_t
RELATIVE_OID__biased_random_arc() {
static const uint16_t values[] = {0, 1, 127, 128, 129, 254, 255, 256};
@@ -276,15 +293,16 @@
asn_random_fill_result_t
RELATIVE_OID_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
- const asn_encoding_constraints_t *constraints,
- size_t max_length) {
+ const asn_encoding_constraints_t *constraints,
+ size_t max_length) {
asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
RELATIVE_OID_t *st;
const int min_arcs = 1; /* A minimum of 1 arc is required */
- size_t arcs_len = asn_random_between(min_arcs, 3);
- uint32_t arcs[3];
+ asn_oid_arc_t arcs[3];
+ size_t arcs_len =
+ asn_random_between(min_arcs, sizeof(arcs) / sizeof(arcs[0]));
size_t i;
(void)constraints;
@@ -301,7 +319,7 @@
arcs[i] = RELATIVE_OID__biased_random_arc();
}
- if(RELATIVE_OID_set_arcs(st, arcs, sizeof(arcs[0]), arcs_len)) {
+ if(RELATIVE_OID_set_arcs(st, arcs, arcs_len)) {
if(st != *sptr) {
ASN_STRUCT_FREE(*td, st);
}
@@ -310,5 +328,6 @@
*sptr = st;
+ result_ok.length = st->size;
return result_ok;
}