aboutsummaryrefslogtreecommitdiffstats
path: root/src/per_opentype.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/per_opentype.c')
-rw-r--r--src/per_opentype.c102
1 files changed, 68 insertions, 34 deletions
diff --git a/src/per_opentype.c b/src/per_opentype.c
index c749c8c..984a96d 100644
--- a/src/per_opentype.c
+++ b/src/per_opentype.c
@@ -18,8 +18,6 @@ static int uper_ugot_refill(asn_per_data_t *pd);
static int per_skip_bits(asn_per_data_t *pd, int skip_nbits);
static asn_dec_rval_t uper_sot_suck(asn_codec_ctx_t *, asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd);
-int asn_debug_indent;
-
/*
* Encode an "open type field".
* #10.1, #10.2
@@ -38,6 +36,37 @@ uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints
for(bptr = buf, toGo = size; toGo;) {
ssize_t maySave = uper_put_length(po, toGo);
+ ASN_DEBUG("Prepending length %d to %s and allowing to save %d",
+ (int)size, td->name, (int)maySave);
+ if(maySave < 0) break;
+ if(per_put_many_bits(po, bptr, maySave * 8)) break;
+ bptr = (char *)bptr + maySave;
+ toGo -= maySave;
+ }
+
+ FREEMEM(buf);
+ if(toGo) return -1;
+
+ ASN_DEBUG("Open type put %s of length %ld + overhead (1byte?)",
+ td->name, (long)size);
+
+ return 0;
+}
+
+int
+aper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
+ void *buf;
+ void *bptr;
+ ssize_t size;
+ size_t toGo;
+
+ ASN_DEBUG("Open type put %s ...", td->name);
+
+ size = aper_encode_to_new_buffer(td, constraints, sptr, &buf);
+ if(size <= 0) return -1;
+
+ for(bptr = buf, toGo = size; toGo;) {
+ ssize_t maySave = aper_put_length(po, -1, toGo);
if(maySave < 0) break;
if(per_put_many_bits(po, bptr, maySave * 8)) break;
bptr = (char *)bptr + maySave;
@@ -48,7 +77,7 @@ uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints
if(toGo) return -1;
ASN_DEBUG("Open type put %s of length %d + overhead (1byte?)",
- td->name, size);
+ td->name, size);
return 0;
}
@@ -92,28 +121,31 @@ uper_open_type_get_simple(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
bufLen += chunk_bytes;
} while(repeat);
- ASN_DEBUG("Getting open type %s encoded in %d bytes", td->name,
- bufLen);
+ ASN_DEBUG("Getting open type %s encoded in %ld bytes", td->name,
+ (long)bufLen);
memset(&spd, 0, sizeof(spd));
spd.buffer = buf;
spd.nbits = bufLen << 3;
- asn_debug_indent += 4;
+ ASN_DEBUG_INDENT_ADD(+4);
rv = td->uper_decoder(ctx, td, constraints, sptr, &spd);
- asn_debug_indent -= 4;
+ ASN_DEBUG_INDENT_ADD(-4);
if(rv.code == RC_OK) {
/* Check padding validity */
padding = spd.nbits - spd.nboff;
- if(padding < 8 && per_get_few_bits(&spd, padding) == 0) {
+ if ((padding < 8 ||
+ /* X.691#10.1.3 */
+ (spd.nboff == 0 && spd.nbits == 8 && spd.buffer == buf)) &&
+ per_get_few_bits(&spd, padding) == 0) {
/* Everything is cool */
FREEMEM(buf);
return rv;
}
FREEMEM(buf);
if(padding >= 8) {
- ASN_DEBUG("Too large padding %d in open type", padding);
+ ASN_DEBUG("Too large padding %d in open type", (int)padding);
_ASN_DECODE_FAILED;
} else {
ASN_DEBUG("Non-zero padding");
@@ -148,9 +180,9 @@ uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
pd->nbits = pd->nboff; /* 0 good bits at this point, will refill */
pd->moved = 0; /* This now counts the open type size in bits */
- asn_debug_indent += 4;
+ ASN_DEBUG_INDENT_ADD(+4);
rv = td->uper_decoder(ctx, td, constraints, sptr, pd);
- asn_debug_indent -= 4;
+ ASN_DEBUG_INDENT_ADD(-4);
#define UPDRESTOREPD do { \
/* buffer and nboff are valid, preserve them. */ \
@@ -165,24 +197,23 @@ uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
return rv;
}
- ASN_DEBUG("OpenType %s pd%s old%s unclaimed=%d, repeat=%d"
- , td->name,
+ ASN_DEBUG("OpenType %s pd%s old%s unclaimed=%d, repeat=%d", td->name,
per_data_string(pd),
per_data_string(&arg.oldpd),
- arg.unclaimed, arg.repeat);
+ (int)arg.unclaimed, (int)arg.repeat);
padding = pd->moved % 8;
if(padding) {
int32_t pvalue;
if(padding > 7) {
ASN_DEBUG("Too large padding %d in open type",
- padding);
+ (int)padding);
rv.code = RC_FAIL;
UPDRESTOREPD;
return rv;
}
padding = 8 - padding;
- ASN_DEBUG("Getting padding of %d bits", padding);
+ ASN_DEBUG("Getting padding of %d bits", (int)padding);
pvalue = per_get_few_bits(pd, padding);
switch(pvalue) {
case -1:
@@ -192,7 +223,7 @@ uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
case 0: break;
default:
ASN_DEBUG("Non-blank padding (%d bits 0x%02x)",
- padding, (int)pvalue);
+ (int)padding, (int)pvalue);
UPDRESTOREPD;
_ASN_DECODE_FAILED;
}
@@ -212,14 +243,14 @@ uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
UPDRESTOREPD;
/* Skip data not consumed by the decoder */
- if(arg.unclaimed) ASN_DEBUG("Getting unclaimed %d", arg.unclaimed);
if(arg.unclaimed) {
+ ASN_DEBUG("Getting unclaimed %d", (int)arg.unclaimed);
switch(per_skip_bits(pd, arg.unclaimed)) {
case -1:
- ASN_DEBUG("Claim of %d failed", arg.unclaimed);
+ ASN_DEBUG("Claim of %d failed", (int)arg.unclaimed);
_ASN_DECODE_STARVED;
case 0:
- ASN_DEBUG("Got claim of %d", arg.unclaimed);
+ ASN_DEBUG("Got claim of %d", (int)arg.unclaimed);
break;
default:
/* Padding must be blank */
@@ -243,9 +274,7 @@ asn_dec_rval_t
uper_open_type_get(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
- return uper_open_type_get_simple(ctx, td, constraints,
- sptr, pd);
-
+ return uper_open_type_get_simple(ctx, td, constraints, sptr, pd);
}
int
@@ -293,8 +322,8 @@ uper_ugot_refill(asn_per_data_t *pd) {
asn_per_data_t *oldpd = &arg->oldpd;
- ASN_DEBUG("REFILLING pd->moved=%d, oldpd->moved=%d",
- pd->moved, oldpd->moved);
+ ASN_DEBUG("REFILLING pd->moved=%ld, oldpd->moved=%ld",
+ (long)pd->moved, (long)oldpd->moved);
/* Advance our position to where pd is */
oldpd->buffer = pd->buffer;
@@ -314,7 +343,8 @@ uper_ugot_refill(asn_per_data_t *pd) {
pd->buffer = oldpd->buffer;
pd->nboff = oldpd->nboff - 1;
pd->nbits = oldpd->nbits;
- ASN_DEBUG("UNCLAIMED <- return from (pd->moved=%d)", pd->moved);
+ ASN_DEBUG("UNCLAIMED <- return from (pd->moved=%ld)",
+ (long)pd->moved);
return 0;
}
@@ -324,8 +354,8 @@ uper_ugot_refill(asn_per_data_t *pd) {
}
next_chunk_bytes = uper_get_length(oldpd, -1, &arg->repeat);
- ASN_DEBUG("Open type LENGTH %d bytes at off %d, repeat %d",
- next_chunk_bytes, oldpd->moved, arg->repeat);
+ ASN_DEBUG("Open type LENGTH %ld bytes at off %ld, repeat %ld",
+ (long)next_chunk_bytes, (long)oldpd->moved, (long)arg->repeat);
if(next_chunk_bytes < 0) return -1;
if(next_chunk_bytes == 0) {
pd->refill = 0; /* No more refills, naturally */
@@ -336,14 +366,16 @@ uper_ugot_refill(asn_per_data_t *pd) {
if(avail >= next_chunk_bits) {
pd->nbits = oldpd->nboff + next_chunk_bits;
arg->unclaimed = 0;
- ASN_DEBUG("!+Parent frame %d bits, alloting %d [%d..%d] (%d)",
- next_chunk_bits, oldpd->moved,
- oldpd->nboff, oldpd->nbits,
- oldpd->nbits - oldpd->nboff);
+ ASN_DEBUG("!+Parent frame %ld bits, alloting %ld [%ld..%ld] (%ld)",
+ (long)next_chunk_bits, (long)oldpd->moved,
+ (long)oldpd->nboff, (long)oldpd->nbits,
+ (long)(oldpd->nbits - oldpd->nboff));
} else {
pd->nbits = oldpd->nbits;
arg->unclaimed = next_chunk_bits - avail;
- ASN_DEBUG("!-Parent frame %d, require %d, will claim %d", avail, next_chunk_bits, arg->unclaimed);
+ ASN_DEBUG("!-Parent frame %ld, require %ld, will claim %ld",
+ (long)avail, (long)next_chunk_bits,
+ (long)arg->unclaimed);
}
pd->buffer = oldpd->buffer;
pd->nboff = oldpd->nboff;
@@ -357,7 +389,9 @@ per_skip_bits(asn_per_data_t *pd, int skip_nbits) {
int hasNonZeroBits = 0;
while(skip_nbits > 0) {
int skip;
- if(skip_nbits < skip)
+
+ /* per_get_few_bits() is more efficient when nbits <= 24 */
+ if(skip_nbits < 24)
skip = skip_nbits;
else
skip = 24;