Skip to content

Commit 3c016d1

Browse files
committed
Merge Velichkov's implementation of OPEN TYPE APER functions
1 parent e8eebe9 commit 3c016d1

File tree

8 files changed

+199
-55
lines changed

8 files changed

+199
-55
lines changed

skeletons/OPEN_TYPE.c

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,5 +400,117 @@ OPEN_TYPE_encode_uper(const asn_TYPE_descriptor_t *td,
400400
ASN__ENCODED_OK(er);
401401
}
402402

403+
asn_dec_rval_t
404+
OPEN_TYPE_aper_get(const asn_codec_ctx_t *opt_codec_ctx,
405+
const asn_TYPE_descriptor_t *td, void *sptr,
406+
const asn_TYPE_member_t *elm, asn_per_data_t *pd) {
407+
asn_type_selector_result_t selected;
408+
void *memb_ptr; /* Pointer to the member */
409+
void **memb_ptr2; /* Pointer to that pointer */
410+
void *inner_value;
411+
asn_dec_rval_t rv;
412+
413+
if(!(elm->flags & ATF_OPEN_TYPE)) {
414+
ASN__DECODE_FAILED;
415+
}
416+
417+
if(!elm->type_selector) {
418+
ASN_DEBUG("Type selector is not defined for Open Type %s->%s->%s",
419+
td->name, elm->name, elm->type->name);
420+
ASN__DECODE_FAILED;
421+
}
422+
423+
selected = elm->type_selector(td, sptr);
424+
if(!selected.presence_index) {
425+
ASN__DECODE_FAILED;
426+
}
427+
428+
/* Fetch the pointer to this member */
429+
assert(elm->flags == ATF_OPEN_TYPE);
430+
if(elm->flags & ATF_POINTER) {
431+
memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
432+
} else {
433+
memb_ptr = (char *)sptr + elm->memb_offset;
434+
memb_ptr2 = &memb_ptr;
435+
}
436+
if(*memb_ptr2 != NULL) {
437+
/* Make sure we reset the structure first before encoding */
438+
if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
439+
!= 0) {
440+
ASN__DECODE_FAILED;
441+
}
442+
}
443+
444+
inner_value =
445+
(char *)*memb_ptr2
446+
+ elm->type->elements[selected.presence_index - 1].memb_offset;
447+
448+
rv = aper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
449+
&inner_value, pd);
450+
switch(rv.code) {
451+
case RC_OK:
452+
if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
453+
selected.presence_index)
454+
== 0) {
455+
break;
456+
} else {
457+
rv.code = RC_FAIL;
458+
}
459+
/* Fall through */
460+
case RC_WMORE:
461+
case RC_FAIL:
462+
if(*memb_ptr2) {
463+
const asn_CHOICE_specifics_t *specs =
464+
selected.type_descriptor->specifics;
465+
if(elm->flags & ATF_POINTER) {
466+
ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
467+
*memb_ptr2 = NULL;
468+
} else {
469+
ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
470+
inner_value);
471+
memset(*memb_ptr2, 0, specs->struct_size);
472+
}
473+
}
474+
}
475+
return rv;
476+
}
477+
478+
asn_enc_rval_t
479+
OPEN_TYPE_encode_aper(const asn_TYPE_descriptor_t *td,
480+
const asn_per_constraints_t *constraints,
481+
const void *sptr, asn_per_outp_t *po) {
482+
const void *memb_ptr; /* Pointer to the member */
483+
asn_TYPE_member_t *elm; /* CHOICE's element */
484+
asn_enc_rval_t er;
485+
unsigned present;
486+
487+
(void)constraints;
488+
489+
present = CHOICE_variant_get_presence(td, sptr);
490+
if(present == 0 || present > td->elements_count) {
491+
ASN__ENCODE_FAILED;
492+
} else {
493+
present--;
494+
}
495+
496+
ASN_DEBUG("Encoding %s OPEN TYPE element %d", td->name, present);
497+
498+
elm = &td->elements[present];
499+
if(elm->flags & ATF_POINTER) {
500+
/* Member is a pointer to another structure */
501+
memb_ptr =
502+
*(const void *const *)((const char *)sptr + elm->memb_offset);
503+
if(!memb_ptr) ASN__ENCODE_FAILED;
504+
} else {
505+
memb_ptr = (const char *)sptr + elm->memb_offset;
506+
}
507+
508+
if(aper_open_type_put(elm->type, NULL, memb_ptr, po) < 0) {
509+
ASN__ENCODE_FAILED;
510+
}
511+
512+
er.encoded = 0;
513+
ASN__ENCODED_OK(er);
514+
}
403515

