aboutsummaryrefslogtreecommitdiffstats
path: root/skeletons
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2005-02-25 12:10:27 +0000
committerLev Walkin <vlm@lionet.info>2005-02-25 12:10:27 +0000
commite0b56e0d581fab0b62db2dae062eb9c472488bc6 (patch)
tree5df7cc6c038e921195c257e80c15441773790f7e /skeletons
parent475d91f0d2674a9dfe9d022241567d3a33686e19 (diff)
XMLValueList support
Diffstat (limited to 'skeletons')
-rw-r--r--skeletons/BOOLEAN.c4
-rw-r--r--skeletons/INTEGER.c169
-rw-r--r--skeletons/INTEGER.h16
-rw-r--r--skeletons/NULL.c3
-rw-r--r--skeletons/NativeInteger.c73
-rw-r--r--skeletons/NativeInteger.h1
-rw-r--r--skeletons/OBJECT_IDENTIFIER.c4
-rw-r--r--skeletons/REAL.c4
-rw-r--r--skeletons/RELATIVE-OID.c4
-rw-r--r--skeletons/asn_codecs_prim.c19
-rw-r--r--skeletons/asn_codecs_prim.h4
-rw-r--r--skeletons/constr_SET.c3
-rw-r--r--skeletons/constr_SET_OF.c5
-rw-r--r--skeletons/xer_decoder.c7
14 files changed, 244 insertions, 72 deletions
diff --git a/skeletons/BOOLEAN.c b/skeletons/BOOLEAN.c
index 6a4cdc7e..ad7321ce 100644
--- a/skeletons/BOOLEAN.c
+++ b/skeletons/BOOLEAN.c
@@ -134,10 +134,12 @@ BOOLEAN_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
* Decode the chunk of XML text encoding INTEGER.
*/
static ssize_t
-BOOLEAN__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) {
+BOOLEAN__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, size_t chunk_size) {
BOOLEAN_t *st = (BOOLEAN_t *)sptr;
char *p = (char *)chunk_buf;
+ (void)td;
+
if(chunk_size == 0) return -1;
if(p[0] == 0x3c /* '<' */) {
diff --git a/skeletons/INTEGER.c b/skeletons/INTEGER.c
index db289cb2..de856d8f 100644
--- a/skeletons/INTEGER.c
+++ b/skeletons/INTEGER.c
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
@@ -92,11 +93,15 @@ INTEGER_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
return der_encode_primitive(td, sptr, tag_mode, tag, cb, app_key);
}
+static const asn_INTEGER_enum_map_t *INTEGER__map_value2enum(asn_INTEGER_specifics_t *specs, long value);
+static const asn_INTEGER_enum_map_t *INTEGER__map_enum2value(asn_INTEGER_specifics_t *specs, const char *lstart, const char *lstop);
+
/*
* INTEGER specific human-readable output.
*/
static ssize_t
-INTEGER__dump(const INTEGER_t *st, asn_app_consume_bytes_f *cb, void *app_key) {
+INTEGER__dump(asn_TYPE_descriptor_t *td, const INTEGER_t *st, asn_app_consume_bytes_f *cb, void *app_key, int plainOrXER) {
+ asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
char scratch[32]; /* Enough for 64-bit integer */
uint8_t *buf = st->buf;
uint8_t *buf_end = st->buf + st->size;
@@ -105,10 +110,6 @@ INTEGER__dump(const INTEGER_t *st, asn_app_consume_bytes_f *cb, void *app_key) {
char *p;
int ret;
- if(st->size == 0) {
- return (cb("0", 1, app_key) < 0) ? -1 : 1;
- }
-
/*
* Advance buf pointer until the start of the value's body.
* This will make us able to process large integers using simple case,
@@ -126,12 +127,49 @@ INTEGER__dump(const INTEGER_t *st, asn_app_consume_bytes_f *cb, void *app_key) {
/* Simple case: the integer size is small */
if((size_t)(buf_end - buf) <= sizeof(accum)) {
- accum = (*buf & 0x80) ? -1 : 0;
- for(; buf < buf_end; buf++)
- accum = (accum << 8) | *buf;
- ret = snprintf(scratch, sizeof(scratch), "%ld", accum);
- assert(ret > 0 && ret < (int)sizeof(scratch));
- return (cb(scratch, ret, app_key) < 0) ? -1 : ret;
+ const asn_INTEGER_enum_map_t *el;
+ size_t scrsize;
+ char *scr;
+
+ if(buf == buf_end) {
+ accum = 0;
+ } else {
+ accum = (*buf & 0x80) ? -1 : 0;
+ for(; buf < buf_end; buf++)
+ accum = (accum << 8) | *buf;
+ }
+
+ el = INTEGER__map_value2enum(specs, accum);
+ if(el) {
+ scrsize = el->enum_len + 32;
+ scr = (char *)alloca(scrsize);
+ if(plainOrXER == 0)
+ ret = snprintf(scr, scrsize,
+ "%ld (%s)", accum, el->enum_name);
+ else
+ ret = snprintf(scr, scrsize,
+ "<%s/>", el->enum_name);
+ } else if(plainOrXER && specs && specs->strict_enumeration) {
+ ASN_DEBUG("ASN.1 forbids dealing with "
+ "unknown value of ENUMERATED type");
+ errno = EPERM;
+ return -1;
+ } else {
+ scrsize = sizeof(scratch);
+ scr = scratch;
+ ret = snprintf(scr, scrsize, "%ld", accum);
+ }
+ assert(ret > 0 && (size_t)ret < scrsize);
+ return (cb(scr, ret, app_key) < 0) ? -1 : ret;
+ } else if(plainOrXER && specs && specs->strict_enumeration) {
+ /*
+ * Here and earlier, we cannot encode the ENUMERATED values
+ * if there is no corresponding identifier.
+ */
+ ASN_DEBUG("ASN.1 forbids dealing with "
+ "unknown value of ENUMERATED type");
+ errno = EPERM;
+ return -1;
}
/* Output in the long xx:yy:zz... format */
@@ -171,22 +209,97 @@ INTEGER_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
if(!st && !st->buf)
ret = cb("<absent>", 8, app_key);
else
- ret = INTEGER__dump(st, cb, app_key);
+ ret = INTEGER__dump(td, st, cb, app_key, 0);
return (ret < 0) ? -1 : 0;
}
+struct e2v_key {
+ const char *start;
+ const char *stop;
+ asn_INTEGER_enum_map_t *vemap;
+ unsigned int *evmap;
+};
+static int
+INTEGER__compar_enum2value(const void *kp, const void *am) {
+ const struct e2v_key *key = (const struct e2v_key *)kp;
+ const asn_INTEGER_enum_map_t *el = (const asn_INTEGER_enum_map_t *)am;
+ const char *ptr, *end, *name;
+
+ /* Remap the element (sort by different criterion) */
+ el = key->vemap + key->evmap[el - key->vemap];
+
+ /* Compare strings */
+ for(ptr = key->start, end = key->stop, name = el->enum_name;
+ ptr < end; ptr++, name++) {
+ if(*ptr != *name)
+ return *(const unsigned char *)ptr
+ - *(const unsigned char *)name;
+ }
+ return name[0] ? -1 : 0;
+}
+
+static const asn_INTEGER_enum_map_t *
+INTEGER__map_enum2value(asn_INTEGER_specifics_t *specs, const char *lstart, const char *lstop) {
+ int count = specs ? specs->map_count : 0;
+ struct e2v_key key;
+ const char *lp;
+
+ if(!count) return NULL;
+
+ /* Guaranteed: assert(lstart < lstop); */
+ /* Figure out the tag name */
+ for(lstart++, lp = lstart; lp < lstop; lp++) {
+ switch(*lp) {
+ case 9: case 10: case 11: case 12: case 13: case 32: /* WSP */
+ case 0x2f: /* '/' */ case 0x3e: /* '>' */
+ break;
+ default:
+ continue;
+ }
+ break;
+ }
+ if(lp == lstop) return NULL; /* No tag found */
+ lstop = lp;
+
+ key.start = lstart;
+ key.stop = lstop;
+ key.vemap = specs->value2enum;
+ key.evmap = specs->enum2value;
+ return (asn_INTEGER_enum_map_t *)bsearch(&key, specs->value2enum, count,
+ sizeof(specs->value2enum[0]), INTEGER__compar_enum2value);
+}
+
+static int
+INTEGER__compar_value2enum(const void *kp, const void *am) {
+ long a = *(const long *)kp;
+ const asn_INTEGER_enum_map_t *el = (const asn_INTEGER_enum_map_t *)am;
+ long b = el->nat_value;
+ if(a < b) return -1;
+ else if(a == b) return 0;
+ else return 1;
+}
+
+static const asn_INTEGER_enum_map_t *
+INTEGER__map_value2enum(asn_INTEGER_specifics_t *specs, long value) {
+ int count = specs ? specs->map_count : 0;
+ if(!count) return 0;
+ return (asn_INTEGER_enum_map_t *)bsearch(&value, specs->value2enum,
+ count, sizeof(specs->value2enum[0]),
+ INTEGER__compar_value2enum);
+}
+
/*
* Decode the chunk of XML text encoding INTEGER.
*/
static ssize_t
-INTEGER__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) {
+INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, size_t chunk_size) {
INTEGER_t *st = (INTEGER_t *)sptr;
long sign = 1;
long value;
- char *lp;
- char *lstart = (char *)chunk_buf;
- char *lstop = lstart + chunk_size;
+ const char *lp;
+ const char *lstart = (const char *)chunk_buf;
+ const char *lstop = lstart + chunk_size;
enum {
ST_SKIPSPACE,
ST_WAITDIGITS,
@@ -194,8 +307,8 @@ INTEGER__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) {
} state = ST_SKIPSPACE;
/*
- * We may receive a tag here. But we aren't ready to deal with it yet.
- * So, just use stroul()-like code and serialize the result.
+ * We may have received a tag here. It will be processed inline.
+ * Use strtoul()-like code and serialize the result.
*/
for(value = 0, lp = lstart; lp < lstop; lp++) {
int lv = *lp;
@@ -242,6 +355,22 @@ INTEGER__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) {
}
}
continue;
+ case 0x3c: /* '<' */
+ if(state == ST_SKIPSPACE) {
+ const asn_INTEGER_enum_map_t *el;
+ el = INTEGER__map_enum2value(
+ (asn_INTEGER_specifics_t *)
+ td->specifics, lstart, lstop);
+ if(el) {
+ ASN_DEBUG("Found \"%s\" => %ld",
+ el->enum_name, el->nat_value);
+ state = ST_DIGITS;
+ value = el->nat_value;
+ break;
+ }
+ ASN_DEBUG("Unknown identifier for INTEGER");
+ }
+ return -1;
}
break;
}
@@ -280,7 +409,7 @@ INTEGER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
if(!st && !st->buf)
_ASN_ENCODE_FAILED;
- er.encoded = INTEGER__dump(st, cb, app_key);
+ er.encoded = INTEGER__dump(td, st, cb, app_key, 1);
if(er.encoded < 0) _ASN_ENCODE_FAILED;
return er;
diff --git a/skeletons/INTEGER.h b/skeletons/INTEGER.h
index 45259e23..a1b555f3 100644
--- a/skeletons/INTEGER.h
+++ b/skeletons/INTEGER.h
@@ -12,6 +12,22 @@ typedef ASN__PRIMITIVE_TYPE_t INTEGER_t;
extern asn_TYPE_descriptor_t asn_DEF_INTEGER;
+/* Map with <tag> to integer value association */
+typedef struct asn_INTEGER_enum_map_s {
+ long nat_value; /* associated native integer value */
+ size_t enum_len; /* strlen("tag") */
+ const char *enum_name; /* "tag" */
+} asn_INTEGER_enum_map_t;
+
+/* This type describes an enumeration for INTEGER and ENUMERATED types */
+typedef struct asn_INTEGER_specifics_s {
+ asn_INTEGER_enum_map_t *value2enum; /* N -> "tag"; sorted by N */
+ unsigned int *enum2value; /* "tag" => N; sorted by tag */
+ int map_count; /* Elements in either map */
+ int extensible; /* This map is extensible */
+ int strict_enumeration; /* Enumeration set is fixed */
+} asn_INTEGER_specifics_t;
+
asn_struct_print_f INTEGER_print;
ber_type_decoder_f INTEGER_decode_ber;
der_type_encoder_f INTEGER_encode_der;
diff --git a/skeletons/NULL.c b/skeletons/NULL.c
index 8cccc66c..6a813fcf 100644
--- a/skeletons/NULL.c
+++ b/skeletons/NULL.c
@@ -68,7 +68,8 @@ NULL_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
static ssize_t
-NULL__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) {
+NULL__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, size_t chunk_size) {
+ (void)td;
(void)sptr;
if(xer_is_whitespace(chunk_buf, chunk_size))
return chunk_size;
diff --git a/skeletons/NativeInteger.c b/skeletons/NativeInteger.c
index d6d1fd88..102372c4 100644
--- a/skeletons/NativeInteger.c
+++ b/skeletons/NativeInteger.c
@@ -11,7 +11,6 @@
*/
#include <asn_internal.h>
#include <NativeInteger.h>
-#include <INTEGER.h>
#include <assert.h>
/*
@@ -45,17 +44,17 @@ asn_TYPE_descriptor_t asn_DEF_NativeInteger = {
asn_dec_rval_t
NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
asn_TYPE_descriptor_t *td,
- void **int_ptr, void *buf_ptr, size_t size, int tag_mode) {
- int *Int = (int *)*int_ptr;
+ void **nint_ptr, void *buf_ptr, size_t size, int tag_mode) {
+ long *native = (long *)*nint_ptr;
asn_dec_rval_t rval;
ber_tlv_len_t length;
/*
* If the structure is not there, allocate it.
*/
- if(Int == NULL) {
- Int = (int *)(*int_ptr = CALLOC(1, sizeof(*Int)));
- if(Int == NULL) {
+ if(native == NULL) {
+ native = (long *)(*nint_ptr = CALLOC(1, sizeof(*native)));
+ if(native == NULL) {
rval.code = RC_FAIL;
rval.consumed = 0;
return rval;
@@ -88,7 +87,7 @@ NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
/*
* ASN.1 encoded INTEGER: buf_ptr, length
- * Fill the Int, at the same time checking for overflow.
+ * Fill the native, at the same time checking for overflow.
* If overflow occured, return with RC_FAIL.
*/
{
@@ -103,15 +102,15 @@ NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
return rval;
}
- *Int = l;
+ *native = l;
/*
- * Note that int might be shorter than long.
+ * Note that native integer size might be other than long.
* This expression hopefully will be optimized away
* by compiler.
*/
- if(sizeof(int) != sizeof(long) && ((long)*Int != l)) {
- *Int = 0; /* Safe value */
+ if(sizeof(*native) != sizeof(long) && ((long)*native != l)) {
+ *native = 0; /* Safe value */
rval.code = RC_FAIL;
rval.consumed = 0;
return rval;
@@ -121,8 +120,8 @@ NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
rval.code = RC_OK;
rval.consumed += length;
- ASN_DEBUG("Took %ld/%ld bytes to encode %s (%d)",
- (long)rval.consumed, (long)length, td->name, *Int);
+ ASN_DEBUG("Took %ld/%ld bytes to encode %s (%ld)",
+ (long)rval.consumed, (long)length, td->name, (long)*native);
return rval;
}
@@ -134,22 +133,22 @@ asn_enc_rval_t
NativeInteger_encode_der(asn_TYPE_descriptor_t *sd, void *ptr,
int tag_mode, ber_tlv_tag_t tag,
asn_app_consume_bytes_f *cb, void *app_key) {
- unsigned int Int = *(unsigned int *)ptr; /* Disable sign ext. */
+ unsigned long native = *(unsigned long *)ptr; /* Disable sign ext. */
asn_enc_rval_t erval;
INTEGER_t tmp;
#ifdef WORDS_BIGENDIAN /* Opportunistic optimization */
- tmp.buf = (uint8_t *)&Int;
- tmp.size = sizeof(Int);
+ tmp.buf = (uint8_t *)&native;
+ tmp.size = sizeof(native);
#else /* Works even if WORDS_BIGENDIAN is not set where should've been */
- uint8_t buf[sizeof(int)];
+ uint8_t buf[sizeof(native)];
uint8_t *p;
/* Prepare a fake INTEGER */
- for(p = buf + sizeof(buf) - 1; p >= buf; p--, Int >>= 8)
- *p = Int;
+ for(p = buf + sizeof(buf) - 1; p >= buf; p--, native >>= 8)
+ *p = native;
tmp.buf = buf;
tmp.size = sizeof(buf);
@@ -174,12 +173,12 @@ NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
asn_dec_rval_t rval;
INTEGER_t *st = 0;
void *st_ptr = (void *)&st;
- int *Int = (int *)*sptr;
+ long *native = (long *)*sptr;
- if(!Int) {
+ if(!native) {
*sptr = CALLOC(1, sizeof(int));
- Int = (int *)*sptr;
- if(!Int) {
+ native = (long *)*sptr;
+ if(!native) {
rval.code = RC_FAIL;
rval.consumed = 0;
return rval;
@@ -194,17 +193,23 @@ NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
rval.code = RC_FAIL;
rval.consumed = 0;
} else {
- *Int = l;
+ *native = l;
- /* int might be shorter than long */
- if(sizeof(int) != sizeof(long) && ((long)*Int != l)) {
- *Int = 0; /* Safe value */
+ /* Native type might be shorter than long */
+ if(sizeof(*native) != sizeof(long)
+ && ((long)*native != l)) {
+ *native = 0; /* Safe value */
rval.code = RC_FAIL;
rval.consumed = 0;
return rval;
}
}
} else {
+ /*
+ * Cannot restart from the middle;
+ * there is no place to save state in the native type.
+ * Request a continuation from the very beginning.
+ */
rval.consumed = 0;
}
asn_DEF_INTEGER.free_struct(&asn_DEF_INTEGER, st, 0);
@@ -218,14 +223,14 @@ NativeInteger_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
asn_app_consume_bytes_f *cb, void *app_key) {
char scratch[32]; /* Enough for 64-bit int */
asn_enc_rval_t er;
- const int *Int = (const int *)sptr;
+ const long *native = (const long *)sptr;
(void)ilevel;
(void)flags;
- if(!Int) _ASN_ENCODE_FAILED;
+ if(!native) _ASN_ENCODE_FAILED;
- er.encoded = snprintf(scratch, sizeof(scratch), "%d", *Int);
+ er.encoded = snprintf(scratch, sizeof(scratch), "%ld", *native);
if(er.encoded <= 0 || (size_t)er.encoded >= sizeof(scratch)
|| cb(scratch, er.encoded, app_key) < 0)
_ASN_ENCODE_FAILED;
@@ -239,16 +244,16 @@ NativeInteger_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
int
NativeInteger_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
asn_app_consume_bytes_f *cb, void *app_key) {
- const int *Int = (const int *)sptr;
+ const long *native = (const long *)sptr;
char scratch[32]; /* Enough for 64-bit int */
int ret;
(void)td; /* Unused argument */
(void)ilevel; /* Unused argument */
- if(Int) {
- ret = snprintf(scratch, sizeof(scratch), "%d", *Int);
- assert(ret > 0 && ret < (int)sizeof(scratch));
+ if(native) {
+ ret = snprintf(scratch, sizeof(scratch), "%ld", *native);
+ assert(ret > 0 && (size_t)ret < sizeof(scratch));
return (cb(scratch, ret, app_key) < 0) ? -1 : 0;
} else {
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
diff --git a/skeletons/NativeInteger.h b/skeletons/NativeInteger.h
index 777f8e65..b66d29ad 100644
--- a/skeletons/NativeInteger.h
+++ b/skeletons/NativeInteger.h
@@ -13,6 +13,7 @@
#define _NativeInteger_H_
#include <asn_application.h>
+#include <INTEGER.h>
extern asn_TYPE_descriptor_t asn_DEF_NativeInteger;
diff --git a/skeletons/OBJECT_IDENTIFIER.c b/skeletons/OBJECT_IDENTIFIER.c
index 3f2454c3..4128e765 100644
--- a/skeletons/OBJECT_IDENTIFIER.c
+++ b/skeletons/OBJECT_IDENTIFIER.c
@@ -264,7 +264,7 @@ OBJECT_IDENTIFIER__dump_body(const OBJECT_IDENTIFIER_t *st, asn_app_consume_byte
}
static ssize_t
-OBJECT_IDENTIFIER__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) {
+OBJECT_IDENTIFIER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, size_t chunk_size) {
OBJECT_IDENTIFIER_t *st = (OBJECT_IDENTIFIER_t *)sptr;
char *endptr;
long s_arcs[10];
@@ -272,6 +272,8 @@ OBJECT_IDENTIFIER__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_siz
int arcs_count;
int ret;
+ (void)td;
+
arcs_count = OBJECT_IDENTIFIER_parse_arcs(
(const char *)chunk_buf, chunk_size, arcs, 10, &endptr);
if(arcs_count <= 0)
diff --git a/skeletons/REAL.c b/skeletons/REAL.c
index bf03db30..717db899 100644
--- a/skeletons/REAL.c
+++ b/skeletons/REAL.c
@@ -258,13 +258,15 @@ REAL_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
* Decode the chunk of XML text encoding REAL.
*/
static ssize_t
-REAL__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) {
+REAL__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, size_t chunk_size) {
REAL_t *st = (REAL_t *)sptr;
double value;
char *xerdata = (char *)chunk_buf;
char *endptr = 0;
char *b;
+ (void)td;
+
if(!chunk_size) return -1;
/*
diff --git a/skeletons/RELATIVE-OID.c b/skeletons/RELATIVE-OID.c
index d36d1f78..b0f6f64f 100644
--- a/skeletons/RELATIVE-OID.c
+++ b/skeletons/RELATIVE-OID.c
@@ -87,7 +87,7 @@ RELATIVE_OID_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
}
static ssize_t
-RELATIVE_OID__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) {
+RELATIVE_OID__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, size_t chunk_size) {
RELATIVE_OID_t *st = (RELATIVE_OID_t *)sptr;
char *endptr;
long s_arcs[6];
@@ -95,6 +95,8 @@ RELATIVE_OID__xer_body_decode(void *sptr, void *chunk_buf, size_t chunk_size) {
int arcs_count;
int ret;
+ (void)td;
+
arcs_count = OBJECT_IDENTIFIER_parse_arcs(
(const char *)chunk_buf, chunk_size,
arcs, 6, &endptr);
diff --git a/skeletons/asn_codecs_prim.c b/skeletons/asn_codecs_prim.c
index 03f107b6..5fe09adb 100644
--- a/skeletons/asn_codecs_prim.c
+++ b/skeletons/asn_codecs_prim.c
@@ -137,9 +137,10 @@ ASN__PRIMITIVE_TYPE_free(asn_TYPE_descriptor_t *td, void *sptr,
* Local internal type passed around as an argument.
*/
struct xdp_arg_s {
+ asn_TYPE_descriptor_t *type_descriptor;
void *struct_key;
- ssize_t (*prim_body_decode)(void *struct_key,
- void *chunk_buf, size_t chunk_size);
+ ssize_t (*prim_body_decode)(asn_TYPE_descriptor_t *td,
+ void *struct_key, void *chunk_buf, size_t chunk_size);
int decoded_something;
int want_more;
};
@@ -159,7 +160,8 @@ xer_decode__unexpected_tag(void *key, void *chunk_buf, size_t chunk_size) {
return -1;
}
- decoded = arg->prim_body_decode(arg->struct_key, chunk_buf, chunk_size);
+ decoded = arg->prim_body_decode(arg->type_descriptor,
+ arg->struct_key, chunk_buf, chunk_size);
if(decoded < 0) {
return -1;
} else {
@@ -196,7 +198,8 @@ xer_decode__body(void *key, void *chunk_buf, size_t chunk_size, int have_more) {
return -1;
}
- decoded = arg->prim_body_decode(arg->struct_key, chunk_buf, chunk_size);
+ decoded = arg->prim_body_decode(arg->type_descriptor,
+ arg->struct_key, chunk_buf, chunk_size);
if(decoded < 0) {
return -1;
} else {
@@ -213,8 +216,8 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
size_t struct_size,
const char *opt_mname,
void *buf_ptr, size_t size,
- ssize_t (*prim_body_decode)(void *struct_key,
- void *chunk_buf, size_t chunk_size)
+ ssize_t (*prim_body_decode)(asn_TYPE_descriptor_t *td,
+ void *struct_key, void *chunk_buf, size_t chunk_size)
) {
const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
asn_struct_ctx_t s_ctx;
@@ -235,6 +238,7 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
}
memset(&s_ctx, 0, sizeof(s_ctx));
+ s_arg.type_descriptor = td;
s_arg.struct_key = *sptr;
s_arg.prim_body_decode = prim_body_decode;
s_arg.decoded_something = 0;
@@ -248,7 +252,8 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
if(!s_arg.decoded_something) {
char ch;
/* Opportunity has come and gone. Where's the result? */
- if(prim_body_decode(s_arg.struct_key, &ch, 0) != 0) {
+ if(prim_body_decode(s_arg.type_descriptor,
+ s_arg.struct_key, &ch, 0) != 0) {
/*
* This decoder does not like empty stuff.
*/
diff --git a/skeletons/asn_codecs_prim.h b/skeletons/asn_codecs_prim.h
index c235f35b..7a6723d3 100644
--- a/skeletons/asn_codecs_prim.h
+++ b/skeletons/asn_codecs_prim.h
@@ -25,8 +25,8 @@ asn_dec_rval_t xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
void **struct_ptr, size_t struct_size,
const char *opt_mname,
void *buf_ptr, size_t size,
- ssize_t (*prim_body_decode)(void *struct_ptr,
- void *chunk_buf, size_t chunk_size)
+ ssize_t (*prim_body_decode)(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, void *chunk_buf, size_t chunk_size)
);
#endif /* ASN_CODECS_PRIM_H */
diff --git a/skeletons/constr_SET.c b/skeletons/constr_SET.c
index 2ee3b81a..4099186c 100644
--- a/skeletons/constr_SET.c
+++ b/skeletons/constr_SET.c
@@ -788,7 +788,8 @@ SET_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
break;
}
- ASN_DEBUG("Unexpected XML tag in SET");
+ ASN_DEBUG("Unexpected XML tag in SET, expected \"%s\"",
+ xml_tag);
break;
}
diff --git a/skeletons/constr_SET_OF.c b/skeletons/constr_SET_OF.c
index 931aab27..c6ec6af2 100644
--- a/skeletons/constr_SET_OF.c
+++ b/skeletons/constr_SET_OF.c
@@ -641,7 +641,7 @@ SET_OF_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) {
asn_enc_rval_t er;
- asn_SET_OF_specifics_t *specs=(asn_SET_OF_specifics_t *)td->specifics;
+ asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics;
asn_TYPE_member_t *element = td->elements;
A_SET_OF(void) *list;
const char *mname = specs->as_XMLValueList
@@ -684,6 +684,8 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
_ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
}
+ if(!xcan && specs->as_XMLValueList)
+ _i_ASN_TEXT_INDENT(1, ilevel + 1);
tmper = element->type->xer_encoder(element->type, memb_ptr,
ilevel + 1, flags, cb, app_key);
if(tmper.encoded == -1) {
@@ -695,7 +697,6 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
const char *name = (*element->name)
? element->name : element->type->xml_tag;
size_t len = strlen(name);
- if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel + 1);
_ASN_CALLBACK3("<", 1, name, len, "/>", 2);
}
diff --git a/skeletons/xer_decoder.c b/skeletons/xer_decoder.c
index 82c084e2..0de6e33f 100644
--- a/skeletons/xer_decoder.c
+++ b/skeletons/xer_decoder.c
@@ -271,7 +271,6 @@ xer_decode_general(asn_codec_ctx_t *opt_codec_ctx,
ctx->phase = 2; /* Phase out */
RETURN(RC_OK);
case XCT_UNKNOWN_BO:
- if(!ctx->phase) break;
/*
* Certain tags in the body may be expected.
*/
@@ -280,6 +279,12 @@ xer_decode_general(asn_codec_ctx_t *opt_codec_ctx,
buf_ptr, ch_size) == 0) {
/* Tag's processed fine */
ADVANCE(ch_size);
+ if(!ctx->phase) {
+ /* We are not expecting
+ * the closing tag anymore. */
+ ctx->phase = 2; /* Phase out */
+ RETURN(RC_OK);
+ }
continue;
}
/* Fall through */