mirror of https://gerrit.osmocom.org/asn1c
XER can decode long values
This commit is contained in:
parent
55f106a8b2
commit
c744a02926
|
@ -3,14 +3,14 @@
|
||||||
|
|
||||||
* skeletons/standard-modules directory is now used for standard types.
|
* skeletons/standard-modules directory is now used for standard types.
|
||||||
* Fixed class field access problem (Test case 98)
|
* Fixed class field access problem (Test case 98)
|
||||||
(Severity: medim; Security impact: none)
|
(Severity: medium; Security impact: none)
|
||||||
* Refactored Information Object Classes parsing.
|
* Refactored Information Object Classes parsing.
|
||||||
* Refactored Parameterization support.
|
* Refactored Parameterization support.
|
||||||
* [typedef enum foo {}] foo_e; is now e_foo, see #1287989
|
* [typedef enum foo {}] foo_e; is now e_foo, see #1287989
|
||||||
* Refactored ValueSetTypeAssignment parsing.
|
* Refactored ValueSetTypeAssignment parsing.
|
||||||
* First release of PER encoder (does not encode SETs yet).
|
|
||||||
* asn-decoder-template.c renamed into converter-sample.c
|
* asn-decoder-template.c renamed into converter-sample.c
|
||||||
* MEGACO (Media Gateway Control Protocol) decoder sample added.
|
* MEGACO (Media Gateway Control Protocol) decoder sample added.
|
||||||
|
* First release of PER encoder (does not encode SETs yet).
|
||||||
|
|
||||||
0.9.20: 2006-Mar-06
|
0.9.20: 2006-Mar-06
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,19 @@ cat Makefile.am.sample \
|
||||||
echo " @touch ${ASN1PDU}.c"
|
echo " @touch ${ASN1PDU}.c"
|
||||||
echo " make"
|
echo " make"
|
||||||
echo
|
echo
|
||||||
|
echo 'check: ${TARGET}'
|
||||||
|
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 ' done; fi'
|
||||||
|
echo ' @echo ================'
|
||||||
|
echo ' @echo All tests passed'
|
||||||
|
echo ' @echo ================'
|
||||||
|
echo
|
||||||
echo "distclean: clean"
|
echo "distclean: clean"
|
||||||
echo ' rm -f $(ASN_MODULE_SOURCES) $(ASN_MODULE_HEADERS)'
|
echo ' rm -f $(ASN_MODULE_SOURCES) $(ASN_MODULE_HEADERS)'
|
||||||
echo ' rm -f $(ASN_CONVERTER_SOURCES) $(ASN_CONVERTER_HEADERS)'
|
echo ' rm -f $(ASN_CONVERTER_SOURCES) $(ASN_CONVERTER_HEADERS)'
|
||||||
|
|
|
@ -196,6 +196,19 @@ LDAPMessage.c: ../sample.makefile.regen
|
||||||
@touch LDAPMessage.c
|
@touch LDAPMessage.c
|
||||||
make
|
make
|
||||||
|
|
||||||
|
check: ${TARGET}
|
||||||
|
@if test -f ./sample-LDAPMessage-1.[db]er ; then \
|
||||||
|
for f in ./sample-LDAPMessage-*.[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].$$; \
|
||||||
|
done; fi
|
||||||
|
@echo ================
|
||||||
|
@echo All tests passed
|
||||||
|
@echo ================
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
rm -f $(ASN_MODULE_SOURCES) $(ASN_MODULE_HEADERS)
|
rm -f $(ASN_MODULE_SOURCES) $(ASN_MODULE_HEADERS)
|
||||||
rm -f $(ASN_CONVERTER_SOURCES) $(ASN_CONVERTER_HEADERS)
|
rm -f $(ASN_CONVERTER_SOURCES) $(ASN_CONVERTER_HEADERS)
|
||||||
|
|
|
@ -318,6 +318,19 @@ MegacoMessage.c: ../sample.makefile.regen
|
||||||
@touch MegacoMessage.c
|
@touch MegacoMessage.c
|
||||||
make
|
make
|
||||||
|
|
||||||
|
check: ${TARGET}
|
||||||
|
@if test -f ./sample-MegacoMessage-1.[db]er ; then \
|
||||||
|
for f in ./sample-MegacoMessage-*.[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].$$; \
|
||||||
|
done; fi
|
||||||
|
@echo ================
|
||||||
|
@echo All tests passed
|
||||||
|
@echo ================
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
rm -f $(ASN_MODULE_SOURCES) $(ASN_MODULE_HEADERS)
|
rm -f $(ASN_MODULE_SOURCES) $(ASN_MODULE_HEADERS)
|
||||||
rm -f $(ASN_CONVERTER_SOURCES) $(ASN_CONVERTER_HEADERS)
|
rm -f $(ASN_CONVERTER_SOURCES) $(ASN_CONVERTER_HEADERS)
|
||||||
|
|
|
@ -378,6 +378,19 @@ Certificate.c: ../sample.makefile.regen
|
||||||
@touch Certificate.c
|
@touch Certificate.c
|
||||||
make
|
make
|
||||||
|
|
||||||
|
check: ${TARGET}
|
||||||
|
@if test -f ./sample-Certificate-1.[db]er ; then \
|
||||||
|
for f in ./sample-Certificate-*.[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].$$; \
|
||||||
|
done; fi
|
||||||
|
@echo ================
|
||||||
|
@echo All tests passed
|
||||||
|
@echo ================
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
rm -f $(ASN_MODULE_SOURCES) $(ASN_MODULE_HEADERS)
|
rm -f $(ASN_MODULE_SOURCES) $(ASN_MODULE_HEADERS)
|
||||||
rm -f $(ASN_CONVERTER_SOURCES) $(ASN_CONVERTER_HEADERS)
|
rm -f $(ASN_CONVERTER_SOURCES) $(ASN_CONVERTER_HEADERS)
|
||||||
|
|
|
@ -297,6 +297,20 @@ INTEGER_map_value2enum(asn_INTEGER_specifics_t *specs, long value) {
|
||||||
INTEGER__compar_value2enum);
|
INTEGER__compar_value2enum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
INTEGER_st_prealloc(INTEGER_t *st, int min_size) {
|
||||||
|
void *p = MALLOC(min_size + 1);
|
||||||
|
if(p) {
|
||||||
|
void *b = st->buf;
|
||||||
|
st->size = 0;
|
||||||
|
st->buf = p;
|
||||||
|
FREEMEM(b);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decode the chunk of XML text encoding INTEGER.
|
* Decode the chunk of XML text encoding INTEGER.
|
||||||
*/
|
*/
|
||||||
|
@ -310,11 +324,19 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
|
||||||
const char *lstop = lstart + chunk_size;
|
const char *lstop = lstart + chunk_size;
|
||||||
enum {
|
enum {
|
||||||
ST_SKIPSPACE,
|
ST_SKIPSPACE,
|
||||||
|
ST_SKIPSPHEX,
|
||||||
ST_WAITDIGITS,
|
ST_WAITDIGITS,
|
||||||
ST_DIGITS,
|
ST_DIGITS,
|
||||||
|
ST_HEXDIGIT1,
|
||||||
|
ST_HEXDIGIT2,
|
||||||
|
ST_HEXCOLON,
|
||||||
ST_EXTRASTUFF
|
ST_EXTRASTUFF
|
||||||
} state = ST_SKIPSPACE;
|
} state = ST_SKIPSPACE;
|
||||||
|
|
||||||
|
if(chunk_size)
|
||||||
|
ASN_DEBUG("INTEGER body %d 0x%2x..0x%2x",
|
||||||
|
chunk_size, *lstart, lstop[-1]);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We may have received a tag here. It will be processed inline.
|
* We may have received a tag here. It will be processed inline.
|
||||||
* Use strtoul()-like code and serialize the result.
|
* Use strtoul()-like code and serialize the result.
|
||||||
|
@ -323,7 +345,19 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
|
||||||
int lv = *lp;
|
int lv = *lp;
|
||||||
switch(lv) {
|
switch(lv) {
|
||||||
case 0x09: case 0x0a: case 0x0d: case 0x20:
|
case 0x09: case 0x0a: case 0x0d: case 0x20:
|
||||||
if(state == ST_SKIPSPACE) continue;
|
switch(state) {
|
||||||
|
case ST_SKIPSPACE:
|
||||||
|
case ST_SKIPSPHEX:
|
||||||
|
continue;
|
||||||
|
case ST_HEXCOLON:
|
||||||
|
if(xer_is_whitespace(lp, lstop - lp)) {
|
||||||
|
lp = lstop - 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0x2d: /* '-' */
|
case 0x2d: /* '-' */
|
||||||
if(state == ST_SKIPSPACE) {
|
if(state == ST_SKIPSPACE) {
|
||||||
|
@ -340,7 +374,24 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
|
||||||
break;
|
break;
|
||||||
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
|
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
|
||||||
case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
|
case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
|
||||||
if(state != ST_DIGITS) state = ST_DIGITS;
|
switch(state) {
|
||||||
|
case ST_DIGITS: break;
|
||||||
|
case ST_SKIPSPHEX: /* Fall through */
|
||||||
|
case ST_HEXDIGIT1:
|
||||||
|
value = (lv - 0x30) << 4;
|
||||||
|
state = ST_HEXDIGIT2;
|
||||||
|
continue;
|
||||||
|
case ST_HEXDIGIT2:
|
||||||
|
value += (lv - 0x30);
|
||||||
|
state = ST_HEXCOLON;
|
||||||
|
st->buf[st->size++] = value;
|
||||||
|
continue;
|
||||||
|
case ST_HEXCOLON:
|
||||||
|
return XPBD_BROKEN_ENCODING;
|
||||||
|
default:
|
||||||
|
state = ST_DIGITS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
long new_value = value * 10;
|
long new_value = value * 10;
|
||||||
|
@ -381,22 +432,86 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
|
||||||
ASN_DEBUG("Unknown identifier for INTEGER");
|
ASN_DEBUG("Unknown identifier for INTEGER");
|
||||||
}
|
}
|
||||||
return XPBD_BROKEN_ENCODING;
|
return XPBD_BROKEN_ENCODING;
|
||||||
|
case 0x3a: /* ':' */
|
||||||
|
if(state == ST_HEXCOLON) {
|
||||||
|
/* This colon is expected */
|
||||||
|
state = ST_HEXDIGIT1;
|
||||||
|
continue;
|
||||||
|
} else if(state == ST_DIGITS) {
|
||||||
|
/* The colon here means that we have
|
||||||
|
* decoded the first two hexadecimal
|
||||||
|
* places as a decimal value.
|
||||||
|
* Switch decoding mode. */
|
||||||
|
ASN_DEBUG("INTEGER re-evaluate as hex form");
|
||||||
|
if(INTEGER_st_prealloc(st, (chunk_size/3) + 1))
|
||||||
|
return XPBD_SYSTEM_FAILURE;
|
||||||
|
state = ST_SKIPSPHEX;
|
||||||
|
lp = lstart - 1;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
ASN_DEBUG("state %d at %d", state, lp - lstart);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* [A-Fa-f] */
|
||||||
|
case 0x41:case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:
|
||||||
|
case 0x61:case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:
|
||||||
|
switch(state) {
|
||||||
|
case ST_SKIPSPHEX:
|
||||||
|
case ST_SKIPSPACE: /* Fall through */
|
||||||
|
case ST_HEXDIGIT1:
|
||||||
|
value = lv - ((lv < 0x61) ? 0x41 : 0x61);
|
||||||
|
value += 10;
|
||||||
|
value <<= 4;
|
||||||
|
state = ST_HEXDIGIT2;
|
||||||
|
continue;
|
||||||
|
case ST_HEXDIGIT2:
|
||||||
|
value += lv - ((lv < 0x61) ? 0x41 : 0x61);
|
||||||
|
value += 10;
|
||||||
|
st->buf[st->size++] = value;
|
||||||
|
state = ST_HEXCOLON;
|
||||||
|
continue;
|
||||||
|
case ST_DIGITS:
|
||||||
|
ASN_DEBUG("INTEGER re-evaluate as hex form");
|
||||||
|
if(INTEGER_st_prealloc(st, (chunk_size/3) + 1))
|
||||||
|
return XPBD_SYSTEM_FAILURE;
|
||||||
|
state = ST_SKIPSPHEX;
|
||||||
|
lp = lstart - 1;
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Found extra non-numeric stuff */
|
/* Found extra non-numeric stuff */
|
||||||
|
ASN_DEBUG("Found non-numeric 0x%2x at %d",
|
||||||
|
lv, lp - lstart);
|
||||||
state = ST_EXTRASTUFF;
|
state = ST_EXTRASTUFF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(state != ST_DIGITS) {
|
switch(state) {
|
||||||
|
case ST_DIGITS:
|
||||||
|
/* Everything is cool */
|
||||||
|
break;
|
||||||
|
case ST_HEXCOLON:
|
||||||
|
st->buf[st->size] = 0; /* Just in case termination */
|
||||||
|
return XPBD_BODY_CONSUMED;
|
||||||
|
case ST_HEXDIGIT1:
|
||||||
|
case ST_HEXDIGIT2:
|
||||||
|
case ST_SKIPSPHEX:
|
||||||
|
return XPBD_BROKEN_ENCODING;
|
||||||
|
default:
|
||||||
if(xer_is_whitespace(lp, lstop - lp)) {
|
if(xer_is_whitespace(lp, lstop - lp)) {
|
||||||
if(state != ST_EXTRASTUFF)
|
if(state != ST_EXTRASTUFF)
|
||||||
return XPBD_NOT_BODY_IGNORE;
|
return XPBD_NOT_BODY_IGNORE;
|
||||||
/* Fall through */
|
break;
|
||||||
} else {
|
} else {
|
||||||
ASN_DEBUG("No useful digits in output");
|
ASN_DEBUG("INTEGER: No useful digits (state %d)",
|
||||||
|
state);
|
||||||
return XPBD_BROKEN_ENCODING; /* No digits */
|
return XPBD_BROKEN_ENCODING; /* No digits */
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
value *= sign; /* Change sign, if needed */
|
value *= sign; /* Change sign, if needed */
|
||||||
|
|
|
@ -35,8 +35,10 @@ extern asn_TYPE_descriptor_t *asn_pdu_collection[];
|
||||||
* Open file and parse its contens.
|
* Open file and parse its contens.
|
||||||
*/
|
*/
|
||||||
static void *data_decode_from_file(asn_TYPE_descriptor_t *asnTypeOfPDU,
|
static void *data_decode_from_file(asn_TYPE_descriptor_t *asnTypeOfPDU,
|
||||||
const char *fname, ssize_t suggested_bufsize);
|
FILE *f, const char *filename, ssize_t suggested_bufsize);
|
||||||
static int write_out(const void *buffer, size_t size, void *key);
|
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);
|
||||||
|
|
||||||
int opt_debug; /* -d */
|
int opt_debug; /* -d */
|
||||||
static int opt_check; /* -c */
|
static int opt_check; /* -c */
|
||||||
|
@ -71,7 +73,7 @@ DEBUG(const char *fmt, ...) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int ac, char **av) {
|
main(int ac, char *av[]) {
|
||||||
static asn_TYPE_descriptor_t *pduType = &PDU_Type;
|
static asn_TYPE_descriptor_t *pduType = &PDU_Type;
|
||||||
ssize_t suggested_bufsize = 8192; /* close or equal to stdio buffer */
|
ssize_t suggested_bufsize = 8192; /* close or equal to stdio buffer */
|
||||||
int number_of_iterations = 1;
|
int number_of_iterations = 1;
|
||||||
|
@ -206,15 +208,17 @@ main(int ac, char **av) {
|
||||||
* Process all files in turn.
|
* Process all files in turn.
|
||||||
*/
|
*/
|
||||||
for(ac_i = 0; ac_i < ac; ac_i++) {
|
for(ac_i = 0; ac_i < ac; ac_i++) {
|
||||||
char *fname = av[ac_i];
|
|
||||||
void *structure;
|
|
||||||
asn_enc_rval_t erv;
|
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);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decode the encoded structure from file.
|
* Decode the encoded structure from file.
|
||||||
*/
|
*/
|
||||||
structure = data_decode_from_file(pduType,
|
structure = data_decode_from_file(pduType,
|
||||||
fname, suggested_bufsize);
|
file, name, suggested_bufsize);
|
||||||
|
if(file && file != stdin) fclose(file);
|
||||||
if(!structure) {
|
if(!structure) {
|
||||||
/* Error message is already printed */
|
/* Error message is already printed */
|
||||||
exit(EX_DATAERR);
|
exit(EX_DATAERR);
|
||||||
|
@ -227,14 +231,14 @@ main(int ac, char **av) {
|
||||||
if(asn_check_constraints(pduType, structure,
|
if(asn_check_constraints(pduType, structure,
|
||||||
errbuf, &errlen)) {
|
errbuf, &errlen)) {
|
||||||
fprintf(stderr, "%s: ASN.1 constraint "
|
fprintf(stderr, "%s: ASN.1 constraint "
|
||||||
"check failed: %s\n", fname, errbuf);
|
"check failed: %s\n", name, errbuf);
|
||||||
exit(EX_DATAERR);
|
exit(EX_DATAERR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(oform) {
|
switch(oform) {
|
||||||
case OUT_NULL:
|
case OUT_NULL:
|
||||||
fprintf(stderr, "%s: decoded successfully\n", fname);
|
fprintf(stderr, "%s: decoded successfully\n", name);
|
||||||
break;
|
break;
|
||||||
case OUT_TEXT: /* -otext */
|
case OUT_TEXT: /* -otext */
|
||||||
asn_fprint(stdout, pduType, structure);
|
asn_fprint(stdout, pduType, structure);
|
||||||
|
@ -242,7 +246,7 @@ main(int ac, char **av) {
|
||||||
case OUT_XER: /* -oxer */
|
case OUT_XER: /* -oxer */
|
||||||
if(xer_fprint(stdout, pduType, structure)) {
|
if(xer_fprint(stdout, pduType, structure)) {
|
||||||
fprintf(stderr, "%s: Cannot convert into XML\n",
|
fprintf(stderr, "%s: Cannot convert into XML\n",
|
||||||
fname);
|
name);
|
||||||
exit(EX_UNAVAILABLE);
|
exit(EX_UNAVAILABLE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -250,7 +254,7 @@ main(int ac, char **av) {
|
||||||
erv = der_encode(pduType, structure, write_out, stdout);
|
erv = der_encode(pduType, structure, write_out, stdout);
|
||||||
if(erv.encoded < 0) {
|
if(erv.encoded < 0) {
|
||||||
fprintf(stderr, "%s: Cannot convert into DER\n",
|
fprintf(stderr, "%s: Cannot convert into DER\n",
|
||||||
fname);
|
name);
|
||||||
exit(EX_UNAVAILABLE);
|
exit(EX_UNAVAILABLE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -258,7 +262,7 @@ main(int ac, char **av) {
|
||||||
erv = uper_encode(pduType, structure, write_out, stdout);
|
erv = uper_encode(pduType, structure, write_out, stdout);
|
||||||
if(erv.encoded < 0) {
|
if(erv.encoded < 0) {
|
||||||
fprintf(stderr, "%s: Cannot convert into Unaligned PER\n",
|
fprintf(stderr, "%s: Cannot convert into Unaligned PER\n",
|
||||||
fname);
|
name);
|
||||||
exit(EX_UNAVAILABLE);
|
exit(EX_UNAVAILABLE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -325,7 +329,8 @@ static void add_bytes_to_buffer(const void *data2add, size_t bySize) {
|
||||||
DynamicBuffer.length += bySize;
|
DynamicBuffer.length += bySize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *data_decode_from_file(asn_TYPE_descriptor_t *pduType, const char *fname, ssize_t suggested_bufsize) {
|
static void *
|
||||||
|
data_decode_from_file(asn_TYPE_descriptor_t *pduType, FILE *file, const char *filename, ssize_t suggested_bufsize) {
|
||||||
static char *fbuf;
|
static char *fbuf;
|
||||||
static ssize_t fbuf_size;
|
static ssize_t fbuf_size;
|
||||||
static asn_codec_ctx_t s_codec_ctx;
|
static asn_codec_ctx_t s_codec_ctx;
|
||||||
|
@ -333,26 +338,18 @@ static void *data_decode_from_file(asn_TYPE_descriptor_t *pduType, const char *f
|
||||||
void *structure = 0;
|
void *structure = 0;
|
||||||
asn_dec_rval_t rval;
|
asn_dec_rval_t rval;
|
||||||
size_t rd;
|
size_t rd;
|
||||||
FILE *fp;
|
|
||||||
|
if(!file) {
|
||||||
|
fprintf(stderr, "%s: %s\n", filename, strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(opt_stack) {
|
if(opt_stack) {
|
||||||
s_codec_ctx.max_stack_size = opt_stack;
|
s_codec_ctx.max_stack_size = opt_stack;
|
||||||
opt_codec_ctx = &s_codec_ctx;
|
opt_codec_ctx = &s_codec_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(strcmp(fname, "-")) {
|
DEBUG("Processing %s", filename);
|
||||||
DEBUG("Processing file %s", fname);
|
|
||||||
fp = fopen(fname, "r");
|
|
||||||
} else {
|
|
||||||
DEBUG("Processing %s", "standard input");
|
|
||||||
fname = "stdin";
|
|
||||||
fp = stdin;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!fp) {
|
|
||||||
fprintf(stderr, "%s: %s\n", fname, strerror(errno));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* prepare the file buffer */
|
/* prepare the file buffer */
|
||||||
if(fbuf_size != suggested_bufsize) {
|
if(fbuf_size != suggested_bufsize) {
|
||||||
|
@ -374,7 +371,7 @@ static void *data_decode_from_file(asn_TYPE_descriptor_t *pduType, const char *f
|
||||||
rval.code = RC_WMORE;
|
rval.code = RC_WMORE;
|
||||||
rval.consumed = 0;
|
rval.consumed = 0;
|
||||||
|
|
||||||
while((rd = fread(fbuf, 1, fbuf_size, fp)) || !feof(fp)) {
|
while((rd = fread(fbuf, 1, fbuf_size, file)) || !feof(file)) {
|
||||||
char *i_bptr;
|
char *i_bptr;
|
||||||
size_t i_size;
|
size_t i_size;
|
||||||
|
|
||||||
|
@ -425,7 +422,6 @@ static void *data_decode_from_file(asn_TYPE_descriptor_t *pduType, const char *f
|
||||||
case RC_OK:
|
case RC_OK:
|
||||||
DEBUG("RC_OK, finishing up with %ld",
|
DEBUG("RC_OK, finishing up with %ld",
|
||||||
(long)rval.consumed);
|
(long)rval.consumed);
|
||||||
if(fp != stdin) fclose(fp);
|
|
||||||
return structure;
|
return structure;
|
||||||
case RC_WMORE:
|
case RC_WMORE:
|
||||||
/*
|
/*
|
||||||
|
@ -448,14 +444,12 @@ static void *data_decode_from_file(asn_TYPE_descriptor_t *pduType, const char *f
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
/* Clean up partially decoded structure */
|
/* Clean up partially decoded structure */
|
||||||
ASN_STRUCT_FREE(*pduType, structure);
|
ASN_STRUCT_FREE(*pduType, structure);
|
||||||
|
|
||||||
fprintf(stderr, "%s: "
|
fprintf(stderr, "%s: "
|
||||||
"Decode failed past byte %ld: %s\n",
|
"Decode failed past byte %ld: %s\n",
|
||||||
fname, (long)(DynamicBuffer.bytes_shifted
|
filename, (long)(DynamicBuffer.bytes_shifted
|
||||||
+ DynamicBuffer.offset + rval.consumed),
|
+ DynamicBuffer.offset + rval.consumed),
|
||||||
(rval.code == RC_WMORE)
|
(rval.code == RC_WMORE)
|
||||||
? "Unexpected end of input"
|
? "Unexpected end of input"
|
||||||
|
@ -469,3 +463,27 @@ static int write_out(const void *buffer, size_t size, void *key) {
|
||||||
FILE *fp = (FILE *)key;
|
FILE *fp = (FILE *)key;
|
||||||
return (fwrite(buffer, 1, size, fp) == size) ? 0 : -1;
|
return (fwrite(buffer, 1, size, fp) == size) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int argument_is_stdin(char *av[], int idx) {
|
||||||
|
if(strcmp(av[idx], "-")) {
|
||||||
|
return 0; /* Certainly not <stdin> */
|
||||||
|
} else {
|
||||||
|
/* This might be <stdin>, unless `./program -- -` */
|
||||||
|
if(strcmp(av[-1], "--"))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static FILE *argument_to_file(char *av[], int idx) {
|
||||||
|
return argument_is_stdin(av, idx)
|
||||||
|
? stdin
|
||||||
|
: fopen(av[idx], "r");
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *argument_to_name(char *av[], int idx) {
|
||||||
|
return argument_is_stdin(av, idx)
|
||||||
|
? "standard input"
|
||||||
|
: av[idx];
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue