* Decode an always-primitive type.
*/
asn_dec_rval_t
-ber_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td,
- void **sptr, const void *buf_ptr, size_t size, int tag_mode) {
- ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)*sptr;
+ber_decode_primitive(const asn_codec_ctx_t *opt_codec_ctx,
+ const asn_TYPE_descriptor_t *td, void **sptr,
+ const void *buf_ptr, size_t size, int tag_mode) {
+ ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)*sptr;
asn_dec_rval_t rval;
- ber_tlv_len_t length;
+ ber_tlv_len_t length = 0; /* =0 to avoid [incorrect] warning. */
/*
* If the structure is not there, allocate it.
*/
if(st == NULL) {
st = (ASN__PRIMITIVE_TYPE_t *)CALLOC(1, sizeof(*st));
- if(st == NULL) _ASN_DECODE_FAILED;
+ if(st == NULL) ASN__DECODE_FAILED;
*sptr = (void *)st;
}
if(sizeof(st->size) != sizeof(length)
&& (ber_tlv_len_t)st->size != length) {
st->size = 0;
- _ASN_DECODE_FAILED;
+ ASN__DECODE_FAILED;
}
st->buf = (uint8_t *)MALLOC(length + 1);
if(!st->buf) {
st->size = 0;
- _ASN_DECODE_FAILED;
+ ASN__DECODE_FAILED;
}
memcpy(st->buf, buf_ptr, length);
* Encode an always-primitive type using DER.
*/
asn_enc_rval_t
-der_encode_primitive(asn_TYPE_descriptor_t *td, void *sptr,
- int tag_mode, ber_tlv_tag_t tag,
- asn_app_consume_bytes_f *cb, void *app_key) {
- asn_enc_rval_t erval;
- ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr;
+der_encode_primitive(const asn_TYPE_descriptor_t *td, const void *sptr,
+ int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t erval;
+ const ASN__PRIMITIVE_TYPE_t *st = (const ASN__PRIMITIVE_TYPE_t *)sptr;
ASN_DEBUG("%s %s as a primitive type (tm=%d)",
cb?"Encoding":"Estimating", td->name, tag_mode);
}
erval.encoded += st->size;
- _ASN_ENCODED_OK(erval);
+ ASN__ENCODED_OK(erval);
}
void
-ASN__PRIMITIVE_TYPE_free(asn_TYPE_descriptor_t *td, void *sptr,
- int contents_only) {
- ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr;
+ASN__PRIMITIVE_TYPE_free(const asn_TYPE_descriptor_t *td, void *sptr,
+ enum asn_struct_free_method method) {
+ ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr;
if(!td || !sptr)
return;
if(st->buf)
FREEMEM(st->buf);
- if(!contents_only)
- FREEMEM(st);
+ switch(method) {
+ case ASFM_FREE_EVERYTHING:
+ FREEMEM(sptr);
+ break;
+ case ASFM_FREE_UNDERLYING:
+ break;
+ case ASFM_FREE_UNDERLYING_AND_RESET:
+ memset(sptr, 0, sizeof(ASN__PRIMITIVE_TYPE_t));
+ break;
+ }
}
* Local internal type passed around as an argument.
*/
struct xdp_arg_s {
- asn_TYPE_descriptor_t *type_descriptor;
- void *struct_key;
+ const asn_TYPE_descriptor_t *type_descriptor;
+ void *struct_key;
xer_primitive_body_decoder_f *prim_body_decoder;
int decoded_something;
int want_more;
};
-
+/*
+ * Since some kinds of primitive values can be encoded using value-specific
+ * tags (<MINUS-INFINITY>, <enum-element>, etc), the primitive decoder must
+ * be supplied with such tags to parse them as needed.
+ */
static int
xer_decode__unexpected_tag(void *key, const void *chunk_buf, size_t chunk_size) {
struct xdp_arg_s *arg = (struct xdp_arg_s *)key;
enum xer_pbd_rval bret;
- if(arg->decoded_something) {
- if(xer_is_whitespace(chunk_buf, chunk_size))
- return 0; /* Skip it. */
- /*
- * Decoding was done once already. Prohibit doing it again.
- */
+ /*
+ * The chunk_buf is guaranteed to start at '<'.
+ */
+ assert(chunk_size && ((const char *)chunk_buf)[0] == 0x3c);
+
+ /*
+ * Decoding was performed once already. Prohibit doing it again.
+ */
+ if(arg->decoded_something)
return -1;
- }
bret = arg->prim_body_decoder(arg->type_descriptor,
arg->struct_key, chunk_buf, chunk_size);
}
static ssize_t
-xer_decode__body(void *key, const void *chunk_buf, size_t chunk_size, int have_more) {
+xer_decode__primitive_body(void *key, const void *chunk_buf, size_t chunk_size, int have_more) {
struct xdp_arg_s *arg = (struct xdp_arg_s *)key;
enum xer_pbd_rval bret;
+ size_t lead_wsp_size;
if(arg->decoded_something) {
- if(xer_is_whitespace(chunk_buf, chunk_size))
+ if(xer_whitespace_span(chunk_buf, chunk_size) == chunk_size) {
+ /*
+ * Example:
+ * "<INTEGER>123<!--/--> </INTEGER>"
+ * ^- chunk_buf position.
+ */
return chunk_size;
+ }
/*
* Decoding was done once already. Prohibit doing it again.
*/
return -1;
}
+ lead_wsp_size = xer_whitespace_span(chunk_buf, chunk_size);
+ chunk_buf = (const char *)chunk_buf + lead_wsp_size;
+ chunk_size -= lead_wsp_size;
+
bret = arg->prim_body_decoder(arg->type_descriptor,
arg->struct_key, chunk_buf, chunk_size);
switch(bret) {
arg->decoded_something = 1;
/* Fall through */
case XPBD_NOT_BODY_IGNORE: /* Safe to proceed further */
- return chunk_size;
+ return lead_wsp_size + chunk_size;
}
return -1;
asn_dec_rval_t
-xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
- asn_TYPE_descriptor_t *td,
- void **sptr,
- size_t struct_size,
- const char *opt_mname,
- const void *buf_ptr, size_t size,
- xer_primitive_body_decoder_f *prim_body_decoder
-) {
- const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
+xer_decode_primitive(const asn_codec_ctx_t *opt_codec_ctx,
+ const asn_TYPE_descriptor_t *td, void **sptr,
+ size_t struct_size, const char *opt_mname,
+ const void *buf_ptr, size_t size,
+ xer_primitive_body_decoder_f *prim_body_decoder) {
+ const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
asn_struct_ctx_t s_ctx;
struct xdp_arg_s s_arg;
asn_dec_rval_t rc;
*/
if(!*sptr) {
*sptr = CALLOC(1, struct_size);
- if(!*sptr) _ASN_DECODE_FAILED;
+ if(!*sptr) ASN__DECODE_FAILED;
}
memset(&s_ctx, 0, sizeof(s_ctx));
rc = xer_decode_general(opt_codec_ctx, &s_ctx, &s_arg,
xml_tag, buf_ptr, size,
- xer_decode__unexpected_tag, xer_decode__body);
+ xer_decode__unexpected_tag, xer_decode__primitive_body);
switch(rc.code) {
case RC_OK:
if(!s_arg.decoded_something) {
/*
* This decoder does not like empty stuff.
*/
- _ASN_DECODE_FAILED;
+ ASN__DECODE_FAILED;
}
}
break;
if(s_arg.want_more)
rc.code = RC_WMORE;
else
- _ASN_DECODE_FAILED;
+ ASN__DECODE_FAILED;
break;
}
return rc;