more granular PER encoding

This commit is contained in:
Lev Walkin 2006-09-17 11:02:53 +00:00
parent 13c92a6409
commit bc6917730d
9 changed files with 177 additions and 99 deletions

View File

@ -60,27 +60,39 @@ cat Makefile.am.sample \
echo " @if test -f ./sample-${ASN1PDU}-1.[db]er ; then \\"
echo " for f in ./sample-${ASN1PDU}-*.[db]er; do \\"
echo ' echo "Recoding $$f into XER and back..."; \'
echo ' ./${TARGET} -iber -oxer $$f > ./.tmp.1.$$ || exit 2; \'
echo ' ./${TARGET} -ixer -oxer ./.tmp.1.$$ > ./.tmp.2.$$ || exit 2; \'
echo ' diff ./.tmp.1.$$ ./.tmp.2.$$ || exit 2; \'
echo ' rm -f ./.tmp.[12].$$; \'
echo ' ./${TARGET} -iber -oxer -b 1 $$f > ./.tmp.1.$$$$ || exit 2; \'
echo ' ./${TARGET} -iber -oxer -b 17 $$f > ./.tmp.1.$$$$ || exit 2; \'
echo ' ./${TARGET} -iber -oxer -b 33 $$f > ./.tmp.1.$$$$ || exit 2; \'
echo ' ./${TARGET} -iber -oxer -b 980 $$f > ./.tmp.1.$$$$ || exit 2; \'
echo ' ./${TARGET} -iber -oxer $$f > ./.tmp.1.$$$$ || exit 2; \'
echo ' ./${TARGET} -ixer -oxer ./.tmp.1.$$$$ > ./.tmp.2.$$$$ || exit 2; \'
echo ' diff ./.tmp.1.$$$$ ./.tmp.2.$$$$ || exit 2; \'
echo ' rm -f ./.tmp.[12].$$$$; \'
echo ' done; fi'
echo " @if test -f ./sample-${ASN1PDU}-1.xer ; then \\"
echo " for f in ./sample-${ASN1PDU}-*.xer; do \\"
echo ' echo "Recoding $$f into DER and back..."; \'
echo ' ./${TARGET} -ixer -oder $$f > ./.tmp.1.$$ || exit 2; \'
echo ' ./${TARGET} -iber -oxer ./.tmp.1.$$ > ./.tmp.2.$$ || exit 2; \'
echo ' diff $$f ./.tmp.2.$$ || exit 2; \'
echo ' rm -f ./.tmp.[12].$$; \'
echo ' ./${TARGET} -ixer -oder -b 1 $$f > ./.tmp.1.$$$$ || exit 2; \'
echo ' ./${TARGET} -ixer -oder -b 17 $$f > ./.tmp.1.$$$$ || exit 2; \'
echo ' ./${TARGET} -ixer -oder -b 33 $$f > ./.tmp.1.$$$$ || exit 2; \'
echo ' ./${TARGET} -ixer -oder -b 980 $$f > ./.tmp.1.$$$$ || exit 2; \'
echo ' ./${TARGET} -ixer -oder $$f > ./.tmp.1.$$$$ || exit 2; \'
echo ' ./${TARGET} -iber -oxer ./.tmp.1.$$$$ > ./.tmp.2.$$$$ || exit 2; \'
echo ' diff $$f ./.tmp.2.$$$$ || exit 2; \'
echo ' rm -f ./.tmp.[12].$$$$; \'
echo ' done; fi'
echo " @if test -f ./sample-${ASN1PDU}-1.per ; then \\"
echo " for f in ./sample-${ASN1PDU}-*.per; do \\"
echo ' echo "Recoding $$f into DER into XER and back..."; \'
echo ' ./${TARGET} -iper -oder $$f > ./.tmp.1.$$ || exit 2; \'
echo ' ./${TARGET} -ider -oxer ./.tmp.1.$$ > ./.tmp.2.$$ || exit 2; \'
echo ' ./${TARGET} -ixer -oper ./.tmp.2.$$ > ./.tmp.1.$$ || exit 2; \'
echo ' diff $$f ./.tmp.1.$$ || exit 2; \'
echo ' rm -f ./.tmp.[12].$$; \'
echo ' ./${TARGET} -iper -oder -b 1 $$f > ./.tmp.1.$$$$ || exit 2; \'
echo ' ./${TARGET} -iper -oder -b 17 $$f > ./.tmp.1.$$$$ || exit 2; \'
echo ' ./${TARGET} -iper -oder -b 33 $$f > ./.tmp.1.$$$$ || exit 2; \'
echo ' ./${TARGET} -iper -oder -b 980 $$f > ./.tmp.1.$$$$ || exit 2; \'
echo ' ./${TARGET} -iper -oder $$f > ./.tmp.1.$$$$ || exit 2; \'
echo ' ./${TARGET} -iber -oxer ./.tmp.1.$$$$ > ./.tmp.2.$$$$ || exit 2; \'
echo ' ./${TARGET} -ixer -oper ./.tmp.2.$$$$ > ./.tmp.1.$$$$ || exit 2; \'
echo ' diff $$f ./.tmp.1.$$$$ || exit 2; \'
echo ' rm -f ./.tmp.[12].$$$$; \'
echo ' done; fi'
echo ' @echo ================'
echo ' @echo All tests passed'

