encode ANY as open type for PER
diff --git a/skeletons/ANY.c b/skeletons/ANY.c
index 7989559..3fbc2ff 100644
--- a/skeletons/ANY.c
+++ b/skeletons/ANY.c
@@ -1,5 +1,5 @@
-/*-
- * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+/*
+ * Copyright (c) 2004-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
@@ -31,7 +31,8 @@
#ifdef ASN_DISABLE_PER_SUPPORT
0, 0,
#else
- 0, 0,
+ ANY_decode_uper,
+ ANY_encode_uper,
#endif /* ASN_DISABLE_PER_SUPPORT */
0, /* Use generic outmost tag fetcher */
0, 0, 0, 0,
@@ -41,6 +42,14 @@
&asn_SPC_ANY_specs,
};
+#undef RETURN
+#define RETURN(_code) \
+ do { \
+ asn_dec_rval_t tmprval; \
+ tmprval.code = _code; \
+ tmprval.consumed = consumed_myself; \
+ return tmprval; \
+ } while(0)
asn_enc_rval_t
ANY_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
@@ -168,3 +177,88 @@
return 0;
}
+#ifndef ASN_DISABLE_PER_SUPPORT
+
+asn_dec_rval_t
+ANY_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_OCTET_STRING_specifics_t *specs =
+ td->specifics ? (asn_OCTET_STRING_specifics_t *)td->specifics
+ : &asn_SPC_ANY_specs;
+ size_t consumed_myself = 0;
+ int repeat;
+ ANY_t *st = (ANY_t *)*sptr;
+
+ /*
+ * Allocate the structure.
+ */
+ if(!st) {
+ st = (ANY_t *)(*sptr = CALLOC(1, specs->struct_size));
+ if(!st) RETURN(RC_FAIL);
+ }
+
+ ASN_DEBUG("PER Decoding ANY type");
+
+
+ st->size = 0;
+ do {
+ ssize_t raw_len;
+ ssize_t len_bytes;
+ ssize_t len_bits;
+ void *p;
+ int ret;
+
+ /* Get the PER length */
+ raw_len = uper_get_length(pd, -1, &repeat);
+ if(raw_len < 0) RETURN(RC_WMORE);
+
+ ASN_DEBUG("Got PER length len %zu, %s (%s)", raw_len,
+ repeat ? "repeat" : "once", td->name);
+ len_bytes = raw_len;
+ len_bits = len_bytes * 8;
+
+ p = REALLOC(st->buf, st->size + len_bytes + 1);
+ if(!p) RETURN(RC_FAIL);
+ st->buf = (uint8_t *)p;
+
+ ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
+ if(ret < 0) RETURN(RC_WMORE);
+ consumed_myself += len_bits;
+ st->size += len_bytes;
+ } while(repeat);
+ st->buf[st->size] = 0; /* nul-terminate */
+
+ RETURN(RC_OK);
+}
+
+asn_enc_rval_t
+ANY_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints,
+ void *sptr, asn_per_outp_t *po) {
+ const ANY_t *st = (const ANY_t *)sptr;
+ asn_enc_rval_t er = {0, 0, 0};
+ const uint8_t *buf;
+ size_t size;
+ int ret;
+
+ if(!st || (!st->buf && st->size)) ASN__ENCODE_FAILED;
+
+ buf = st->buf;
+ size = st->size;
+ while(size) {
+ ssize_t may_save = uper_put_length(po, size);
+ if(may_save < 0) ASN__ENCODE_FAILED;
+
+ ret = per_put_many_bits(po, buf, may_save * 8);
+ if(ret) ASN__ENCODE_FAILED;
+
+ buf += may_save;
+ size -= may_save;
+ assert(!(may_save & 0x07) || !size);
+ }
+
+ ASN__ENCODED_OK(er);
+}
+
+#endif /* ASN_DISABLE_PER_SUPPORT */
+
diff --git a/skeletons/ANY.h b/skeletons/ANY.h
index 3df5b76..01579c2 100644
--- a/skeletons/ANY.h
+++ b/skeletons/ANY.h
@@ -26,6 +26,8 @@
ber_type_decoder_f ANY_decode_ber;
der_type_encoder_f ANY_encode_der;
xer_type_encoder_f ANY_encode_xer;
+per_type_decoder_f ANY_decode_uper;
+per_type_encoder_f ANY_encode_uper;
#define ANY_free OCTET_STRING_free
#define ANY_print OCTET_STRING_print