From 9218bc1ed25cc6597c5522d9c3db06d72135ce3f Mon Sep 17 00:00:00 2001 From: Lev Walkin Date: Wed, 27 Jun 2007 04:09:37 +0000 Subject: [PATCH] shared stuff split off to per_opentype.[ch] --- skeletons/constr_SEQUENCE.c | 236 +--------------------------------- skeletons/file-dependencies | 1 + skeletons/per_opentype.c | 245 ++++++++++++++++++++++++++++++++++++ skeletons/per_opentype.h | 22 ++++ skeletons/per_support.c | 3 +- skeletons/per_support.h | 3 +- 6 files changed, 276 insertions(+), 234 deletions(-) create mode 100644 skeletons/per_opentype.c create mode 100644 skeletons/per_opentype.h diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c index 5e1a0538..0cfcdade 100644 --- a/skeletons/constr_SEQUENCE.c +++ b/skeletons/constr_SEQUENCE.c @@ -5,6 +5,7 @@ */ #include #include +#include /* * Number of bytes left for this structure. @@ -1026,235 +1027,6 @@ SEQUENCE_constraint(asn_TYPE_descriptor_t *td, const void *sptr, return 0; } -/* - * #10.1, #10.2 - */ -static int -uper_put_open_type(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { - void *buf; - ssize_t size; - - ASN_DEBUG("Encoding as open type %s", td->name); - size = uper_encode_to_new_buffer(td, constraints, sptr, &buf); - if(size <= 0) return -1; - - ASN_DEBUG("Putting %s of length %d", td->name, size); - while(size) { - ssize_t maySave = uper_put_length(po, size); - if(maySave < 0) break; - if(per_put_many_bits(po, buf, maySave * 8)) break; - buf = (char *)buf + maySave; - size -= maySave; - } - - if(size) { - FREEMEM(buf); - return -1; - } - - return 0; -} - -typedef struct uper_ugot_key { - asn_per_data_t oldpd; /* Old per data source */ - size_t unclaimed; - size_t ot_moved; /* Number of bits moved by OT processing */ - int repeat; -} uper_ugot_key; -static int -uper_ugot_refill(asn_per_data_t *pd) { - uper_ugot_key *arg = pd->refill_key; - ssize_t next_chunk_bytes, next_chunk_bits; - ssize_t avail; - - asn_per_data_t *oldpd = &arg->oldpd; - - ASN_DEBUG("REFILLING (%+db) [from %d (%d->%d)_%d] now [%d (%d->%d)_%d] uncl %d", - pd->buffer - oldpd->buffer, - oldpd->nbits - oldpd->nboff, oldpd->nboff, oldpd->nbits, oldpd->moved, - pd->nbits - pd->nboff, pd->nboff, pd->nbits, pd->moved, arg->unclaimed); - - /* Advance our position to where pd is */ - oldpd->buffer = pd->buffer; - oldpd->nboff = pd->nboff; - oldpd->nbits -= pd->moved - arg->ot_moved; - oldpd->moved += pd->moved - arg->ot_moved; - arg->ot_moved = pd->moved; - - if(arg->unclaimed) { - /* Refill the container */ - if(per_get_few_bits(oldpd, 1)) - return -1; - if(oldpd->nboff == 0) { - assert(0); - return -1; - } - pd->buffer = oldpd->buffer; - pd->nboff = oldpd->nboff - 1; - pd->nbits = oldpd->nbits; - ASN_DEBUG("Return from UNCLAIMED"); - return 0; - } - - if(!arg->repeat) { - ASN_DEBUG("Want more but refill doesn't have it"); - return -1; - } - - 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); - if(next_chunk_bytes < 0) return -1; - if(next_chunk_bytes == 0) { - pd->refill = 0; /* No more refills, naturally */ - assert(!arg->repeat); /* Implementation guarantee */ - } - next_chunk_bits = next_chunk_bytes << 3; - avail = oldpd->nbits - oldpd->nboff; - if(avail >= next_chunk_bits) { - pd->nbits = oldpd->nboff + next_chunk_bits; - arg->unclaimed = 0; - } else { - pd->nbits = oldpd->nbits; - arg->unclaimed = next_chunk_bits - avail; - ASN_DEBUG("Parent has %d, require %d, will claim %d", avail, next_chunk_bits, arg->unclaimed); - } - pd->buffer = oldpd->buffer; - pd->nboff = oldpd->nboff; - return 0; -} - -asn_dec_rval_t -uper_get_open_type(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { - uper_ugot_key arg; - asn_dec_rval_t rv; - ssize_t padding; - - _ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx); - - ASN_DEBUG("Getting open type off %d (%d+%d), %p", pd->moved, pd->nboff, pd->nbits, pd->buffer); - arg.oldpd = *pd; - arg.unclaimed = 0; - arg.ot_moved = 0; - arg.repeat = 1; - pd->refill = uper_ugot_refill; - pd->refill_key = &arg; - pd->nbits = pd->nboff; /* 0 good bits at this point, will refill */ - pd->moved = 0; /* This now counts the open type size in bits */ - - rv = td->uper_decoder(opt_codec_ctx, td, constraints, sptr, pd); - - ASN_DEBUG("Open type %s consumed %d off of %d unclaimed=%d, repeat=%d", - td->name, pd->moved, arg.oldpd.moved, - arg.unclaimed, arg.repeat); - - ASN_DEBUG("OT1 moved %d, estimated %d uncl=%d", - arg.oldpd.moved, - arg.oldpd.nboff + ((((int)arg.oldpd.buffer) & 0x7) << 3), - arg.unclaimed - ); - - padding = pd->moved % 8; - if(padding) { - int32_t pvalue; - if(padding > 7) { - ASN_DEBUG("Too large padding %d in open type", - padding); - rv.code = RC_FAIL; - return rv; - } - padding = 8 - padding; - ASN_DEBUG("Getting padding of %d bits", padding); - pvalue = per_get_few_bits(pd, padding); - switch(pvalue) { - case -1: - ASN_DEBUG("Padding skip failed"); - _ASN_DECODE_STARVED; - case 0: break; - default: - ASN_DEBUG("Non-blank padding (%d bits 0x%02x)", - padding, pvalue); - _ASN_DECODE_FAILED; - } - } - if(pd->nbits != pd->nboff) { - ASN_DEBUG("Open type container overhead of %d bits!", pd->nbits - pd->nboff); - if(1) _ASN_DECODE_FAILED; - arg.unclaimed += pd->nbits - pd->nboff; - } - - /* Adjust pd back so it points to original data */ - pd->nbits = arg.oldpd.nbits - (pd->moved - arg.ot_moved); - pd->moved = arg.oldpd.moved + (pd->moved - arg.ot_moved); - pd->refill = arg.oldpd.refill; - pd->refill_key = arg.oldpd.refill_key; - - /* Skip data not consumed by the decoder */ - if(arg.unclaimed) ASN_DEBUG("Getting unclaimed %d", arg.unclaimed); - while(arg.unclaimed) { - size_t toget = 24; - if(arg.unclaimed < toget) - toget = arg.unclaimed; - arg.unclaimed -= toget; - switch(per_get_few_bits(pd, toget)) { - case -1: - ASN_DEBUG("Claim of %d failed", toget); - _ASN_DECODE_STARVED; - case 0: - ASN_DEBUG("Got claim of %d", toget); - continue; - default: - /* Padding must be blank */ - ASN_DEBUG("Non-blank unconsumed padding"); - _ASN_DECODE_FAILED; - } - } - - assert(pd->moved == pd->nboff + ((((int)pd->buffer) & 0x7) << 3)); - - if(arg.repeat) { - ASN_DEBUG("Not consumed the whole thing"); - rv.code = RC_FAIL; - return rv; - } - - return rv; -} - -asn_dec_rval_t -uper_sot_suck(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_dec_rval_t rv; - - (void)opt_codec_ctx; - (void)td; - (void)constraints; - (void)sptr; - - while(per_get_few_bits(pd, 24) >= 0); - - rv.code = RC_OK; - rv.consumed = pd->moved; - - return rv; -} - -static int -uper_skip_open_type(asn_codec_ctx_t *opt_codec_ctx, asn_per_data_t *pd) { - asn_TYPE_descriptor_t s_td; - asn_dec_rval_t rv; - - s_td.name = ""; - s_td.uper_decoder = uper_sot_suck; - - rv = uper_get_open_type(opt_codec_ctx, &s_td, 0, 0, pd); - if(rv.code != RC_OK) - return -1; - else - return 0; -} - asn_dec_rval_t SEQUENCE_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) { @@ -1413,7 +1185,7 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, } ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name, *memb_ptr2); - rv = uper_get_open_type(opt_codec_ctx, elm->type, + rv = uper_open_type_get(opt_codec_ctx, elm->type, elm->per_constraints, memb_ptr2, pd); if(rv.code != RC_OK) { FREEMEM(epres); @@ -1429,7 +1201,7 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, case -1: break; case 0: continue; default: - if(uper_skip_open_type(opt_codec_ctx, pd)) { + if(uper_open_type_skip(opt_codec_ctx, pd)) { FREEMEM(epres); _ASN_DECODE_STARVED; } @@ -1511,7 +1283,7 @@ SEQUENCE_handle_extensions(asn_TYPE_descriptor_t *td, void *sptr, if(po1 && per_put_few_bits(po1, present, 1)) return -1; /* Encode as open type field */ - if(po2 && present && uper_put_open_type(elm->type, + if(po2 && present && uper_open_type_put(elm->type, elm->per_constraints, *memb_ptr2, po2)) return -1; diff --git a/skeletons/file-dependencies b/skeletons/file-dependencies index 8fc6f03c..c2a5dae7 100644 --- a/skeletons/file-dependencies +++ b/skeletons/file-dependencies @@ -61,6 +61,7 @@ xer_encoder.h xer_encoder.c # XER encoding support per_support.h per_support.c # PER parsing per_decoder.h per_decoder.c # PER decoding support per_encoder.h per_encoder.c # PER encoding support +per_opentype.h per_opentype.c # PER "open type" handling CONVERTER: # THIS IS A SPECIAL SECTION converter-sample.c # A default name for sample transcoder diff --git a/skeletons/per_opentype.c b/skeletons/per_opentype.c new file mode 100644 index 00000000..f2cac938 --- /dev/null +++ b/skeletons/per_opentype.c @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2007 Lev Walkin . All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#include +#include +#include +#include + +typedef struct uper_ugot_key { + asn_per_data_t oldpd; /* Old per data source */ + size_t unclaimed; + size_t ot_moved; /* Number of bits moved by OT processing */ + int repeat; +} uper_ugot_key; + +static int uper_ugot_refill(asn_per_data_t *pd); +static asn_dec_rval_t uper_sot_suck(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd); + +/* + * #10.1, #10.2 + */ +int +uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { + void *buf; + ssize_t size; + + ASN_DEBUG("Encoding as open type %s", td->name); + size = uper_encode_to_new_buffer(td, constraints, sptr, &buf); + if(size <= 0) return -1; + + ASN_DEBUG("Putting %s of length %d", td->name, size); + while(size) { + ssize_t maySave = uper_put_length(po, size); + if(maySave < 0) break; + if(per_put_many_bits(po, buf, maySave * 8)) break; + buf = (char *)buf + maySave; + size -= maySave; + } + + if(size) { + FREEMEM(buf); + return -1; + } + + return 0; +} + +asn_dec_rval_t +uper_open_type_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + uper_ugot_key arg; + asn_dec_rval_t rv; + ssize_t padding; + + _ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx); + + ASN_DEBUG("Getting open type off %d (%d+%d), %p", pd->moved, pd->nboff, pd->nbits, pd->buffer); + arg.oldpd = *pd; + arg.unclaimed = 0; + arg.ot_moved = 0; + arg.repeat = 1; + pd->refill = uper_ugot_refill; + pd->refill_key = &arg; + pd->nbits = pd->nboff; /* 0 good bits at this point, will refill */ + pd->moved = 0; /* This now counts the open type size in bits */ + + rv = td->uper_decoder(opt_codec_ctx, td, constraints, sptr, pd); + + ASN_DEBUG("Open type %s consumed %d off of %d unclaimed=%d, repeat=%d", + td->name, pd->moved, arg.oldpd.moved, + arg.unclaimed, arg.repeat); + + ASN_DEBUG("OT1 moved %d, estimated %d uncl=%d", + arg.oldpd.moved, + arg.oldpd.nboff + ((((int)arg.oldpd.buffer) & 0x7) << 3), + arg.unclaimed + ); + + padding = pd->moved % 8; + if(padding) { + int32_t pvalue; + if(padding > 7) { + ASN_DEBUG("Too large padding %d in open type", + padding); + rv.code = RC_FAIL; + return rv; + } + padding = 8 - padding; + ASN_DEBUG("Getting padding of %d bits", padding); + pvalue = per_get_few_bits(pd, padding); + switch(pvalue) { + case -1: + ASN_DEBUG("Padding skip failed"); + _ASN_DECODE_STARVED; + case 0: break; + default: + ASN_DEBUG("Non-blank padding (%d bits 0x%02x)", + padding, pvalue); + _ASN_DECODE_FAILED; + } + } + if(pd->nbits != pd->nboff) { + ASN_DEBUG("Open type container overhead of %d bits!", pd->nbits - pd->nboff); + if(1) _ASN_DECODE_FAILED; + arg.unclaimed += pd->nbits - pd->nboff; + } + + /* Adjust pd back so it points to original data */ + pd->nbits = arg.oldpd.nbits - (pd->moved - arg.ot_moved); + pd->moved = arg.oldpd.moved + (pd->moved - arg.ot_moved); + pd->refill = arg.oldpd.refill; + pd->refill_key = arg.oldpd.refill_key; + + /* Skip data not consumed by the decoder */ + if(arg.unclaimed) ASN_DEBUG("Getting unclaimed %d", arg.unclaimed); + while(arg.unclaimed) { + size_t toget = 24; + if(arg.unclaimed < toget) + toget = arg.unclaimed; + arg.unclaimed -= toget; + switch(per_get_few_bits(pd, toget)) { + case -1: + ASN_DEBUG("Claim of %d failed", toget); + _ASN_DECODE_STARVED; + case 0: + ASN_DEBUG("Got claim of %d", toget); + continue; + default: + /* Padding must be blank */ + ASN_DEBUG("Non-blank unconsumed padding"); + _ASN_DECODE_FAILED; + } + } + + assert(pd->moved == pd->nboff + ((((int)pd->buffer) & 0x7) << 3)); + + if(arg.repeat) { + ASN_DEBUG("Not consumed the whole thing"); + rv.code = RC_FAIL; + return rv; + } + + return rv; +} + +int +uper_open_type_skip(asn_codec_ctx_t *opt_codec_ctx, asn_per_data_t *pd) { + asn_TYPE_descriptor_t s_td; + asn_dec_rval_t rv; + + s_td.name = ""; + s_td.uper_decoder = uper_sot_suck; + + rv = uper_open_type_get(opt_codec_ctx, &s_td, 0, 0, pd); + if(rv.code != RC_OK) + return -1; + else + return 0; +} + +/* + * Internal functions. + */ + +static asn_dec_rval_t +uper_sot_suck(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_dec_rval_t rv; + + (void)opt_codec_ctx; + (void)td; + (void)constraints; + (void)sptr; + + while(per_get_few_bits(pd, 24) >= 0); + + rv.code = RC_OK; + rv.consumed = pd->moved; + + return rv; +} + +static int +uper_ugot_refill(asn_per_data_t *pd) { + uper_ugot_key *arg = pd->refill_key; + ssize_t next_chunk_bytes, next_chunk_bits; + ssize_t avail; + + asn_per_data_t *oldpd = &arg->oldpd; + + ASN_DEBUG("REFILLING (%+db) [from %d (%d->%d)_%d] now [%d (%d->%d)_%d] uncl %d", + pd->buffer - oldpd->buffer, + oldpd->nbits - oldpd->nboff, oldpd->nboff, oldpd->nbits, oldpd->moved, + pd->nbits - pd->nboff, pd->nboff, pd->nbits, pd->moved, arg->unclaimed); + + /* Advance our position to where pd is */ + oldpd->buffer = pd->buffer; + oldpd->nboff = pd->nboff; + oldpd->nbits -= pd->moved - arg->ot_moved; + oldpd->moved += pd->moved - arg->ot_moved; + arg->ot_moved = pd->moved; + + if(arg->unclaimed) { + /* Refill the container */ + if(per_get_few_bits(oldpd, 1)) + return -1; + if(oldpd->nboff == 0) { + assert(0); + return -1; + } + pd->buffer = oldpd->buffer; + pd->nboff = oldpd->nboff - 1; + pd->nbits = oldpd->nbits; + ASN_DEBUG("Return from UNCLAIMED"); + return 0; + } + + if(!arg->repeat) { + ASN_DEBUG("Want more but refill doesn't have it"); + return -1; + } + + 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); + if(next_chunk_bytes < 0) return -1; + if(next_chunk_bytes == 0) { + pd->refill = 0; /* No more refills, naturally */ + assert(!arg->repeat); /* Implementation guarantee */ + } + next_chunk_bits = next_chunk_bytes << 3; + avail = oldpd->nbits - oldpd->nboff; + if(avail >= next_chunk_bits) { + pd->nbits = oldpd->nboff + next_chunk_bits; + arg->unclaimed = 0; + } else { + pd->nbits = oldpd->nbits; + arg->unclaimed = next_chunk_bits - avail; + ASN_DEBUG("Parent has %d, require %d, will claim %d", avail, next_chunk_bits, arg->unclaimed); + } + pd->buffer = oldpd->buffer; + pd->nboff = oldpd->nboff; + return 0; +} diff --git a/skeletons/per_opentype.h b/skeletons/per_opentype.h new file mode 100644 index 00000000..facfaa63 --- /dev/null +++ b/skeletons/per_opentype.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2007 Lev Walkin . All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef _PER_OPENTYPE_H_ +#define _PER_OPENTYPE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +asn_dec_rval_t uper_open_type_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd); + +int uper_open_type_skip(asn_codec_ctx_t *opt_codec_ctx, asn_per_data_t *pd); + +int uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po); + +#ifdef __cplusplus +} +#endif + +#endif /* _PER_OPENTYPE_H_ */ diff --git a/skeletons/per_support.c b/skeletons/per_support.c index bfd733aa..9406d963 100644 --- a/skeletons/per_support.c +++ b/skeletons/per_support.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2005, 2006 Lev Walkin . All rights reserved. + * Copyright (c) 2005, 2006, 2007 Lev Walkin . + * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #include diff --git a/skeletons/per_support.h b/skeletons/per_support.h index bf06f056..653c3517 100644 --- a/skeletons/per_support.h +++ b/skeletons/per_support.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2005, 2006 Lev Walkin . All rights reserved. + * Copyright (c) 2005, 2006, 2007 Lev Walkin . + * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _PER_SUPPORT_H_