aboutsummaryrefslogtreecommitdiffstats
path: root/skeletons
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2004-09-22 16:06:28 +0000
committerLev Walkin <vlm@lionet.info>2004-09-22 16:06:28 +0000
commita9cc46e3f3c30ddd3f2a8f712c9f0acdc793fda7 (patch)
tree3ca369d58e29a24dc08ec01d4a3e4cac2020fe26 /skeletons
parente4d6ab83d7937337f1c19acfb4353fd0d43180dd (diff)
XER support
Diffstat (limited to 'skeletons')
-rw-r--r--skeletons/ANY.c28
-rw-r--r--skeletons/ANY.h5
-rw-r--r--skeletons/BIT_STRING.c68
-rw-r--r--skeletons/BIT_STRING.h1
-rw-r--r--skeletons/BMPString.c78
-rw-r--r--skeletons/BMPString.h3
-rw-r--r--skeletons/BOOLEAN.c34
-rw-r--r--skeletons/BOOLEAN.h5
-rw-r--r--skeletons/ENUMERATED.c7
-rw-r--r--skeletons/GeneralString.c7
-rw-r--r--skeletons/GeneralizedTime.c41
-rw-r--r--skeletons/GeneralizedTime.h3
-rw-r--r--skeletons/GraphicString.c7
-rw-r--r--skeletons/IA5String.c8
-rw-r--r--skeletons/INTEGER.c71
-rw-r--r--skeletons/INTEGER.h5
-rw-r--r--skeletons/ISO646String.c7
-rw-r--r--skeletons/NULL.c36
-rw-r--r--skeletons/NULL.h3
-rw-r--r--skeletons/NativeEnumerated.c7
-rw-r--r--skeletons/NativeInteger.c34
-rw-r--r--skeletons/NativeInteger.h5
-rw-r--r--skeletons/NativeReal.c55
-rw-r--r--skeletons/NativeReal.h5
-rw-r--r--skeletons/NumericString.c7
-rw-r--r--skeletons/OBJECT_IDENTIFIER.c119
-rw-r--r--skeletons/OBJECT_IDENTIFIER.h9
-rw-r--r--skeletons/OCTET_STRING.c96
-rw-r--r--skeletons/OCTET_STRING.h8
-rw-r--r--skeletons/ObjectDescriptor.c7
-rw-r--r--skeletons/PrintableString.c7
-rw-r--r--skeletons/REAL.c107
-rw-r--r--skeletons/REAL.h3
-rw-r--r--skeletons/RELATIVE-OID.c69
-rw-r--r--skeletons/RELATIVE-OID.h1
-rw-r--r--skeletons/T61String.c7
-rw-r--r--skeletons/TeletexString.c7
-rw-r--r--skeletons/UTCTime.c37
-rw-r--r--skeletons/UTCTime.h3
-rw-r--r--skeletons/UTF8String.c7
-rw-r--r--skeletons/UTF8String.h2
-rw-r--r--skeletons/UniversalString.c85
-rw-r--r--skeletons/UniversalString.h3
-rw-r--r--skeletons/VideotexString.c7
-rw-r--r--skeletons/VisibleString.c7
-rw-r--r--skeletons/asn_SEQUENCE_OF.c1
-rw-r--r--skeletons/asn_SET_OF.c1
-rw-r--r--skeletons/asn_internal.h72
-rw-r--r--skeletons/asn_types.h30
-rw-r--r--skeletons/ber_decoder.c1
-rw-r--r--skeletons/ber_tlv_length.c1
-rw-r--r--skeletons/ber_tlv_tag.c1
-rw-r--r--skeletons/constr_CHOICE.c58
-rw-r--r--skeletons/constr_CHOICE.h5
-rw-r--r--skeletons/constr_SEQUENCE.c51
-rw-r--r--skeletons/constr_SEQUENCE.h5
-rw-r--r--skeletons/constr_SEQUENCE_OF.c52
-rw-r--r--skeletons/constr_SEQUENCE_OF.h5
-rw-r--r--skeletons/constr_SET.c55
-rw-r--r--skeletons/constr_SET.h5
-rw-r--r--skeletons/constr_SET_OF.c52
-rw-r--r--skeletons/constr_SET_OF.h8
-rw-r--r--skeletons/constr_TYPE.c6
-rw-r--r--skeletons/constr_TYPE.h51
-rw-r--r--skeletons/constraints.c1
-rw-r--r--skeletons/der_encoder.c3
-rw-r--r--skeletons/der_encoder.h27
-rw-r--r--skeletons/file-dependencies2
-rw-r--r--skeletons/tests/check-GeneralizedTime.c18
-rw-r--r--skeletons/tests/check-UTCTime.c18
-rw-r--r--skeletons/tests/check-length.c2
-rw-r--r--skeletons/xer_encoder.c71
-rw-r--r--skeletons/xer_encoder.h51
73 files changed, 1448 insertions, 326 deletions
diff --git a/skeletons/ANY.c b/skeletons/ANY.c
index 389452cd..a1c77118 100644
--- a/skeletons/ANY.c
+++ b/skeletons/ANY.c
@@ -2,17 +2,20 @@
* Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <ANY.h>
#include <assert.h>
#include <errno.h>
asn1_TYPE_descriptor_t asn1_DEF_ANY = {
"ANY",
+ OCTET_STRING_free,
+ OCTET_STRING_print,
asn_generic_no_constraint,
OCTET_STRING_decode_ber,
OCTET_STRING_encode_der,
- OCTET_STRING_print,
- OCTET_STRING_free,
+ 0, /* Not implemented yet */
+ ANY_encode_xer,
0, /* Use generic outmost tag fetcher */
0, 0, 0, 0,
-1, /* Both ways are fine (primitive and constructed) */
@@ -21,6 +24,23 @@ asn1_TYPE_descriptor_t asn1_DEF_ANY = {
};
+asn_enc_rval_t
+ANY_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+
+ (void)ilevel;
+ (void)flags;
+ (void)cb;
+ (void)app_key;
+
+ /*
+ * XER-encoding of ANY type is not supported.
+ */
+
+ _ASN_ENCODE_FAILED;
+}
+
struct _callback_arg {
uint8_t *buffer;
size_t offset;
@@ -32,7 +52,7 @@ static int ANY__consume_bytes(const void *buffer, size_t size, void *key);
int
ANY_fromType(ANY_t *st, asn1_TYPE_descriptor_t *td, void *sptr) {
struct _callback_arg arg;
- der_enc_rval_t erval;
+ asn_enc_rval_t erval;
if(!st || !td) {
errno = EINVAL;
@@ -53,7 +73,7 @@ ANY_fromType(ANY_t *st, asn1_TYPE_descriptor_t *td, void *sptr) {
if(arg.buffer) FREEMEM(arg.buffer);
return -1;
}
- assert(erval.encoded == arg.offset);
+ assert((size_t)erval.encoded == arg.offset);
if(st->buf) FREEMEM(st->buf);
st->buf = arg.buffer;
diff --git a/skeletons/ANY.h b/skeletons/ANY.h
index 719b3a99..d010de4a 100644
--- a/skeletons/ANY.h
+++ b/skeletons/ANY.h
@@ -17,10 +17,11 @@ typedef struct ANY {
extern asn1_TYPE_descriptor_t asn1_DEF_ANY;
+asn_struct_free_f ANY_free;
+asn_struct_print_f ANY_print;
ber_type_decoder_f ANY_decode_ber;
der_type_encoder_f ANY_encode_der;
-asn_struct_print_f ANY_print;
-asn_struct_free_f ANY_free;
+xer_type_encoder_f ANY_encode_xer;
/******************************
* Handy conversion routines. *
diff --git a/skeletons/BIT_STRING.c b/skeletons/BIT_STRING.c
index a43a22aa..b6da3aea 100644
--- a/skeletons/BIT_STRING.c
+++ b/skeletons/BIT_STRING.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <BIT_STRING.h>
/*
@@ -12,11 +13,13 @@ static ber_tlv_tag_t asn1_DEF_BIT_STRING_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_BIT_STRING = {
"BIT STRING",
+ OCTET_STRING_free, /* Implemented in terms of OCTET STRING */
+ BIT_STRING_print,
BIT_STRING_constraint,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
- BIT_STRING_print,
- OCTET_STRING_free, /* Implemented in terms of OCTET STRING */
+ 0, /* Not implemented yet */
+ BIT_STRING_encode_xer,
0, /* Use generic outmost tag fetcher */
asn1_DEF_BIT_STRING_tags,
sizeof(asn1_DEF_BIT_STRING_tags)
@@ -61,6 +64,66 @@ BIT_STRING_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
return 0;
}
+static char *_bit_pattern[16] = {
+ "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
+ "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
+};
+
+asn_enc_rval_t
+BIT_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t er;
+ char scratch[128];
+ char *p = scratch;
+ char *scend = scratch + (sizeof(scratch) - 10);
+ const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
+ uint8_t *buf;
+ uint8_t *end;
+
+ if(!st || !st->buf)
+ _ASN_ENCODE_FAILED;
+
+ er.encoded = 0;
+
+ buf = st->buf;
+ end = buf + st->size - 1; /* Last byte is special */
+
+ /*
+ * Binary dump
+ */
+ for(buf++; buf < end; buf++) {
+ int v = *buf;
+ int nline = (flags & XER_F_CANONICAL)
+ ?0:((((buf - st->buf) - 1) % 16) == 0);
+ if(p >= scend || nline) {
+ er.encoded += p - scratch;
+ _ASN_CALLBACK(scratch, p - scratch);
+ p = scratch;
+ if(nline) _i_ASN_TEXT_INDENT(1, ilevel);
+ }
+ memcpy(p + 0, _bit_pattern[v >> 4], 4);
+ memcpy(p + 4, _bit_pattern[v & 0x0f], 4);
+ p += 8;
+ }
+
+ er.encoded += p - scratch;
+ _ASN_CALLBACK(scratch, p - scratch);
+
+ if(buf < end + 1) {
+ int v = *buf;
+ int mbit = st->buf[0]; /* bits to skip from the right */
+ int i;
+ for(i = 7; i >= mbit; i--)
+ *p++ = (v & (1 << i)) ? '1' : '0';
+ er.encoded += p - scratch;
+ _ASN_CALLBACK(scratch, p - scratch);
+ }
+
+ return er;
+}
+
+
/*
* BIT STRING specific contents printer.
*/
@@ -99,6 +162,7 @@ BIT_STRING_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
*p++ = h2c[*buf & 0x0F];
*p++ = 0x20;
}
+ if(p > scratch) p--; /* Eat the tailing space */
/* Dump the incomplete 16-bytes row */
return cb(scratch, p - scratch, app_key);
diff --git a/skeletons/BIT_STRING.h b/skeletons/BIT_STRING.h
index 1def8bb2..f9ebf9b7 100644
--- a/skeletons/BIT_STRING.h
+++ b/skeletons/BIT_STRING.h
@@ -14,5 +14,6 @@ extern asn1_TYPE_descriptor_t asn1_DEF_BIT_STRING;
asn_struct_print_f BIT_STRING_print; /* Human-readable output */
asn_constr_check_f BIT_STRING_constraint;
+xer_type_encoder_f BIT_STRING_encode_xer;
#endif /* _BIT_STRING_H_ */
diff --git a/skeletons/BMPString.c b/skeletons/BMPString.c
index 3e779cce..bdbd40d6 100644
--- a/skeletons/BMPString.c
+++ b/skeletons/BMPString.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <BMPString.h>
/*
@@ -13,11 +14,13 @@ static ber_tlv_tag_t asn1_DEF_BMPString_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_BMPString = {
"BMPString",
+ OCTET_STRING_free, /* Implemented in terms of OCTET STRING */
+ BMPString_print,
asn_generic_no_constraint, /* No constraint by default */
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
- BMPString_print,
- OCTET_STRING_free, /* -//- */
+ 0, /* Not implemented yet */
+ BMPString_encode_xer, /* Conver to UTF8 */
0, /* Use generic outmost tag fetcher */
asn1_DEF_BMPString_tags,
sizeof(asn1_DEF_BMPString_tags)
@@ -33,27 +36,22 @@ asn1_TYPE_descriptor_t asn1_DEF_BMPString = {
/*
* BMPString specific contents printer.
*/
-int
-BMPString_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
+static ssize_t
+BMPString__dump(const BMPString_t *st,
asn_app_consume_bytes_f *cb, void *app_key) {
- const BMPString_t *st = (const BMPString_t *)sptr;
- uint16_t *wchar;
- uint16_t *wend;
char scratch[128]; /* Scratchpad buffer */
- char *p;
+ char *p = scratch;
+ ssize_t wrote = 0;
+ uint8_t *ch;
+ uint8_t *end;
- (void)td; /* Unused argument */
- (void)ilevel; /* Unused argument */
-
- if(!st || !st->buf) return cb("<absent>", 8, app_key);
-
- wchar = (uint16_t *)st->buf;
- wend = (uint16_t *)(st->buf + st->size);
- for(p = scratch; wchar < wend; wchar++) {
- uint16_t wc = (((uint8_t *)wchar)[0] << 8)
- | ((uint8_t *)wchar)[1]; /* 2 bytes */
+ ch = st->buf;
+ end = (st->buf + st->size);
+ for(end--; ch < end; ch += 2) {
+ uint16_t wc = (ch[0] << 8) | ch[1]; /* 2 bytes */
if(sizeof(scratch) - (p - scratch) < 3) {
- if(cb(scratch, p - scratch, app_key))
+ wrote += p - scratch;
+ if(cb(scratch, p - scratch, app_key) < 0)
return -1;
p = scratch;
}
@@ -69,5 +67,45 @@ BMPString_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
}
}
- return cb(scratch, p - scratch, app_key);
+ wrote += p - scratch;
+ if(cb(scratch, p - scratch, app_key) < 0)
+ return -1;
+
+ return wrote;
}
+
+asn_enc_rval_t
+BMPString_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ const BMPString_t *st = (const BMPString_t *)sptr;
+ asn_enc_rval_t er;
+
+ (void)ilevel;
+ (void)flags;
+
+ if(!st || !st->buf)
+ _ASN_ENCODE_FAILED;
+
+ er.encoded = BMPString__dump(st, cb, app_key);
+ if(er.encoded < 0) _ASN_ENCODE_FAILED;
+
+ return er;
+}
+
+int
+BMPString_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ const BMPString_t *st = (const BMPString_t *)sptr;
+
+ (void)td; /* Unused argument */
+ (void)ilevel; /* Unused argument */
+
+ if(!st || !st->buf) return cb("<absent>", 8, app_key);
+
+ if(BMPString__dump(st, cb, app_key) < 0)
+ return -1;
+
+ return 0;
+}
+
diff --git a/skeletons/BMPString.h b/skeletons/BMPString.h
index e3957ca0..31d67eae 100644
--- a/skeletons/BMPString.h
+++ b/skeletons/BMPString.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#ifndef _BMPString_H_
@@ -13,5 +13,6 @@ typedef OCTET_STRING_t BMPString_t; /* Implemented in terms of OCTET STRING */
extern asn1_TYPE_descriptor_t asn1_DEF_BMPString;
asn_struct_print_f BMPString_print; /* Human-readable output */
+xer_type_encoder_f BMPString_encode_xer;
#endif /* _BMPString_H_ */
diff --git a/skeletons/BOOLEAN.c b/skeletons/BOOLEAN.c
index 5ba2e4f8..9609a19e 100644
--- a/skeletons/BOOLEAN.c
+++ b/skeletons/BOOLEAN.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <BOOLEAN.h>
/*
@@ -12,11 +13,13 @@ static ber_tlv_tag_t asn1_DEF_BOOLEAN_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_BOOLEAN = {
"BOOLEAN",
+ BOOLEAN_free,
+ BOOLEAN_print,
asn_generic_no_constraint,
BOOLEAN_decode_ber,
BOOLEAN_encode_der,
- BOOLEAN_print,
- BOOLEAN_free,
+ 0, /* Not implemented yet */
+ BOOLEAN_encode_xer,
0, /* Use generic outmost tag fetcher */
asn1_DEF_BOOLEAN_tags,
sizeof(asn1_DEF_BOOLEAN_tags) / sizeof(asn1_DEF_BOOLEAN_tags[0]),
@@ -93,11 +96,11 @@ BOOLEAN_decode_ber(asn1_TYPE_descriptor_t *td,
return rval;
}
-der_enc_rval_t
+asn_enc_rval_t
BOOLEAN_encode_der(asn1_TYPE_descriptor_t *td, void *sptr,
int tag_mode, ber_tlv_tag_t tag,
asn_app_consume_bytes_f *cb, void *app_key) {
- der_enc_rval_t erval;
+ asn_enc_rval_t erval;
BOOLEAN_t *st = (BOOLEAN_t *)sptr;
erval.encoded = der_write_tags(td, 1, tag_mode, tag, cb, app_key);
@@ -126,6 +129,29 @@ BOOLEAN_encode_der(asn1_TYPE_descriptor_t *td, void *sptr,
return erval;
}
+asn_enc_rval_t
+BOOLEAN_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
+ asn_enc_rval_t er;
+
+ (void)ilevel;
+ (void)flags;
+
+ if(!st) _ASN_ENCODE_FAILED;
+
+ if(*st) {
+ _ASN_CALLBACK("<true/>", 7);
+ er.encoded = 7;
+ } else {
+ _ASN_CALLBACK("<false/>", 8);
+ er.encoded = 8;
+ }
+
+ return er;
+}
+
int
BOOLEAN_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
asn_app_consume_bytes_f *cb, void *app_key) {
diff --git a/skeletons/BOOLEAN.h b/skeletons/BOOLEAN.h
index 6ad69a45..b9b836ee 100644
--- a/skeletons/BOOLEAN.h
+++ b/skeletons/BOOLEAN.h
@@ -16,9 +16,10 @@ typedef int BOOLEAN_t;
extern asn1_TYPE_descriptor_t asn1_DEF_BOOLEAN;
+asn_struct_free_f BOOLEAN_free;
+asn_struct_print_f BOOLEAN_print;
ber_type_decoder_f BOOLEAN_decode_ber;
der_type_encoder_f BOOLEAN_encode_der;
-asn_struct_print_f BOOLEAN_print;
-asn_struct_free_f BOOLEAN_free;
+xer_type_encoder_f BOOLEAN_encode_xer;
#endif /* _BOOLEAN_H_ */
diff --git a/skeletons/ENUMERATED.c b/skeletons/ENUMERATED.c
index ed908b56..158119d6 100644
--- a/skeletons/ENUMERATED.c
+++ b/skeletons/ENUMERATED.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <ENUMERATED.h>
/*
@@ -12,11 +13,13 @@ static ber_tlv_tag_t asn1_DEF_ENUMERATED_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_ENUMERATED = {
"ENUMERATED",
+ INTEGER_free, /* Implemented in terms of INTEGER */
+ INTEGER_print, /* Implemented in terms of INTEGER */
asn_generic_no_constraint,
INTEGER_decode_ber, /* Implemented in terms of INTEGER */
INTEGER_encode_der, /* Implemented in terms of INTEGER */
- INTEGER_print, /* Implemented in terms of INTEGER */
- INTEGER_free, /* Implemented in terms of INTEGER */
+ 0, /* Not implemented yet */
+ INTEGER_encode_xer, /* Implemented in terms of INTEGER */
0, /* Use generic outmost tag fetcher */
asn1_DEF_ENUMERATED_tags,
sizeof(asn1_DEF_ENUMERATED_tags) / sizeof(asn1_DEF_ENUMERATED_tags[0]),
diff --git a/skeletons/GeneralString.c b/skeletons/GeneralString.c
index dfca2cac..c9d82480 100644
--- a/skeletons/GeneralString.c
+++ b/skeletons/GeneralString.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <GeneralString.h>
/*
@@ -13,11 +14,13 @@ static ber_tlv_tag_t asn1_DEF_GeneralString_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_GeneralString = {
"GeneralString",
+ OCTET_STRING_free,
+ OCTET_STRING_print, /* non-ascii string */
asn_generic_unknown_constraint,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
- OCTET_STRING_print, /* non-ascii string */
- OCTET_STRING_free,
+ 0, /* Not implemented yet */
+ OCTET_STRING_encode_xer, /* Implemented in terms of OCTET STRING */
0, /* Use generic outmost tag fetcher */
asn1_DEF_GeneralString_tags,
sizeof(asn1_DEF_GeneralString_tags)
diff --git a/skeletons/GeneralizedTime.c b/skeletons/GeneralizedTime.c
index 88806f91..8f8fff21 100644
--- a/skeletons/GeneralizedTime.c
+++ b/skeletons/GeneralizedTime.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <GeneralizedTime.h>
#include <time.h>
#include <errno.h>
@@ -113,11 +114,13 @@ static ber_tlv_tag_t asn1_DEF_GeneralizedTime_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_GeneralizedTime = {
"GeneralizedTime",
+ OCTET_STRING_free,
+ GeneralizedTime_print,
GeneralizedTime_constraint, /* Check validity of time */
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
GeneralizedTime_encode_der, /* Implemented in terms of OCTET STRING */
- GeneralizedTime_print,
- OCTET_STRING_free,
+ 0, /* Not implemented yet */
+ GeneralizedTime_encode_xer,
0, /* Use generic outmost tag fetcher */
asn1_DEF_GeneralizedTime_tags,
sizeof(asn1_DEF_GeneralizedTime_tags)
@@ -153,12 +156,12 @@ GeneralizedTime_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
return 0;
}
-der_enc_rval_t
+asn_enc_rval_t
GeneralizedTime_encode_der(asn1_TYPE_descriptor_t *td, void *ptr,
int tag_mode, ber_tlv_tag_t tag,
asn_app_consume_bytes_f *cb, void *app_key) {
GeneralizedTime_t *st = (GeneralizedTime_t *)ptr;
- der_enc_rval_t erval;
+ asn_enc_rval_t erval;
/* If not canonical DER, re-encode into canonical DER. */
if(st->size && st->buf[st->size-1] != 'Z') {
@@ -194,6 +197,36 @@ GeneralizedTime_encode_der(asn1_TYPE_descriptor_t *td, void *ptr,
return erval;
}
+asn_enc_rval_t
+GeneralizedTime_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ OCTET_STRING_t st;
+
+ if(flags & XER_F_CANONICAL) {
+ char buf[32];
+ struct tm tm;
+ ssize_t ret;
+
+ errno = EPERM;
+ if(asn_GT2time((GeneralizedTime_t *)sptr, &tm, 1) == -1
+ && errno != EPERM)
+ _ASN_ENCODE_FAILED;
+
+ ret = snprintf(buf, sizeof(buf), "%04d%02d%02d%02d%02d%02dZ",
+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+ assert(ret > 0 && ret < (int)sizeof(buf));
+
+ st.buf = (uint8_t *)buf;
+ st.size = ret;
+ sptr = &st;
+ }
+
+ return OCTET_STRING_encode_xer_ascii(td, sptr, ilevel, flags,
+ cb, app_key);
+}
+
int
GeneralizedTime_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
asn_app_consume_bytes_f *cb, void *app_key) {
diff --git a/skeletons/GeneralizedTime.h b/skeletons/GeneralizedTime.h
index a7a8a4a2..06b4ca5f 100644
--- a/skeletons/GeneralizedTime.h
+++ b/skeletons/GeneralizedTime.h
@@ -12,9 +12,10 @@ typedef OCTET_STRING_t GeneralizedTime_t; /* Implemented using OCTET STRING */
extern asn1_TYPE_descriptor_t asn1_DEF_GeneralizedTime;
+asn_struct_print_f GeneralizedTime_print;
asn_constr_check_f GeneralizedTime_constraint;
der_type_encoder_f GeneralizedTime_encode_der;
-asn_struct_print_f GeneralizedTime_print;
+xer_type_encoder_f GeneralizedTime_encode_xer;
/***********************
* Some handy helpers. *
diff --git a/skeletons/GraphicString.c b/skeletons/GraphicString.c
index ceb247d6..e8fa7975 100644
--- a/skeletons/GraphicString.c
+++ b/skeletons/GraphicString.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <GraphicString.h>
/*
@@ -13,11 +14,13 @@ static ber_tlv_tag_t asn1_DEF_GraphicString_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_GraphicString = {
"GraphicString",
+ OCTET_STRING_free,
+ OCTET_STRING_print, /* non-ascii string */
asn_generic_unknown_constraint,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
- OCTET_STRING_print, /* non-ascii string */
- OCTET_STRING_free,
+ 0, /* Not implemented yet */
+ OCTET_STRING_encode_xer, /* Implemented in terms of OCTET STRING */
0, /* Use generic outmost tag fetcher */
asn1_DEF_GraphicString_tags,
sizeof(asn1_DEF_GraphicString_tags)
diff --git a/skeletons/IA5String.c b/skeletons/IA5String.c
index 9fc308b1..a2c828dd 100644
--- a/skeletons/IA5String.c
+++ b/skeletons/IA5String.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <IA5String.h>
/*
@@ -13,11 +14,13 @@ static ber_tlv_tag_t asn1_DEF_IA5String_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_IA5String = {
"IA5String",
+ OCTET_STRING_free,
+ OCTET_STRING_print_ascii, /* ASCII subset */
IA5String_constraint, /* Constraint on the alphabet */
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
- OCTET_STRING_print_ascii, /* ASCII subset */
- OCTET_STRING_free,
+ 0, /* Not implemented yet */
+ OCTET_STRING_encode_xer_ascii,/* Implemented in terms of OCTET STRING */
0, /* Use generic outmost tag fetcher */
asn1_DEF_IA5String_tags,
sizeof(asn1_DEF_IA5String_tags)
@@ -63,3 +66,4 @@ IA5String_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
return 0;
}
+
diff --git a/skeletons/INTEGER.c b/skeletons/INTEGER.c
index 5bfcf1fb..75782a68 100644
--- a/skeletons/INTEGER.c
+++ b/skeletons/INTEGER.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <INTEGER.h>
#include <assert.h>
#include <errno.h>
@@ -14,11 +15,13 @@ static ber_tlv_tag_t asn1_DEF_INTEGER_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_INTEGER = {
"INTEGER",
+ INTEGER_free,
+ INTEGER_print,
asn_generic_no_constraint,
INTEGER_decode_ber,
INTEGER_encode_der,
- INTEGER_print,
- INTEGER_free,
+ 0, /* Not implemented yet */
+ INTEGER_encode_xer,
0, /* Use generic outmost tag fetcher */
asn1_DEF_INTEGER_tags,
sizeof(asn1_DEF_INTEGER_tags) / sizeof(asn1_DEF_INTEGER_tags[0]),
@@ -100,11 +103,11 @@ INTEGER_decode_ber(asn1_TYPE_descriptor_t *td,
/*
* Encode INTEGER type using DER.
*/
-der_enc_rval_t
+asn_enc_rval_t
INTEGER_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
int tag_mode, ber_tlv_tag_t tag,
asn_app_consume_bytes_f *cb, void *app_key) {
- der_enc_rval_t erval;
+ asn_enc_rval_t erval;
INTEGER_t *st = (INTEGER_t *)ptr;
ASN_DEBUG("%s %s as INTEGER (tm=%d)",
@@ -185,24 +188,19 @@ INTEGER_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
/*
* INTEGER specific human-readable output.
*/
-int
-INTEGER_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
- asn_app_consume_bytes_f *cb, void *app_key) {
+static ssize_t
+INTEGER__dump(const INTEGER_t *st, asn_app_consume_bytes_f *cb, void *app_key) {
char scratch[32]; /* Enough for 64-bit integer */
- const INTEGER_t *st = (const INTEGER_t *)sptr;
uint8_t *buf = st->buf;
uint8_t *buf_end = st->buf + st->size;
signed long accum;
+ ssize_t wrote = 0;
char *p;
int ret;
- (void)td; /* Unused argument */
- (void)ilevel; /* Unused argument */
-
- if(!st && !st->buf) return cb("<absent>", 8, app_key);
-
- if(st->size == 0)
- return cb("0", 1, app_key);
+ if(st->size == 0) {
+ return (cb("0", 1, app_key) < 0) ? -1 : 1;
+ }
/*
* Advance buf pointer until the start of the value's body.
@@ -226,7 +224,7 @@ INTEGER_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
accum = (accum << 8) | *buf;
ret = snprintf(scratch, sizeof(scratch), "%ld", accum);
assert(ret > 0 && ret < (int)sizeof(scratch));
- return cb(scratch, ret, app_key);
+ return (cb(scratch, ret, app_key) < 0) ? -1 : ret;
}
/* Output in the long xx:yy:zz... format */
@@ -235,8 +233,9 @@ INTEGER_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
static const char *h2c = "0123456789ABCDEF";
if((p - scratch) >= (ssize_t)(sizeof(scratch) - 4)) {
/* Flush buffer */
- if(cb(scratch, p - scratch, app_key))
+ if(cb(scratch, p - scratch, app_key) < 0)
return -1;
+ wrote += p - scratch;
p = scratch;
}
*p++ = h2c[*buf >> 4];
@@ -246,7 +245,43 @@ INTEGER_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
if(p != scratch)
p--; /* Remove the last ':' */
- return cb(scratch, p - scratch, app_key);
+ wrote += p - scratch;
+ return (cb(scratch, p - scratch, app_key) < 0) ? -1 : wrote;
+}
+
+/*
+ * INTEGER specific human-readable output.
+ */
+int
+INTEGER_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ const INTEGER_t *st = (const INTEGER_t *)sptr;
+
+ (void)td;
+ (void)ilevel;
+
+ if(!st && !st->buf) return cb("<absent>", 8, app_key);
+
+ return (INTEGER__dump(st, cb, app_key) < 0) ? -1 : 0;
+}
+
+asn_enc_rval_t
+INTEGER_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ const INTEGER_t *st = (const INTEGER_t *)sptr;
+ asn_enc_rval_t er;
+
+ (void)ilevel;
+ (void)flags;
+
+ if(!st && !st->buf)
+ _ASN_ENCODE_FAILED;
+
+ er.encoded = INTEGER__dump(st, cb, app_key);
+ if(er.encoded < 0) _ASN_ENCODE_FAILED;
+
+ return er;
}
void
diff --git a/skeletons/INTEGER.h b/skeletons/INTEGER.h
index ef4d3f25..8e3c5458 100644
--- a/skeletons/INTEGER.h
+++ b/skeletons/INTEGER.h
@@ -14,10 +14,11 @@ typedef struct INTEGER {
extern asn1_TYPE_descriptor_t asn1_DEF_INTEGER;
+asn_struct_free_f INTEGER_free;
+asn_struct_print_f INTEGER_print;
ber_type_decoder_f INTEGER_decode_ber;
der_type_encoder_f INTEGER_encode_der;
-asn_struct_print_f INTEGER_print;
-asn_struct_free_f INTEGER_free;
+xer_type_encoder_f INTEGER_encode_xer;
/***********************************
* Some handy conversion routines. *
diff --git a/skeletons/ISO646String.c b/skeletons/ISO646String.c
index 8a99cbcb..e5a4d444 100644
--- a/skeletons/ISO646String.c
+++ b/skeletons/ISO646String.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <ISO646String.h>
/*
@@ -13,11 +14,13 @@ static ber_tlv_tag_t asn1_DEF_ISO646String_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_ISO646String = {
"ISO646String",
+ OCTET_STRING_free,
+ OCTET_STRING_print_ascii, /* ASCII subset */
VisibleString_constraint,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
- OCTET_STRING_print_ascii, /* ASCII subset */
- OCTET_STRING_free,
+ 0, /* Not implemented yet */
+ OCTET_STRING_encode_xer_ascii,/* Implemented in terms of OCTET STRING */
0, /* Use generic outmost tag fetcher */
asn1_DEF_ISO646String_tags,
sizeof(asn1_DEF_ISO646String_tags)
diff --git a/skeletons/NULL.c b/skeletons/NULL.c
index 36796b8a..e15b9af8 100644
--- a/skeletons/NULL.c
+++ b/skeletons/NULL.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <NULL.h>
#include <BOOLEAN.h> /* Implemented in terms of BOOLEAN type */
@@ -13,11 +14,13 @@ static ber_tlv_tag_t asn1_DEF_NULL_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_NULL = {
"NULL",
+ BOOLEAN_free,
+ NULL_print,
asn_generic_no_constraint,
BOOLEAN_decode_ber, /* Implemented in terms of BOOLEAN */
NULL_encode_der, /* Special handling of DER encoding */
- NULL_print,
- BOOLEAN_free,
+ 0, /* Not implemented yet */
+ NULL_encode_xer, /* Special handling of DER encoding */
0, /* Use generic outmost tag fetcher */
asn1_DEF_NULL_tags,
sizeof(asn1_DEF_NULL_tags) / sizeof(asn1_DEF_NULL_tags[0]),
@@ -28,21 +31,40 @@ asn1_TYPE_descriptor_t asn1_DEF_NULL = {
0 /* No specifics */
};
-der_enc_rval_t
-NULL_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
+asn_enc_rval_t
+NULL_encode_der(asn1_TYPE_descriptor_t *td, void *ptr,
int tag_mode, ber_tlv_tag_t tag,
asn_app_consume_bytes_f *cb, void *app_key) {
- der_enc_rval_t erval;
+ asn_enc_rval_t erval;
- erval.encoded = der_write_tags(sd, 0, tag_mode, tag, cb, app_key);
+ erval.encoded = der_write_tags(td, 0, tag_mode, tag, cb, app_key);
if(erval.encoded == -1) {
- erval.failed_type = sd;
+ erval.failed_type = td;
erval.structure_ptr = ptr;
}
return erval;
}
+asn_enc_rval_t
+NULL_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t er;
+
+ (void)td;
+ (void)sptr;
+ (void)ilevel;
+ (void)flags;
+ (void)cb;
+ (void)app_key;
+
+ /* XMLNullValue is empty */
+ er.encoded = 0;
+
+ return er;
+}
+
int
NULL_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
asn_app_consume_bytes_f *cb, void *app_key) {
diff --git a/skeletons/NULL.h b/skeletons/NULL.h
index 003a5a63..0c07ffe8 100644
--- a/skeletons/NULL.h
+++ b/skeletons/NULL.h
@@ -15,7 +15,8 @@ typedef int NULL_t;
extern asn1_TYPE_descriptor_t asn1_DEF_NULL;
-der_type_encoder_f NULL_encode_der;
asn_struct_print_f NULL_print;
+der_type_encoder_f NULL_encode_der;
+xer_type_encoder_f NULL_encode_xer;
#endif /* NULL_H */
diff --git a/skeletons/NativeEnumerated.c b/skeletons/NativeEnumerated.c
index 53ce5012..ec4dd88d 100644
--- a/skeletons/NativeEnumerated.c
+++ b/skeletons/NativeEnumerated.c
@@ -9,6 +9,7 @@
* implementation deals with the standard (machine-specific) representation
* of them instead of using the platform-independent buffer.
*/
+#include <asn_internal.h>
#include <NativeEnumerated.h>
/*
@@ -19,11 +20,13 @@ static ber_tlv_tag_t asn1_DEF_NativeEnumerated_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_NativeEnumerated = {
"ENUMERATED", /* The ASN.1 type is still ENUMERATED */
+ NativeInteger_free,
+ NativeInteger_print,
asn_generic_no_constraint,
NativeInteger_decode_ber,
NativeInteger_encode_der,
- NativeInteger_print,
- NativeInteger_free,
+ 0, /* Not implemented yet */
+ NativeInteger_encode_xer,
0, /* Use generic outmost tag fetcher */
asn1_DEF_NativeEnumerated_tags,
sizeof(asn1_DEF_NativeEnumerated_tags) / sizeof(asn1_DEF_NativeEnumerated_tags[0]),
diff --git a/skeletons/NativeInteger.c b/skeletons/NativeInteger.c
index 98fee965..b0872a2e 100644
--- a/skeletons/NativeInteger.c
+++ b/skeletons/NativeInteger.c
@@ -9,6 +9,7 @@
* implementation deals with the standard (machine-specific) representation
* of them instead of using the platform-independent buffer.
*/
+#include <asn_internal.h>
#include <NativeInteger.h>
#include <INTEGER.h>
#include <assert.h>
@@ -21,11 +22,13 @@ static ber_tlv_tag_t asn1_DEF_NativeInteger_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_NativeInteger = {
"INTEGER", /* The ASN.1 type is still INTEGER */
+ NativeInteger_free,
+ NativeInteger_print,
asn_generic_no_constraint,
NativeInteger_decode_ber,
NativeInteger_encode_der,
- NativeInteger_print,
- NativeInteger_free,
+ 0, /* Not implemented yet */
+ NativeInteger_encode_xer,
0, /* Use generic outmost tag fetcher */
asn1_DEF_NativeInteger_tags,
sizeof(asn1_DEF_NativeInteger_tags) / sizeof(asn1_DEF_NativeInteger_tags[0]),
@@ -127,17 +130,17 @@ NativeInteger_decode_ber(asn1_TYPE_descriptor_t *td,
/*
* Encode the NativeInteger using the standard INTEGER type DER encoder.
*/
-der_enc_rval_t
+asn_enc_rval_t
NativeInteger_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
int tag_mode, ber_tlv_tag_t tag,
asn_app_consume_bytes_f *cb, void *app_key) {
unsigned int Int = *(unsigned int *)ptr; /* Disable sign ext. */
- der_enc_rval_t erval;
+ asn_enc_rval_t erval;
INTEGER_t tmp;
#ifdef WORDS_BIGENDIAN /* Opportunistic optimization */
- tmp.buf = &Int;
+ tmp.buf = (uint8_t *)&Int;
tmp.size = sizeof(Int);
#else /* Works even if WORDS_BIGENDIAN is not set where should've been */
@@ -161,6 +164,27 @@ NativeInteger_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
return erval;
}
+asn_enc_rval_t
+NativeInteger_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ char scratch[32]; /* Enough for 64-bit int */
+ asn_enc_rval_t er;
+ const int *Int = (const int *)sptr;
+
+ (void)ilevel;
+ (void)flags;
+
+ if(!Int) _ASN_ENCODE_FAILED;
+
+ er.encoded = snprintf(scratch, sizeof(scratch), "%d", *Int);
+ if(er.encoded <= 0 || (size_t)er.encoded >= sizeof(scratch)
+ || cb(scratch, er.encoded, app_key) < 0)
+ _ASN_ENCODE_FAILED;
+
+ return er;
+}
+
/*
* INTEGER specific human-readable output.
*/
diff --git a/skeletons/NativeInteger.h b/skeletons/NativeInteger.h
index e0f26c78..2d0cddaa 100644
--- a/skeletons/NativeInteger.h
+++ b/skeletons/NativeInteger.h
@@ -16,9 +16,10 @@
extern asn1_TYPE_descriptor_t asn1_DEF_NativeInteger;
+asn_struct_free_f NativeInteger_free;
+asn_struct_print_f NativeInteger_print;
ber_type_decoder_f NativeInteger_decode_ber;
der_type_encoder_f NativeInteger_encode_der;
-asn_struct_print_f NativeInteger_print;
-asn_struct_free_f NativeInteger_free;
+xer_type_encoder_f NativeInteger_encode_xer;
#endif /* _NativeInteger_H_ */
diff --git a/skeletons/NativeReal.c b/skeletons/NativeReal.c
index e7cc28f9..1566a7fb 100644
--- a/skeletons/NativeReal.c
+++ b/skeletons/NativeReal.c
@@ -9,6 +9,7 @@
* implementation deals with the standard (machine-specific) representation
* of them instead of using the platform-independent buffer.
*/
+#include <asn_internal.h>
#include <NativeReal.h>
#include <INTEGER.h>
#include <REAL.h>
@@ -22,11 +23,13 @@ static ber_tlv_tag_t asn1_DEF_NativeReal_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_NativeReal = {
"REAL", /* The ASN.1 type is still REAL */
+ NativeReal_free,
+ NativeReal_print,
asn_generic_no_constraint,
NativeReal_decode_ber,
NativeReal_encode_der,
- NativeReal_print,
- NativeReal_free,
+ 0, /* Not implemented yet */
+ NativeReal_encode_xer,
0, /* Use generic outmost tag fetcher */
asn1_DEF_NativeReal_tags,
sizeof(asn1_DEF_NativeReal_tags) / sizeof(asn1_DEF_NativeReal_tags[0]),
@@ -116,12 +119,12 @@ NativeReal_decode_ber(asn1_TYPE_descriptor_t *td,
/*
* Encode the NativeReal using the standard REAL type DER encoder.
*/
-der_enc_rval_t
+asn_enc_rval_t
NativeReal_encode_der(asn1_TYPE_descriptor_t *td, void *ptr,
int tag_mode, ber_tlv_tag_t tag,
asn_app_consume_bytes_f *cb, void *app_key) {
double Dbl = *(const double *)ptr;
- der_enc_rval_t erval;
+ asn_enc_rval_t erval;
REAL_t tmp;
if(asn1_double2REAL(&tmp, Dbl)) {
@@ -140,6 +143,25 @@ NativeReal_encode_der(asn1_TYPE_descriptor_t *td, void *ptr,
return erval;
}
+
+asn_enc_rval_t
+NativeReal_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ const double *Dbl = (const double *)sptr;
+ asn_enc_rval_t er;
+ double d;
+
+ (void)ilevel;
+
+ if(!Dbl) _ASN_ENCODE_FAILED;
+
+ er.encoded = REAL__dump(d, flags & XER_F_CANONICAL, cb, app_key);
+ if(er.encoded < 0) _ASN_ENCODE_FAILED;
+
+ return er;
+}
+
/*
* REAL specific human-readable output.
*/
@@ -147,32 +169,13 @@ int
NativeReal_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
asn_app_consume_bytes_f *cb, void *app_key) {
const double *Dbl = (const double *)sptr;
- char scratch[64];
- int ret;
(void)td; /* Unused argument */
(void)ilevel; /* Unused argument */
- if(Dbl) {
- char *p = scratch;
- int buf_size = sizeof(scratch);
- for(;;) {
- ret = snprintf(p, buf_size, "%f", *Dbl);
- if(ret >= 0 && ret < buf_size) {
- ret = cb(p, ret, app_key);
- if(p != scratch) free(p);
- return ret;
- } else {
- if(p != scratch) free(p);
- }
- if(ret < 0) buf_size <<= 2; /* Old libc. */
- else buf_size = ret + 1;
- (void *)p = MALLOC(ret);
- if(!p) return -1;
- }
- } else {
- return cb("<absent>", 8, app_key);
- }
+ if(!Dbl) return cb("<absent>", 8, app_key);
+
+ return (REAL__dump(*Dbl, 0, cb, app_key) < 0) ? -1 : 0;
}
void
diff --git a/skeletons/NativeReal.h b/skeletons/NativeReal.h
index 1a5436df..a130a334 100644
--- a/skeletons/NativeReal.h
+++ b/skeletons/NativeReal.h
@@ -15,9 +15,10 @@
extern asn1_TYPE_descriptor_t asn1_DEF_NativeReal;
+asn_struct_free_f NativeReal_free;
+asn_struct_print_f NativeReal_print;
ber_type_decoder_f NativeReal_decode_ber;
der_type_encoder_f NativeReal_encode_der;
-asn_struct_print_f NativeReal_print;
-asn_struct_free_f NativeReal_free;
+xer_type_encoder_f NativeReal_encode_xer;
#endif /* ASN_TYPE_NativeReal_H */
diff --git a/skeletons/NumericString.c b/skeletons/NumericString.c
index a23e39f1..b4a6df92 100644
--- a/skeletons/NumericString.c
+++ b/skeletons/NumericString.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <NumericString.h>
/*
@@ -13,11 +14,13 @@ static ber_tlv_tag_t asn1_DEF_NumericString_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_NumericString = {
"NumericString",
+ OCTET_STRING_free,
+ OCTET_STRING_print_ascii, /* ASCII subset */
NumericString_constraint,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
- OCTET_STRING_print_ascii, /* ASCII subset */
- OCTET_STRING_free,
+ 0, /* Not implemented yet */
+ OCTET_STRING_encode_xer_ascii,/* Implemented in terms of OCTET STRING */
0, /* Use generic outmost tag fetcher */
asn1_DEF_NumericString_tags,
sizeof(asn1_DEF_NumericString_tags)
diff --git a/skeletons/OBJECT_IDENTIFIER.c b/skeletons/OBJECT_IDENTIFIER.c
index c55410d5..43ced796 100644
--- a/skeletons/OBJECT_IDENTIFIER.c
+++ b/skeletons/OBJECT_IDENTIFIER.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <OBJECT_IDENTIFIER.h>
#include <limits.h> /* for CHAR_BIT */
#include <assert.h>
@@ -15,11 +16,13 @@ static ber_tlv_tag_t asn1_DEF_OBJECT_IDENTIFIER_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_OBJECT_IDENTIFIER = {
"OBJECT IDENTIFIER",
+ INTEGER_free,
+ OBJECT_IDENTIFIER_print,
OBJECT_IDENTIFIER_constraint,
INTEGER_decode_ber, /* Implemented in terms of INTEGER type */
OBJECT_IDENTIFIER_encode_der,
- OBJECT_IDENTIFIER_print,
- INTEGER_free,
+ 0, /* Not implemented yet */
+ OBJECT_IDENTIFIER_encode_xer,
0, /* Use generic outmost tag fetcher */
asn1_DEF_OBJECT_IDENTIFIER_tags,
sizeof(asn1_DEF_OBJECT_IDENTIFIER_tags)
@@ -36,11 +39,11 @@ asn1_TYPE_descriptor_t asn1_DEF_OBJECT_IDENTIFIER = {
/*
* Encode OBJECT IDENTIFIER type using DER.
*/
-der_enc_rval_t
+asn_enc_rval_t
OBJECT_IDENTIFIER_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
int tag_mode, ber_tlv_tag_t tag,
asn_app_consume_bytes_f *cb, void *app_key) {
- der_enc_rval_t erval;
+ asn_enc_rval_t erval;
OBJECT_IDENTIFIER_t *st = (OBJECT_IDENTIFIER_t *)ptr;
ASN_DEBUG("%s %s as OBJECT IDENTIFIER (tm=%d)",
@@ -57,10 +60,8 @@ OBJECT_IDENTIFIER_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
}
if(cb && st->buf) {
- ssize_t ret;
-
- ret = cb(st->buf, st->size, app_key);
- if(ret == -1) {
+ int ret = cb(st->buf, st->size, app_key);
+ if(ret < 0) {
erval.encoded = -1;
erval.failed_type = sd;
erval.structure_ptr = ptr;
@@ -215,9 +216,8 @@ OBJECT_IDENTIFIER_get_single_arc(uint8_t *arcbuf, unsigned int arclen, signed in
return 0;
}
-
-int
-OBJECT_IDENTIFIER_print_arc(uint8_t *arcbuf, int arclen, int add,
+ssize_t
+OBJECT_IDENTIFIER__dump_arc(uint8_t *arcbuf, int arclen, int add,
asn_app_consume_bytes_f *cb, void *app_key) {
char scratch[64]; /* Conservative estimate */
unsigned long accum; /* Bits accumulator */
@@ -228,35 +228,41 @@ OBJECT_IDENTIFIER_print_arc(uint8_t *arcbuf, int arclen, int add,
return -1;
if(accum) {
+ ssize_t len;
+
/* Fill the scratch buffer in reverse. */
p = scratch + sizeof(scratch);
for(; accum; accum /= 10)
- *(--p) = (char)(accum % 10) + 0x30;
+ *(--p) = (char)(accum % 10) + 0x30; /* Put a digit */
- return cb(p, sizeof(scratch) - (p - scratch), app_key);
+ len = sizeof(scratch) - (p - scratch);
+ if(cb(p, len, app_key) < 0)
+ return -1;
+ return len;
} else {
*scratch = 0x30;
- return cb(scratch, 1, app_key);
+ if(cb(scratch, 1, app_key) < 0)
+ return -1;
+ return 1;
}
}
int
-OBJECT_IDENTIFIER_print(asn1_TYPE_descriptor_t *td, const void *sptr,
- int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
- const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;
- int startn;
- int add = 0;
- int i;
+OBJECT_IDENTIFIER_print_arc(uint8_t *arcbuf, int arclen, int add,
+ asn_app_consume_bytes_f *cb, void *app_key) {
- (void)td; /* Unused argument */
- (void)ilevel; /* Unused argument */
+ if(OBJECT_IDENTIFIER__dump_arc(arcbuf, arclen, add, cb, app_key) < 0)
+ return -1;
- if(!st || !st->buf)
- return cb("<absent>", 8, app_key);
+ return 0;
+}
- /* Dump preamble */
- if(cb("{ ", 2, app_key))
- return -1;
+static ssize_t
+OBJECT_IDENTIFIER__dump_body(const OBJECT_IDENTIFIER_t *st, asn_app_consume_bytes_f *cb, void *app_key) {
+ ssize_t wrote_len = 0;
+ int startn;
+ int add = 0;
+ int i;
for(i = 0, startn = 0; i < st->size; i++) {
uint8_t b = st->buf[i];
@@ -269,30 +275,71 @@ OBJECT_IDENTIFIER_print(asn1_TYPE_descriptor_t *td, const void *sptr,
*/
if(i) {
add = -80;
- if(cb("2", 1, app_key)) return -1;
+ if(cb("2", 1, app_key) < 0) return -1;
} else if(b <= 39) {
add = 0;
- if(cb("0", 1, app_key)) return -1;
+ if(cb("0", 1, app_key) < 0) return -1;
} else if(b < 79) {
add = -40;
- if(cb("1", 1, app_key)) return -1;
+ if(cb("1", 1, app_key) < 0) return -1;
} else {
add = -80;
- if(cb("2", 1, app_key)) return -1;
+ if(cb("2", 1, app_key) < 0) return -1;
}
+ wrote_len += 1;
}
- if(cb(" ", 1, app_key)) /* Separate arcs */
+ if(cb(".", 1, app_key) < 0) /* Separate arcs */
return -1;
- if(OBJECT_IDENTIFIER_print_arc(&st->buf[startn],
- i - startn + 1, add,
- cb, app_key))
- return -1;
+ add = OBJECT_IDENTIFIER__dump_arc(&st->buf[startn],
+ i - startn + 1, add, cb, app_key);
+ if(add < 0) return -1;
+ wrote_len += 1 + add;
startn = i + 1;
add = 0;
}
+ return wrote_len;
+}
+
+asn_enc_rval_t
+OBJECT_IDENTIFIER_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;
+ asn_enc_rval_t er;
+
+ (void)ilevel;
+ (void)flags;
+
+ if(!st || !st->buf)
+ _ASN_ENCODE_FAILED;
+
+ er.encoded = OBJECT_IDENTIFIER__dump_body(st, cb, app_key);
+ if(er.encoded < 0) _ASN_ENCODE_FAILED;
+
+ return er;
+}
+
+int
+OBJECT_IDENTIFIER_print(asn1_TYPE_descriptor_t *td, const void *sptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;
+
+ (void)td; /* Unused argument */
+ (void)ilevel; /* Unused argument */
+
+ if(!st || !st->buf)
+ return cb("<absent>", 8, app_key);
+
+ /* Dump preamble */
+ if(cb("{ ", 2, app_key))
+ return -1;
+
+ if(OBJECT_IDENTIFIER__dump_body(st, cb, app_key) < 0)
+ return -1;
+
return cb(" }", 2, app_key);
}
diff --git a/skeletons/OBJECT_IDENTIFIER.h b/skeletons/OBJECT_IDENTIFIER.h
index 8d43c997..4f45090c 100644
--- a/skeletons/OBJECT_IDENTIFIER.h
+++ b/skeletons/OBJECT_IDENTIFIER.h
@@ -12,9 +12,10 @@ typedef INTEGER_t OBJECT_IDENTIFIER_t; /* Implemented in terms of INTEGER */
extern asn1_TYPE_descriptor_t asn1_DEF_OBJECT_IDENTIFIER;
-der_type_encoder_f OBJECT_IDENTIFIER_encode_der;
-asn_constr_check_f OBJECT_IDENTIFIER_constraint;
asn_struct_print_f OBJECT_IDENTIFIER_print;
+asn_constr_check_f OBJECT_IDENTIFIER_constraint;
+der_type_encoder_f OBJECT_IDENTIFIER_encode_der;
+xer_type_encoder_f OBJECT_IDENTIFIER_encode_xer;
/**********************************
* Some handy conversion routines *
@@ -27,6 +28,10 @@ int OBJECT_IDENTIFIER_print_arc(uint8_t *arcbuf, int arclen,
int add, /* Arbitrary offset, required to process the first two arcs */
asn_app_consume_bytes_f *cb, void *app_key);
+/* Same as above, but returns the number of written digits, instead of 0 */
+ssize_t OBJECT_IDENTIFIER__dump_arc(uint8_t *arcbuf, int arclen, int add,
+ asn_app_consume_bytes_f *cb, void *app_key);
+
/*
* This function fills an (_arcs) array with OBJECT IDENTIFIER arcs
* up to specified (_arc_slots) elements.
diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c
index e0af730a..4b7bd66e 100644
--- a/skeletons/OCTET_STRING.c
+++ b/skeletons/OCTET_STRING.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <OCTET_STRING.h>
#include <assert.h>
#include <errno.h>
@@ -14,11 +15,13 @@ static ber_tlv_tag_t asn1_DEF_OCTET_STRING_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_OCTET_STRING = {
"OCTET STRING",
+ OCTET_STRING_free,
+ OCTET_STRING_print, /* non-ascii stuff, generally */
asn_generic_no_constraint,
OCTET_STRING_decode_ber,
OCTET_STRING_encode_der,
- OCTET_STRING_print, /* non-ascii stuff, generally */
- OCTET_STRING_free,
+ 0, /* Not implemented yet */
+ OCTET_STRING_encode_xer,
0, /* Use generic outmost tag fetcher */
asn1_DEF_OCTET_STRING_tags,
sizeof(asn1_DEF_OCTET_STRING_tags)
@@ -440,11 +443,11 @@ OCTET_STRING_decode_ber(asn1_TYPE_descriptor_t *td,
/*
* Encode OCTET STRING type using DER.
*/
-der_enc_rval_t
+asn_enc_rval_t
OCTET_STRING_encode_der(asn1_TYPE_descriptor_t *td, void *ptr,
int tag_mode, ber_tlv_tag_t tag,
asn_app_consume_bytes_f *cb, void *app_key) {
- der_enc_rval_t erval;
+ asn_enc_rval_t erval;
OCTET_STRING_t *st = (OCTET_STRING_t *)ptr;
int add_byte = 0;
int is_bit_str = (td->specifics == (void *)-1);
@@ -514,6 +517,84 @@ OCTET_STRING_encode_der(asn1_TYPE_descriptor_t *td, void *ptr,
return erval;
}
+asn_enc_rval_t
+OCTET_STRING_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ static const char *h2c = "0123456789ABCDEF";
+ const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
+ asn_enc_rval_t er;
+ char scratch[16 * 3 + 4];
+ char *p = scratch;
+ uint8_t *buf;
+ uint8_t *end;
+ size_t i;
+
+ if(!st || !st->buf) {
+ er.encoded = -1;
+ er.failed_type = td;
+ er.structure_ptr = sptr;
+ return er;
+ }
+
+ er.encoded = 0;
+
+ /*
+ * Dump the contents of the buffer in hexadecimal.
+ */
+ buf = st->buf;
+ end = buf + st->size;
+ if(flags & XER_F_CANONICAL) {
+ char *scend = scratch + (sizeof(scratch) - 2);
+ for(; buf < end; buf++) {
+ if(p >= scend) {
+ _ASN_CALLBACK(scratch, p - scratch);
+ er.encoded += p - scratch;
+ p = scratch;
+ }
+ *p++ = h2c[(*buf >> 4) & 0x0F];
+ *p++ = h2c[*buf & 0x0F];
+ }
+ } else {
+ for(i = 0; buf < end; buf++, i++) {
+ if(!(i % 16) && (i || st->size > 16)) {
+ _ASN_CALLBACK(scratch, p-scratch);
+ er.encoded += (p-scratch);
+ p = scratch;
+ _i_ASN_TEXT_INDENT(1, ilevel);
+ }
+ *p++ = h2c[(*buf >> 4) & 0x0F];
+ *p++ = h2c[*buf & 0x0F];
+ *p++ = 0x20;
+ }
+ if(i) p--; /* Remove the tail space */
+ }
+
+ _ASN_CALLBACK(scratch, p-scratch); /* Dump the rest */
+ er.encoded += p - scratch;
+
+ return er;
+}
+
+asn_enc_rval_t
+OCTET_STRING_encode_xer_ascii(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
+ asn_enc_rval_t er;
+
+ (void)ilevel; /* Unused argument */
+ (void)flags; /* Unused argument */
+
+ if(!st || !st->buf)
+ _ASN_ENCODE_FAILED;
+
+ _ASN_CALLBACK(st->buf, st->size);
+ er.encoded = st->size;
+
+ return er;
+}
+
int
OCTET_STRING_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
asn_app_consume_bytes_f *cb, void *app_key) {
@@ -524,7 +605,7 @@ OCTET_STRING_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
uint8_t *buf;
uint8_t *end;
size_t i;
- int ret;
+ int lvl;
(void)td; /* Unused argument */
@@ -540,14 +621,15 @@ OCTET_STRING_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
if(cb(scratch, p - scratch, app_key)
|| cb("\n", 1, app_key))
return -1;
- for(ret = 0; ret < ilevel; ret++)
+ for(lvl = 0; lvl < ilevel; lvl++)
cb(" ", 1, app_key);
p = scratch;
}
*p++ = h2c[(*buf >> 4) & 0x0F];
*p++ = h2c[*buf & 0x0F];
- *p++ = ' ';
+ *p++ = 0x20;
}
+ if(i) p--; /* Remove the tail space */
return cb(scratch, p - scratch, app_key);
}
diff --git a/skeletons/OCTET_STRING.h b/skeletons/OCTET_STRING.h
index df6ff4f2..a67cef94 100644
--- a/skeletons/OCTET_STRING.h
+++ b/skeletons/OCTET_STRING.h
@@ -16,11 +16,13 @@ typedef struct OCTET_STRING {
extern asn1_TYPE_descriptor_t asn1_DEF_OCTET_STRING;
-ber_type_decoder_f OCTET_STRING_decode_ber;
-der_type_encoder_f OCTET_STRING_encode_der;
+asn_struct_free_f OCTET_STRING_free;
asn_struct_print_f OCTET_STRING_print;
asn_struct_print_f OCTET_STRING_print_ascii;
-asn_struct_free_f OCTET_STRING_free;
+ber_type_decoder_f OCTET_STRING_decode_ber;
+der_type_encoder_f OCTET_STRING_encode_der;
+xer_type_encoder_f OCTET_STRING_encode_xer;
+xer_type_encoder_f OCTET_STRING_encode_xer_ascii;
/***********************************
* Some handy conversion routines. *
diff --git a/skeletons/ObjectDescriptor.c b/skeletons/ObjectDescriptor.c
index 5017918e..4ddcaac7 100644
--- a/skeletons/ObjectDescriptor.c
+++ b/skeletons/ObjectDescriptor.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <ObjectDescriptor.h>
/*
@@ -13,11 +14,13 @@ static ber_tlv_tag_t asn1_DEF_ObjectDescriptor_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_ObjectDescriptor = {
"ObjectDescriptor",
+ OCTET_STRING_free,
+ OCTET_STRING_print_ascii, /* Treat as ASCII subset (it's not) */
asn_generic_unknown_constraint,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
- OCTET_STRING_print_ascii, /* Treat as ASCII subset (it's not) */
- OCTET_STRING_free,
+ 0, /* Not implemented yet */
+ OCTET_STRING_encode_xer_ascii,/* Implemented in terms of OCTET STRING */
0, /* Use generic outmost tag fetcher */
asn1_DEF_ObjectDescriptor_tags,
sizeof(asn1_DEF_ObjectDescriptor_tags)
diff --git a/skeletons/PrintableString.c b/skeletons/PrintableString.c
index c37de497..1368447f 100644
--- a/skeletons/PrintableString.c
+++ b/skeletons/PrintableString.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <PrintableString.h>
/*
@@ -13,11 +14,13 @@ static ber_tlv_tag_t asn1_DEF_PrintableString_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_PrintableString = {
"PrintableString",
+ OCTET_STRING_free,
+ OCTET_STRING_print_ascii, /* ASCII subset */
PrintableString_constraint,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
- OCTET_STRING_print_ascii, /* ASCII subset */
- OCTET_STRING_free,
+ 0, /* Not implemented yet */
+ OCTET_STRING_encode_xer_ascii,/* Implemented in terms of OCTET STRING */
0, /* Use generic outmost tag fetcher */
asn1_DEF_PrintableString_tags,
sizeof(asn1_DEF_PrintableString_tags)
diff --git a/skeletons/REAL.c b/skeletons/REAL.c
index e42a0613..7c230103 100644
--- a/skeletons/REAL.c
+++ b/skeletons/REAL.c
@@ -2,6 +2,7 @@
* Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <REAL.h>
#include <INTEGER.h>
#include <stdlib.h> /* for strtod(3) */
@@ -29,11 +30,13 @@ static ber_tlv_tag_t asn1_DEF_REAL_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_REAL = {
"REAL",
+ INTEGER_free,
+ REAL_print,
asn_generic_no_constraint,
INTEGER_decode_ber, /* Implemented in terms of INTEGER type */
INTEGER_encode_der,
- REAL_print,
- INTEGER_free,
+ 0, /* Not implemented yet */
+ REAL_encode_xer,
0, /* Use generic outmost tag fetcher */
asn1_DEF_REAL_tags,
sizeof(asn1_DEF_REAL_tags) / sizeof(asn1_DEF_REAL_tags[0]),
@@ -44,33 +47,113 @@ asn1_TYPE_descriptor_t asn1_DEF_REAL = {
0 /* No specifics */
};
+ssize_t
+REAL__dump(double d, int canonical, asn_app_consume_bytes_f *cb, void *app_key) {
+ char local_buf[32];
+ char *buf = local_buf;
+ ssize_t buflen = sizeof(local_buf);
+ const char *fmt = canonical?"%15E":"f";
+ ssize_t ret;
+
+ do {
+ ret = snprintf(buf, buflen, fmt, d);
+ if(ret < 0) {
+ buflen <<= 1;
+ } else if(ret >= buflen) {
+ buflen = ret + 1;
+ } else {
+ buflen = ret;
+ break;
+ }
+ if(buf != local_buf) free(buf);
+ (void *)buf = MALLOC(buflen);
+ if(!buf) return -1;
+ } while(1);
+
+ /*
+ * Transform the "[-]d.dddE+-dd" output into "[-]d.dddE[-]d"
+ */
+ if(canonical) {
+ char *dot, *E;
+ char *end = buf + buflen;
+
+ dot = (buf[0] == '-') ? (buf + 2) : (buf + 1);
+ if(*dot >= 0x30) {
+ errno = EINVAL;
+ return -1; /* Not a dot, really */
+ }
+ *dot = '.'; /* Replace possible comma */
+
+ for(E = dot; dot < end; E++) {
+ if(*E == 'E') {
+ char *s = ++E;
+ if(*E == '+') {
+ /* Skip the "+" too */
+ buflen -= 2;
+ } else {
+ buflen -= 1;
+ s++;
+ }
+ E += 2;
+ if(E[-1] != '0' || E > end) {
+ errno = EINVAL;
+ return -1;
+ }
+ for(; E <= end; s++, E++)
+ *s = *E;
+ }
+ }
+ if(E == end) {
+ errno = EINVAL;
+ return -1; /* No promised E */
+ }
+ }
+
+ ret = cb(buf, buflen, app_key);
+ if(buf != local_buf) free(buf);
+ return (ret < 0) ? -1 : buflen;
+}
+
int
REAL_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
asn_app_consume_bytes_f *cb, void *app_key) {
const REAL_t *st = (const REAL_t *)sptr;
- char buf[128];
double d;
- int ret;
(void)td; /* Unused argument */
(void)ilevel; /* Unused argument */
- if(!st)
+ if(!st || !st->buf)
return cb("<absent>", 8, app_key);
if(asn1_REAL2double(st, &d))
return cb("<error>", 7, app_key);
- ret = snprintf(buf, sizeof(buf), "%f", d);
- if(ret < 0 || ret >= sizeof(buf))
- return cb("<error>", 7, app_key);
+ return (REAL__dump(d, 0, cb, app_key) < 0) ? -1 : 0;
+}
+
+asn_enc_rval_t
+REAL_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ REAL_t *st = (REAL_t *)sptr;
+ asn_enc_rval_t er;
+ double d;
+
+ (void)ilevel;
+
+ if(!st || !st->buf || asn1_REAL2double(st, &d))
+ _ASN_ENCODE_FAILED;
+
+ er.encoded = REAL__dump(d, flags & XER_F_CANONICAL, cb, app_key);
+ if(er.encoded < 0) _ASN_ENCODE_FAILED;
- return cb(buf, ret, app_key);
+ return er;
}
int
asn1_REAL2double(const REAL_t *st, double *dbl_value) {
- unsigned long octv;
+ unsigned int octv;
if(!st || !st->buf) {
errno = EINVAL;
@@ -158,7 +241,7 @@ asn1_REAL2double(const REAL_t *st, double *dbl_value) {
sign = (octv & 0x40); /* bit 7 */
scaleF = (octv & 0x0C) >> 2; /* bits 4 to 3 */
- if(st->size <= (1 + (octv & 0x03))) {
+ if(st->size <= (int)(1 + (octv & 0x03))) {
errno = EINVAL;
return -1;
}
@@ -166,7 +249,7 @@ asn1_REAL2double(const REAL_t *st, double *dbl_value) {
if((octv & 0x03) == 0x11) {
/* 8.5.6.4, case d) */
elen = st->buf[1]; /* unsigned binary number */
- if(elen == 0 || st->size <= (2 + elen)) {
+ if(elen == 0 || st->size <= (int)(2 + elen)) {
errno = EINVAL;
return -1;
}
diff --git a/skeletons/REAL.h b/skeletons/REAL.h
index 751000b8..83f96d01 100644
--- a/skeletons/REAL.h
+++ b/skeletons/REAL.h
@@ -15,11 +15,14 @@ typedef struct REAL {
extern asn1_TYPE_descriptor_t asn1_DEF_REAL;
asn_struct_print_f REAL_print;
+xer_type_encoder_f REAL_encode_xer;
/***********************************
* Some handy conversion routines. *
***********************************/
+ssize_t REAL__dump(double d, int canonical, asn_app_consume_bytes_f *cb, void *app_key);
+
/*
* Convert between native double type and REAL representation (DER).
* RETURN VALUES:
diff --git a/skeletons/RELATIVE-OID.c b/skeletons/RELATIVE-OID.c
index bee795c4..5d1e1a9d 100644
--- a/skeletons/RELATIVE-OID.c
+++ b/skeletons/RELATIVE-OID.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <RELATIVE-OID.h>
#include <limits.h> /* for CHAR_BIT */
#include <assert.h>
@@ -15,11 +16,13 @@ static ber_tlv_tag_t asn1_DEF_RELATIVE_OID_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_RELATIVE_OID = {
"RELATIVE-OID",
+ INTEGER_free,
+ RELATIVE_OID_print,
asn_generic_no_constraint,
INTEGER_decode_ber, /* Implemented in terms of INTEGER type */
OBJECT_IDENTIFIER_encode_der,
- RELATIVE_OID_print,
- INTEGER_free,
+ 0, /* Not implemented yet */
+ RELATIVE_OID_encode_xer,
0, /* Use generic outmost tag fetcher */
asn1_DEF_RELATIVE_OID_tags,
sizeof(asn1_DEF_RELATIVE_OID_tags)
@@ -32,12 +35,39 @@ asn1_TYPE_descriptor_t asn1_DEF_RELATIVE_OID = {
0 /* No specifics */
};
+static ssize_t
+RELATIVE_OID__dump_body(const RELATIVE_OID_t *st, asn_app_consume_bytes_f *cb, void *app_key) {
+ ssize_t wrote = 0;
+ ssize_t ret;
+ int startn;
+ int i;
+
+ for(i = 0, startn = 0; i < st->size; i++) {
+ uint8_t b = st->buf[i];
+ if((b & 0x80)) /* Continuation expected */
+ continue;
+ if(startn) {
+ /* Separate arcs */
+ if(cb(".", 1, app_key) < 0)
+ return -1;
+ wrote++;
+ }
+
+ ret = OBJECT_IDENTIFIER__dump_arc(&st->buf[startn],
+ i - startn + 1, 0, cb, app_key);
+ if(ret < 0) return -1;
+ wrote += ret;
+
+ startn = i + 1;
+ }
+
+ return wrote;
+}
+
int
RELATIVE_OID_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
asn_app_consume_bytes_f *cb, void *app_key) {
const RELATIVE_OID_t *st = (const RELATIVE_OID_t *)sptr;
- int startn;
- int i;
(void)td; /* Unused argument */
(void)ilevel; /* Unused argument */
@@ -49,21 +79,30 @@ RELATIVE_OID_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
if(cb("{ ", 2, app_key))
return -1;
- for(i = 0, startn = 0; i < st->size; i++) {
- uint8_t b = st->buf[i];
- if((b & 0x80)) /* Continuation expected */
- continue;
- if(startn && cb(" ", 1, app_key)) /* Separate arcs */
- return -1;
- if(OBJECT_IDENTIFIER_print_arc(&st->buf[startn],
- i - startn + 1, 0, cb, app_key))
- return -1;
- startn = i + 1;
- }
+ if(RELATIVE_OID__dump_body(st, cb, app_key) < 0)
+ return -1;
return cb(" }", 2, app_key);
}
+asn_enc_rval_t
+RELATIVE_OID_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ RELATIVE_OID_t *st = (RELATIVE_OID_t *)sptr;
+ asn_enc_rval_t er;
+
+ (void)ilevel; /* Unused argument */
+ (void)flags; /* Unused argument */
+
+ if(!st || !st->buf)
+ _ASN_ENCODE_FAILED;
+
+ er.encoded = RELATIVE_OID__dump_body(st, cb, app_key);
+ if(er.encoded < 0) _ASN_ENCODE_FAILED;
+
+ return er;
+}
int
RELATIVE_OID_get_arcs(RELATIVE_OID_t *roid,
diff --git a/skeletons/RELATIVE-OID.h b/skeletons/RELATIVE-OID.h
index 1dafb62d..e6af9346 100644
--- a/skeletons/RELATIVE-OID.h
+++ b/skeletons/RELATIVE-OID.h
@@ -14,6 +14,7 @@ typedef OBJECT_IDENTIFIER_t RELATIVE_OID_t;
extern asn1_TYPE_descriptor_t asn1_DEF_RELATIVE_OID;
asn_struct_print_f RELATIVE_OID_print;
+xer_type_encoder_f RELATIVE_OID_encode_xer;
/**********************************
* Some handy conversion routines *
diff --git a/skeletons/T61String.c b/skeletons/T61String.c
index b306a5ba..d2ac2d5f 100644
--- a/skeletons/T61String.c
+++ b/skeletons/T61String.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <T61String.h>
/*
@@ -13,11 +14,13 @@ static ber_tlv_tag_t asn1_DEF_T61String_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_T61String = {
"T61String",
+ OCTET_STRING_free,
+ OCTET_STRING_print, /* non-ascii string */
asn_generic_unknown_constraint,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
- OCTET_STRING_print, /* non-ascii string */
- OCTET_STRING_free,
+ 0, /* Not implemented yet */
+ OCTET_STRING_encode_xer, /* Implemented in terms of OCTET STRING */
0, /* Use generic outmost tag fetcher */
asn1_DEF_T61String_tags,
sizeof(asn1_DEF_T61String_tags)
diff --git a/skeletons/TeletexString.c b/skeletons/TeletexString.c
index 09f3eb6a..7a569534 100644
--- a/skeletons/TeletexString.c
+++ b/skeletons/TeletexString.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <TeletexString.h>
/*
@@ -13,11 +14,13 @@ static ber_tlv_tag_t asn1_DEF_TeletexString_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_TeletexString = {
"TeletexString",
+ OCTET_STRING_free,
+ OCTET_STRING_print, /* non-ascii string */
asn_generic_unknown_constraint,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
- OCTET_STRING_print, /* non-ascii string */
- OCTET_STRING_free,
+ 0, /* Not implemented yet */
+ OCTET_STRING_encode_xer, /* Implemented in terms of OCTET STRING */
0, /* Use generic outmost tag fetcher */
asn1_DEF_TeletexString_tags,
sizeof(asn1_DEF_TeletexString_tags)
diff --git a/skeletons/UTCTime.c b/skeletons/UTCTime.c
index 029a43e4..22e5498f 100644
--- a/skeletons/UTCTime.c
+++ b/skeletons/UTCTime.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <UTCTime.h>
#include <GeneralizedTime.h>
#include <time.h>
@@ -18,11 +19,13 @@ static ber_tlv_tag_t asn1_DEF_UTCTime_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_UTCTime = {
"UTCTime",
+ OCTET_STRING_free,
+ UTCTime_print,
UTCTime_constraint,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
- UTCTime_print,
- OCTET_STRING_free,
+ 0, /* Not implemented yet */
+ UTCTime_encode_xer,
0, /* Use generic outmost tag fetcher */
asn1_DEF_UTCTime_tags,
sizeof(asn1_DEF_UTCTime_tags)
@@ -58,6 +61,36 @@ UTCTime_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
return 0;
}
+asn_enc_rval_t
+UTCTime_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ OCTET_STRING_t st;
+
+ if(flags & XER_F_CANONICAL) {
+ char buf[32];
+ struct tm tm;
+ ssize_t ret;
+
+ errno = EPERM;
+ if(asn_UT2time((UTCTime_t *)sptr, &tm, 1) == -1
+ && errno != EPERM)
+ _ASN_ENCODE_FAILED;
+
+ ret = snprintf(buf, sizeof(buf), "%02d%02d%02d%02d%02d%02dZ",
+ tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+ assert(ret > 0 && ret < (int)sizeof(buf));
+
+ st.buf = (uint8_t *)buf;
+ st.size = ret;
+ sptr = &st;
+ }
+
+ return OCTET_STRING_encode_xer_ascii(td, sptr, ilevel, flags,
+ cb, app_key);
+}
+
int
UTCTime_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
asn_app_consume_bytes_f *cb, void *app_key) {
diff --git a/skeletons/UTCTime.h b/skeletons/UTCTime.h
index d00dafb5..b026dedd 100644
--- a/skeletons/UTCTime.h
+++ b/skeletons/UTCTime.h
@@ -12,8 +12,9 @@ typedef OCTET_STRING_t UTCTime_t; /* Implemented using OCTET STRING */
extern asn1_TYPE_descriptor_t asn1_DEF_UTCTime;
-asn_constr_check_f UTCTime_constraint;
asn_struct_print_f UTCTime_print;
+asn_constr_check_f UTCTime_constraint;
+xer_type_encoder_f UTCTime_encode_xer;
/***********************
* Some handy helpers. *
diff --git a/skeletons/UTF8String.c b/skeletons/UTF8String.c
index 40fef39b..7220a674 100644
--- a/skeletons/UTF8String.c
+++ b/skeletons/UTF8String.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <UTF8String.h>
/*
@@ -13,11 +14,13 @@ static ber_tlv_tag_t asn1_DEF_UTF8String_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_UTF8String = {
"UTF8String",
+ OCTET_STRING_free,
+ UTF8String_print,
UTF8String_constraint, /* Check for invalid codes, etc. */
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
- UTF8String_print,
- OCTET_STRING_free,
+ 0, /* Not implemented yet */
+ OCTET_STRING_encode_xer_ascii, /* Already in UTF-8 format */
0, /* Use generic outmost tag fetcher */
asn1_DEF_UTF8String_tags,
sizeof(asn1_DEF_UTF8String_tags)
diff --git a/skeletons/UTF8String.h b/skeletons/UTF8String.h
index f18bf703..543d3196 100644
--- a/skeletons/UTF8String.h
+++ b/skeletons/UTF8String.h
@@ -12,8 +12,8 @@ typedef OCTET_STRING_t UTF8String_t; /* Implemented in terms of OCTET STRING */
extern asn1_TYPE_descriptor_t asn1_DEF_UTF8String;
-asn_constr_check_f UTF8String_constraint;
asn_struct_print_f UTF8String_print;
+asn_constr_check_f UTF8String_constraint;
/* Returns length of UTF-8 string in characters or -1 if error. */
ssize_t UTF8String_length(const UTF8String_t *st, const char *opt_type_name,
diff --git a/skeletons/UniversalString.c b/skeletons/UniversalString.c
index 14988966..d56cd925 100644
--- a/skeletons/UniversalString.c
+++ b/skeletons/UniversalString.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <UniversalString.h>
/*
@@ -13,11 +14,13 @@ static ber_tlv_tag_t asn1_DEF_UniversalString_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_UniversalString = {
"UniversalString",
+ OCTET_STRING_free,
+ UniversalString_print, /* Convert into UTF8 and print */
asn_generic_no_constraint,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
- UniversalString_print, /* Convert into UTF8 and print */
- OCTET_STRING_free,
+ 0, /* Not implemented yet */
+ UniversalString_encode_xer, /* Conver into UTF8 */
0, /* Use generic outmost tag fetcher */
asn1_DEF_UniversalString_tags,
sizeof(asn1_DEF_UniversalString_tags)
@@ -31,29 +34,25 @@ asn1_TYPE_descriptor_t asn1_DEF_UniversalString = {
};
-int
-UniversalString_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
- asn_app_consume_bytes_f *cb, void *app_key) {
- const UniversalString_t *st = (const UniversalString_t *)sptr;
- uint32_t *wchar;
- uint32_t *wend;
+static ssize_t
+UniversalString__dump(const UniversalString_t *st,
+ asn_app_consume_bytes_f *cb, void *app_key) {
char scratch[128]; /* Scratchpad buffer */
- char *p;
-
- (void)td; /* Unused argument */
- (void)ilevel; /* Unused argument */
+ char *p = scratch;
+ ssize_t wrote = 0;
+ uint8_t *ch;
+ uint8_t *end;
- if(!st || !st->buf) return cb("<absent>", 8, app_key);
-
- wchar = (uint32_t *)st->buf;
- wend = (uint32_t *)(st->buf + st->size);
- for(p = scratch; wchar < wend; wchar++) {
- uint32_t wc = (((uint8_t *)wchar)[0] << 24)
- | (((uint8_t *)wchar)[1] << 16)
- | (((uint8_t *)wchar)[2] << 8)
- | ((uint8_t *)wchar)[3]; /* 4 bytes */
+ ch = st->buf;
+ end = (st->buf + st->size);
+ for(end -= 3; ch < end; ch += 4) {
+ uint32_t wc = (ch[0] << 24)
+ | (ch[1] << 16)
+ | (ch[2] << 8)
+ | ch[3]; /* 4 bytes */
if(sizeof(scratch) - (p - scratch) < 6) {
- if(cb(scratch, p - scratch, app_key))
+ wrote += p - scratch;
+ if(cb(scratch, p - scratch, app_key) < 0)
return -1;
p = scratch;
}
@@ -87,5 +86,45 @@ UniversalString_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
}
}
- return cb(scratch, p - scratch, app_key);
+ wrote += p - scratch;
+ if(cb(scratch, p - scratch, app_key) < 0)
+ return -1;
+
+ return wrote;
}
+
+asn_enc_rval_t
+UniversalString_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ const UniversalString_t *st = (const UniversalString_t *)sptr;
+ asn_enc_rval_t er;
+
+ (void)ilevel;
+ (void)flags;
+
+ if(!st || !st->buf)
+ _ASN_ENCODE_FAILED;
+
+ er.encoded = UniversalString__dump(st, cb, app_key);
+ if(er.encoded < 0) _ASN_ENCODE_FAILED;
+
+ return er;
+}
+
+int
+UniversalString_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ const UniversalString_t *st = (const UniversalString_t *)sptr;
+
+ (void)td; /* Unused argument */
+ (void)ilevel; /* Unused argument */
+
+ if(!st || !st->buf) return cb("<absent>", 8, app_key);
+
+ if(UniversalString__dump(st, cb, app_key) < 0)
+ return -1;
+
+ return 0;
+}
+
diff --git a/skeletons/UniversalString.h b/skeletons/UniversalString.h
index cafbc80c..88875236 100644
--- a/skeletons/UniversalString.h
+++ b/skeletons/UniversalString.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
#ifndef _UniversalString_H_
@@ -13,5 +13,6 @@ typedef OCTET_STRING_t UniversalString_t; /* Implemented in terms of OCTET STRIN
extern asn1_TYPE_descriptor_t asn1_DEF_UniversalString;
asn_struct_print_f UniversalString_print; /* Human-readable output */
+xer_type_encoder_f UniversalString_encode_xer;
#endif /* _UniversalString_H_ */
diff --git a/skeletons/VideotexString.c b/skeletons/VideotexString.c
index 6d2eaeb6..f313ecb6 100644
--- a/skeletons/VideotexString.c
+++ b/skeletons/VideotexString.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <VideotexString.h>
/*
@@ -13,11 +14,13 @@ static ber_tlv_tag_t asn1_DEF_VideotexString_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_VideotexString = {
"VideotexString",
+ OCTET_STRING_free,
+ OCTET_STRING_print, /* non-ascii string */
asn_generic_unknown_constraint,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
- OCTET_STRING_print, /* non-ascii string */
- OCTET_STRING_free,
+ 0, /* Not implemented yet */
+ OCTET_STRING_encode_xer, /* Implemented in terms of OCTET STRING */
0, /* Use generic outmost tag fetcher */
asn1_DEF_VideotexString_tags,
sizeof(asn1_DEF_VideotexString_tags)
diff --git a/skeletons/VisibleString.c b/skeletons/VisibleString.c
index 9ddb0f1c..dbd0e92e 100644
--- a/skeletons/VisibleString.c
+++ b/skeletons/VisibleString.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <VisibleString.h>
/*
@@ -13,11 +14,13 @@ static ber_tlv_tag_t asn1_DEF_VisibleString_tags[] = {
};
asn1_TYPE_descriptor_t asn1_DEF_VisibleString = {
"VisibleString",
+ OCTET_STRING_free,
+ OCTET_STRING_print_ascii, /* ASCII subset */
VisibleString_constraint,
OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */
OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */
- OCTET_STRING_print_ascii, /* ASCII subset */
- OCTET_STRING_free,
+ 0, /* Not implemented yet */
+ OCTET_STRING_encode_xer_ascii,/* Implemented in terms of OCTET STRING */
0, /* Use generic outmost tag fetcher */
asn1_DEF_VisibleString_tags,
sizeof(asn1_DEF_VisibleString_tags)
diff --git a/skeletons/asn_SEQUENCE_OF.c b/skeletons/asn_SEQUENCE_OF.c
index 7cfd45f3..b2d5f1fa 100644
--- a/skeletons/asn_SEQUENCE_OF.c
+++ b/skeletons/asn_SEQUENCE_OF.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <asn_types.h> /* for MALLOC/REALLOC/FREEMEM */
#include <asn_SEQUENCE_OF.h>
diff --git a/skeletons/asn_SET_OF.c b/skeletons/asn_SET_OF.c
index c6afc30f..7aeafddb 100644
--- a/skeletons/asn_SET_OF.c
+++ b/skeletons/asn_SET_OF.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <asn_types.h> /* for MALLOC/REALLOC/FREEMEM */
#include <asn_SET_OF.h>
#include <errno.h>
diff --git a/skeletons/asn_internal.h b/skeletons/asn_internal.h
new file mode 100644
index 00000000..6a44cab5
--- /dev/null
+++ b/skeletons/asn_internal.h
@@ -0,0 +1,72 @@
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+/*
+ * Declarations internally useful for the ASN.1 support code.
+ */
+#ifndef _ASN_INTERNAL_H_
+#define _ASN_INTERNAL_H_
+
+#define ASN1C_ENVIRONMENT_VERSION 96 /* Compile-time version */
+int get_asn1c_environment_version(void); /* Run-time version */
+
+#include <asn_types.h>
+#include <constr_TYPE.h>
+
+#define CALLOC(nmemb, size) calloc(nmemb, size)
+#define MALLOC(size) malloc(size)
+#define REALLOC(oldptr, size) realloc(oldptr, size)
+#define FREEMEM(ptr) free(ptr)
+
+/*
+ * A macro for debugging the ASN.1 internals.
+ * You may enable or override it.
+ */
+#ifndef ASN_DEBUG /* If debugging code is not defined elsewhere... */
+#if EMIT_ASN_DEBUG == 1 /* And it was asked to emit this code... */
+#ifdef __GNUC__
+#define ASN_DEBUG(fmt, args...) do { \
+ fprintf(stderr, fmt, ##args); \
+ fprintf(stderr, "\n"); \
+ } while(0)
+#else /* !__GNUC__ */
+extern void ASN_DEBUG_f(const char *fmt, ...);
+#define ASN_DEBUG ASN_DEBUG_f
+#endif /* __GNUC__ */
+#else /* EMIT_ASN_DEBUG != 1 */
+#ifdef __GNUC__
+#define ASN_DEBUG(fmt, args...) ((void)0) /* Emit a no-op operator */
+#else /* __GNUC__ */
+static void ASN_DEBUG(const char *fmt, ...) { (void)fmt; };
+#endif /* __GNUC__ */
+#endif /* EMIT_ASN_DEBUG */
+#endif /* ASN_DEBUG */
+
+/*
+ * Invoke the application-supplied callback and fail, if something is wrong.
+ */
+#define __ASN_E_cbc(buf, size) (cb((buf), (size), app_key) == -1)
+#define _ASN_E_CALLBACK(foo) do { \
+ if(foo) _ASN_ENCODE_FAILED; \
+ } while(0)
+#define _ASN_CALLBACK(buf, size) \
+ _ASN_E_CALLBACK(__ASN_E_cbc(buf, size))
+#define _ASN_CALLBACK2(buf1, size1, buf2, size2) \
+ _ASN_E_CALLBACK(__ASN_E_cbc(buf1, size1) || __ASN_E_cbc(buf2, size2))
+#define _ASN_CALLBACK3(buf1, size1, buf2, size2, buf3, size3) \
+ _ASN_E_CALLBACK(__ASN_E_cbc(buf1, size1) \
+ || __ASN_E_cbc(buf2, size2) \
+ || __ASN_E_cbc(buf3, size3))
+
+#define _i_ASN_TEXT_INDENT(nl, level) do { \
+ int __level = (level); \
+ int __nl = ((nl) != 0); \
+ int __i; \
+ if(__nl) _ASN_CALLBACK("\n", 1); \
+ for(__i = 0; __i < __level; __i++) \
+ _ASN_CALLBACK(" ", 4); \
+ er.encoded += __nl + 4 * __level; \
+} while(0)
+
+#endif /* _ASN_INTERNAL_H_ */
diff --git a/skeletons/asn_types.h b/skeletons/asn_types.h
index a5620b55..80ab061e 100644
--- a/skeletons/asn_types.h
+++ b/skeletons/asn_types.h
@@ -43,11 +43,6 @@
#define offsetof(s, m) ((ptrdiff_t)&(((s *)0)->m) - (ptrdiff_t)((s *)0))
#endif /* offsetof */
-#define CALLOC(nmemb, size) calloc(nmemb, size)
-#define MALLOC(size) malloc(size)
-#define REALLOC(oldptr, size) realloc(oldptr, size)
-#define FREEMEM(ptr) free(ptr)
-
#ifndef MIN /* Suitable for comparing primitive types (integers) */
#if defined(__GNUC__)
#define MIN(a,b) ({ __typeof a _a = a; __typeof b _b = b; \
@@ -58,31 +53,6 @@
#endif /* MIN */
/*
- * A macro for debugging the ASN.1 internals.
- * You may enable or override it.
- */
-#ifndef ASN_DEBUG /* If debugging code is not defined elsewhere... */
-#if EMIT_ASN_DEBUG == 1 /* And it was asked to emit this code... */
-#ifdef __GNUC__
-#define ASN_DEBUG(fmt, args...) do { \
- fprintf(stderr, fmt, ##args); \
- fprintf(stderr, "\n"); \
- } while(0)
-#else /* !__GNUC__ */
-extern void ASN_DEBUG_f(const char *fmt, ...);
-#define ASN_DEBUG ASN_DEBUG_f
-#endif /* __GNUC__ */
-#else /* EMIT_ASN_DEBUG != 1 */
-#ifdef __GNUC__
-#define ASN_DEBUG(fmt, args...) ((void)0) /* Emit a no-op operator */
-#else /* __GNUC__ */
-static void ASN_DEBUG(const char *fmt, ...) { (void)fmt; };
-#endif /* __GNUC__ */
-#endif /* EMIT_ASN_DEBUG */
-#endif /* ASN_DEBUG */
-
-
-/*
* Generic type of an application-defined callback to return various
* types of data to the application.
* EXPECTED RETURN VALUES:
diff --git a/skeletons/ber_decoder.c b/skeletons/ber_decoder.c
index 24a47ac9..cd407283 100644
--- a/skeletons/ber_decoder.c
+++ b/skeletons/ber_decoder.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <constr_TYPE.h>
#include <assert.h>
diff --git a/skeletons/ber_tlv_length.c b/skeletons/ber_tlv_length.c
index 508bc39f..7daaaef6 100644
--- a/skeletons/ber_tlv_length.c
+++ b/skeletons/ber_tlv_length.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <constr_TYPE.h>
#include <ber_tlv_length.h>
#include <ber_tlv_tag.h>
diff --git a/skeletons/ber_tlv_tag.c b/skeletons/ber_tlv_tag.c
index c0a0d6a6..d66b7883 100644
--- a/skeletons/ber_tlv_tag.c
+++ b/skeletons/ber_tlv_tag.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <constr_TYPE.h>
#include <ber_tlv_tag.h>
#include <errno.h>
diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c
index b7d38fba..ac2bbd68 100644
--- a/skeletons/constr_CHOICE.c
+++ b/skeletons/constr_CHOICE.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <constr_CHOICE.h>
#include <assert.h>
@@ -348,14 +349,14 @@ CHOICE_decode_ber(asn1_TYPE_descriptor_t *td,
RETURN(RC_OK);
}
-der_enc_rval_t
+asn_enc_rval_t
CHOICE_encode_der(asn1_TYPE_descriptor_t *td,
void *struct_ptr,
int tag_mode, ber_tlv_tag_t tag,
asn_app_consume_bytes_f *cb, void *app_key) {
asn1_CHOICE_specifics_t *specs = (asn1_CHOICE_specifics_t *)td->specifics;
asn1_TYPE_member_t *elm; /* CHOICE element */
- der_enc_rval_t erval;
+ asn_enc_rval_t erval;
void *memb_ptr;
size_t computed_size = 0;
int present;
@@ -536,6 +537,57 @@ CHOICE_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
}
}
+asn_enc_rval_t
+CHOICE_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn1_CHOICE_specifics_t *specs=(asn1_CHOICE_specifics_t *)td->specifics;
+ asn_enc_rval_t er;
+ int present;
+
+ if(!sptr)
+ _ASN_ENCODE_FAILED;
+
+ /*
+ * Figure out which CHOICE element is encoded.
+ */
+ present = _fetch_present_idx(sptr, specs->pres_offset,specs->pres_size);
+
+ if(present <= 0 || present > td->elements_count) {
+ _ASN_ENCODE_FAILED;
+ } else {
+ asn_enc_rval_t tmper;
+ asn1_TYPE_member_t *elm = &td->elements[present-1];
+ void *memb_ptr;
+ const char *mname = elm->name;
+ unsigned int mlen = strlen(mname);
+
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
+ if(!memb_ptr) _ASN_ENCODE_FAILED;
+ } else {
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
+ }
+
+ er.encoded = 0;
+
+ if(!(flags & XER_F_CANONICAL)) _i_ASN_TEXT_INDENT(1, ilevel);
+ _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
+
+ tmper = elm->type->xer_encoder(elm->type, memb_ptr,
+ ilevel + 1, flags, cb, app_key);
+ if(tmper.encoded == -1) return tmper;
+
+ _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
+
+ er.encoded += 5 + (2 * mlen) + tmper.encoded;
+ }
+
+ if(!(flags & XER_F_CANONICAL)) _i_ASN_TEXT_INDENT(1, ilevel - 1);
+
+ return er;
+}
+
int
CHOICE_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
asn_app_consume_bytes_f *cb, void *app_key) {
@@ -550,7 +602,7 @@ CHOICE_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
present = _fetch_present_idx(sptr, specs->pres_offset,specs->pres_size);
/*
- * Free that element.
+ * Print that element.
*/
if(present > 0 && present <= td->elements_count) {
asn1_TYPE_member_t *elm = &td->elements[present-1];
diff --git a/skeletons/constr_CHOICE.h b/skeletons/constr_CHOICE.h
index 327bae2e..35b95110 100644
--- a/skeletons/constr_CHOICE.h
+++ b/skeletons/constr_CHOICE.h
@@ -31,11 +31,12 @@ typedef struct asn1_CHOICE_specifics_s {
/*
* A set specialized functions dealing with the CHOICE type.
*/
+asn_struct_free_f CHOICE_free;
+asn_struct_print_f CHOICE_print;
asn_constr_check_f CHOICE_constraint;
ber_type_decoder_f CHOICE_decode_ber;
der_type_encoder_f CHOICE_encode_der;
+xer_type_encoder_f CHOICE_encode_xer;
asn_outmost_tag_f CHOICE_outmost_tag;
-asn_struct_print_f CHOICE_print;
-asn_struct_free_f CHOICE_free;
#endif /* _CONSTR_CHOICE_H_ */
diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c
index 36412a65..9057ac03 100644
--- a/skeletons/constr_SEQUENCE.c
+++ b/skeletons/constr_SEQUENCE.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <constr_SEQUENCE.h>
#include <assert.h>
@@ -490,12 +491,12 @@ SEQUENCE_decode_ber(asn1_TYPE_descriptor_t *td,
/*
* The DER encoder of the SEQUENCE type.
*/
-der_enc_rval_t
+asn_enc_rval_t
SEQUENCE_encode_der(asn1_TYPE_descriptor_t *td,
void *ptr, int tag_mode, ber_tlv_tag_t tag,
asn_app_consume_bytes_f *cb, void *app_key) {
size_t computed_size = 0;
- der_enc_rval_t erval;
+ asn_enc_rval_t erval;
ssize_t ret;
int edx;
@@ -544,7 +545,7 @@ SEQUENCE_encode_der(asn1_TYPE_descriptor_t *td,
*/
for(edx = 0; edx < td->elements_count; edx++) {
asn1_TYPE_member_t *elm = &td->elements[edx];
- der_enc_rval_t tmperval;
+ asn_enc_rval_t tmperval;
void *memb_ptr;
if(elm->flags & ATF_POINTER) {
@@ -575,6 +576,50 @@ SEQUENCE_encode_der(asn1_TYPE_descriptor_t *td,
return erval;
}
+asn_enc_rval_t
+SEQUENCE_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t er;
+ int xcan = (flags & XER_F_CANONICAL);
+ int edx;
+
+ if(!sptr)
+ _ASN_ENCODE_FAILED;
+
+ er.encoded = 0;
+
+ for(edx = 0; edx < td->elements_count; edx++) {
+ asn_enc_rval_t tmper;
+ asn1_TYPE_member_t *elm = &td->elements[edx];
+ void *memb_ptr;
+ const char *mname = elm->name;
+ unsigned int mlen = strlen(mname);
+
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
+ if(!memb_ptr) continue; /* OPTIONAL element? */
+ } else {
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
+ }
+
+ if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel);
+ _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
+
+ /* Print the member itself */
+ tmper = elm->type->xer_encoder(elm->type, memb_ptr,
+ ilevel + 1, flags, cb, app_key);
+ if(tmper.encoded == -1) return tmper;
+
+ _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
+ er.encoded += 5 + (2 * mlen) + tmper.encoded;
+ }
+
+ if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
+
+ return er;
+}
+
int
SEQUENCE_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
asn_app_consume_bytes_f *cb, void *app_key) {
diff --git a/skeletons/constr_SEQUENCE.h b/skeletons/constr_SEQUENCE.h
index 1e282c2b..156db8c7 100644
--- a/skeletons/constr_SEQUENCE.h
+++ b/skeletons/constr_SEQUENCE.h
@@ -31,10 +31,11 @@ typedef struct asn1_SEQUENCE_specifics_s {
/*
* A set specialized functions dealing with the SEQUENCE type.
*/
+asn_struct_free_f SEQUENCE_free;
+asn_struct_print_f SEQUENCE_print;
asn_constr_check_f SEQUENCE_constraint;
ber_type_decoder_f SEQUENCE_decode_ber;
der_type_encoder_f SEQUENCE_encode_der;
-asn_struct_print_f SEQUENCE_print;
-asn_struct_free_f SEQUENCE_free;
+xer_type_encoder_f SEQUENCE_encode_xer;
#endif /* _CONSTR_SEQUENCE_H_ */
diff --git a/skeletons/constr_SEQUENCE_OF.c b/skeletons/constr_SEQUENCE_OF.c
index 0a58f09a..7330f659 100644
--- a/skeletons/constr_SEQUENCE_OF.c
+++ b/skeletons/constr_SEQUENCE_OF.c
@@ -2,13 +2,14 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <constr_SEQUENCE_OF.h>
#include <asn_SEQUENCE_OF.h>
/*
* The DER encoder of the SEQUENCE OF type.
*/
-der_enc_rval_t
+asn_enc_rval_t
SEQUENCE_OF_encode_der(asn1_TYPE_descriptor_t *td, void *ptr,
int tag_mode, ber_tlv_tag_t tag,
asn_app_consume_bytes_f *cb, void *app_key) {
@@ -16,7 +17,7 @@ SEQUENCE_OF_encode_der(asn1_TYPE_descriptor_t *td, void *ptr,
A_SEQUENCE_OF(void) *list;
size_t computed_size = 0;
ssize_t encoding_size = 0;
- der_enc_rval_t erval;
+ asn_enc_rval_t erval;
int edx;
ASN_DEBUG("Estimating size of SEQUENCE OF %s", td->name);
@@ -82,3 +83,50 @@ SEQUENCE_OF_encode_der(asn1_TYPE_descriptor_t *td, void *ptr,
return erval;
}
+asn_enc_rval_t
+SEQUENCE_OF_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t er;
+ asn1_SET_OF_specifics_t *specs = (asn1_SET_OF_specifics_t *)td->specifics;
+ asn1_TYPE_member_t *element = td->elements;
+ A_SEQUENCE_OF(void) *list;
+ const char *mname = specs->as_XMLValueList
+ ? 0 : ((*element->name) ? element->name : element->type->name);
+ unsigned int mlen = mname ? strlen(mname) : 0;
+ int xcan = (flags & XER_F_CANONICAL);
+ int i;
+
+ if(!sptr) _ASN_ENCODE_FAILED;
+
+ er.encoded = 0;
+
+ (void *)list = sptr;
+ for(i = 0; i < list->count; i++) {
+ asn_enc_rval_t tmper;
+
+ void *memb_ptr = list->array[i];
+ if(!memb_ptr) continue;
+
+ if(mname) {
+ if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel);
+ _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
+ }
+
+ tmper = element->type->xer_encoder(element->type, memb_ptr,
+ ilevel + 1, flags, cb, app_key);
+ if(tmper.encoded == -1) return tmper;
+
+ if(mname) {
+ _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
+ er.encoded += 5;
+ }
+
+ er.encoded += (2 * mlen) + tmper.encoded;
+ }
+
+ if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
+
+ return er;
+}
+
diff --git a/skeletons/constr_SEQUENCE_OF.h b/skeletons/constr_SEQUENCE_OF.h
index d2560c6a..ee117508 100644
--- a/skeletons/constr_SEQUENCE_OF.h
+++ b/skeletons/constr_SEQUENCE_OF.h
@@ -12,10 +12,11 @@
* A set specialized functions dealing with the SEQUENCE OF type.
* Implemented using SET OF.
*/
+#define SEQUENCE_OF_free SET_OF_free
+#define SEQUENCE_OF_print SET_OF_print
#define SEQUENCE_OF_constraint SET_OF_constraint
#define SEQUENCE_OF_decode_ber SET_OF_decode_ber
der_type_encoder_f SEQUENCE_OF_encode_der;
-#define SEQUENCE_OF_print SET_OF_print
-#define SEQUENCE_OF_free SET_OF_free
+xer_type_encoder_f SEQUENCE_OF_encode_xer;
#endif /* _CONSTR_SET_OF_H_ */
diff --git a/skeletons/constr_SET.c b/skeletons/constr_SET.c
index 7a313340..4c0c3b77 100644
--- a/skeletons/constr_SET.c
+++ b/skeletons/constr_SET.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <constr_SET.h>
#include <assert.h> /* for assert() */
@@ -430,13 +431,13 @@ SET_decode_ber(asn1_TYPE_descriptor_t *td,
/*
* The DER encoder of the SET type.
*/
-der_enc_rval_t
+asn_enc_rval_t
SET_encode_der(asn1_TYPE_descriptor_t *td,
void *ptr, int tag_mode, ber_tlv_tag_t tag,
asn_app_consume_bytes_f *cb, void *app_key) {
asn1_SET_specifics_t *specs = (asn1_SET_specifics_t *)td->specifics;
size_t computed_size = 0;
- der_enc_rval_t my_erval;
+ asn_enc_rval_t my_erval;
int t2m_build_own = (specs->tag2el_count != td->elements_count);
asn1_TYPE_tag2member_t *t2m;
int t2m_count;
@@ -469,7 +470,7 @@ SET_encode_der(asn1_TYPE_descriptor_t *td,
*/
for(edx = 0; edx < td->elements_count; edx++) {
asn1_TYPE_member_t *elm = &td->elements[edx];
- der_enc_rval_t erval;
+ asn_enc_rval_t erval;
void *memb_ptr;
/*
@@ -545,7 +546,7 @@ SET_encode_der(asn1_TYPE_descriptor_t *td,
*/
for(edx = 0; edx < td->elements_count; edx++) {
asn1_TYPE_member_t *elm;
- der_enc_rval_t erval;
+ asn_enc_rval_t erval;
void *memb_ptr;
/* Encode according to the tag order */
@@ -577,6 +578,52 @@ SET_encode_der(asn1_TYPE_descriptor_t *td,
return my_erval;
}
+asn_enc_rval_t
+SET_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t er;
+ int xcan = (flags & XER_F_CANONICAL);
+ int edx;
+
+ if(!sptr)
+ _ASN_ENCODE_FAILED;
+
+ er.encoded = 0;
+
+ for(edx = 0; edx < td->elements_count; edx++) {
+ asn_enc_rval_t tmper;
+ asn1_TYPE_member_t *elm = &td->elements[edx];
+ void *memb_ptr;
+ const char *mname = elm->name;
+ unsigned int mlen = strlen(elm->name);
+
+ if(elm->flags & ATF_POINTER) {
+ memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
+ if(!memb_ptr) continue; /* OPTIONAL element? */
+ } else {
+ memb_ptr = (void *)((char *)sptr + elm->memb_offset);
+ }
+
+ if(!xcan)
+ _i_ASN_TEXT_INDENT(1, ilevel);
+ _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
+
+ /* Print the member itself */
+ tmper = elm->type->xer_encoder(elm->type, memb_ptr,
+ ilevel + 1, flags, cb, app_key);
+ if(tmper.encoded == -1) return tmper;
+
+ _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
+
+ er.encoded += 5 + (2 * mlen) + tmper.encoded;
+ }
+
+ if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
+
+ return er;
+}
+
int
SET_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
asn_app_consume_bytes_f *cb, void *app_key) {
diff --git a/skeletons/constr_SET.h b/skeletons/constr_SET.h
index eab2c307..eaf7df0a 100644
--- a/skeletons/constr_SET.h
+++ b/skeletons/constr_SET.h
@@ -32,11 +32,12 @@ typedef struct asn1_SET_specifics_s {
/*
* A set specialized functions dealing with the SET type.
*/
+asn_struct_free_f SET_free;
+asn_struct_print_f SET_print;
asn_constr_check_f SET_constraint;
ber_type_decoder_f SET_decode_ber;
der_type_encoder_f SET_encode_der;
-asn_struct_print_f SET_print;
-asn_struct_free_f SET_free;
+xer_type_encoder_f SET_encode_xer;
/***********************
* Some handy helpers. *
diff --git a/skeletons/constr_SET_OF.c b/skeletons/constr_SET_OF.c
index d8dadf50..0a8ee281 100644
--- a/skeletons/constr_SET_OF.c
+++ b/skeletons/constr_SET_OF.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <constr_SET_OF.h>
#include <asn_SET_OF.h>
@@ -304,7 +305,7 @@ static int _el_buf_cmp(const void *ap, const void *bp) {
/*
* The DER encoder of the SET OF type.
*/
-der_enc_rval_t
+asn_enc_rval_t
SET_OF_encode_der(asn1_TYPE_descriptor_t *td, void *ptr,
int tag_mode, ber_tlv_tag_t tag,
asn_app_consume_bytes_f *cb, void *app_key) {
@@ -316,7 +317,7 @@ SET_OF_encode_der(asn1_TYPE_descriptor_t *td, void *ptr,
ssize_t encoding_size = 0;
struct _el_buffer *encoded_els;
size_t max_encoded_len = 1;
- der_enc_rval_t erval;
+ asn_enc_rval_t erval;
int ret;
int edx;
@@ -444,6 +445,53 @@ SET_OF_encode_der(asn1_TYPE_descriptor_t *td, void *ptr,
return erval;
}
+asn_enc_rval_t
+SET_OF_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t er;
+ asn1_SET_OF_specifics_t *specs=(asn1_SET_OF_specifics_t *)td->specifics;
+ asn1_TYPE_member_t *element = td->elements;
+ A_SET_OF(void) *list;
+ const char *mname = specs->as_XMLValueList
+ ? 0 : ((*element->name) ? element->name : element->type->name);
+ size_t mlen = mname ? strlen(mname) : 0;
+ int xcan = (flags & XER_F_CANONICAL);
+ int i;
+
+ if(!sptr) _ASN_ENCODE_FAILED;
+
+ er.encoded = 0;
+
+ (void *)list = sptr;
+ for(i = 0; i < list->count; i++) {
+ asn_enc_rval_t tmper;
+
+ void *memb_ptr = list->array[i];
+ if(!memb_ptr) continue;
+
+ if(mname) {
+ if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel);
+ _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
+ }
+
+ tmper = element->type->xer_encoder(element->type, memb_ptr,
+ ilevel + 1, flags, cb, app_key);
+ if(tmper.encoded == -1) return tmper;
+
+ if(mname) {
+ _ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
+ er.encoded += 5;
+ }
+
+ er.encoded += (2 * mlen) + tmper.encoded;
+ }
+
+ if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
+
+ return er;
+}
+
int
SET_OF_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
asn_app_consume_bytes_f *cb, void *app_key) {
diff --git a/skeletons/constr_SET_OF.h b/skeletons/constr_SET_OF.h
index 0dd6040b..1a1384da 100644
--- a/skeletons/constr_SET_OF.h
+++ b/skeletons/constr_SET_OF.h
@@ -13,15 +13,19 @@ typedef struct asn1_SET_OF_specifics_s {
*/
int struct_size; /* Size of the target structure. */
int ctx_offset; /* Offset of the ber_dec_ctx_t member */
+
+ /* XER-specific stuff */
+ int as_XMLValueList; /* The member type must be encoded like this */
} asn1_SET_OF_specifics_t;
/*
* A set specialized functions dealing with the SET OF type.
*/
+asn_struct_free_f SET_OF_free;
+asn_struct_print_f SET_OF_print;
asn_constr_check_f SET_OF_constraint;
ber_type_decoder_f SET_OF_decode_ber;
der_type_encoder_f SET_OF_encode_der;
-asn_struct_print_f SET_OF_print;
-asn_struct_free_f SET_OF_free;
+xer_type_encoder_f SET_OF_encode_xer;
#endif /* _CONSTR_SET_OF_H_ */
diff --git a/skeletons/constr_TYPE.c b/skeletons/constr_TYPE.c
index 68cc50fa..5085e4aa 100644
--- a/skeletons/constr_TYPE.c
+++ b/skeletons/constr_TYPE.c
@@ -2,9 +2,15 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <constr_TYPE.h>
#include <errno.h>
+/*
+ * Version of the ASN.1 infrastructure shipped with compiler.
+ */
+int get_asn1c_environment_version() { return ASN1C_ENVIRONMENT_VERSION; }
+
static asn_app_consume_bytes_f _print2fp;
/*
diff --git a/skeletons/constr_TYPE.h b/skeletons/constr_TYPE.h
index 15a67261..28e8e2cd 100644
--- a/skeletons/constr_TYPE.h
+++ b/skeletons/constr_TYPE.h
@@ -2,19 +2,53 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
-#ifndef _CONSTR_TYPE_H_
-#define _CONSTR_TYPE_H_
+/*
+ * This file contains the declaration structure called "ASN.1 Type Definition",
+ * which holds all information necessary for encoding and decoding routines.
+ * This structure even contains pointer to these encoding and decoding routines
+ * for each defined ASN.1 type.
+ */
+#ifndef _CONSTR_TYPE_H
+#define _CONSTR_TYPE_H
#include <asn_types.h> /* System-dependent types */
+
+struct asn1_TYPE_descriptor_s; /* Forward declaration */
+struct asn1_TYPE_member_s; /* Forward declaration */
+
+/*
+ * Type of the return value of the encoding functions (der_encode, xer_encode).
+ */
+typedef struct asn_enc_rval_s {
+ /*
+ * Number of bytes encoded.
+ * -1 indicates failure to encode the structure.
+ * In this case, the members below this one are meaningful.
+ */
+ ssize_t encoded;
+
+ /*
+ * Members meaningful when (encoded == -1), for post mortem analysis.
+ */
+
+ /* Type which cannot be encoded */
+ struct asn1_TYPE_descriptor_s *failed_type;
+
+ /* Pointer to the structure of that type */
+ void *structure_ptr;
+} asn_enc_rval_t;
+#define _ASN_ENCODE_FAILED do { \
+ asn_enc_rval_t __er = { -1, td, sptr }; \
+ return __er; \
+} while(0)
+
#include <ber_tlv_length.h>
#include <ber_tlv_tag.h>
#include <ber_decoder.h>
#include <der_encoder.h>
+#include <xer_encoder.h>
#include <constraints.h>
-struct asn1_TYPE_descriptor_s; /* Forward declaration */
-struct asn1_TYPE_member_s; /* Forward declaration */
-
/*
* Free the structure according to its specification.
* If (free_contents_only) is set, the wrapper structure itself (struct_ptr)
@@ -58,11 +92,13 @@ typedef struct asn1_TYPE_descriptor_s {
* Generalized functions for dealing with the specific type.
* May be directly invoked by applications.
*/
+ asn_struct_free_f *free_struct; /* Free the structure */
+ asn_struct_print_f *print_struct; /* Human readable output */
asn_constr_check_f *check_constraints; /* Constraints validator */
ber_type_decoder_f *ber_decoder; /* Free-form BER decoder */
der_type_encoder_f *der_encoder; /* Canonical DER encoder */
- asn_struct_print_f *print_struct; /* Human readable output */
- asn_struct_free_f *free_struct; /* Free the structure */
+ int (*xer_decoder);/* PLACEHOLDER */ /* Free-form XER decoder */
+ xer_type_encoder_f *xer_encoder; /* [Canonical] XER encoder */
/*
* Functions used internally. Should not be used by applications.
@@ -129,6 +165,7 @@ typedef struct asn1_TYPE_tag2member_s {
* RETURN VALUES:
* 0: The structure is printed.
* -1: Problem dumping the structure.
+ * (See also xer_fprint() in xer_encoder.h)
*/
int asn_fprint(FILE *stream, /* Destination stream descriptor */
asn1_TYPE_descriptor_t *td, /* ASN.1 type descriptor */
diff --git a/skeletons/constraints.c b/skeletons/constraints.c
index 862d8f1e..d95e3cbd 100644
--- a/skeletons/constraints.c
+++ b/skeletons/constraints.c
@@ -1,3 +1,4 @@
+#include <asn_internal.h>
#include <constraints.h>
#include <constr_TYPE.h>
diff --git a/skeletons/der_encoder.c b/skeletons/der_encoder.c
index be714925..4f1936f8 100644
--- a/skeletons/der_encoder.c
+++ b/skeletons/der_encoder.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* Redistribution and modifications are permitted subject to BSD license.
*/
+#include <asn_internal.h>
#include <constr_TYPE.h>
#include <assert.h>
#include <errno.h>
@@ -12,7 +13,7 @@ static ssize_t der_write_TL(ber_tlv_tag_t tag, ber_tlv_len_t len,
/*
* The DER encoder of any type.
*/
-der_enc_rval_t
+asn_enc_rval_t
der_encode(asn1_TYPE_descriptor_t *type_descriptor, void *struct_ptr,
asn_app_consume_bytes_f *consume_bytes, void *app_key) {
diff --git a/skeletons/der_encoder.h b/skeletons/der_encoder.h
index 052d9f4c..fe64bccf 100644
--- a/skeletons/der_encoder.h
+++ b/skeletons/der_encoder.h
@@ -10,32 +10,9 @@
struct asn1_TYPE_descriptor_s; /* Forward declaration */
/*
- * Type of the return value of the der_encode function.
- */
-typedef struct der_enc_rval_s {
- /*
- * Number of bytes encoded.
- * -1 indicates failure to encode the structure.
- * In this case, the members below this one are meaningful.
- */
- ssize_t encoded;
-
- /*
- * Members meaningful when (encoded == -1), for post-mortem analysis.
- */
-
- /* Type which cannot be encoded */
- struct asn1_TYPE_descriptor_s *failed_type;
-
- /* Pointer to the structure of that type */
- void *structure_ptr;
-} der_enc_rval_t;
-
-
-/*
* The DER encoder of any type. May be invoked by the application.
*/
-der_enc_rval_t der_encode(struct asn1_TYPE_descriptor_s *type_descriptor,
+asn_enc_rval_t der_encode(struct asn1_TYPE_descriptor_s *type_descriptor,
void *struct_ptr, /* Structure to be encoded */
asn_app_consume_bytes_f *consume_bytes_cb,
void *app_key /* Arbitrary callback argument */
@@ -44,7 +21,7 @@ der_enc_rval_t der_encode(struct asn1_TYPE_descriptor_s *type_descriptor,
/*
* Type of the generic DER encoder.
*/
-typedef der_enc_rval_t (der_type_encoder_f)(
+typedef asn_enc_rval_t (der_type_encoder_f)(
struct asn1_TYPE_descriptor_s *type_descriptor,
void *struct_ptr, /* Structure to be encoded */
int tag_mode, /* {-1,0,1}: IMPLICIT, no, EXPLICIT */
diff --git a/skeletons/file-dependencies b/skeletons/file-dependencies
index 2fdb5818..25d10a07 100644
--- a/skeletons/file-dependencies
+++ b/skeletons/file-dependencies
@@ -44,6 +44,7 @@ constr_SET_OF.h constr_SET_OF.c asn_SET_OF.h
COMMON-FILES: # This is a special section
asn_types.h
+asn_internal.h
OCTET_STRING.h OCTET_STRING.c # This one is used too widely
ber_decoder.h ber_decoder.c
ber_tlv_length.h ber_tlv_length.c
@@ -51,3 +52,4 @@ ber_tlv_tag.h ber_tlv_tag.c
constr_TYPE.h constr_TYPE.c
constraints.h constraints.c
der_encoder.h der_encoder.c
+xer_encoder.h xer_encoder.c
diff --git a/skeletons/tests/check-GeneralizedTime.c b/skeletons/tests/check-GeneralizedTime.c
index 59474e42..40008f0b 100644
--- a/skeletons/tests/check-GeneralizedTime.c
+++ b/skeletons/tests/check-GeneralizedTime.c
@@ -97,9 +97,9 @@ main(int ac, char **av) {
* Dummy function.
*/
-der_enc_rval_t
+asn_enc_rval_t
OCTET_STRING_encode_der(asn1_TYPE_descriptor_t *td, void *ptr, int tag_mode, ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, void *app_key) {
- der_enc_rval_t erval;
+ asn_enc_rval_t erval;
(void)td;
(void)ptr;
@@ -110,3 +110,17 @@ OCTET_STRING_encode_der(asn1_TYPE_descriptor_t *td, void *ptr, int tag_mode, ber
return erval;
}
+
+asn_enc_rval_t
+OCTET_STRING_encode_xer_ascii(asn1_TYPE_descriptor_t *td, void *ptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t erval;
+
+ (void)td;
+ (void)ptr;
+ (void)ilevel;
+ (void)flags;
+ (void)cb;
+ (void)app_key;
+
+ return erval;
+}
diff --git a/skeletons/tests/check-UTCTime.c b/skeletons/tests/check-UTCTime.c
index 1bd49b3c..b8ad57b3 100644
--- a/skeletons/tests/check-UTCTime.c
+++ b/skeletons/tests/check-UTCTime.c
@@ -64,9 +64,9 @@ main(int ac, char **av) {
* Dummy function.
*/
-der_enc_rval_t
+asn_enc_rval_t
OCTET_STRING_encode_der(asn1_TYPE_descriptor_t *td, void *ptr, int tag_mode, ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, void *app_key) {
- der_enc_rval_t erval;
+ asn_enc_rval_t erval;
(void)td;
(void)ptr;
@@ -77,3 +77,17 @@ OCTET_STRING_encode_der(asn1_TYPE_descriptor_t *td, void *ptr, int tag_mode, ber
return erval;
}
+
+asn_enc_rval_t
+OCTET_STRING_encode_xer_ascii(asn1_TYPE_descriptor_t *td, void *ptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t erval;
+
+ (void)td;
+ (void)ptr;
+ (void)ilevel;
+ (void)flags;
+ (void)cb;
+ (void)app_key;
+
+ return erval;
+}
diff --git a/skeletons/tests/check-length.c b/skeletons/tests/check-length.c
index 7746bcf3..6176ddd9 100644
--- a/skeletons/tests/check-length.c
+++ b/skeletons/tests/check-length.c
@@ -36,7 +36,7 @@ static void
check(int size) {
OCTET_STRING_t *os;
OCTET_STRING_t *nos = 0;
- der_enc_rval_t erval;
+ asn_enc_rval_t erval;
ber_dec_rval_t rval;
int i;
diff --git a/skeletons/xer_encoder.c b/skeletons/xer_encoder.c
new file mode 100644
index 00000000..51f8d1d5
--- /dev/null
+++ b/skeletons/xer_encoder.c
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <constr_TYPE.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+
+/*
+ * The XER encoder of any type. May be invoked by the application.
+ */
+asn_enc_rval_t
+xer_encode(asn1_TYPE_descriptor_t *td, void *sptr,
+ enum xer_encoder_flags_e xer_flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ asn_enc_rval_t er, tmper;
+ const char *mname;
+ size_t mlen;
+ int xcan = (xer_flags & XER_F_CANONICAL) ? 1 : 2;
+
+ if(!td || !sptr) {
+ er.encoded = -1;
+ er.failed_type = td;
+ er.structure_ptr = sptr;
+ return er;
+ }
+
+ mname = td->name;
+ mlen = strlen(mname);
+
+ _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
+
+ tmper = td->xer_encoder(td, sptr, 1, xer_flags, cb, app_key);
+ if(tmper.encoded == -1) return tmper;
+
+ _ASN_CALLBACK3("</", xcan, mname, mlen, ">\n",xcan);
+
+ er.encoded = 2 + (2 * xcan) + (2 * mlen) + tmper.encoded;
+
+ return er;
+}
+
+static int _print2fp(const void *buffer, size_t size, void *app_key);
+
+int
+xer_fprint(FILE *stream, asn1_TYPE_descriptor_t *td, void *sptr) {
+ asn_enc_rval_t er;
+
+ if(!stream) stream = stdout;
+ if(!td || !sptr)
+ return -1;
+
+ er = xer_encode(td, sptr, XER_F_BASIC, _print2fp, stream);
+ if(er.encoded == -1)
+ return -1;
+
+ return fflush(stream);
+}
+
+static int
+_print2fp(const void *buffer, size_t size, void *app_key) {
+ FILE *stream = (FILE *)app_key;
+
+ if(fwrite(buffer, 1, size, stream) != size)
+ return -1;
+
+ return 0;
+}
+
diff --git a/skeletons/xer_encoder.h b/skeletons/xer_encoder.h
new file mode 100644
index 00000000..43c192d3
--- /dev/null
+++ b/skeletons/xer_encoder.h
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef _XER_ENCODER_H_
+#define _XER_ENCODER_H_
+
+#include <constr_TYPE.h>
+
+struct asn1_TYPE_descriptor_s; /* Forward declaration */
+
+/* Flags used by the xer_encode() and (*xer_type_encoder_f), defined below */
+enum xer_encoder_flags_e {
+ /* Mode of encoding */
+ XER_F_BASIC = 0x01, /* BASIC-XER (pretty-printing) */
+ XER_F_CANONICAL = 0x02, /* Canonical XER (strict rules, unreadable) */
+};
+
+/*
+ * The XER encoder of any type. May be invoked by the application.
+ */
+asn_enc_rval_t xer_encode(struct asn1_TYPE_descriptor_s *type_descriptor,
+ void *struct_ptr, /* Structure to be encoded */
+ enum xer_encoder_flags_e xer_flags,
+ asn_app_consume_bytes_f *consume_bytes_cb,
+ void *app_key /* Arbitrary callback argument */
+ );
+
+/*
+ * The variant of the above function which dumps the BASIC-XER (XER_F_BASIC)
+ * output into the chosen file pointer.
+ * RETURN VALUES:
+ * 0: The structure is printed.
+ * -1: Problem printing the structure.
+ * WARNING: No sensible errno value is returned.
+ */
+int xer_fprint(FILE *stream, struct asn1_TYPE_descriptor_s *td, void *sptr);
+
+/*
+ * Type of the generic XER encoder.
+ */
+typedef asn_enc_rval_t (xer_type_encoder_f)(
+ struct asn1_TYPE_descriptor_s *type_descriptor,
+ void *struct_ptr, /* Structure to be encoded */
+ int ilevel, /* Level of indentation */
+ enum xer_encoder_flags_e xer_flags,
+ asn_app_consume_bytes_f *consume_bytes_cb, /* Callback */
+ void *app_key /* Arbitrary callback argument */
+ );
+
+#endif /* _XER_ENCODER_H_ */