diff options
author | Lev Walkin <vlm@lionet.info> | 2004-09-22 16:06:28 +0000 |
---|---|---|
committer | Lev Walkin <vlm@lionet.info> | 2004-09-22 16:06:28 +0000 |
commit | a9cc46e3f3c30ddd3f2a8f712c9f0acdc793fda7 (patch) | |
tree | 3ca369d58e29a24dc08ec01d4a3e4cac2020fe26 /skeletons | |
parent | e4d6ab83d7937337f1c19acfb4353fd0d43180dd (diff) |
XER support
Diffstat (limited to 'skeletons')
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 = ∬ + tmp.buf = (uint8_t *)∬ 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_ */ |