View File

@ -493,27 +493,27 @@ check: ${TARGET}
@if test -f ./sample-InterchangedObject-1.[db]er ; then \
for f in ./sample-InterchangedObject-*.[db]er; do \
echo "Recoding $$f into XER and back..."; \
./${TARGET} -iber -oxer $$f > ./.tmp.1.$$ || exit 2; \
./${TARGET} -ixer -oxer ./.tmp.1.$$ > ./.tmp.2.$$ || exit 2; \
diff ./.tmp.1.$$ ./.tmp.2.$$ || exit 2; \
rm -f ./.tmp.[12].$$; \
./${TARGET} -iber -oxer $$f > ./.tmp.1.$$$$ || exit 2; \
./${TARGET} -ixer -oxer ./.tmp.1.$$$$ > ./.tmp.2.$$$$ || exit 2; \
diff ./.tmp.1.$$$$ ./.tmp.2.$$$$ || exit 2; \
rm -f ./.tmp.[12].$$$$; \
done; fi
@if test -f ./sample-InterchangedObject-1.xer ; then \
for f in ./sample-InterchangedObject-*.xer; do \
echo "Recoding $$f into DER and back..."; \
./${TARGET} -ixer -oder $$f > ./.tmp.1.$$ || exit 2; \
./${TARGET} -iber -oxer ./.tmp.1.$$ > ./.tmp.2.$$ || exit 2; \
diff $$f ./.tmp.2.$$ || exit 2; \
rm -f ./.tmp.[12].$$; \
./${TARGET} -ixer -oder $$f > ./.tmp.1.$$$$ || exit 2; \
./${TARGET} -iber -oxer ./.tmp.1.$$$$ > ./.tmp.2.$$$$ || exit 2; \
diff $$f ./.tmp.2.$$$$ || exit 2; \
rm -f ./.tmp.[12].$$$$; \
done; fi
@if test -f ./sample-InterchangedObject-1.per ; then \
for f in ./sample-InterchangedObject-*.per; do \
echo "Recoding $$f into DER into XER and back..."; \
./${TARGET} -iper -oder $$f > ./.tmp.1.$$ || exit 2; \
./${TARGET} -ider -oxer ./.tmp.1.$$ > ./.tmp.2.$$ || exit 2; \
./${TARGET} -ixer -oper ./.tmp.2.$$ > ./.tmp.1.$$ || exit 2; \
diff $$f ./.tmp.1.$$ || exit 2; \
rm -f ./.tmp.[12].$$; \
./${TARGET} -iper -oder $$f > ./.tmp.1.$$$$ || exit 2; \
./${TARGET} -iber -oxer ./.tmp.1.$$$$ > ./.tmp.2.$$$$ || exit 2; \
./${TARGET} -ixer -oper ./.tmp.2.$$$$ > ./.tmp.1.$$$$ || exit 2; \
diff $$f ./.tmp.1.$$$$ || exit 2; \
rm -f ./.tmp.[12].$$$$; \
done; fi
@echo ================
@echo All tests passed

View File

