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, ...@@ -400,5 +400,117 @@ OPEN_TYPE_encode_uper(const asn_TYPE_descriptor_t *td,
ASN__ENCODED_OK(er); 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 */ #endif /* ASN_DISABLE_PER_SUPPORT */
...@@ -21,7 +21,6 @@ extern "C" { ...@@ -21,7 +21,6 @@ extern "C" {
#define OPEN_TYPE_encode_xer CHOICE_encode_xer #define OPEN_TYPE_encode_xer CHOICE_encode_xer
#define OPEN_TYPE_decode_uper NULL #define OPEN_TYPE_decode_uper NULL
#define OPEN_TYPE_decode_aper NULL #define OPEN_TYPE_decode_aper NULL
#define OPEN_TYPE_encode_aper CHOICE_encode_aper
extern asn_TYPE_operation_t asn_OP_OPEN_TYPE; 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, ...@@ -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, const asn_TYPE_member_t *element,
asn_per_data_t *pd); 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( asn_enc_rval_t OPEN_TYPE_encode_uper(
const asn_TYPE_descriptor_t *type_descriptor, const asn_TYPE_descriptor_t *type_descriptor,
const asn_per_constraints_t *constraints, const void *struct_ptr, const asn_per_constraints_t *constraints, const void *struct_ptr,
asn_per_outp_t *per_output); 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 #ifdef __cplusplus
} }
#endif #endif
......
...@@ -317,6 +317,8 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -317,6 +317,8 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
#ifdef ASN_DISABLE_PER_SUPPORT #ifdef ASN_DISABLE_PER_SUPPORT
case ATS_UNALIGNED_BASIC_PER: case ATS_UNALIGNED_BASIC_PER:
case ATS_UNALIGNED_CANONICAL_PER: case ATS_UNALIGNED_CANONICAL_PER:
case ATS_ALIGNED_BASIC_PER:
case ATS_ALIGNED_CANONICAL_PER:
errno = ENOENT; /* PER is not defined. */ errno = ENOENT; /* PER is not defined. */
ASN__ENCODE_FAILED; ASN__ENCODE_FAILED;
break; break;
...@@ -351,6 +353,36 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -351,6 +353,36 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
ASN__ENCODE_FAILED; ASN__ENCODE_FAILED;
} }
break; 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 */ #endif /* ASN_DISABLE_PER_SUPPORT */
case ATS_BASIC_XER: case ATS_BASIC_XER:
......
...@@ -1594,9 +1594,14 @@ SEQUENCE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -1594,9 +1594,14 @@ SEQUENCE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
} }
/* Fetch the member from the stream */ /* Fetch the member from the stream */
ASN_DEBUG("Decoding member %s in %s", elm->name, td->name); 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); 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) { if(rv.code != RC_OK) {
ASN_DEBUG("Failed decode %s in %s", ASN_DEBUG("Failed decode %s in %s",
elm->name, td->name); elm->name, td->name);
......
...@@ -96,7 +96,9 @@ uper_decode(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -96,7 +96,9 @@ uper_decode(const asn_codec_ctx_t *opt_codec_ctx,
} }
asn_dec_rval_t 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; asn_dec_rval_t rval;
rval = aper_decode(opt_codec_ctx, td, sptr, buffer, size, 0, 0); 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, ...@@ -125,7 +127,9 @@ aper_decode_complete(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
} }
asn_dec_rval_t 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_codec_ctx_t s_codec_ctx;
asn_dec_rval_t rval; asn_dec_rval_t rval;
asn_per_data_t pd; asn_per_data_t pd;
......
...@@ -44,8 +44,9 @@ asn_dec_rval_t uper_decode( ...@@ -44,8 +44,9 @@ asn_dec_rval_t uper_decode(
* Aligned PER decoder of a "complete encoding" as per X.691#10.1. * 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. * 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, asn_dec_rval_t aper_decode_complete(
struct asn_TYPE_descriptor_s *type_descriptor, /* Type to 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 */ void **struct_ptr, /* Pointer to a target structure's pointer */
const void *buffer, /* Data to be decoded */ const void *buffer, /* Data to be decoded */
size_t size /* Size of data buffer */ 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, ...@@ -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. * 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. * 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, asn_dec_rval_t aper_decode(
struct asn_TYPE_descriptor_s *type_descriptor, /* Type to 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 */ void **struct_ptr, /* Pointer to a target structure's pointer */
const void *buffer, /* Data to be decoded */ const void *buffer, /* Data to be decoded */
size_t size, /* Size of data buffer */ size_t size, /* Size of data buffer */
......
...@@ -163,57 +163,34 @@ _uper_encode_flush_outp(asn_per_outp_t *po) { ...@@ -163,57 +163,34 @@ _uper_encode_flush_outp(asn_per_outp_t *po) {
return po->output(po->tmpspace, buf - po->tmpspace, po->op_key); 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 ssize_t
aper_encode_to_new_buffer(const asn_TYPE_descriptor_t *td, aper_encode_to_new_buffer(const asn_TYPE_descriptor_t *td,
const asn_per_constraints_t *constraints, const asn_per_constraints_t *constraints,
const void *sptr, void **buffer_r) { const void *sptr, void **buffer_r) {
asn_enc_rval_t er; asn_enc_rval_t er;
enc_dyn_arg key; enc_dyn_arg key;
memset(&key, 0, sizeof(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) { switch(er.encoded) {
case -1: case -1:
FREEMEM(key.buffer); FREEMEM(key.buffer);
return -1; return -1;
case 0: case 0:
FREEMEM(key.buffer); FREEMEM(key.buffer);
key.buffer = MALLOC(1); key.buffer = MALLOC(1);
if(key.buffer) { if(key.buffer) {
*(char *)key.buffer = '\0'; *(char *)key.buffer = '\0';
*buffer_r = key.buffer;
return 1;
} else {
return -1;
}
default:
*buffer_r = key.buffer; *buffer_r = key.buffer;
ASN_DEBUG("Complete encoded in %ld bits", er.encoded); return 1;
return ((er.encoded + 7) >> 3); } 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) { ...@@ -237,8 +214,8 @@ _aper_encode_flush_outp(asn_per_outp_t *po) {
return 0; return 0;
} }
static asn_enc_rval_t asn_enc_rval_t
aper_encode_internal(const asn_TYPE_descriptor_t *td, aper_encode(const asn_TYPE_descriptor_t *td,
const asn_per_constraints_t *constraints, const asn_per_constraints_t *constraints,
const void *sptr, asn_app_consume_bytes_f *cb, void *app_key) { const void *sptr, asn_app_consume_bytes_f *cb, void *app_key) {
asn_per_outp_t po; asn_per_outp_t po;
......
...@@ -30,6 +30,7 @@ asn_enc_rval_t uper_encode( ...@@ -30,6 +30,7 @@ asn_enc_rval_t uper_encode(
asn_enc_rval_t aper_encode( asn_enc_rval_t aper_encode(
const struct asn_TYPE_descriptor_s *type_descriptor, const struct asn_TYPE_descriptor_s *type_descriptor,
const asn_per_constraints_t *constraints,
const void *struct_ptr, /* Structure to be encoded */ const void *struct_ptr, /* Structure to be encoded */
asn_app_consume_bytes_f *consume_bytes_cb, /* Data collector */ asn_app_consume_bytes_f *consume_bytes_cb, /* Data collector */
void *app_key /* Arbitrary callback argument */ void *app_key /* Arbitrary callback argument */
...@@ -50,6 +51,7 @@ asn_enc_rval_t uper_encode_to_buffer( ...@@ -50,6 +51,7 @@ asn_enc_rval_t uper_encode_to_buffer(
asn_enc_rval_t aper_encode_to_buffer( asn_enc_rval_t aper_encode_to_buffer(
const struct asn_TYPE_descriptor_s *type_descriptor, const struct asn_TYPE_descriptor_s *type_descriptor,
const asn_per_constraints_t *constraints,
const void *struct_ptr, /* Structure to be encoded */ const void *struct_ptr, /* Structure to be encoded */
void *buffer, /* Pre-allocated buffer */ void *buffer, /* Pre-allocated buffer */
size_t buffer_size /* Initial buffer size (max) */ 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