Skip to content

Commit

Permalink
Merge Velichkov's implementation of OPEN TYPE APER functions
Browse files Browse the repository at this point in the history
  • Loading branch information
brchiu committed Nov 2, 2017
1 parent 1b0d2f4 commit ddbabf4
Show file tree
Hide file tree
Showing 8 changed files with 199 additions and 55 deletions.
112 changes: 112 additions & 0 deletions skeletons/OPEN_TYPE.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
12 changes: 11 additions & 1 deletion skeletons/OPEN_TYPE.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down
32 changes: 32 additions & 0 deletions skeletons/asn_application.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,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;
Expand Down Expand Up @@ -273,6 +275,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:
Expand Down
11 changes: 8 additions & 3 deletions skeletons/constr_SEQUENCE.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
8 changes: 6 additions & 2 deletions skeletons/per_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
10 changes: 6 additions & 4 deletions skeletons/per_decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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 */
Expand Down
67 changes: 22 additions & 45 deletions skeletons/per_encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,57 +155,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);
}
}

Expand All @@ -229,8 +206,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;
Expand Down
2 changes: 2 additions & 0 deletions skeletons/per_encoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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) */
Expand Down

0 comments on commit ddbabf4

Please sign in to comment.