introduce generic encoder
diff --git a/skeletons/converter-sample.c b/skeletons/converter-sample.c
index 8ec45f2..bbf276c 100644
--- a/skeletons/converter-sample.c
+++ b/skeletons/converter-sample.c
@@ -22,20 +22,31 @@
#include <asn_internal.h> /* for ASN__DEFAULT_STACK_MAX */
/* Convert "Type" defined by -DPDU into "asn_DEF_Type" */
+
+#ifndef NO_ASN_PDU
+#ifndef PDU
+#error Define -DPDU to compile this sample converter.
+#endif
+#ifdef ASN_PDU_COLLECTION /* Generated by asn1c: -pdu=... */
+extern asn_TYPE_descriptor_t *asn_pdu_collection[];
+#endif
#define ASN_DEF_PDU(t) asn_DEF_ ## t
#define DEF_PDU_Type(t) ASN_DEF_PDU(t)
#define PDU_Type DEF_PDU_Type(PDU)
extern asn_TYPE_descriptor_t PDU_Type; /* ASN.1 type to be decoded */
-#ifdef ASN_PDU_COLLECTION /* Generated by asn1c: -pdu=... */
-extern asn_TYPE_descriptor_t *asn_pdu_collection[];
-#endif
+#define PDU_Type_Ptr (&PDU_Type)
+#else /* NO_ASN_PDU */
+#define PDU_Type_Ptr NULL
+#endif /* NO_ASN_PDU */
/*
* Open file and parse its contens.
*/
-static void *data_decode_from_file(asn_TYPE_descriptor_t *asnTypeOfPDU,
- FILE *file, const char *name, ssize_t suggested_bufsize, int first_pdu);
+static void *data_decode_from_file(enum asn_transfer_syntax,
+ asn_TYPE_descriptor_t *asnTypeOfPDU,
+ 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);
@@ -46,24 +57,6 @@
static int opt_nopad; /* -per-nopad (PER input is not padded) */
static int opt_onepdu; /* -1 (decode single PDU) */
-/* Input data format selector */
-static enum input_format {
- INP_BER, /* -iber: BER input */
- INP_XER, /* -ixer: XER input */
- INP_OER, /* -ioer: OER input */
- INP_PER /* -iper: Unaligned PER input */
-} iform; /* -i<format> */
-
-/* Output data format selector */
-static enum output_format {
- OUT_XER, /* -oxer: XER (XML) output */
- OUT_DER, /* -oder: DER (BER) output */
- OUT_OER, /* -ooer: Canonical OER output */
- OUT_PER, /* -oper: Unaligned PER output */
- OUT_TEXT, /* -otext: semi-structured text */
- OUT_NULL /* -onull: No pretty-printing */
-} oform; /* -o<format> */
-
#ifdef JUNKTEST /* Enable -J <probability> */
#define JUNKOPT "J:"
static double opt_jprob; /* Junk bit probability */
@@ -85,20 +78,60 @@
fprintf(stderr, "\n");
}
+static const char *
+ats_simple_name(enum asn_transfer_syntax syntax) {
+ switch(syntax) {
+ case ATS_INVALID:
+ return "/dev/null";
+ case ATS_NONSTANDARD_PLAINTEXT:
+ return "plaintext";
+ case ATS_BER:
+ return "BER";
+ case ATS_DER:
+ return "DER";
+ case ATS_CER:
+ return "CER";
+ case ATS_BASIC_OER:
+ case ATS_CANONICAL_OER:
+ return "OER";
+ case ATS_BASIC_XER:
+ case ATS_CANONICAL_XER:
+ return "XER";
+ case ATS_UNALIGNED_BASIC_PER:
+ case ATS_UNALIGNED_CANONICAL_PER:
+ return "PER";
+ default:
+ return "<?>";
+ }
+}
+
int
main(int ac, char *av[]) {
FILE *binary_out;
- static asn_TYPE_descriptor_t *pduType = &PDU_Type;
+ static asn_TYPE_descriptor_t *pduType = PDU_Type_Ptr;
ssize_t suggested_bufsize = 8192; /* close or equal to stdio buffer */
int number_of_iterations = 1;
int num;
int ch;
+ enum asn_transfer_syntax isyntax = ATS_INVALID;
+ enum asn_transfer_syntax osyntax = ATS_INVALID;
+
+#ifndef PDU
+ if(!pduType) {
+ fprintf(stderr, "No -DPDU defined during compilation.\n");
+#ifdef NO_ASN_PDU
+ exit(0);
+#else
+ exit(EX_SOFTWARE);
+#endif
+ }
+#endif
/* Figure out if specialty decoder needs to be default */
if(pduType->op->oer_decoder)
- iform = INP_OER;
+ isyntax = ATS_BASIC_OER;
else if(pduType->op->uper_decoder)
- iform = INP_PER;
+ isyntax = ATS_UNALIGNED_BASIC_PER;
/*
* Pocess the command-line argments.
@@ -106,24 +139,24 @@
while((ch = getopt(ac, av, "i:o:1b:cdn:p:hs:" JUNKOPT)) != -1)
switch(ch) {
case 'i':
- if(optarg[0] == 'b') { iform = INP_BER; break; }
- if(optarg[0] == 'x') { iform = INP_XER; break; }
+ if(optarg[0] == 'b') { isyntax = ATS_BER; break; }
+ if(optarg[0] == 'x') { isyntax = ATS_BASIC_XER; break; }
if(pduType->op->oer_decoder
- && optarg[0] == 'o') { iform = INP_OER; break; }
+ && optarg[0] == 'o') { isyntax = ATS_BASIC_OER; break; }
if(pduType->op->uper_decoder
- && optarg[0] == 'p') { iform = INP_PER; break; }
+ && optarg[0] == 'p') { isyntax = ATS_UNALIGNED_BASIC_PER; break; }
fprintf(stderr, "-i<format>: '%s': improper format selector\n",
optarg);
exit(EX_UNAVAILABLE);
case 'o':
- if(optarg[0] == 'd') { oform = OUT_DER; break; }
+ if(optarg[0] == 'd') { osyntax = ATS_DER; break; }
if(pduType->op->oer_encoder
- && optarg[0] == 'o') { oform = OUT_OER; break; }
+ && optarg[0] == 'o') { osyntax = ATS_CANONICAL_OER; break; }
if(pduType->op->uper_encoder
- && optarg[0] == 'p') { oform = OUT_PER; break; }
- if(optarg[0] == 'x') { oform = OUT_XER; break; }
- if(optarg[0] == 't') { oform = OUT_TEXT; break; }
- if(optarg[0] == 'n') { oform = OUT_NULL; break; }
+ && optarg[0] == 'p') { osyntax = ATS_UNALIGNED_CANONICAL_PER; break; }
+ if(optarg[0] == 'x') { osyntax = ATS_BASIC_XER; break; }
+ if(optarg[0] == 't') { osyntax = ATS_NONSTANDARD_PLAINTEXT; break; }
+ if(optarg[0] == 'n') { osyntax = ATS_INVALID; break; }
fprintf(stderr, "-o<format>: '%s': improper format selector\n",
optarg);
exit(EX_UNAVAILABLE);
@@ -219,14 +252,14 @@
if(pduType->op->oer_decoder)
fprintf(stderr,
" -ioer Input is in OER (Octet Encoding Rules)%s\n",
- iform == INP_OER ? " (DEFAULT)" : "");
+ isyntax == ATS_BASIC_OER ? " (DEFAULT)" : "");
if(pduType->op->uper_decoder)
fprintf(stderr,
" -iper Input is in Unaligned PER (Packed Encoding Rules)%s\n",
- iform == INP_PER ? " (DEFAULT)" : "");
+ isyntax == ATS_UNALIGNED_BASIC_PER ? " (DEFAULT)" : "");
fprintf(stderr,
" -iber Input is in BER (Basic Encoding Rules)%s\n",
- iform == INP_BER ? " (DEFAULT)" : "");
+ isyntax == ATS_BER ? " (DEFAULT)" : "");
fprintf(stderr,
" -ixer Input is in XER (XML Encoding Rules)\n");
if(pduType->op->oer_encoder)
@@ -273,7 +306,7 @@
}
if(isatty(1)) {
- const int is_text_output = oform == OUT_TEXT || oform == OUT_XER;
+ const int is_text_output = osyntax == ATS_NONSTANDARD_PLAINTEXT || osyntax == ATS_CANONICAL_XER || osyntax == ATS_BASIC_XER;
if(is_text_output) {
binary_out = stdout;
} else {
@@ -301,11 +334,11 @@
char *name = argument_to_name(av, ac_i);
int first_pdu;
- for(first_pdu = 1; first_pdu || !opt_onepdu; first_pdu = 0) {
+ for(first_pdu = 1; file && (first_pdu || !opt_onepdu); first_pdu = 0) {
/*
* Decode the encoded structure from file.
*/
- structure = data_decode_from_file(pduType, file, name,
+ structure = data_decode_from_file(isyntax, pduType, file, name,
suggested_bufsize, first_pdu);
if(!structure) {
if(errno) {
@@ -330,59 +363,24 @@
}
}
- switch(oform) {
- case OUT_NULL:
+ if(osyntax == ATS_INVALID) {
#ifdef JUNKTEST
- if(opt_jprob == 0.0)
-#endif
+ if(opt_jprob == 0.0) {
fprintf(stderr, "%s: decoded successfully\n", name);
- break;
- case OUT_TEXT: /* -otext */
- asn_fprint(stdout, pduType, structure);
- break;
- case OUT_XER: /* -oxer */
- if(xer_fprint(stdout, pduType, structure)) {
- fprintf(stderr, "%s: Cannot convert %s into XML\n", name,
- pduType->name);
- exit(EX_UNAVAILABLE);
}
- break;
- case OUT_DER:
- erv = der_encode(pduType, structure, write_out, binary_out);
- if(erv.encoded < 0) {
- fprintf(stderr, "%s: Cannot convert %s into DER\n", name,
- pduType->name);
- exit(EX_UNAVAILABLE);
- }
- DEBUG("Encoded in %ld bytes of DER", (long)erv.encoded);
- break;
- case OUT_OER:
-#ifdef ASN_DISABLE_OER_SUPPORT
- erv.encoded = -1;
#else
- erv = oer_encode(pduType, structure, write_out, binary_out);
+ fprintf(stderr, "%s: decoded successfully\n", name);
#endif
- if(erv.encoded < 0) {
- fprintf(stderr, "%s: Cannot convert %s into OER\n", name,
- pduType->name);
+ } else {
+ erv = asn_encode(NULL, osyntax, pduType, structure, write_out, binary_out);
+
+ if(erv.encoded == -1) {
+ fprintf(stderr, "%s: Cannot convert %s into %s\n", name,
+ pduType->name, ats_simple_name(osyntax));
exit(EX_UNAVAILABLE);
}
- DEBUG("Encoded in %ld bytes of OER", (long)erv.encoded);
- break;
- case OUT_PER:
-#ifdef ASN_DISABLE_PER_SUPPORT
- erv.encoded = -1;
-#else
- erv = uper_encode(pduType, structure, write_out, binary_out);
-#endif
- if(erv.encoded < 0) {
- fprintf(stderr,
- "%s: Cannot convert %s into Unaligned PER\n", name,
- pduType->name);
- exit(EX_UNAVAILABLE);
- }
- DEBUG("Encoded in %ld bits of UPER", (long)erv.encoded);
- break;
+ DEBUG("Encoded in %zd bytes of %s", erv.encoded,
+ ats_simple_name(osyntax));
}
ASN_STRUCT_FREE(*pduType, structure);
@@ -610,7 +608,7 @@
}
static void *
-data_decode_from_file(asn_TYPE_descriptor_t *pduType, FILE *file, const char *name, ssize_t suggested_bufsize, int on_first_pdu) {
+data_decode_from_file(enum asn_transfer_syntax isyntax, asn_TYPE_descriptor_t *pduType, FILE *file, const char *name, ssize_t suggested_bufsize, int on_first_pdu) {
static uint8_t *fbuf;
static ssize_t fbuf_size;
static asn_codec_ctx_t s_codec_ctx;
@@ -688,12 +686,12 @@
junk_bytes_with_probability(i_bptr, i_size, opt_jprob);
#endif
- switch(iform) {
- case INP_BER:
+ switch(isyntax) {
+ case ATS_BER:
rval = ber_decode(opt_codec_ctx, pduType,
(void **)&structure, i_bptr, i_size);
break;
- case INP_OER:
+ case ATS_BASIC_OER:
#ifdef ASN_DISABLE_OER_SUPPORT
rval.code = RC_FAIL;
rval.consumed = 0;
@@ -702,11 +700,11 @@
(void **)&structure, i_bptr, i_size);
#endif
break;
- case INP_XER:
+ case ATS_BASIC_XER:
rval = xer_decode(opt_codec_ctx, pduType,
(void **)&structure, i_bptr, i_size);
break;
- case INP_PER:
+ case ATS_UNALIGNED_BASIC_PER:
#ifdef ASN_DISABLE_PER_SUPPORT
rval.code = RC_FAIL;
rval.consumed = 0;
@@ -740,6 +738,9 @@
break;
}
break;
+ default:
+ rval.consumed = 0;
+ /* Fall through */
}
DEBUG("decode(%ld) consumed %ld+%db (%ld), code %d",
(long)DynamicBuffer.length,
@@ -804,7 +805,7 @@
*/
if(on_first_pdu
|| DynamicBuffer.length
- || new_offset - old_offset > ((iform == INP_XER)?sizeof("\r\n")-1:0)
+ || new_offset - old_offset > ((isyntax == ATS_BASIC_XER)?sizeof("\r\n")-1:0)
) {
#ifdef JUNKTEST