mirror of https://gerrit.osmocom.org/asn1c
BIT STRING decode for OER
This commit is contained in:
parent
aa7c5a635a
commit
cfc16d354a
|
@ -288,6 +288,7 @@ ASN_MODULE_SOURCES+=NativeEnumerated_oer.c
|
||||||
ASN_MODULE_SOURCES+=constr_SEQUENCE_oer.c
|
ASN_MODULE_SOURCES+=constr_SEQUENCE_oer.c
|
||||||
ASN_MODULE_SOURCES+=constr_CHOICE_oer.c
|
ASN_MODULE_SOURCES+=constr_CHOICE_oer.c
|
||||||
ASN_MODULE_SOURCES+=constr_SET_OF_oer.c
|
ASN_MODULE_SOURCES+=constr_SET_OF_oer.c
|
||||||
|
ASN_MODULE_SOURCES+=BIT_STRING_oer.c
|
||||||
ASN_CONVERTER_SOURCES+=pdu_collection.c
|
ASN_CONVERTER_SOURCES+=pdu_collection.c
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,8 @@ asn_TYPE_operation_t asn_OP_BIT_STRING = {
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
#else
|
#else
|
||||||
0,
|
BIT_STRING_decode_oer,
|
||||||
0,
|
BIT_STRING_encode_oer,
|
||||||
#endif /* ASN_DISABLE_OER_SUPPORT */
|
#endif /* ASN_DISABLE_OER_SUPPORT */
|
||||||
#ifdef ASN_DISABLE_PER_SUPPORT
|
#ifdef ASN_DISABLE_PER_SUPPORT
|
||||||
0,
|
0,
|
||||||
|
|
|
@ -28,6 +28,8 @@ asn_struct_print_f BIT_STRING_print; /* Human-readable output */
|
||||||
asn_struct_compare_f BIT_STRING_compare;
|
asn_struct_compare_f BIT_STRING_compare;
|
||||||
asn_constr_check_f BIT_STRING_constraint;
|
asn_constr_check_f BIT_STRING_constraint;
|
||||||
xer_type_encoder_f BIT_STRING_encode_xer;
|
xer_type_encoder_f BIT_STRING_encode_xer;
|
||||||
|
oer_type_decoder_f BIT_STRING_decode_oer;
|
||||||
|
oer_type_encoder_f BIT_STRING_encode_oer;
|
||||||
|
|
||||||
#define BIT_STRING_free OCTET_STRING_free
|
#define BIT_STRING_free OCTET_STRING_free
|
||||||
#define BIT_STRING_decode_ber OCTET_STRING_decode_ber
|
#define BIT_STRING_decode_ber OCTET_STRING_decode_ber
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
|
||||||
|
* All rights reserved.
|
||||||
|
* Redistribution and modifications are permitted subject to BSD license.
|
||||||
|
*/
|
||||||
|
#ifndef ASN_DISABLE_OER_SUPPORT
|
||||||
|
|
||||||
|
#include <asn_internal.h>
|
||||||
|
#include <BIT_STRING.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
asn_dec_rval_t
|
||||||
|
BIT_STRING_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||||
|
const asn_oer_constraints_t *constraints, void **sptr,
|
||||||
|
const void *ptr, size_t size) {
|
||||||
|
BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
|
||||||
|
const asn_oer_constraints_t *cts =
|
||||||
|
constraints ? constraints : td->oer_constraints;
|
||||||
|
ssize_t ct_size = cts ? cts->size : -1;
|
||||||
|
asn_dec_rval_t rval = {RC_OK, 0};
|
||||||
|
size_t expected_length = 0;
|
||||||
|
|
||||||
|
(void)opt_codec_ctx;
|
||||||
|
|
||||||
|
if(!st) {
|
||||||
|
st = (BIT_STRING_t *)(*sptr = CALLOC(1, sizeof(*st)));
|
||||||
|
if(!st) ASN__DECODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ct_size >= 0) {
|
||||||
|
expected_length = (ct_size + 7) >> 3;
|
||||||
|
st->bits_unused = (8 - (ct_size & 7)) & 7;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* X.696 (08/2015) #13.3.1
|
||||||
|
* Encode length determinant as _number of octets_, but only
|
||||||
|
* if upper bound is not equal to lower bound.
|
||||||
|
*/
|
||||||
|
ssize_t len_len = oer_fetch_length(ptr, size, &expected_length);
|
||||||
|
if(len_len > 0) {
|
||||||
|
ptr = (const char *)ptr + len_len;
|
||||||
|
size -= len_len;
|
||||||
|
} else if(len_len == 0) {
|
||||||
|
ASN__DECODE_STARVED;
|
||||||
|
} else if(len_len < 0) {
|
||||||
|
ASN__DECODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(expected_length < 1) {
|
||||||
|
ASN__DECODE_STARVED;
|
||||||
|
}
|
||||||
|
|
||||||
|
st->bits_unused = ((const uint8_t *)ptr)[0];
|
||||||
|
if(st->bits_unused & ~7) {
|
||||||
|
ASN_DEBUG("%s: unused bits outside of 0..7 range", td->name);
|
||||||
|
ASN__DECODE_FAILED;
|
||||||
|
}
|
||||||
|
ptr = (const char *)ptr + 1;
|
||||||
|
size--;
|
||||||
|
expected_length--;
|
||||||
|
rval.consumed = len_len + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(size < expected_length) {
|
||||||
|
ASN__DECODE_STARVED;
|
||||||
|
} else {
|
||||||
|
uint8_t *buf = MALLOC(expected_length + 1);
|
||||||
|
if(buf == NULL) {
|
||||||
|
ASN__DECODE_FAILED;
|
||||||
|
} else {
|
||||||
|
memcpy(buf, ptr, expected_length);
|
||||||
|
buf[expected_length] = '\0';
|
||||||
|
}
|
||||||
|
FREEMEM(st->buf);
|
||||||
|
st->buf = buf;
|
||||||
|
st->size = expected_length;
|
||||||
|
if(expected_length > 0) {
|
||||||
|
buf[expected_length - 1] &= (0xff << st->bits_unused);
|
||||||
|
}
|
||||||
|
|
||||||
|
rval.consumed += expected_length;
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encode as Canonical OER.
|
||||||
|
*/
|
||||||
|
asn_enc_rval_t
|
||||||
|
BIT_STRING_encode_oer(asn_TYPE_descriptor_t *td,
|
||||||
|
const asn_oer_constraints_t *constraints, void *sptr,
|
||||||
|
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||||
|
asn_enc_rval_t er = {-1,td,sptr};
|
||||||
|
(void)constraints;
|
||||||
|
(void)cb;
|
||||||
|
(void)app_key;
|
||||||
|
return er;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ASN_DISABLE_OER_SUPPORT */
|
|
@ -24,6 +24,7 @@ libasn1cskeletons_la_CFLAGS = $(SKELETONS_CFLAGS)
|
||||||
libasn1cskeletons_la_SOURCES = \
|
libasn1cskeletons_la_SOURCES = \
|
||||||
ANY.c ANY.h \
|
ANY.c ANY.h \
|
||||||
BIT_STRING.c BIT_STRING.h \
|
BIT_STRING.c BIT_STRING.h \
|
||||||
|
BIT_STRING_oer.c \
|
||||||
BMPString.c BMPString.h \
|
BMPString.c BMPString.h \
|
||||||
BOOLEAN.c BOOLEAN.h \
|
BOOLEAN.c BOOLEAN.h \
|
||||||
ENUMERATED.c ENUMERATED.h \
|
ENUMERATED.c ENUMERATED.h \
|
||||||
|
|
|
@ -54,10 +54,16 @@
|
||||||
/*
|
/*
|
||||||
* Return pointer to a member.
|
* Return pointer to a member.
|
||||||
*/
|
*/
|
||||||
static void **element_ptrptr(void *struct_ptr, asn_TYPE_member_t *elm) {
|
static void **
|
||||||
assert(elm->flags & ATF_POINTER);
|
element_ptrptr(void *struct_ptr, asn_TYPE_member_t *elm, void **tmp_save_ptr) {
|
||||||
/* Member is a pointer to another structure */
|
if(elm->flags & ATF_POINTER) {
|
||||||
return (void **)((char *)struct_ptr + elm->memb_offset);
|
/* Member is a pointer to another structure */
|
||||||
|
return (void **)((char *)struct_ptr + elm->memb_offset);
|
||||||
|
} else {
|
||||||
|
assert(tmp_save_ptr);
|
||||||
|
*tmp_save_ptr = (void *)((char *)struct_ptr + elm->memb_offset);
|
||||||
|
return tmp_save_ptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *element_ptr(void *struct_ptr, asn_TYPE_member_t *elm) {
|
static void *element_ptr(void *struct_ptr, asn_TYPE_member_t *elm) {
|
||||||
|
@ -172,7 +178,9 @@ SEQUENCE_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||||
} else if(present == 0) {
|
} else if(present == 0) {
|
||||||
if(elm->default_value) {
|
if(elm->default_value) {
|
||||||
/* Fill-in DEFAULT */
|
/* Fill-in DEFAULT */
|
||||||
if(elm->default_value(1, element_ptrptr(st, elm))) {
|
void *tmp;
|
||||||
|
if(elm->default_value(1,
|
||||||
|
element_ptrptr(st, elm, &tmp))) {
|
||||||
RETURN(RC_FAIL);
|
RETURN(RC_FAIL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,7 +314,7 @@ SEQUENCE_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
||||||
asn_bit_data_t *extadds = ctx->ptr;
|
asn_bit_data_t *extadds = ctx->ptr;
|
||||||
size_t edx = ctx->step;
|
size_t edx = ctx->step;
|
||||||
asn_TYPE_member_t *elm = &td->elements[edx];
|
asn_TYPE_member_t *elm = &td->elements[edx];
|
||||||
void **memb_ptr2 = element_ptrptr(st, elm);
|
void **memb_ptr2 = element_ptrptr(st, elm, 0);
|
||||||
|
|
||||||
switch(asn_get_few_bits(extadds, 1)) {
|
switch(asn_get_few_bits(extadds, 1)) {
|
||||||
case -1:
|
case -1:
|
||||||
|
|
|
@ -79,5 +79,6 @@ NativeEnumerated_oer.c
|
||||||
constr_SEQUENCE_oer.c
|
constr_SEQUENCE_oer.c
|
||||||
constr_CHOICE_oer.c
|
constr_CHOICE_oer.c
|
||||||
constr_SET_OF_oer.c constr_SET_OF.h asn_SET_OF.h asn_SET_OF.c
|
constr_SET_OF_oer.c constr_SET_OF.h asn_SET_OF.h asn_SET_OF.c
|
||||||
|
BIT_STRING_oer.c
|
||||||
|
|
||||||
CODEC-PER: # THIS IS A SPECIAL SECTION
|
CODEC-PER: # THIS IS A SPECIAL SECTION
|
||||||
|
|
Loading…
Reference in New Issue