diff options
author | Lev Walkin <vlm@lionet.info> | 2004-06-03 03:38:44 +0000 |
---|---|---|
committer | Lev Walkin <vlm@lionet.info> | 2004-06-03 03:38:44 +0000 |
commit | f15320bf6b50a0c02636405561ac8323ae901abd (patch) | |
tree | 33461d45122896c6dde35f82f5c7d19b62004a6b /skeletons/BOOLEAN.c | |
parent | 746cb60bbccf47019563665f4aec4b6c462c4163 (diff) |
Initial revision
Diffstat (limited to 'skeletons/BOOLEAN.c')
-rw-r--r-- | skeletons/BOOLEAN.c | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/skeletons/BOOLEAN.c b/skeletons/BOOLEAN.c new file mode 100644 index 00000000..705d37e0 --- /dev/null +++ b/skeletons/BOOLEAN.c @@ -0,0 +1,147 @@ +/*- + * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#include <BOOLEAN.h> + +/* + * BOOLEAN basic type description. + */ +static ber_tlv_tag_t asn1_DEF_BOOLEAN_tags[] = { + (ASN_TAG_CLASS_UNIVERSAL | (1 << 2)) +}; +asn1_TYPE_descriptor_t asn1_DEF_BOOLEAN = { + "BOOLEAN", + asn_generic_no_constraint, + BOOLEAN_decode_ber, + BOOLEAN_encode_der, + BOOLEAN_print, + BOOLEAN_free, + 0, /* Use generic outmost tag fetcher */ + asn1_DEF_BOOLEAN_tags, + sizeof(asn1_DEF_BOOLEAN_tags)/sizeof(asn1_DEF_BOOLEAN_tags[0]), + 1, /* Single UNIVERSAL tag may be implicitly overriden */ + 0 /* Always in primitive form */ +}; + +/* + * Decode BOOLEAN type. + */ +ber_dec_rval_t +BOOLEAN_decode_ber(asn1_TYPE_descriptor_t *td, + void **bool_structure, void *buf_ptr, size_t size, + int tag_mode) { + BOOLEAN_t *st = *bool_structure; + ber_dec_rval_t rval; + ber_dec_ctx_t ctx = { 0 }; + ber_tlv_len_t length; + ber_tlv_len_t lidx; + + if(st == NULL) { + st = *bool_structure = CALLOC(1, sizeof(*st)); + if(st == NULL) { + rval.code = RC_FAIL; + rval.consumed = 0; + return rval; + } + } + + ASN_DEBUG("Decoding %s as BOOLEAN (tm=%d)", + td->name, tag_mode); + + /* + * Check tags. + */ + rval = ber_check_tags(td, &ctx, + buf_ptr, size, tag_mode, &length, 0); + if(rval.code != RC_OK) + return rval; + + ASN_DEBUG("Boolean length is %d bytes", (int)length); + + buf_ptr += rval.consumed; + size -= rval.consumed; + if(length > size) { + rval.code = RC_WMORE; + rval.consumed = 0; + return rval; + } + + /* + * Compute boolean value. + */ + for(st->value = 0, lidx = 0; + (lidx < length) && st->value == 0; lidx++) { + /* + * Very simple approach: read bytes until the end or + * value is already TRUE. + * BOOLEAN is not supposed to contain meaningful data anyway. + */ + st->value |= ((uint8_t *)buf_ptr)[lidx]; + } + + rval.code = RC_OK; + rval.consumed += length; + + ASN_DEBUG("Took %ld/%ld bytes to encode %s, value=%ld", + (long)rval.consumed, (long)length, + td->name, (long)st->value); + + return rval; +} + +der_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; + BOOLEAN_t *st = sptr; + + erval.encoded = der_write_tags(td, 1, tag_mode, tag, cb, app_key); + if(erval.encoded == -1) { + erval.failed_type = td; + erval.structure_ptr = sptr; + return erval; + } + + if(cb) { + uint8_t bool_value; + ssize_t ret; + + bool_value = st->value?0xff:0; /* 0xff mandated by DER */ + ret = cb(&bool_value, 1, app_key); + if(ret == -1) { + erval.encoded = -1; + erval.failed_type = td; + erval.structure_ptr = sptr; + return erval; + } + } + + erval.encoded += 1; + + return erval; +} + +int +BOOLEAN_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel, + asn_app_consume_bytes_f *cb, void *app_key) { + const BOOLEAN_t *st = sptr; + + if(st) { + if(st->value) + return cb("TRUE", 4, app_key); + else + return cb("FALSE", 5, app_key); + } else { + return cb("<absent>", 8, app_key); + } +} + +void +BOOLEAN_free(asn1_TYPE_descriptor_t *td, void *ptr, int contents_only) { + if(td && ptr && !contents_only) { + FREEMEM(ptr); + } +} + |