aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2006-09-18 20:05:55 +0000
committerLev Walkin <vlm@lionet.info>2006-09-18 20:05:55 +0000
commit0a8aa6043f01268efe03bade3688d50249129bc1 (patch)
tree99317b3d03080ca0332b711d949a6892a9ec7cab
parent5a621d6a521599d478f0b3da72c6668bb2eaad89 (diff)
per encoding support
-rw-r--r--skeletons/INTEGER.c8
-rw-r--r--skeletons/NativeEnumerated.c6
-rw-r--r--skeletons/OCTET_STRING.c23
-rw-r--r--skeletons/asn_codecs.h6
-rw-r--r--skeletons/constr_CHOICE.c10
-rw-r--r--skeletons/constr_SEQUENCE.c4
-rw-r--r--skeletons/constr_SET_OF.c9
-rw-r--r--skeletons/per_decoder.c17
-rw-r--r--skeletons/per_decoder.h3
-rw-r--r--skeletons/per_support.c6
10 files changed, 56 insertions, 36 deletions
diff --git a/skeletons/INTEGER.c b/skeletons/INTEGER.c
index 5a0eccee..9c8b9ed3 100644
--- a/skeletons/INTEGER.c
+++ b/skeletons/INTEGER.c
@@ -571,7 +571,7 @@ INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
if(ct && ct->flags & APC_EXTENSIBLE) {
int inext = per_get_few_bits(pd, 1);
- if(inext < 0) _ASN_DECODE_FAILED;
+ if(inext < 0) _ASN_DECODE_STARVED;
if(inext) ct = 0;
}
@@ -599,7 +599,7 @@ INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
ASN_DEBUG("Integer with range %d bits", ct->range_bits);
if(ct->range_bits >= 0) {
long value = per_get_few_bits(pd, ct->range_bits);
- if(value < 0) _ASN_DECODE_FAILED;
+ if(value < 0) _ASN_DECODE_STARVED;
ASN_DEBUG("Got value %ld + low %ld",
value, ct->lower_bound);
value += ct->lower_bound;
@@ -619,14 +619,14 @@ INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
/* Get the PER length */
len = uper_get_length(pd, -1, &repeat);
- if(len < 0) _ASN_DECODE_FAILED;
+ if(len < 0) _ASN_DECODE_STARVED;
p = REALLOC(st->buf, st->size + len + 1);
if(!p) _ASN_DECODE_FAILED;
st->buf = (uint8_t *)p;
ret = per_get_many_bits(pd, &st->buf[st->size], 0, 8 * len);
- if(ret < 0) _ASN_DECODE_FAILED;
+ if(ret < 0) _ASN_DECODE_STARVED;
st->size += len;
} while(repeat);
st->buf[st->size] = 0; /* JIC */
diff --git a/skeletons/NativeEnumerated.c b/skeletons/NativeEnumerated.c
index fa16eb07..e3af1ca4 100644
--- a/skeletons/NativeEnumerated.c
+++ b/skeletons/NativeEnumerated.c
@@ -96,13 +96,13 @@ NativeEnumerated_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
if(ct->flags & APC_EXTENSIBLE) {
int inext = per_get_few_bits(pd, 1);
- if(inext < 0) _ASN_DECODE_FAILED;
+ if(inext < 0) _ASN_DECODE_STARVED;
if(inext) ct = 0;
}
if(ct && ct->range_bits >= 0) {
value = per_get_few_bits(pd, ct->range_bits);
- if(value < 0) _ASN_DECODE_FAILED;
+ if(value < 0) _ASN_DECODE_STARVED;
if(value >= (specs->extension
? specs->extension - 1 : specs->map_count))
_ASN_DECODE_FAILED;
@@ -113,7 +113,7 @@ NativeEnumerated_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
* X.691, #10.6: normally small non-negative whole number;
*/
value = uper_get_nsnnwn(pd);
- if(value < 0) _ASN_DECODE_FAILED;
+ if(value < 0) _ASN_DECODE_STARVED;
value += specs->extension - 1;
if(value >= specs->map_count)
_ASN_DECODE_FAILED;
diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c
index 7b83b618..3bef5608 100644
--- a/skeletons/OCTET_STRING.c
+++ b/skeletons/OCTET_STRING.c
@@ -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.
*/
@@ -1231,7 +1231,7 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
if(ct->flags & APC_EXTENSIBLE) {
int inext = per_get_few_bits(pd, 1);
- if(inext < 0) RETURN(RC_FAIL);
+ if(inext < 0) RETURN(RC_WMORE);
if(inext) ct = &asn_DEF_OCTET_STRING_constraint;
consumed_myself = 0;
}
@@ -1254,7 +1254,7 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
if(ct->effective_bits == 0) {
int ret = per_get_many_bits(pd, st->buf, 0,
unit_bits * ct->upper_bound);
- if(ret < 0) RETURN(RC_FAIL);
+ if(ret < 0) RETURN(RC_WMORE);
consumed_myself += unit_bits * ct->upper_bound;
st->buf[st->size] = 0;
if(unit_bits == 1 && (ct->upper_bound & 0x7))
@@ -1271,11 +1271,12 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
/* Get the PER length */
len_bits = uper_get_length(pd, ct->effective_bits, &repeat);
- if(len_bits < 0) RETURN(RC_FAIL);
+ if(len_bits < 0) RETURN(RC_WMORE);
len_bits += ct->lower_bound;
- ASN_DEBUG("Got per length eb %ld, len %ld",
- (long)ct->effective_bits, (long)len_bits);
+ ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)",
+ (long)ct->effective_bits, (long)len_bits,
+ repeat ? "repeat" : "once", td->name);
if(unit_bits == 1) {
len_bytes = (len_bits + 7) >> 3;
if(len_bits & 0x7)
@@ -1290,7 +1291,7 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
st->buf = (uint8_t *)p;
ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
- if(ret < 0) RETURN(RC_FAIL);
+ if(ret < 0) RETURN(RC_WMORE);
st->size += len_bytes;
} while(repeat);
st->buf[st->size] = 0; /* nul-terminate */
@@ -1327,8 +1328,8 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
sizeinunits = sizeinunits * 8 - (st->bits_unused & 0x07);
}
- ASN_DEBUG("Encoding %s into %d units",
- td->name, sizeinunits);
+ ASN_DEBUG("Encoding %s into %d units of %d bits",
+ td->name, sizeinunits, unit_bits);
/* Figure out wheter size lies within PER visible consrtaint */
@@ -1361,7 +1362,7 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
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);
+ ret = per_put_many_bits(po, st->buf, sizeinunits * unit_bits);
if(ret) _ASN_ENCODE_FAILED;
_ASN_ENCODED_OK(er);
}
@@ -1381,7 +1382,7 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
ASN_DEBUG("Encoding %d of %d", maySave, sizeinunits);
- ret = per_put_many_bits(po, buf, maySave);
+ ret = per_put_many_bits(po, buf, maySave * unit_bits);
if(ret) _ASN_ENCODE_FAILED;
if(unit_bits == 1)
diff --git a/skeletons/asn_codecs.h b/skeletons/asn_codecs.h
index bd6b946f..1ee73776 100644
--- a/skeletons/asn_codecs.h
+++ b/skeletons/asn_codecs.h
@@ -93,6 +93,12 @@ typedef struct asn_dec_rval_s {
tmp_error.consumed = 0; \
return tmp_error; \
} while(0)
+#define _ASN_DECODE_STARVED do { \
+ asn_dec_rval_t tmp_error; \
+ tmp_error.code = RC_WMORE; \
+ tmp_error.consumed = 0; \
+ return tmp_error; \
+} while(0)
#ifdef __cplusplus
}
diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c
index a0a6d76a..b8d6fa9a 100644
--- a/skeletons/constr_CHOICE.c
+++ b/skeletons/constr_CHOICE.c
@@ -852,22 +852,22 @@ CHOICE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
if(ct && ct->flags & APC_EXTENSIBLE) {
value = per_get_few_bits(pd, 1);
- if(value < 0) _ASN_DECODE_FAILED;
+ if(value < 0) _ASN_DECODE_STARVED;
if(value) ct = 0; /* Not restricted */
}
if(ct && ct->range_bits >= 0) {
value = per_get_few_bits(pd, ct->range_bits);
- if(value < 0) _ASN_DECODE_FAILED;
- if(value > ct->upper_bound)
- _ASN_DECODE_FAILED;
+ if(value < 0) _ASN_DECODE_STARVED;
ASN_DEBUG("CHOICE %s got index %d in range %d",
td->name, value, ct->range_bits);
+ if(value > ct->upper_bound)
+ _ASN_DECODE_FAILED;
} else {
if(specs->ext_start == -1)
_ASN_DECODE_FAILED;
value = uper_get_nsnnwn(pd);
- if(value < 0) _ASN_DECODE_FAILED;
+ if(value < 0) _ASN_DECODE_STARVED;
value += specs->ext_start;
if(value >= td->elements_count)
_ASN_DECODE_FAILED;
diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c
index 9b7dcf32..b7694343 100644
--- a/skeletons/constr_SEQUENCE.c
+++ b/skeletons/constr_SEQUENCE.c
@@ -1048,7 +1048,7 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
/* Handle extensions */
if(specs->ext_before >= 0) {
extpresent = per_get_few_bits(pd, 1);
- if(extpresent < 0) _ASN_DECODE_FAILED;
+ if(extpresent < 0) _ASN_DECODE_STARVED;
}
/* Prepare a place and read-in the presence bitmap */
@@ -1058,7 +1058,7 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
/* Get the presence map */
if(per_get_many_bits(pd, opres, 0, specs->roms_count)) {
FREEMEM(opres);
- _ASN_DECODE_FAILED;
+ _ASN_DECODE_STARVED;
}
opmd.buffer = opres;
opmd.nboff = 0;
diff --git a/skeletons/constr_SET_OF.c b/skeletons/constr_SET_OF.c
index 03c6fe28..09f27db5 100644
--- a/skeletons/constr_SET_OF.c
+++ b/skeletons/constr_SET_OF.c
@@ -883,7 +883,7 @@ SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
if(ct && ct->flags & APC_EXTENSIBLE) {
int value = per_get_few_bits(pd, 1);
- if(value < 0) _ASN_DECODE_FAILED;
+ if(value < 0) _ASN_DECODE_STARVED;
if(value) ct = 0; /* Not restricted! */
}
@@ -892,7 +892,7 @@ SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
nelems = per_get_few_bits(pd, ct->effective_bits);
ASN_DEBUG("Preparing to fetch %ld+%ld elements from %s",
(long)nelems, ct->lower_bound, td->name);
- if(nelems < 0) _ASN_DECODE_FAILED;
+ if(nelems < 0) _ASN_DECODE_STARVED;
nelems += ct->lower_bound;
} else {
nelems = -1;
@@ -905,7 +905,7 @@ SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
ct ? ct->effective_bits : -1, &repeat);
ASN_DEBUG("Got to decode %d elements (eff %d)",
(int)nelems, (int)ct ? ct->effective_bits : -1);
- if(nelems < 0) _ASN_DECODE_FAILED;
+ if(nelems < 0) _ASN_DECODE_STARVED;
}
for(i = 0; i < nelems; i++) {
@@ -921,12 +921,13 @@ SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
ASN_DEBUG("Failed to add element into %s",
td->name);
/* Fall through */
+ rv.code == RC_FAIL;
} else {
ASN_DEBUG("Failed decoding %s of %s (SET OF)",
elm->type->name, td->name);
}
if(ptr) ASN_STRUCT_FREE(*elm->type, ptr);
- _ASN_DECODE_FAILED;
+ return rv;
}
nelems = -1; /* Allow uper_get_length() */
diff --git a/skeletons/per_decoder.c b/skeletons/per_decoder.c
index f1b723f2..16dee369 100644
--- a/skeletons/per_decoder.c
+++ b/skeletons/per_decoder.c
@@ -3,12 +3,14 @@
#include <per_decoder.h>
asn_dec_rval_t
-uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size, int skip_bits) {
+uper_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) {
asn_codec_ctx_t s_codec_ctx;
asn_dec_rval_t rval;
asn_per_data_t pd;
- if(skip_bits < 0 || skip_bits > 7 || (skip_bits > 0 && !size))
+ if(skip_bits < 0 || skip_bits > 7
+ || unused_bits < 0 || unused_bits > 7
+ || (unused_bits > 0 && !size))
_ASN_DECODE_FAILED;
/*
@@ -30,7 +32,9 @@ uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sp
/* Fill in the position indicator */
pd.buffer = (const uint8_t *)buffer;
pd.nboff = skip_bits;
- pd.nbits = 8 * size; /* 8 is CHAR_BIT from <limits.h> */
+ pd.nbits = 8 * size - unused_bits; /* 8 is CHAR_BIT from <limits.h> */
+ if(pd.nboff > pd.nbits)
+ _ASN_DECODE_FAILED;
/*
* Invoke type-specific decoder.
@@ -38,12 +42,13 @@ uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sp
if(!td->uper_decoder)
_ASN_DECODE_FAILED; /* PER is not compiled in */
rval = td->uper_decoder(opt_codec_ctx, td, 0, sptr, &pd);
- if(rval.code == RC_FAIL) {
- rval.consumed = 0;
- } else {
+ if(rval.code == RC_OK) {
/* Return the number of consumed bits */
rval.consumed = ((pd.buffer - (const uint8_t *)buffer) << 3)
+ pd.nboff - skip_bits;
+ } else {
+ /* PER codec is not a restartable */
+ rval.consumed = 0;
}
return rval;
}
diff --git a/skeletons/per_decoder.h b/skeletons/per_decoder.h
index 23cb7d7a..26aaf594 100644
--- a/skeletons/per_decoder.h
+++ b/skeletons/per_decoder.h
@@ -22,7 +22,8 @@ asn_dec_rval_t uper_decode(struct asn_codec_ctx_s *opt_codec_ctx,
void **struct_ptr, /* Pointer to a target structure's pointer */
const void *buffer, /* Data to be decoded */
size_t size, /* Size of data buffer */
- int skip_bits /* Number of unused leading bits, 0..7 */
+ int skip_bits, /* Number of unused leading bits, 0..7 */
+ int unused_bits /* Number of unused tailing bits, 0..7 */
);
diff --git a/skeletons/per_support.c b/skeletons/per_support.c
index b0149f89..c8344193 100644
--- a/skeletons/per_support.c
+++ b/skeletons/per_support.c
@@ -18,6 +18,9 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) {
if(nbits < 0 || pd->nboff + nbits > pd->nbits)
return -1;
+ ASN_DEBUG("[PER get %d bits from %p+%d bits]",
+ nbits, pd->buffer, pd->nboff);
+
/*
* Normalize position indicator.
*/
@@ -190,6 +193,9 @@ per_put_few_bits(asn_per_outp_t *po, uint32_t bits, int obits) {
if(obits <= 0 || obits >= 32) return obits ? -1 : 0;
+ ASN_DEBUG("[PER put %d bits to %p+%d bits]",
+ obits, po->buffer, po->nboff);
+
/*
* Normalize position indicator.
*/