404516
#endif /* ASN_DISABLE_PER_SUPPORT */

skeletons/OPEN_TYPE.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ extern "C" {
2121
#define OPEN_TYPE_encode_xer CHOICE_encode_xer
2222
#define OPEN_TYPE_decode_uper NULL
2323
#define OPEN_TYPE_decode_aper NULL
24-
#define OPEN_TYPE_encode_aper CHOICE_encode_aper
2524

2625
extern asn_TYPE_operation_t asn_OP_OPEN_TYPE;
2726

@@ -53,11 +52,22 @@ asn_dec_rval_t OPEN_TYPE_uper_get(const asn_codec_ctx_t *opt_codec_ctx,
5352
const asn_TYPE_member_t *element,
5453
asn_per_data_t *pd);
5554

55+
asn_dec_rval_t OPEN_TYPE_aper_get(const asn_codec_ctx_t *opt_codec_ctx,
56+
const asn_TYPE_descriptor_t *parent_type,
57+
void *parent_structure,
58+
const asn_TYPE_member_t *element,
59+
asn_per_data_t *pd);
60+
5661
asn_enc_rval_t OPEN_TYPE_encode_uper(
5762
const asn_TYPE_descriptor_t *type_descriptor,
5863
const asn_per_constraints_t *constraints, const void *struct_ptr,
5964
asn_per_outp_t *per_output);
6065

66+
asn_enc_rval_t OPEN_TYPE_encode_aper(
67+
const asn_TYPE_descriptor_t *type_descriptor,
68+
const asn_per_constraints_t *constraints, const void *struct_ptr,
69+
asn_per_outp_t *per_output);
70+
6171
#ifdef __cplusplus
6272
}
6373
#endif

skeletons/asn_application.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
239239
#ifdef ASN_DISABLE_PER_SUPPORT
240240
case ATS_UNALIGNED_BASIC_PER:
241241
case ATS_UNALIGNED_CANONICAL_PER:
242+
case ATS_ALIGNED_BASIC_PER:
243+
case ATS_ALIGNED_CANONICAL_PER:
242244
errno = ENOENT; /* PER is not defined. */
243245
ASN__ENCODE_FAILED;
244246
break;
@@ -273,6 +275,36 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
273275
ASN__ENCODE_FAILED;
274276
}
275277
break;
278+
case ATS_ALIGNED_BASIC_PER:
279+
/* CANONICAL-APER is a superset of BASIC-APER. */
280+
/* Fall through. */
281+
case ATS_ALIGNED_CANONICAL_PER:
282+
if(td->op->aper_encoder) {
283+
er = aper_encode(td, 0, sptr, callback, callback_key);
284+
if(er.encoded == -1) {
285+
if(er.failed_type && er.failed_type->op->aper_encoder) {
286+
errno = EBADF; /* Structure has incorrect form. */
287+
} else {
288+
errno = ENOENT; /* APER is not defined for this type. */
289+
}
290+
} else {
291+
ASN_DEBUG("Complete encoded in %ld bits", (long)er.encoded);
292+
if(er.encoded == 0) {
293+
/* Enforce "Complete Encoding" of X.691 #11.1 */
294+
if(callback("\0", 1, callback_key) < 0) {
295+
errno = EBADF;
296+
ASN__ENCODE_FAILED;
297+
}
298+
er.encoded = 8; /* Exactly 8 zero bits is added. */
299+
}
300+
/* Convert bits into bytes */
301+
er.encoded = (er.encoded + 7) >> 3;
302+
}
303+
} else {
304+
errno = ENOENT; /* Transfer syntax is not defined for this type. */
305+
ASN__ENCODE_FAILED;
306+
}
307+
break;
276308
#endif /* ASN_DISABLE_PER_SUPPORT */
277309

278310
case ATS_BASIC_XER:

skeletons/constr_SEQUENCE.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,9 +1594,14 @@ SEQUENCE_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
15941594
}
15951595

15961596
/* Fetch the member from the stream */
1597-
ASN_DEBUG("Decoding member %s in %s", elm->name, td->name);
1598-
rv = elm->type->op->aper_decoder(opt_codec_ctx, elm->type,
1599-
elm->encoding_constraints.per_constraints, memb_ptr2, pd);
1597+
ASN_DEBUG("Decoding member \"%s\" in %s", elm->name, td->name);
1598+
1599+
if(elm->flags & ATF_OPEN_TYPE) {
1600+
rv = OPEN_TYPE_aper_get(opt_codec_ctx, td, st, elm, pd);
1601+
} else {
1602+
rv = elm->type->op->aper_decoder(opt_codec_ctx, elm->type,
1603+
elm->encoding_constraints.per_constraints, memb_ptr2, pd);
1604+
}
16001605
if(rv.code != RC_OK) {
16011606
ASN_DEBUG("Failed decode %s in %s",
16021607
elm->name, td->name);

skeletons/per_decoder.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ uper_decode(const asn_codec_ctx_t *opt_codec_ctx,
9696
}
9797

9898
asn_dec_rval_t
99-
aper_decode_complete(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size) {
99+
aper_decode_complete(const asn_codec_ctx_t *opt_codec_ctx,
100+
const asn_TYPE_descriptor_t *td, void **sptr,
101+
const void *buffer, size_t size) {
100102
asn_dec_rval_t rval;
101103

102104
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,
125127
}
126128

127129
asn_dec_rval_t
128-
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) {
130+
aper_decode(const asn_codec_ctx_t *opt_codec_ctx,
131+
const asn_TYPE_descriptor_t *td, void **sptr, const void *buffer,
132+
size_t size, int skip_bits, int unused_bits) {
129133
asn_codec_ctx_t s_codec_ctx;
130134
asn_dec_rval_t rval;
131135
asn_per_data_t pd;

skeletons/per_decoder.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ asn_dec_rval_t uper_decode(
4444
* Aligned PER decoder of a "complete encoding" as per X.691#10.1.
4545
* On success, this call always returns (.consumed >= 1), in BITS, as per X.691#10.1.3.
4646
*/
47-
asn_dec_rval_t aper_decode_complete(struct asn_codec_ctx_s *opt_codec_ctx,
48-
struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
47+
asn_dec_rval_t aper_decode_complete(
48+
const struct asn_codec_ctx_s *opt_codec_ctx,
49+
const struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
4950
void **struct_ptr, /* Pointer to a target structure's pointer */
5051
const void *buffer, /* Data to be decoded */
5152
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,
5556
* Aligned PER decoder of any ASN.1 type. May be invoked by the application.
5657
* WARNING: This call returns the number of BITS read from the stream. Beware.
5758
*/
58-
asn_dec_rval_t aper_decode(struct asn_codec_ctx_s *opt_codec_ctx,
59-
struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
59+
asn_dec_rval_t aper_decode(
60+
const struct asn_codec_ctx_s *opt_codec_ctx,
61+
const struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
6062
void **struct_ptr, /* Pointer to a target structure's pointer */
6163
const void *buffer, /* Data to be decoded */
6264
size_t size, /* Size of data buffer */

skeletons/per_encoder.c

Lines changed: 22 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -155,57 +155,34 @@ _uper_encode_flush_outp(asn_per_outp_t *po) {
155155
return po->output(po->tmpspace, buf - po->tmpspace, po->op_key);
156156
}
157157

158-
static asn_enc_rval_t aper_encode_internal(const asn_TYPE_descriptor_t *td,
159-
const asn_per_constraints_t *,
160-
const void *sptr, asn_app_consume_bytes_f *cb, void *app_key);
161-
162-
asn_enc_rval_t
163-
aper_encode(const asn_TYPE_descriptor_t *td,
164-
const void *sptr, asn_app_consume_bytes_f *cb, void *app_key) {
165-
return aper_encode_internal(td, 0, sptr, cb, app_key);
166-
}
167-
168-
asn_enc_rval_t
169-
aper_encode_to_buffer(const asn_TYPE_descriptor_t *td,
170-
const void *sptr, void *buffer, size_t buffer_size) {
171-
enc_to_buf_arg key;
172-
173-
key.buffer = buffer;
174-
key.left = buffer_size;
175-
176-
if(td) ASN_DEBUG("Encoding \"%s\" using ALIGNED PER", td->name);
177-
178-
return aper_encode_internal(td, 0, sptr, encode_to_buffer_cb, &key);
179-
}
180-
181158
ssize_t
182159
aper_encode_to_new_buffer(const asn_TYPE_descriptor_t *td,
183-
const asn_per_constraints_t *constraints,
184-
const void *sptr, void **buffer_r) {
185-
asn_enc_rval_t er;
160+
const asn_per_constraints_t *constraints,
161+
const void *sptr, void **buffer_r) {
162+
asn_enc_rval_t er;
186163
enc_dyn_arg key;
187164

188165
memset(&key, 0, sizeof(key));
189166

190-
er = aper_encode_internal(td, constraints, sptr, encode_dyn_cb, &key);
167+
er = aper_encode(td, constraints, sptr, encode_dyn_cb, &key);
191168
switch(er.encoded) {
192-
case -1:
193-
FREEMEM(key.buffer);
194-
return -1;
195-
case 0:
196-
FREEMEM(key.buffer);
197-
key.buffer = MALLOC(1);
198-
if(key.buffer) {
199-
*(char *)key.buffer = '\0';
200-
*buffer_r = key.buffer;
201-
return 1;
202-
} else {
203-
return -1;
204-
}
205-
default:
169+
case -1:
170+
FREEMEM(key.buffer);
171+
return -1;
172+
case 0:
173+
FREEMEM(key.buffer);
174+
key.buffer = MALLOC(1);
175+
if(key.buffer) {
176+
*(char *)key.buffer = '\0';
206177
*buffer_r = key.buffer;
207-
ASN_DEBUG("Complete encoded in %ld bits", er.encoded);
208-
return ((er.encoded + 7) >> 3);
178+
return 1;
179+
} else {
180+
return -1;
181+
}
182+
default:
183+
*buffer_r = key.buffer;
184+
ASN_DEBUG("Complete encoded in %ld bits", (long)er.encoded);
185+
return ((er.encoded + 7) >> 3);
209186
}
210187
}
211188

@@ -229,8 +206,8 @@ _aper_encode_flush_outp(asn_per_outp_t *po) {
229206
return 0;
230207
}
231208

232-
static asn_enc_rval_t
233-
aper_encode_internal(const asn_TYPE_descriptor_t *td,
209+
asn_enc_rval_t
210+
aper_encode(const asn_TYPE_descriptor_t *td,
234211
const asn_per_constraints_t *constraints,
235212
const void *sptr, asn_app_consume_bytes_f *cb, void *app_key) {
236213
asn_per_outp_t po;

skeletons/per_encoder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ asn_enc_rval_t uper_encode(
3030

3131
asn_enc_rval_t aper_encode(
3232
const struct asn_TYPE_descriptor_s *type_descriptor,
33+
const asn_per_constraints_t *constraints,
3334
const void *struct_ptr, /* Structure to be encoded */
3435
asn_app_consume_bytes_f *consume_bytes_cb, /* Data collector */
3536
void *app_key /* Arbitrary callback argument */
@@ -50,6 +51,7 @@ asn_enc_rval_t uper_encode_to_buffer(
5051

5152
asn_enc_rval_t aper_encode_to_buffer(
5253
const struct asn_TYPE_descriptor_s *type_descriptor,
54+
const asn_per_constraints_t *constraints,
5355
const void *struct_ptr, /* Structure to be encoded */
5456
void *buffer, /* Pre-allocated buffer */
5557
size_t buffer_size /* Initial buffer size (max) */

0 commit comments

Comments
 (0)