mirror of https://gerrit.osmocom.org/asn1c
per support
parent
1dc8529923
commit
523de9eba2
|
@ -21,7 +21,7 @@ asn_TYPE_descriptor_t asn_DEF_ANY = {
|
|||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_hex,
|
||||
ANY_encode_xer,
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
0, 0, 0, 0,
|
||||
0, /* No PER visible constraints */
|
||||
|
|
|
@ -28,6 +28,7 @@ asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
|
|||
OCTET_STRING_decode_xer_binary,
|
||||
BIT_STRING_encode_xer,
|
||||
OCTET_STRING_decode_uper, /* Unaligned PER decoder */
|
||||
OCTET_STRING_encode_uper, /* Unaligned PER encoder */
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_BIT_STRING_tags,
|
||||
sizeof(asn_DEF_BIT_STRING_tags)
|
||||
|
|
|
@ -23,7 +23,7 @@ asn_TYPE_descriptor_t asn_DEF_BMPString = {
|
|||
OCTET_STRING_encode_der,
|
||||
BMPString_decode_xer, /* Convert from UTF-8 */
|
||||
BMPString_encode_xer, /* Convert to UTF-8 */
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_BMPString_tags,
|
||||
sizeof(asn_DEF_BMPString_tags)
|
||||
|
|
|
@ -23,6 +23,7 @@ asn_TYPE_descriptor_t asn_DEF_BOOLEAN = {
|
|||
BOOLEAN_decode_xer,
|
||||
BOOLEAN_encode_xer,
|
||||
BOOLEAN_decode_uper, /* Unaligned PER decoder */
|
||||
BOOLEAN_encode_uper, /* Unaligned PER encoder */
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_BOOLEAN_tags,
|
||||
sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]),
|
||||
|
@ -266,3 +267,18 @@ BOOLEAN_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
|||
return rv;
|
||||
}
|
||||
|
||||
|
||||
asn_enc_rval_t
|
||||
BOOLEAN_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
||||
const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
|
||||
asn_enc_rval_t er;
|
||||
|
||||
(void)constraints;
|
||||
|
||||
if(!st) _ASN_ENCODE_FAILED;
|
||||
|
||||
per_put_few_bits(po, *st ? 1 : 0, 1);
|
||||
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ der_type_encoder_f BOOLEAN_encode_der;
|
|||
xer_type_decoder_f BOOLEAN_decode_xer;
|
||||
xer_type_encoder_f BOOLEAN_encode_xer;
|
||||
per_type_decoder_f BOOLEAN_decode_uper;
|
||||
per_type_encoder_f BOOLEAN_encode_uper;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*-
|
||||
* Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Copyright (c) 2003, 2005, 2006 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
|
@ -24,6 +25,7 @@ asn_TYPE_descriptor_t asn_DEF_ENUMERATED = {
|
|||
INTEGER_decode_xer, /* This is temporary! */
|
||||
INTEGER_encode_xer,
|
||||
ENUMERATED_decode_uper, /* Unaligned PER decoder */
|
||||
ENUMERATED_encode_uper, /* Unaligned PER encoder */
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_ENUMERATED_tags,
|
||||
sizeof(asn_DEF_ENUMERATED_tags) / sizeof(asn_DEF_ENUMERATED_tags[0]),
|
||||
|
@ -54,3 +56,16 @@ ENUMERATED_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td
|
|||
rval.code = RC_FAIL;
|
||||
return rval;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
ENUMERATED_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
||||
ENUMERATED_t *st = (ENUMERATED_t *)sptr;
|
||||
long value;
|
||||
|
||||
if(asn_INTEGER2long(st, &value))
|
||||
_ASN_ENCODE_FAILED;
|
||||
|
||||
return NativeEnumerated_encode_uper(td, constraints, &value, po);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ typedef INTEGER_t ENUMERATED_t; /* Implemented via INTEGER */
|
|||
extern asn_TYPE_descriptor_t asn_DEF_ENUMERATED;
|
||||
|
||||
per_type_decoder_f ENUMERATED_decode_uper;
|
||||
per_type_encoder_f ENUMERATED_encode_uper;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_GeneralString = {
|
|||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_hex,
|
||||
OCTET_STRING_encode_xer,
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_GeneralString_tags,
|
||||
sizeof(asn_DEF_GeneralString_tags)
|
||||
|
|
|
@ -152,7 +152,7 @@ asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = {
|
|||
GeneralizedTime_encode_der,
|
||||
OCTET_STRING_decode_xer_utf8,
|
||||
GeneralizedTime_encode_xer,
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_GeneralizedTime_tags,
|
||||
sizeof(asn_DEF_GeneralizedTime_tags)
|
||||
|
|
|
@ -22,7 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_GraphicString = {
|
|||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_hex,
|
||||
OCTET_STRING_encode_xer, /* Can't expect it to be ASCII/UTF8 */
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_GraphicString_tags,
|
||||
sizeof(asn_DEF_GraphicString_tags)
|
||||
|
|
|
@ -22,7 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_IA5String = {
|
|||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_utf8,
|
||||
OCTET_STRING_encode_xer_utf8,
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_IA5String_tags,
|
||||
sizeof(asn_DEF_IA5String_tags)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
|
||||
* Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
|
@ -25,6 +25,7 @@ asn_TYPE_descriptor_t asn_DEF_INTEGER = {
|
|||
INTEGER_decode_xer,
|
||||
INTEGER_encode_xer,
|
||||
INTEGER_decode_uper, /* Unaligned PER decoder */
|
||||
INTEGER_encode_uper, /* Unaligned PER encoder */
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_INTEGER_tags,
|
||||
sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]),
|
||||
|
@ -530,6 +531,78 @@ INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
|||
return rval;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
INTEGER_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
||||
asn_enc_rval_t er;
|
||||
INTEGER_t *st = (INTEGER_t *)sptr;
|
||||
const uint8_t *buf;
|
||||
const uint8_t *end;
|
||||
asn_per_constraint_t *ct;
|
||||
long value = 0;
|
||||
|
||||
if(!st || st->size == 0) _ASN_ENCODE_FAILED;
|
||||
|
||||
if(!constraints) constraints = td->per_constraints;
|
||||
ct = constraints ? &constraints->value : 0;
|
||||
|
||||
er.encoded = 0;
|
||||
|
||||
if(ct) {
|
||||
int inext = 0;
|
||||
if(asn_INTEGER2long(st, &value))
|
||||
_ASN_ENCODE_FAILED;
|
||||
/* Check proper range */
|
||||
if(ct->flags & APC_SEMI_CONSTRAINED) {
|
||||
if(value < ct->lower_bound)
|
||||
inext = 1;
|
||||
} else if(ct->range_bits >= 0) {
|
||||
if(value < ct->lower_bound
|
||||
|| value > ct->upper_bound)
|
||||
inext = 1;
|
||||
}
|
||||
ASN_DEBUG("Value %ld (%02x/%d) lb %ld ub %ld %s",
|
||||
value, st->buf[0], st->size,
|
||||
ct->lower_bound, ct->upper_bound,
|
||||
inext ? "ext" : "fix");
|
||||
if(ct->flags & APC_EXTENSIBLE) {
|
||||
if(per_put_few_bits(po, inext, 1))
|
||||
_ASN_ENCODE_FAILED;
|
||||
if(inext) ct = 0;
|
||||
} else if(inext) {
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* X.691, #12.2.2 */
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
/* #10.5.6 */
|
||||
ASN_DEBUG("Encoding integer with range %d bits",
|
||||
ct->range_bits);
|
||||
if(per_put_few_bits(po, value - ct->lower_bound,
|
||||
ct->range_bits))
|
||||
_ASN_ENCODE_FAILED;
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
|
||||
if(ct && ct->lower_bound) {
|
||||
ASN_DEBUG("Adjust lower bound to %ld", ct->lower_bound);
|
||||
/* TODO: adjust lower bound */
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
|
||||
for(buf = st->buf, end = st->buf + st->size; buf < end;) {
|
||||
ssize_t mayEncode = uper_put_length(po, end - buf);
|
||||
if(mayEncode < 0)
|
||||
_ASN_ENCODE_FAILED;
|
||||
if(per_put_many_bits(po, buf, 8 * mayEncode))
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
|
||||
int
|
||||
asn_INTEGER2long(const INTEGER_t *iptr, long *lptr) {
|
||||
uint8_t *b, *end;
|
||||
|
|
|
@ -38,6 +38,7 @@ der_type_encoder_f INTEGER_encode_der;
|
|||
xer_type_decoder_f INTEGER_decode_xer;
|
||||
xer_type_encoder_f INTEGER_encode_xer;
|
||||
per_type_decoder_f INTEGER_decode_uper;
|
||||
per_type_encoder_f INTEGER_encode_uper;
|
||||
|
||||
/***********************************
|
||||
* Some handy conversion routines. *
|
||||
|
|
|
@ -22,7 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_ISO646String = {
|
|||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_utf8,
|
||||
OCTET_STRING_encode_xer_utf8,
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_ISO646String_tags,
|
||||
sizeof(asn_DEF_ISO646String_tags)
|
||||
|
|
|
@ -24,6 +24,7 @@ asn_TYPE_descriptor_t asn_DEF_NULL = {
|
|||
NULL_decode_xer,
|
||||
NULL_encode_xer,
|
||||
NULL_decode_uper, /* Unaligned PER decoder */
|
||||
NULL_encode_uper, /* Unaligned PER encoder */
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_NULL_tags,
|
||||
sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]),
|
||||
|
@ -130,3 +131,17 @@ NULL_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
|||
rv.consumed = 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
NULL_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints,
|
||||
void *sptr, asn_per_outp_t *po) {
|
||||
asn_enc_rval_t er;
|
||||
|
||||
(void)td;
|
||||
(void)constraints;
|
||||
(void)sptr;
|
||||
(void)po;
|
||||
|
||||
er.encoded = 0;
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ der_type_encoder_f NULL_encode_der;
|
|||
xer_type_decoder_f NULL_decode_xer;
|
||||
xer_type_encoder_f NULL_encode_xer;
|
||||
per_type_decoder_f NULL_decode_uper;
|
||||
per_type_encoder_f NULL_encode_uper;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ asn_TYPE_descriptor_t asn_DEF_NativeEnumerated = {
|
|||
NativeInteger_decode_xer,
|
||||
NativeEnumerated_encode_xer,
|
||||
NativeEnumerated_decode_uper,
|
||||
NativeEnumerated_encode_uper,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_NativeEnumerated_tags,
|
||||
sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]),
|
||||
|
@ -70,8 +71,9 @@ NativeEnumerated_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
|
|||
}
|
||||
|
||||
asn_dec_rval_t
|
||||
NativeEnumerated_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) {
|
||||
NativeEnumerated_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_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_dec_rval_t rval = { RC_OK, 0 };
|
||||
long *native = (long *)*sptr;
|
||||
|
@ -123,3 +125,80 @@ NativeEnumerated_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor
|
|||
return rval;
|
||||
}
|
||||
|
||||
static int
|
||||
NativeEnumerated__compar_value2enum(const void *ap, const void *bp) {
|
||||
const asn_INTEGER_enum_map_t *a = ap;
|
||||
const asn_INTEGER_enum_map_t *b = bp;
|
||||
if(a->nat_value == b->nat_value)
|
||||
return 0;
|
||||
if(a->nat_value < b->nat_value)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
NativeEnumerated_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
||||
asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics;
|
||||
asn_enc_rval_t er;
|
||||
long native, value;
|
||||
asn_per_constraint_t *ct;
|
||||
int inext = 0;
|
||||
asn_INTEGER_enum_map_t key;
|
||||
asn_INTEGER_enum_map_t *kf;
|
||||
|
||||
if(!sptr) _ASN_ENCODE_FAILED;
|
||||
if(!specs) _ASN_ENCODE_FAILED;
|
||||
|
||||
if(constraints) ct = &constraints->value;
|
||||
else if(td->per_constraints) ct = &td->per_constraints->value;
|
||||
else _ASN_ENCODE_FAILED; /* Mandatory! */
|
||||
|
||||
ASN_DEBUG("Encoding %s as NativeEnumerated", td->name);
|
||||
|
||||
er.encoded = 0;
|
||||
|
||||
native = *(long *)sptr;
|
||||
if(native < 0) _ASN_ENCODE_FAILED;
|
||||
|
||||
key.nat_value = native;
|
||||
kf = bsearch(&key, specs->value2enum, specs->map_count,
|
||||
sizeof(key), NativeEnumerated__compar_value2enum);
|
||||
if(!kf) {
|
||||
ASN_DEBUG("No element corresponds to %ld", native);
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
value = kf - specs->value2enum;
|
||||
|
||||
if(ct->range_bits >= 0) {
|
||||
int cmpWith = specs->extension
|
||||
? specs->extension - 1 : specs->map_count;
|
||||
if(value >= cmpWith)
|
||||
inext = 1;
|
||||
}
|
||||
if(ct->flags & APC_EXTENSIBLE) {
|
||||
if(per_put_few_bits(po, inext, 0))
|
||||
_ASN_ENCODE_FAILED;
|
||||
ct = 0;
|
||||
} else if(inext) {
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
if(per_put_few_bits(po, value, ct->range_bits))
|
||||
_ASN_ENCODE_FAILED;
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
|
||||
if(!specs->extension)
|
||||
_ASN_ENCODE_FAILED;
|
||||
|
||||
/*
|
||||
* X.691, #10.6: normally small non-negative whole number;
|
||||
*/
|
||||
if(uper_put_nsnnwn(po, value - (specs->extension - 1)))
|
||||
_ASN_ENCODE_FAILED;
|
||||
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*-
|
||||
* Copyright (c) 2004, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Copyright (c) 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
/*
|
||||
|
@ -22,6 +23,7 @@ extern asn_TYPE_descriptor_t asn_DEF_NativeEnumerated;
|
|||
|
||||
xer_type_encoder_f NativeEnumerated_encode_xer;
|
||||
per_type_decoder_f NativeEnumerated_decode_uper;
|
||||
per_type_encoder_f NativeEnumerated_encode_uper;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*-
|
||||
* Copyright (c) 2004, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Copyright (c) 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
/*
|
||||
|
@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_NativeInteger = {
|
|||
NativeInteger_decode_xer,
|
||||
NativeInteger_encode_xer,
|
||||
NativeInteger_decode_uper, /* Unaligned PER decoder */
|
||||
NativeInteger_encode_uper, /* Unaligned PER encoder */
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_NativeInteger_tags,
|
||||
sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
|
||||
|
@ -253,6 +255,27 @@ NativeInteger_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
|
|||
return rval;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
NativeInteger_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
||||
asn_enc_rval_t er;
|
||||
long native;
|
||||
INTEGER_t tmpint;
|
||||
|
||||
if(!sptr) _ASN_ENCODE_FAILED;
|
||||
|
||||
native = *(long *)sptr;
|
||||
|
||||
ASN_DEBUG("Encoding NativeInteger %s %ld (UPER)", td->name, native);
|
||||
|
||||
memset(&tmpint, 0, sizeof(tmpint));
|
||||
if(asn_long2INTEGER(&tmpint, native))
|
||||
_ASN_ENCODE_FAILED;
|
||||
er = INTEGER_encode_uper(td, constraints, &tmpint, po);
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
|
||||
return er;
|
||||
}
|
||||
|
||||
/*
|
||||
* INTEGER specific human-readable output.
|
||||
*/
|
||||
|
|
|
@ -28,6 +28,7 @@ der_type_encoder_f NativeInteger_encode_der;
|
|||
xer_type_decoder_f NativeInteger_decode_xer;
|
||||
xer_type_encoder_f NativeInteger_encode_xer;
|
||||
per_type_decoder_f NativeInteger_decode_uper;
|
||||
per_type_encoder_f NativeInteger_encode_uper;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ asn_TYPE_descriptor_t asn_DEF_NativeReal = {
|
|||
NativeReal_encode_der,
|
||||
NativeReal_decode_xer,
|
||||
NativeReal_encode_xer,
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_NativeReal_tags,
|
||||
sizeof(asn_DEF_NativeReal_tags) / sizeof(asn_DEF_NativeReal_tags[0]),
|
||||
|
|
|
@ -22,7 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_NumericString = {
|
|||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_utf8,
|
||||
OCTET_STRING_encode_xer_utf8,
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_NumericString_tags,
|
||||
sizeof(asn_DEF_NumericString_tags)
|
||||
|
|
|
@ -23,7 +23,7 @@ asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = {
|
|||
der_encode_primitive,
|
||||
OBJECT_IDENTIFIER_decode_xer,
|
||||
OBJECT_IDENTIFIER_encode_xer,
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_OBJECT_IDENTIFIER_tags,
|
||||
sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
|
||||
|
@ -425,6 +425,7 @@ OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf, const void *arcval, unsigned i
|
|||
* The following conditions must hold:
|
||||
* assert(arcval);
|
||||
* assert(arcval_size > 0);
|
||||
* assert(arcval_size <= 16);
|
||||
* assert(arcbuf);
|
||||
*/
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
|
@ -437,12 +438,7 @@ OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf, const void *arcval, unsigned i
|
|||
unsigned int cache;
|
||||
uint8_t *bp = arcbuf;
|
||||
int bits;
|
||||
#ifdef __GNUC__
|
||||
uint8_t buffer[arcval_size];
|
||||
#else
|
||||
uint8_t *buffer = alloca(arcval_size);
|
||||
if(!buffer) { errno = ENOMEM; return -1; }
|
||||
#endif
|
||||
uint8_t buffer[16];
|
||||
|
||||
if(isLittleEndian && !prepared_order) {
|
||||
const uint8_t *a = (const unsigned char *)arcval + arcval_size - 1;
|
||||
|
@ -502,7 +498,9 @@ OBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *oid, const void *arcs, unsigned
|
|||
unsigned size;
|
||||
unsigned i;
|
||||
|
||||
if(!oid || !arcs || arc_type_size < 1 || arc_slots < 2) {
|
||||
if(!oid || !arcs || arc_type_size < 1
|
||||
|| arc_type_size > 16
|
||||
|| arc_slots < 2) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -586,17 +584,8 @@ OBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *oid, const void *arcs, unsigned
|
|||
*/
|
||||
{
|
||||
uint8_t *tp;
|
||||
#ifdef __GNUC__
|
||||
uint8_t first_value[1 + arc_type_size]; /* of two arcs */
|
||||
uint8_t first_value[1 + 16]; /* of two arcs */
|
||||
uint8_t *fv = first_value;
|
||||
#else
|
||||
uint8_t *first_value = alloca(1 + arc_type_size);
|
||||
uint8_t *fv = first_value;
|
||||
if(!first_value) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simulate first_value = arc0 * 40 + arc1;
|
||||
|
|
|
@ -33,6 +33,7 @@ asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = {
|
|||
OCTET_STRING_decode_xer_hex,
|
||||
OCTET_STRING_encode_xer,
|
||||
OCTET_STRING_decode_uper, /* Unaligned PER decoder */
|
||||
OCTET_STRING_encode_uper, /* Unaligned PER encoder */
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_OCTET_STRING_tags,
|
||||
sizeof(asn_DEF_OCTET_STRING_tags)
|
||||
|
@ -1297,6 +1298,103 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
|
|||
return rval;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
||||
|
||||
asn_OCTET_STRING_specifics_t *specs = td->specifics
|
||||
? (asn_OCTET_STRING_specifics_t *)td->specifics
|
||||
: &asn_DEF_OCTET_STRING_specs;
|
||||
asn_per_constraint_t *ct = constraints ? &constraints->size
|
||||
: (td->per_constraints
|
||||
? &td->per_constraints->size
|
||||
: &asn_DEF_OCTET_STRING_constraint);
|
||||
const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
|
||||
int unit_bits = (specs->subvariant != 1) * 7 + 1;
|
||||
asn_enc_rval_t er;
|
||||
int ct_extensible = ct->flags & APC_EXTENSIBLE;
|
||||
int inext = 0; /* Lies not within extension root */
|
||||
int sizeinunits = st->size;
|
||||
const uint8_t *buf;
|
||||
int ret;
|
||||
|
||||
if(!st || !st->buf)
|
||||
_ASN_ENCODE_FAILED;
|
||||
|
||||
if(unit_bits == 1) {
|
||||
ASN_DEBUG("BIT STRING of %d bytes, %d bits unused",
|
||||
sizeinunits, st->bits_unused);
|
||||
sizeinunits = sizeinunits * 8 - (st->bits_unused & 0x07);
|
||||
}
|
||||
|
||||
ASN_DEBUG("Encoding %s into %d units",
|
||||
td->name, sizeinunits);
|
||||
|
||||
/* Figure out wheter size lies within PER visible consrtaint */
|
||||
|
||||
if(ct->effective_bits >= 0) {
|
||||
if(sizeinunits < ct->lower_bound
|
||||
|| sizeinunits > ct->upper_bound) {
|
||||
if(ct_extensible) {
|
||||
ct = &asn_DEF_OCTET_STRING_constraint;
|
||||
inext = 1;
|
||||
} else
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
} else {
|
||||
inext = 0;
|
||||
}
|
||||
|
||||
if(ct_extensible) {
|
||||
/* Declare whether length is [not] within extension root */
|
||||
if(per_put_few_bits(po, inext, 1))
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
|
||||
/* X.691, #16.5: zero-length encoding */
|
||||
/* X.691, #16.6: short fixed length encoding (up to 2 octets) */
|
||||
/* X.691, #16.7: long fixed length encoding (up to 64K octets) */
|
||||
if(ct->effective_bits >= 0) {
|
||||
ASN_DEBUG("Encoding %d bytes (%ld), length in %d bits",
|
||||
st->size, sizeinunits - ct->lower_bound,
|
||||
ct->effective_bits);
|
||||
ret = per_put_few_bits(po, sizeinunits - ct->lower_bound,
|
||||
ct->effective_bits);
|
||||
if(ret) _ASN_ENCODE_FAILED;
|
||||
ret = per_put_many_bits(po, st->buf, sizeinunits);
|
||||
if(ret) _ASN_ENCODE_FAILED;
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
|
||||
ASN_DEBUG("Encoding %d bytes", st->size);
|
||||
|
||||
if(sizeinunits == 0) {
|
||||
if(uper_put_length(po, 0))
|
||||
_ASN_ENCODE_FAILED;
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
|
||||
buf = st->buf;
|
||||
while(sizeinunits) {
|
||||
ssize_t maySave = uper_put_length(po, sizeinunits);
|
||||
if(maySave < 0) _ASN_ENCODE_FAILED;
|
||||
|
||||
ASN_DEBUG("Encoding %d of %d", maySave, sizeinunits);
|
||||
|
||||
ret = per_put_many_bits(po, buf, maySave);
|
||||
if(ret) _ASN_ENCODE_FAILED;
|
||||
|
||||
if(unit_bits == 1)
|
||||
buf += maySave >> 3;
|
||||
else
|
||||
buf += maySave;
|
||||
sizeinunits -= maySave;
|
||||
assert(!(maySave & 0x07) || !sizeinunits);
|
||||
}
|
||||
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
|
||||
int
|
||||
OCTET_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
|
|
|
@ -31,6 +31,7 @@ xer_type_decoder_f OCTET_STRING_decode_xer_utf8; /* ASCII/UTF-8 */
|
|||
xer_type_encoder_f OCTET_STRING_encode_xer;
|
||||
xer_type_encoder_f OCTET_STRING_encode_xer_utf8;
|
||||
per_type_decoder_f OCTET_STRING_decode_uper;
|
||||
per_type_encoder_f OCTET_STRING_encode_uper;
|
||||
|
||||
/******************************
|
||||
* Handy conversion routines. *
|
||||
|
|
|
@ -22,7 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_ObjectDescriptor = {
|
|||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_utf8,
|
||||
OCTET_STRING_encode_xer_utf8,
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_ObjectDescriptor_tags,
|
||||
sizeof(asn_DEF_ObjectDescriptor_tags)
|
||||
|
|
|
@ -22,7 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_PrintableString = {
|
|||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_utf8,
|
||||
OCTET_STRING_encode_xer_utf8,
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_PrintableString_tags,
|
||||
sizeof(asn_DEF_PrintableString_tags)
|
||||
|
|
|
@ -42,7 +42,7 @@ asn_TYPE_descriptor_t asn_DEF_REAL = {
|
|||
der_encode_primitive,
|
||||
REAL_decode_xer,
|
||||
REAL_encode_xer,
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_REAL_tags,
|
||||
sizeof(asn_DEF_REAL_tags) / sizeof(asn_DEF_REAL_tags[0]),
|
||||
|
|
|
@ -25,7 +25,7 @@ asn_TYPE_descriptor_t asn_DEF_RELATIVE_OID = {
|
|||
der_encode_primitive,
|
||||
RELATIVE_OID_decode_xer,
|
||||
RELATIVE_OID_encode_xer,
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_RELATIVE_OID_tags,
|
||||
sizeof(asn_DEF_RELATIVE_OID_tags)
|
||||
|
|
|
@ -22,7 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_T61String = {
|
|||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_hex,
|
||||
OCTET_STRING_encode_xer,
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_T61String_tags,
|
||||
sizeof(asn_DEF_T61String_tags)
|
||||
|
|
|
@ -22,7 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_TeletexString = {
|
|||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_hex,
|
||||
OCTET_STRING_encode_xer,
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_TeletexString_tags,
|
||||
sizeof(asn_DEF_TeletexString_tags)
|
||||
|
|
|
@ -28,7 +28,7 @@ asn_TYPE_descriptor_t asn_DEF_UTCTime = {
|
|||
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
|
||||
OCTET_STRING_decode_xer_utf8,
|
||||
UTCTime_encode_xer,
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_UTCTime_tags,
|
||||
sizeof(asn_DEF_UTCTime_tags)
|
||||
|
|
|
@ -22,7 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_UTF8String = {
|
|||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_utf8,
|
||||
OCTET_STRING_encode_xer_utf8,
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_UTF8String_tags,
|
||||
sizeof(asn_DEF_UTF8String_tags)
|
||||
|
|
|
@ -23,7 +23,7 @@ asn_TYPE_descriptor_t asn_DEF_UniversalString = {
|
|||
OCTET_STRING_encode_der,
|
||||
UniversalString_decode_xer, /* Convert from UTF-8 */
|
||||
UniversalString_encode_xer, /* Convert into UTF-8 */
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_UniversalString_tags,
|
||||
sizeof(asn_DEF_UniversalString_tags)
|
||||
|
|
|
@ -22,7 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_VideotexString = {
|
|||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_hex,
|
||||
OCTET_STRING_encode_xer,
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_VideotexString_tags,
|
||||
sizeof(asn_DEF_VideotexString_tags)
|
||||
|
|
|
@ -22,7 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_VisibleString = {
|
|||
OCTET_STRING_encode_der,
|
||||
OCTET_STRING_decode_xer_utf8,
|
||||
OCTET_STRING_encode_xer_utf8,
|
||||
0,
|
||||
0, 0,
|
||||
0, /* Use generic outmost tag fetcher */
|
||||
asn_DEF_VisibleString_tags,
|
||||
sizeof(asn_DEF_VisibleString_tags)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
|
@ -363,6 +363,8 @@ CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
|
|||
size_t computed_size = 0;
|
||||
int present;
|
||||
|
||||
if(!sptr) _ASN_ENCODE_FAILED;
|
||||
|
||||
ASN_DEBUG("%s %s as CHOICE",
|
||||
cb?"Encoding":"Estimating", td->name);
|
||||
|
||||
|
@ -892,6 +894,82 @@ CHOICE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
|||
return rv;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
CHOICE_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
||||
asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
|
||||
asn_TYPE_member_t *elm; /* CHOICE's element */
|
||||
asn_per_constraint_t *ct;
|
||||
void *memb_ptr;
|
||||
int present;
|
||||
|
||||
if(!sptr) _ASN_ENCODE_FAILED;
|
||||
|
||||
ASN_DEBUG("Encoding %s as CHOICE", td->name);
|
||||
|
||||
if(constraints) ct = &constraints->value;
|
||||
else if(td->per_constraints) ct = &td->per_constraints->value;
|
||||
else ct = 0;
|
||||
|
||||
present = _fetch_present_idx(sptr,
|
||||
specs->pres_offset, specs->pres_size);
|
||||
|
||||
/*
|
||||
* If the structure was not initialized properly, it cannot be encoded:
|
||||
* can't deduce what to encode in the choice type.
|
||||
*/
|
||||
if(present <= 0 || present > td->elements_count)
|
||||
_ASN_ENCODE_FAILED;
|
||||
else
|
||||
present--;
|
||||
|
||||
/* Adjust if canonical order is different from natural order */
|
||||
if(specs->canonical_order)
|
||||
present = specs->canonical_order[present];
|
||||
|
||||
ASN_DEBUG("Encoding %s CHOICE element %d", td->name, present);
|
||||
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
if(present < ct->lower_bound
|
||||
|| present > ct->upper_bound) {
|
||||
if(ct->flags & APC_EXTENSIBLE) {
|
||||
if(per_put_few_bits(po, 1, 1))
|
||||
_ASN_ENCODE_FAILED;
|
||||
} else {
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
ct = 0;
|
||||
}
|
||||
}
|
||||
if(ct && ct->flags & APC_EXTENSIBLE)
|
||||
if(per_put_few_bits(po, 0, 1))
|
||||
_ASN_ENCODE_FAILED;
|
||||
|
||||
if(ct && ct->range_bits >= 0) {
|
||||
if(per_put_few_bits(po, present, ct->range_bits))
|
||||
_ASN_ENCODE_FAILED;
|
||||
} else {
|
||||
if(specs->ext_start == -1)
|
||||
_ASN_ENCODE_FAILED;
|
||||
if(uper_put_nsnnwn(po, present - specs->ext_start))
|
||||
_ASN_ENCODE_FAILED;
|
||||
ASN_DEBUG("NOT IMPLEMENTED YET");
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
|
||||
elm = &td->elements[present];
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
/* Member is a pointer to another structure */
|
||||
memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
|
||||
if(!memb_ptr) _ASN_ENCODE_FAILED;
|
||||
} else {
|
||||
memb_ptr = (char *)sptr + elm->memb_offset;
|
||||
}
|
||||
|
||||
return elm->type->uper_encoder(elm->type, elm->per_constraints,
|
||||
memb_ptr, po);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
CHOICE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
|
|
|
@ -47,6 +47,7 @@ der_type_encoder_f CHOICE_encode_der;
|
|||
xer_type_decoder_f CHOICE_decode_xer;
|
||||
xer_type_encoder_f CHOICE_encode_xer;
|
||||
per_type_decoder_f CHOICE_decode_uper;
|
||||
per_type_encoder_f CHOICE_encode_uper;
|
||||
asn_outmost_tag_f CHOICE_outmost_tag;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
|
||||
* Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
|
@ -1097,7 +1097,7 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
|||
/* This element is not present */
|
||||
if(elm->default_value) {
|
||||
/* Fill-in DEFAULT */
|
||||
if(elm->default_value(memb_ptr2)) {
|
||||
if(elm->default_value(1, memb_ptr2)) {
|
||||
FREEMEM(opres);
|
||||
_ASN_DECODE_FAILED;
|
||||
}
|
||||
|
@ -1137,14 +1137,15 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
|||
|
||||
/* Fetch the pointer to this member */
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
memb_ptr2 = (void **)((char *)st + elm->memb_offset);
|
||||
memb_ptr2 = (void **)((char *)st
|
||||
+ elm->memb_offset);
|
||||
} else {
|
||||
memb_ptr = (char *)st + elm->memb_offset;
|
||||
memb_ptr2 = &memb_ptr;
|
||||
}
|
||||
|
||||
/* Set default value */
|
||||
if(elm->default_value(memb_ptr2)) {
|
||||
if(elm->default_value(1, memb_ptr2)) {
|
||||
FREEMEM(opres);
|
||||
_ASN_DECODE_FAILED;
|
||||
}
|
||||
|
@ -1157,3 +1158,92 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
|||
return rv;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
||||
asn_SEQUENCE_specifics_t *specs
|
||||
= (asn_SEQUENCE_specifics_t *)td->specifics;
|
||||
asn_enc_rval_t er;
|
||||
int edx;
|
||||
int i;
|
||||
|
||||
(void)constraints;
|
||||
|
||||
if(!sptr)
|
||||
_ASN_ENCODE_FAILED;
|
||||
|
||||
er.encoded = 0;
|
||||
|
||||
ASN_DEBUG("Encoding %s as SEQUENCE (UPER)", td->name);
|
||||
if(specs->ext_before >= 0)
|
||||
_ASN_ENCODE_FAILED; /* We don't encode extensions yet */
|
||||
|
||||
/* Encode a presence bitmap */
|
||||
for(i = 0; i < specs->roms_count; i++) {
|
||||
void *memb_ptr; /* Pointer to the member */
|
||||
void **memb_ptr2; /* Pointer to that pointer */
|
||||
edx = specs->oms[i];
|
||||
asn_TYPE_member_t *elm = &td->elements[edx];
|
||||
int present;
|
||||
|
||||
/* Fetch the pointer to this member */
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
|
||||
present = (*memb_ptr2 != 0);
|
||||
} else {
|
||||
memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
||||
memb_ptr2 = &memb_ptr;
|
||||
present = 1;
|
||||
}
|
||||
|
||||
/* Eliminate default values */
|
||||
if(present && elm->default_value
|
||||
&& elm->default_value(0, memb_ptr2) == 1)
|
||||
present = 0;
|
||||
|
||||
ASN_DEBUG("Element %s %s %s->%s is %s",
|
||||
elm->flags & ATF_POINTER ? "ptr" : "inline",
|
||||
elm->default_value ? "def" : "wtv",
|
||||
td->name, elm->name, present ? "present" : "absent");
|
||||
if(per_put_few_bits(po, present, 1))
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the sequence ROOT elements.
|
||||
*/
|
||||
for(edx = 0; edx < ((specs->ext_before < 0)
|
||||
? td->elements_count : specs->ext_before + 1); edx++) {
|
||||
asn_TYPE_member_t *elm = &td->elements[edx];
|
||||
void *memb_ptr; /* Pointer to the member */
|
||||
void **memb_ptr2; /* Pointer to that pointer */
|
||||
|
||||
/* Fetch the pointer to this member */
|
||||
if(elm->flags & ATF_POINTER) {
|
||||
memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
|
||||
if(!*memb_ptr2) {
|
||||
ASN_DEBUG("Element %s %d not present",
|
||||
elm->name, edx);
|
||||
if(elm->optional)
|
||||
continue;
|
||||
/* Mandatory element is missing */
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
} else {
|
||||
memb_ptr = (void *)((char *)sptr + elm->memb_offset);
|
||||
memb_ptr2 = &memb_ptr;
|
||||
}
|
||||
|
||||
/* Eliminate default values */
|
||||
if(elm->default_value && elm->default_value(0, memb_ptr2) == 1)
|
||||
continue;
|
||||
|
||||
er = elm->type->uper_encoder(elm->type, elm->per_constraints,
|
||||
*memb_ptr2, po);
|
||||
if(er.encoded == -1)
|
||||
return er;
|
||||
}
|
||||
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ der_type_encoder_f SEQUENCE_encode_der;
|
|||
xer_type_decoder_f SEQUENCE_decode_xer;
|
||||
xer_type_encoder_f SEQUENCE_encode_xer;
|
||||
per_type_decoder_f SEQUENCE_decode_uper;
|
||||
per_type_encoder_f SEQUENCE_encode_uper;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*-
|
||||
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
|
||||
* Copyright (c) 2003, 2004, 2006 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
#include <asn_internal.h>
|
||||
|
@ -139,3 +140,69 @@ cb_failed:
|
|||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
|
||||
asn_enc_rval_t
|
||||
SEQUENCE_OF_encode_uper(asn_TYPE_descriptor_t *td,
|
||||
asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
|
||||
asn_anonymous_sequence_ *list;
|
||||
asn_per_constraint_t *ct;
|
||||
asn_enc_rval_t er;
|
||||
asn_TYPE_member_t *elm = td->elements;
|
||||
int seq;
|
||||
|
||||
if(!sptr) _ASN_ENCODE_FAILED;
|
||||
list = _A_SEQUENCE_FROM_VOID(sptr);
|
||||
|
||||
er.encoded = 0;
|
||||
|
||||
ASN_DEBUG("Encoding %s as SEQUENCE OF (%d)", td->name, list->count);
|
||||
|
||||
if(constraints) ct = &constraints->size;
|
||||
else if(td->per_constraints) ct = &td->per_constraints->size;
|
||||
else ct = 0;
|
||||
|
||||
/* If extensible constraint, check if size is in root */
|
||||
if(ct) {
|
||||
int not_in_root = (list->count < ct->lower_bound
|
||||
|| list->count > ct->upper_bound);
|
||||
ASN_DEBUG("lb %ld ub %ld %s",
|
||||
ct->lower_bound, ct->upper_bound,
|
||||
ct->flags & APC_EXTENSIBLE ? "ext" : "fix");
|
||||
if(ct->flags & APC_EXTENSIBLE) {
|
||||
/* Declare whether size is in extension root */
|
||||
if(per_put_few_bits(po, not_in_root, 1))
|
||||
_ASN_ENCODE_FAILED;
|
||||
if(not_in_root) ct = 0;
|
||||
} else if(not_in_root && ct->effective_bits >= 0)
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
|
||||
if(ct && ct->effective_bits >= 0) {
|
||||
/* X.691, #19.5: No length determinant */
|
||||
if(per_put_few_bits(po, list->count - ct->lower_bound,
|
||||
ct->effective_bits))
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
|
||||
for(seq = -1; seq < list->count;) {
|
||||
ssize_t mayEncode;
|
||||
if(seq < 0) seq = 0;
|
||||
if(ct && ct->effective_bits >= 0) {
|
||||
mayEncode = list->count;
|
||||
} else {
|
||||
mayEncode = uper_put_length(po, list->count - seq);
|
||||
if(mayEncode < 0) _ASN_ENCODE_FAILED;
|
||||
}
|
||||
|
||||
while(mayEncode--) {
|
||||
void *memb_ptr = list->array[seq++];
|
||||
if(!memb_ptr) _ASN_ENCODE_FAILED;
|
||||
er = elm->type->uper_encoder(elm->type,
|
||||
elm->per_constraints, memb_ptr, po);
|
||||
if(er.encoded == -1)
|
||||
_ASN_ENCODE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
_ASN_ENCODED_OK(er);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ extern "C" {
|
|||
#define SEQUENCE_OF_decode_uper SET_OF_decode_uper
|
||||
der_type_encoder_f SEQUENCE_OF_encode_der;
|
||||
xer_type_encoder_f SEQUENCE_OF_encode_xer;
|
||||
per_type_encoder_f SEQUENCE_OF_encode_uper;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ der_type_encoder_f SET_OF_encode_der;
|
|||
xer_type_decoder_f SET_OF_decode_xer;
|
||||
xer_type_encoder_f SET_OF_encode_xer;
|
||||
per_type_decoder_f SET_OF_decode_uper;
|
||||
per_type_encoder_f SET_OF_encode_uper;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
|
||||
* Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
|
||||
* All rights reserved.
|
||||
* Redistribution and modifications are permitted subject to BSD license.
|
||||
*/
|
||||
|
@ -40,6 +40,7 @@ typedef struct asn_struct_ctx_s {
|
|||
#include <xer_decoder.h> /* Decoder of XER (XML, text) */
|
||||
#include <xer_encoder.h> /* Encoder into XER (XML, text) */
|
||||
#include <per_decoder.h> /* Packet Encoding Rules decoder */
|
||||
#include <per_encoder.h> /* Packet Encoding Rules encoder */
|
||||
#include <constraints.h> /* Subtype constraints support */
|
||||
|
||||
/*
|
||||
|
@ -97,6 +98,7 @@ typedef struct asn_TYPE_descriptor_s {
|
|||
xer_type_decoder_f *xer_decoder; /* Generic XER decoder */
|
||||
xer_type_encoder_f *xer_encoder; /* [Canonical] XER encoder */
|
||||
per_type_decoder_f *uper_decoder; /* Unaligned PER decoder */
|
||||
per_type_encoder_f *uper_encoder; /* Unaligned PER encoder */
|
||||
|
||||
/***********************************************************************
|
||||
* Internally useful members. Not to be used by applications directly. *
|
||||
|
@ -144,7 +146,7 @@ typedef struct asn_TYPE_member_s {
|
|||
asn_TYPE_descriptor_t *type; /* Member type descriptor */
|
||||
asn_constr_check_f *memb_constraints; /* Constraints validator */
|
||||
asn_per_constraints_t *per_constraints; /* PER compiled constraints */
|
||||
int (*default_value)(void **sptr); /* DEFAULT <value> */
|
||||
int (*default_value)(int setval, void **sptr); /* DEFAULT <value> */
|
||||
char *name; /* ASN.1 identifier of the element */
|
||||
} asn_TYPE_member_t;
|
||||
|
||||
|
|
|
@ -52,20 +52,19 @@ static int encode_to_buffer_cb(const void *buffer, size_t size, void *key) {
|
|||
*/
|
||||
asn_enc_rval_t
|
||||
der_encode_to_buffer(asn_TYPE_descriptor_t *type_descriptor, void *struct_ptr,
|
||||
void *buffer, size_t *buffer_size) {
|
||||
void *buffer, size_t buffer_size) {
|
||||
enc_to_buf_arg arg;
|
||||
asn_enc_rval_t ec;
|
||||
|
||||
arg.buffer = buffer;
|
||||
arg.left = *buffer_size;
|
||||
arg.left = buffer_size;
|
||||
|
||||
ec = type_descriptor->der_encoder(type_descriptor,
|
||||
struct_ptr, /* Pointer to the destination structure */
|
||||
0, 0, encode_to_buffer_cb, &arg);
|
||||
if(ec.encoded != -1) {
|
||||
assert(ec.encoded == (ssize_t)(*buffer_size - arg.left));
|
||||
assert(ec.encoded == (ssize_t)(buffer_size - arg.left));
|
||||
/* Return the encoded contents size */
|
||||
*buffer_size = ec.encoded;
< |