mirror of https://gerrit.osmocom.org/asn1c
more granular PER encoding
This commit is contained in:
parent
13c92a6409
commit
bc6917730d
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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> */
|
||||
|
||||
/*
|
||||
|
|
|
@ -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 */
|
||||
);
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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) */
|
||||
|
|
Loading…
Reference in New Issue