@ -4780,27 +4780,35 @@ check: ${TARGET}
@if test -f ./sample-DL-DCCH-Message-1.[db]er ; then \
for f in ./sample-DL-DCCH-Message-*.[db]er; do \
echo "Recoding $$f into XER and back..."; \
./${TARGET} -iber -oxer $$f > ./.tmp.1.$$ || exit 2; \
./${TARGET} -ixer -oxer ./.tmp.1.$$ > ./.tmp.2.$$ || exit 2; \
diff ./.tmp.1.$$ ./.tmp.2.$$ || exit 2; \
rm -f ./.tmp.[12].$$; \
./${TARGET} -iber -oxer -b 1 $$f > ./.tmp.1.$$$$ || exit 2; \
./${TARGET} -iber -oxer -b 17 $$f > ./.tmp.1.$$$$ || exit 2; \
./${TARGET} -iber -oxer -b 33 $$f > ./.tmp.1.$$$$ || exit 2; \
./${TARGET} -iber -oxer -b 980 $$f > ./.tmp.1.$$$$ || exit 2; \
./${TARGET} -iber -oxer $$f > ./.tmp.1.$$$$ || exit 2; \
./${TARGET} -ixer -oxer ./.tmp.1.$$$$ > ./.tmp.2.$$$$ || exit 2; \
diff ./.tmp.1.$$$$ ./.tmp.2.$$$$ || exit 2; \
rm -f ./.tmp.[12].$$$$; \
done; fi
@if test -f ./sample-DL-DCCH-Message-1.xer ; then \
for f in ./sample-DL-DCCH-Message-*.xer; do \
echo "Recoding $$f into DER and back..."; \
./${TARGET} -ixer -oder $$f > ./.tmp.1.$$ || exit 2; \
./${TARGET} -iber -oxer ./.tmp.1.$$ > ./.tmp.2.$$ || exit 2; \
diff $$f ./.tmp.2.$$ || exit 2; \
rm -f ./.tmp.[12].$$; \
./${TARGET} -ixer -oder -b 1 $$f > ./.tmp.1.$$$$ || exit 2; \
./${TARGET} -ixer -oder -b 17 $$f > ./.tmp.1.$$$$ || exit 2; \
./${TARGET} -ixer -oder -b 33 $$f > ./.tmp.1.$$$$ || exit 2; \
./${TARGET} -ixer -oder -b 980 $$f > ./.tmp.1.$$$$ || exit 2; \
./${TARGET} -ixer -oder $$f > ./.tmp.1.$$$$ || exit 2; \
./${TARGET} -iber -oxer ./.tmp.1.$$$$ > ./.tmp.2.$$$$ || exit 2; \
diff $$f ./.tmp.2.$$$$ || exit 2; \
rm -f ./.tmp.[12].$$$$; \
done; fi
@if test -f ./sample-DL-DCCH-Message-1.per ; then \
for f in ./sample-DL-DCCH-Message-*.per; do \
echo "Recoding $$f into DER into XER and back..."; \
./${TARGET} -iper -oder $$f > ./.tmp.1.$$ || exit 2; \
./${TARGET} -ider -oxer ./.tmp.1.$$ > ./.tmp.2.$$ || exit 2; \
./${TARGET} -ixer -oper ./.tmp.2.$$ > ./.tmp.1.$$ || exit 2; \
diff $$f ./.tmp.1.$$ || exit 2; \
rm -f ./.tmp.[12].$$; \
./${TARGET} -iper -oder $$f > ./.tmp.1.$$$$ || exit 2; \
./${TARGET} -iber -oxer ./.tmp.1.$$$$ > ./.tmp.2.$$$$ || exit 2; \
./${TARGET} -ixer -oper ./.tmp.2.$$$$ > ./.tmp.1.$$$$ || exit 2; \
diff $$f ./.tmp.1.$$$$ || exit 2; \
rm -f ./.tmp.[12].$$$$; \
done; fi
@echo ================
@echo All tests passed

View File

@ -35,7 +35,7 @@ extern asn_TYPE_descriptor_t *asn_pdu_collection[];
* Open file and parse its contens.
*/
static void *data_decode_from_file(asn_TYPE_descriptor_t *asnTypeOfPDU,
FILE *f, const char *filename, ssize_t suggested_bufsize);
FILE *file, const char *name, ssize_t suggested_bufsize, int first_pdu);
static int write_out(const void *buffer, size_t size, void *key);
static FILE *argument_to_file(char *av[], int idx);
static char *argument_to_name(char *av[], int idx);
@ -43,6 +43,7 @@ static char *argument_to_name(char *av[], int idx);
int opt_debug; /* -d */
static int opt_check; /* -c */
static int opt_stack; /* -s */
static int opt_onepdu; /* -1 */
/* Input data format selector */
static enum input_format {
@ -107,21 +108,9 @@ main(int ac, char *av[]) {
fprintf(stderr, "-o<format>: '%s': improper format selector\n",
optarg);
exit(EX_UNAVAILABLE);
case 'p':
#ifdef ASN_PDU_COLLECTION
{
asn_TYPE_descriptor_t **pdu = asn_pdu_collection;
if(optarg[0] < 'A' || optarg[0] > 'Z') {
fprintf(stderr, "Available PDU types:\n");
for(; *pdu; pdu++) printf("%s\n", (*pdu)->name);
exit(0);
}
while(*pdu && strcmp((*pdu)->name, optarg)) pdu++;
if(*pdu) { pduType = *pdu; break; }
}
#endif /* ASN_PDU_COLLECTION */
fprintf(stderr, "-p %s: Unrecognized PDU\n", optarg);
exit(EX_UNAVAILABLE);
case '1':
opt_onepdu = 1;
break;
case 'b':
suggested_bufsize = atoi(optarg);
if(suggested_bufsize < 1
@ -146,6 +135,21 @@ main(int ac, char *av[]) {
exit(EX_UNAVAILABLE);
}
break;
case 'p':
#ifdef ASN_PDU_COLLECTION
{
asn_TYPE_descriptor_t **pdu = asn_pdu_collection;
if(optarg[0] < 'A' || optarg[0] > 'Z') {
fprintf(stderr, "Available PDU types:\n");
for(; *pdu; pdu++) printf("%s\n", (*pdu)->name);
exit(0);
}
while(*pdu && strcmp((*pdu)->name, optarg)) pdu++;
if(*pdu) { pduType = *pdu; break; }
}
#endif /* ASN_PDU_COLLECTION */
fprintf(stderr, "-p %s: Unrecognized PDU\n", optarg);
exit(EX_UNAVAILABLE);
case 's':
opt_stack = atoi(optarg);
if(opt_stack < 0) {
@ -208,20 +212,26 @@ main(int ac, char *av[]) {
* Process all files in turn.
*/
for(ac_i = 0; ac_i < ac; ac_i++) {
asn_enc_rval_t erv;
void *structure; /* Decoded structure */
FILE *file = argument_to_file(av, ac_i);
char *name = argument_to_name(av, ac_i);
asn_enc_rval_t erv;
void *structure; /* Decoded structure */
FILE *file = argument_to_file(av, ac_i);
char *name = argument_to_name(av, ac_i);
int first_pdu;
for(first_pdu = 1; first_pdu || !opt_onepdu; first_pdu = 0) {
/*
* Decode the encoded structure from file.
*/
structure = data_decode_from_file(pduType,
file, name, suggested_bufsize);
if(file && file != stdin) fclose(file);
file, name, suggested_bufsize, first_pdu);
if(!structure) {
/* Error message is already printed */
exit(EX_DATAERR);
if(errno) {
/* Error message is already printed */
exit(EX_DATAERR);
} else {
/* EOF */
break;
}
}
/* Check ASN.1 constraints */
@ -257,6 +267,7 @@ main(int ac, char *av[]) {
name);
exit(EX_UNAVAILABLE);
}
DEBUG("Encoded in %ld bytes of DER", (long)erv.encoded);
break;
case OUT_PER:
erv = uper_encode(pduType, structure, write_out, stdout);
@ -265,10 +276,15 @@ main(int ac, char *av[]) {
name);
exit(EX_UNAVAILABLE);
}
DEBUG("Encoded in %ld bits of UPER", (long)erv.encoded);
break;
}
ASN_STRUCT_FREE(*pduType, structure);
}
if(file && file != stdin)
fclose(file);
}
}
@ -279,6 +295,7 @@ static struct dynamic_buffer {
char *data; /* Pointer to the data bytes */
size_t offset; /* Offset from the start */
size_t length; /* Length of meaningful contents */
size_t unbit; /* Unused bits in the last byte */
size_t allocated; /* Allocated memory for data */
int nreallocs; /* Number of data reallocations */
off_t bytes_shifted; /* Number of bytes ever shifted */
@ -332,17 +349,20 @@ static void add_bytes_to_buffer(const void *data2add, size_t bySize) {
}
static void *
data_decode_from_file(asn_TYPE_descriptor_t *pduType, FILE *file, const char *filename, ssize_t suggested_bufsize) {
data_decode_from_file(asn_TYPE_descriptor_t *pduType, FILE *file, const char *name, ssize_t suggested_bufsize, int on_first_pdu) {
static char *fbuf;
static ssize_t fbuf_size;
static asn_codec_ctx_t s_codec_ctx;
asn_codec_ctx_t *opt_codec_ctx = 0;
void *structure = 0;
asn_dec_rval_t rval;
size_t old_offset;
size_t new_offset;
size_t rd;
if(!file) {
fprintf(stderr, "%s: %s\n", filename, strerror(errno));
fprintf(stderr, "%s: %s\n", name, strerror(errno));
errno = EINVAL;
return 0;
}
@ -351,7 +371,7 @@ data_decode_from_file(asn_TYPE_descriptor_t *pduType, FILE *file, const char *fi
opt_codec_ctx = &s_codec_ctx;
}
DEBUG("Processing %s", filename);
DEBUG("Processing %s", name);
/* prepare the file buffer */
if(fbuf_size != suggested_bufsize) {
@ -363,17 +383,23 @@ data_decode_from_file(asn_TYPE_descriptor_t *pduType, FILE *file, const char *fi
fbuf_size = suggested_bufsize;
}
DynamicBuffer.offset = 0;
DynamicBuffer.length = 0;
DynamicBuffer.allocated = 0;
DynamicBuffer.bytes_shifted = 0;
DynamicBuffer.nreallocs = 0;
if(on_first_pdu) {
DynamicBuffer.offset = 0;
DynamicBuffer.length = 0;
DynamicBuffer.unbit = 0;
DynamicBuffer.allocated = 0;
DynamicBuffer.bytes_shifted = 0;
DynamicBuffer.nreallocs = 0;
}
old_offset = DynamicBuffer.bytes_shifted + DynamicBuffer.offset;
/* Pretend immediate EOF */
rval.code = RC_WMORE;
rval.consumed = 0;
while((rd = fread(fbuf, 1, fbuf_size, file)) || !feof(file)) {
int ecbits = 0; /* Extra consumed bits in case of PER */
char *i_bptr;
size_t i_size;
@ -390,6 +416,8 @@ data_decode_from_file(asn_TYPE_descriptor_t *pduType, FILE *file, const char *fi
i_size = rd;
}
DEBUG("Decoding %ld bytes", (long)i_size);
switch(iform) {
case INP_BER:
rval = ber_decode(opt_codec_ctx, pduType,
@ -401,7 +429,11 @@ data_decode_from_file(asn_TYPE_descriptor_t *pduType, FILE *file, const char *fi
break;
case INP_PER:
rval = uper_decode(opt_codec_ctx, pduType,
(void **)&structure, i_bptr, i_size);
(void **)&structure, i_bptr, i_size, 0);
ecbits = rval.consumed % 8; /* Extra bits */
DEBUG("PER unused %d bits (consumed %ld, %d)",
ecbits, (long)rval.consumed);
rval.consumed /= 8; /* Convert to value in bytes! */
break;
}
DEBUG("decode(%ld) consumed %ld (%ld), code %d",
@ -411,34 +443,37 @@ data_decode_from_file(asn_TYPE_descriptor_t *pduType, FILE *file, const char *fi
if(DynamicBuffer.allocated == 0) {
/*
* Flush the remainder into the intermediate buffer.
* Flush remainder into the intermediate buffer.
*/
if(rval.code != RC_FAIL && rval.consumed < rd) {
DEBUG("Saving %d bytes", rd - rval.consumed);
add_bytes_to_buffer(fbuf + rval.consumed,
rd - rval.consumed);
rval.consumed = 0;
}
}
/*
* Adjust position inside the source buffer.
*/
if(DynamicBuffer.allocated) {
DynamicBuffer.offset += rval.consumed;
DynamicBuffer.length -= rval.consumed;
} else {
DynamicBuffer.bytes_shifted += rval.consumed;
}
switch(rval.code) {
case RC_OK:
DEBUG("RC_OK, finishing up with %ld",
(long)rval.consumed);
return structure;
case RC_WMORE:
/*
* Adjust position inside the source buffer.
*/
if(DynamicBuffer.allocated) {
DynamicBuffer.offset += rval.consumed;
DynamicBuffer.length -= rval.consumed;
}
DEBUG("RC_WMORE, continuing %ld with %ld..%ld..%ld",
(long)rval.consumed,
(long)DynamicBuffer.offset,
(long)DynamicBuffer.length,
(long)DynamicBuffer.allocated);
rval.consumed = 0;
continue;
case RC_FAIL:
break;
@ -449,13 +484,24 @@ data_decode_from_file(asn_TYPE_descriptor_t *pduType, FILE *file, const char *fi
/* Clean up partially decoded structure */
ASN_STRUCT_FREE(*pduType, structure);
fprintf(stderr, "%s: "
"Decode failed past byte %ld: %s\n",
filename, (long)(DynamicBuffer.bytes_shifted
+ DynamicBuffer.offset + rval.consumed),
(rval.code == RC_WMORE)
? "Unexpected end of input"
: "Input processing error");
new_offset = DynamicBuffer.bytes_shifted + DynamicBuffer.offset;
/*
* Print a message and return failure only if not EOF,
* unless this is our first PDU (empty file).
*/
if(on_first_pdu || new_offset != old_offset) {
fprintf(stderr, "%s: "
"Decode failed past byte %ld: %s\n",
name, (long)new_offset,
(rval.code == RC_WMORE)
? "Unexpected end of input"
: "Input processing error");
errno = (rval.code == RC_WMORE) ? ENOMSG : EBADMSG;
} else {
/* Got EOF after a few successful PDU */
errno = 0;
}
return 0;
}

View File

@ -3,10 +3,13 @@
#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) {
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) {
asn_codec_ctx_t s_codec_ctx;
asn_per_data_t pd;
if(skip_bits < 0 || skip_bits > 7 || (skip_bits > 0 && !size))
_ASN_DECODE_FAILED;
/*
* Stack checker requires that the codec context
* must be allocated on the stack.
@ -25,7 +28,7 @@ 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 = 0;
pd.nboff = skip_bits;
pd.nbits = 8 * size; /* 8 is CHAR_BIT from <limits.h> */
/*

View File

@ -21,7 +21,8 @@ asn_dec_rval_t uper_decode(struct asn_codec_ctx_s *opt_codec_ctx,
struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
void **struct_ptr, /* Pointer to a target structure's pointer */
const void *buffer, /* Data to be decoded */
size_t size /* Size of data buffer */
size_t size, /* Size of data buffer */
int skip_bits /* Number of unused leading bits, 0..7 */
);

View File

@ -21,10 +21,20 @@ uper_encode(asn_TYPE_descriptor_t *td, void *sptr, asn_app_consume_bytes_f *cb,
po.nbits = 8 * sizeof(po.tmpspace);
po.outper = cb;
po.op_key = app_key;
po.flushed_bytes = 0;
er = td->uper_encoder(td, 0, sptr, &po);
if(er.encoded != -1 && _uper_encode_flush_outp(&po))
_ASN_ENCODE_FAILED;
if(er.encoded != -1) {
size_t bits_to_flush;
bits_to_flush = ((po.buffer - po.tmpspace) << 3) + po.nboff;
/* Set number of bits encoded to a firm value */
er.encoded = (po.flushed_bytes << 3) + bits_to_flush;
if(_uper_encode_flush_outp(&po))
_ASN_ENCODE_FAILED;
}
return er;
}
@ -52,7 +62,6 @@ static int encode_to_buffer_cb(const void *buffer, size_t size, void *key) {
asn_enc_rval_t
uper_encode_to_buffer(asn_TYPE_descriptor_t *td, void *sptr, void *buffer, size_t buffer_size) {
enc_to_buf_arg key;
asn_enc_rval_t er;
/*
* Invoke type-specific encoder.
@ -65,10 +74,7 @@ uper_encode_to_buffer(asn_TYPE_descriptor_t *td, void *sptr, void *buffer, size_
ASN_DEBUG("Encoding \"%s\" using UNALIGNED PER", td->name);
er = uper_encode(td, sptr, encode_to_buffer_cb, &key);
if(er.encoded != -1)
er.encoded = buffer_size - key.left;
return er;
return uper_encode(td, sptr, encode_to_buffer_cb, &key);
}
static int

View File

@ -210,6 +210,7 @@ per_put_few_bits(asn_per_outp_t *po, uint32_t bits, int obits) {
po->tmpspace[0] = po->buffer[0];
po->buffer = po->tmpspace;
po->nbits = 8 * sizeof(po->tmpspace);
po->flushed_bytes += complete_bytes;
}
/*

View File

@ -76,7 +76,8 @@ typedef struct asn_per_outp_s {
size_t nbits; /* Number of bits left in (tmpspace) */
uint8_t tmpspace[32]; /* Preliminary storage to hold data */
int (*outper)(const void *data, size_t size, void *op_key);
void *op_key;
void *op_key; /* Key for (outper) data callback */
size_t flushed_bytes; /* Bytes already flushed through (outper) */
} asn_per_outp_t;
/* Output a small number of bits (<= 31) */