Commit f52ec009 authored by Bi-Ruei, Chiu's avatar Bi-Ruei, Chiu

Merge Velichkov's implementation of OPEN TYPE APER functions

parent 2a5ea088
......@@ -400,5 +400,117 @@ OPEN_TYPE_encode_uper(const asn_TYPE_descriptor_t *td,
ASN__ENCODED_OK(er);
}
asn_dec_rval_t
OPEN_TYPE_aper_get(const asn_codec_ctx_t *opt_codec_ctx,
const asn_TYPE_descriptor_t *td, void *sptr,
const asn_TYPE_member_t *elm, asn_per_data_t *pd) {
asn_type_selector_result_t selected;
void *memb_ptr; /* Pointer to the member */
void **memb_ptr2; /* Pointer to that pointer */
void *inner_value;
asn_dec_rval_t rv;
if(!(elm->flags & ATF_OPEN_TYPE)) {
ASN__DECODE_FAILED;
}
if(!elm->type_selector) {
ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
td->name, elm->name, elm->type->name);
ASN__DECODE_FAILED;
}
selected = elm->type_selector(td, sptr);
if(!selected.presence_index) {
ASN__DECODE_FAILED;
}
/* Fetch the pointer to this member */
assert(elm->flags == ATF_OPEN_TYPE);
if(elm->flags & ATF_POINTER) {
memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
} else {
memb_ptr = (char *)sptr + elm->memb_offset;
memb_ptr2 = &memb_ptr;
}
if(*memb_ptr2 != NULL) {
/* Make sure we reset the structure first before encoding */
if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
!= 0) {
ASN__DECODE_FAILED;
}
}
inner_value =
(char *)*memb_ptr2
+ elm->type->elements[selected.presence_index - 1].memb_offset;
rv = aper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
&inner_value, pd);
switch(rv.code) {
case RC_OK:
if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
selected.presence_index)
== 0) {
break;
} else {
rv.code = RC_FAIL;
}
/* Fall through */
case RC_WMORE:
case RC_FAIL:
if(*memb_ptr2) {
const asn_CHOICE_specifics_t *specs =
selected.type_descriptor->specifics;
if(elm->flags & ATF_POINTER) {
ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
*memb_ptr2 = NULL;
} else {
ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
inner_value);
memset(*memb_ptr2, 0, specs->struct_size);
}
}
}
return rv;
}
asn_enc_rval_t
OPEN_TYPE_encode_aper(const asn_TYPE_descriptor_t *td,
const asn_per_constraints_t *constraints,
const void *sptr, asn_per_outp_t *po) {
const void *memb_ptr; /* Pointer to the member */
asn_TYPE_member_t *elm; /* CHOICE's element */
asn_enc_rval_t er;
unsigned present;
(void)constraints;
present = CHOICE_variant_get_presence(td, sptr);
if(present == 0 || present > td->elements_count) {
ASN__ENCODE_FAILED;
} else {
present--;
}
ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
elm = &td->elements[present];
if(elm->flags & ATF_POINTER) {
/* Member is a pointer to another structure */
memb_ptr =
*(const void *const *)((const char *)sptr + elm->memb_offset);
if(!memb_ptr) ASN__ENCODE_FAILED;
} else {
memb_ptr = (const char *)sptr + elm->memb_offset;
}
if(aper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
ASN__ENCODE_FAILED;
}
er.encoded = 0;
ASN__ENCODED_OK(er);
}
#endif /* ASN_DISABLE_PER_SUPPORT */
......@@ -21,7 +21,6 @@ extern "C" {
#define OPEN_TYPE_encode_xer CHOICE_encode_xer
#define OPEN_TYPE_decode_uper NULL
#define OPEN_TYPE_decode_aper NULL
#define OPEN_TYPE_encode_aper CHOICE_encode_aper
extern asn_TYPE_operation_t asn_OP_OPEN_TYPE;
......@@ -53,11 +52,22 @@ asn_dec_rval_t OPEN_TYPE_uper_get(const asn_codec_ctx_t *opt_codec_ctx,
const asn_TYPE_member_t *element,
asn_per_data_t *pd);
asn_dec_rval_t OPEN_TYPE_aper_get(const asn_codec_ctx_t *opt_codec_ctx,
const asn_TYPE_descriptor_t *parent_type,
void *parent_structure,
const asn_TYPE_member_t *element,
asn_per_data_t *pd);
asn_enc_rval_t OPEN_TYPE_encode_uper(
const asn_TYPE_descriptor_t *type_descriptor,
const asn_per_constraints_t *constraints, const void *struct_ptr,
asn_per_outp_t *per_output);
asn_enc_rval_t OPEN_TYPE_encode_aper(
const asn_TYPE_descriptor_t *type_descriptor,
const asn_per_constraints_t *constraints, const void *struct_ptr,
asn_per_outp_t *per_output);
#ifdef __cplusplus
}
#endif
......
......@@ -317,6 +317,8 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
#ifdef ASN_DISABLE_PER_SUPPORT
case ATS_UNALIGNED_BASIC_PER:
case ATS_UNALIGNED_CANONICAL_PER:
case ATS_ALIGNED_BASIC_PER:
case ATS_ALIGNED_CANONICAL_PER:
errno = ENOENT; /* PER is not defined. */
ASN__ENCODE_FAILED;
break;
......@@ -351,6 +353,36 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
ASN__ENCODE_FAILED;
}
break;
case ATS_ALIGNED_BASIC_PER:
/* CANONICAL-APER is a superset of BASIC-APER. */
/* Fall through. */
case ATS_ALIGNED_CANONICAL_PER:
if(td->op->aper_encoder) {
er = aper_encode(td, 0, sptr, callback, callback_key);
if(er.encoded == -1) {
if(er.failed_type && er.failed_type->op->aper_encoder) {
errno = EBADF; /* Structure has incorrect form. */
} else {
errno = ENOENT; /* APER is not defined for this type. */
}
} else {
ASN_DEBUG("Complete encoded in %ld bits", (long)er.encoded);
if(er.encoded == 0) {
/* Enforce "Complete Encoding" of X.691 #11.1 */
if(callback("\0", 1, callback_key) < 0) {
errno = EBADF;
ASN__ENCODE_FAILED;
}
er.encoded = 8; /* Exactly 8 zero bits is added. */
}
/* Convert bits into bytes */
er.encoded = (er.encoded + 7) >> 3;
}
} else {
errno = ENOENT; /* Transfer syntax is not defined for this type. */
ASN__ENCODE_FAILED;
}
break;
#endif /* ASN_DISABLE_PER_SUPPORT */
case ATS_BASIC_XER:
......
......@@ -1594,9 +1594,14 @@ SEQUENCE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
}
/* Fetch the member from the stream */
ASN_DEBUG("Decoding member %s in %s", elm->name, td->name);
rv = elm->type->op->aper_decoder(opt_codec_ctx, elm->type,
elm->encoding_constraints.per_constraints, memb_ptr2, pd);
ASN_DEBUG("Decoding member \"%s\" in %s", elm->name, td->name);
if(elm->flags & ATF_OPEN_TYPE) {
rv = OPEN_TYPE_aper_get(opt_codec_ctx, td, st, elm, pd);
} else {
rv = elm->type->op->aper_decoder(opt_codec_ctx, elm->type,
elm->encoding_constraints.per_constraints, memb_ptr2, pd);
}
if(rv.code != RC_OK) {
ASN_DEBUG("Failed decode %s in %s",
elm->name, td->name);
......
......@@ -96,7 +96,9 @@ uper_decode(const asn_codec_ctx_t *opt_codec_ctx,
}
asn_dec_rval_t
aper_decode_complete(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size) {
aper_decode_complete(const asn_codec_ctx_t *opt_codec_ctx,
const asn_TYPE_descriptor_t *td, void **sptr,
const void *buffer, size_t size) {
asn_dec_rval_t rval;
rval = aper_decode(opt_codec_ctx, td, sptr, buffer, size, 0, 0);
......@@ -125,7 +127,9 @@ aper_decode_complete(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
}
asn_dec_rval_t
aper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size, int skip_bits, int unused_bits) {
aper_decode(const asn_codec_ctx_t *opt_codec_ctx,
const asn_TYPE_descriptor_t *td, void **sptr, const void *buffer,
size_t size, int skip_bits, int unused_bits) {
asn_codec_ctx_t s_codec_ctx;
asn_dec_rval_t rval;
asn_per_data_t pd;
......
......@@ -44,8 +44,9 @@ asn_dec_rval_t uper_decode(
* Aligned PER decoder of a "complete encoding" as per X.691#10.1.
* On success, this call always returns (.consumed >= 1), in BITS, as per X.691#10.1.3.
*/
asn_dec_rval_t aper_decode_complete(struct asn_codec_ctx_s *opt_codec_ctx,
struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
asn_dec_rval_t aper_decode_complete(
const struct asn_codec_ctx_s *opt_codec_ctx,
const struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
void **struct_ptr, /* Pointer to a target structure's pointer */
const void *buffer, /* Data to be decoded */
size_t size /* Size of data buffer */
......@@ -55,8 +56,9 @@ asn_dec_rval_t aper_decode_complete(struct asn_codec_ctx_s *opt_codec_ctx,
* Aligned PER decoder of any ASN.1 type. May be invoked by the application.
* WARNING: This call returns the number of BITS read from the stream. Beware.
*/
asn_dec_rval_t aper_decode(struct asn_codec_ctx_s *opt_codec_ctx,
struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
asn_dec_rval_t aper_decode(
const struct asn_codec_ctx_s *opt_codec_ctx,
const struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
void **struct_ptr, /* Pointer to a target structure's pointer */
const void *buffer, /* Data to be decoded */
size_t size, /* Size of data buffer */
......
......@@ -163,57 +163,34 @@ _uper_encode_flush_outp(asn_per_outp_t *po) {
return po->output(po->tmpspace, buf - po->tmpspace, po->op_key);
}
static asn_enc_rval_t aper_encode_internal(const asn_TYPE_descriptor_t *td,
const asn_per_constraints_t *,
const void *sptr, asn_app_consume_bytes_f *cb, void *app_key);
asn_enc_rval_t
aper_encode(const asn_TYPE_descriptor_t *td,
const void *sptr, asn_app_consume_bytes_f *cb, void *app_key) {
return aper_encode_internal(td, 0, sptr, cb, app_key);
}
asn_enc_rval_t
aper_encode_to_buffer(const asn_TYPE_descriptor_t *td,
const void *sptr, void *buffer, size_t buffer_size) {
enc_to_buf_arg key;
key.buffer = buffer;
key.left = buffer_size;
if(td) ASN_DEBUG("Encoding \"%s\" using ALIGNED PER", td->name);
return aper_encode_internal(td, 0, sptr, encode_to_buffer_cb, &key);
}
ssize_t
aper_encode_to_new_buffer(const asn_TYPE_descriptor_t *td,
const asn_per_constraints_t *constraints,
const void *sptr, void **buffer_r) {
asn_enc_rval_t er;
const asn_per_constraints_t *constraints,
const void *sptr, void **buffer_r) {
asn_enc_rval_t er;
enc_dyn_arg key;
memset(&key, 0, sizeof(key));
er = aper_encode_internal(td, constraints, sptr, encode_dyn_cb, &key);
er = aper_encode(td, constraints, sptr, encode_dyn_cb, &key);
switch(er.encoded) {
case -1:
FREEMEM(key.buffer);
return -1;
case 0:
FREEMEM(key.buffer);
key.buffer = MALLOC(1);
if(key.buffer) {
*(char *)key.buffer = '\0';
*buffer_r = key.buffer;
return 1;
} else {
return -1;
}
default:
case -1:
FREEMEM(key.buffer);
return -1;
case 0:
FREEMEM(key.buffer);
key.buffer = MALLOC(1);
if(key.buffer) {
*(char *)key.buffer = '\0';
*buffer_r = key.buffer;
ASN_DEBUG("Complete encoded in %ld bits", er.encoded);
return ((er.encoded + 7) >> 3);
return 1;
} else {
return -1;
}
default:
*buffer_r = key.buffer;
ASN_DEBUG("Complete encoded in %ld bits", (long)er.encoded);
return ((er.encoded + 7) >> 3);
}
}
......@@ -237,8 +214,8 @@ _aper_encode_flush_outp(asn_per_outp_t *po) {
return 0;
}
static asn_enc_rval_t
aper_encode_internal(const asn_TYPE_descriptor_t *td,
asn_enc_rval_t
aper_encode(const asn_TYPE_descriptor_t *td,
const asn_per_constraints_t *constraints,
const void *sptr, asn_app_consume_bytes_f *cb, void *app_key) {
asn_per_outp_t po;
......
......@@ -30,6 +30,7 @@ asn_enc_rval_t uper_encode(
asn_enc_rval_t aper_encode(
const struct asn_TYPE_descriptor_s *type_descriptor,
const asn_per_constraints_t *constraints,
const void *struct_ptr, /* Structure to be encoded */
asn_app_consume_bytes_f *consume_bytes_cb, /* Data collector */
void *app_key /* Arbitrary callback argument */
......@@ -50,6 +51,7 @@ asn_enc_rval_t uper_encode_to_buffer(
asn_enc_rval_t aper_encode_to_buffer(
const struct asn_TYPE_descriptor_s *type_descriptor,
const asn_per_constraints_t *constraints,
const void *struct_ptr, /* Structure to be encoded */
void *buffer, /* Pre-allocated buffer */
size_t buffer_size /* Initial buffer size (max) */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment