blob: 5ba2e4f87ae8a397191ad98397431480dd791aef [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001/*-
2 * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
3 * Redistribution and modifications are permitted subject to BSD license.
4 */
5#include <BOOLEAN.h>
6
7/*
8 * BOOLEAN basic type description.
9 */
10static ber_tlv_tag_t asn1_DEF_BOOLEAN_tags[] = {
11 (ASN_TAG_CLASS_UNIVERSAL | (1 << 2))
12};
13asn1_TYPE_descriptor_t asn1_DEF_BOOLEAN = {
14 "BOOLEAN",
15 asn_generic_no_constraint,
16 BOOLEAN_decode_ber,
17 BOOLEAN_encode_der,
18 BOOLEAN_print,
19 BOOLEAN_free,
20 0, /* Use generic outmost tag fetcher */
21 asn1_DEF_BOOLEAN_tags,
Lev Walkin188ed2c2004-09-13 08:31:01 +000022 sizeof(asn1_DEF_BOOLEAN_tags) / sizeof(asn1_DEF_BOOLEAN_tags[0]),
23 asn1_DEF_BOOLEAN_tags, /* Same as above */
24 sizeof(asn1_DEF_BOOLEAN_tags) / sizeof(asn1_DEF_BOOLEAN_tags[0]),
Lev Walkind9bd7752004-06-05 08:17:50 +000025 0, /* Always in primitive form */
Lev Walkin449f8322004-08-20 13:23:42 +000026 0, 0, /* No members */
Lev Walkind9bd7752004-06-05 08:17:50 +000027 0 /* No specifics */
Lev Walkinf15320b2004-06-03 03:38:44 +000028};
29
30/*
31 * Decode BOOLEAN type.
32 */
33ber_dec_rval_t
34BOOLEAN_decode_ber(asn1_TYPE_descriptor_t *td,
Lev Walkin958d7a82004-08-19 13:26:36 +000035 void **bool_value, void *buf_ptr, size_t size,
Lev Walkinf15320b2004-06-03 03:38:44 +000036 int tag_mode) {
Lev Walkin958d7a82004-08-19 13:26:36 +000037 BOOLEAN_t *st = (BOOLEAN_t *)*bool_value;
Lev Walkinf15320b2004-06-03 03:38:44 +000038 ber_dec_rval_t rval;
Lev Walkind9bd7752004-06-05 08:17:50 +000039 ber_dec_ctx_t ctx = { 0, 0, 0, 0 };
Lev Walkinf15320b2004-06-03 03:38:44 +000040 ber_tlv_len_t length;
41 ber_tlv_len_t lidx;
42
43 if(st == NULL) {
Lev Walkin958d7a82004-08-19 13:26:36 +000044 (void *)st = *bool_value = CALLOC(1, sizeof(*st));
Lev Walkinf15320b2004-06-03 03:38:44 +000045 if(st == NULL) {
46 rval.code = RC_FAIL;
47 rval.consumed = 0;
48 return rval;
49 }
50 }
51
52 ASN_DEBUG("Decoding %s as BOOLEAN (tm=%d)",
53 td->name, tag_mode);
54
55 /*
56 * Check tags.
57 */
58 rval = ber_check_tags(td, &ctx,
59 buf_ptr, size, tag_mode, &length, 0);
60 if(rval.code != RC_OK)
61 return rval;
62
63 ASN_DEBUG("Boolean length is %d bytes", (int)length);
64
Lev Walkin4ce78ca2004-08-25 01:34:11 +000065 buf_ptr = ((char *)buf_ptr) + rval.consumed;
Lev Walkinf15320b2004-06-03 03:38:44 +000066 size -= rval.consumed;
Lev Walkind9bd7752004-06-05 08:17:50 +000067 if(length > (ber_tlv_len_t)size) {
Lev Walkinf15320b2004-06-03 03:38:44 +000068 rval.code = RC_WMORE;
69 rval.consumed = 0;
70 return rval;
71 }
72
73 /*
74 * Compute boolean value.
75 */
Lev Walkin958d7a82004-08-19 13:26:36 +000076 for(*st = 0, lidx = 0;
77 (lidx < length) && *st == 0; lidx++) {
Lev Walkinf15320b2004-06-03 03:38:44 +000078 /*
79 * Very simple approach: read bytes until the end or
80 * value is already TRUE.
81 * BOOLEAN is not supposed to contain meaningful data anyway.
82 */
Lev Walkin958d7a82004-08-19 13:26:36 +000083 *st |= ((uint8_t *)buf_ptr)[lidx];
Lev Walkinf15320b2004-06-03 03:38:44 +000084 }
85
86 rval.code = RC_OK;
87 rval.consumed += length;
88
Lev Walkin958d7a82004-08-19 13:26:36 +000089 ASN_DEBUG("Took %ld/%ld bytes to encode %s, value=%d",
Lev Walkinf15320b2004-06-03 03:38:44 +000090 (long)rval.consumed, (long)length,
Lev Walkin958d7a82004-08-19 13:26:36 +000091 td->name, *st);
Lev Walkinf15320b2004-06-03 03:38:44 +000092
93 return rval;
94}
95
96der_enc_rval_t
97BOOLEAN_encode_der(asn1_TYPE_descriptor_t *td, void *sptr,
98 int tag_mode, ber_tlv_tag_t tag,
99 asn_app_consume_bytes_f *cb, void *app_key) {
100 der_enc_rval_t erval;
Lev Walkinc2346572004-08-11 09:07:36 +0000101 BOOLEAN_t *st = (BOOLEAN_t *)sptr;
Lev Walkinf15320b2004-06-03 03:38:44 +0000102
103 erval.encoded = der_write_tags(td, 1, tag_mode, tag, cb, app_key);
104 if(erval.encoded == -1) {
105 erval.failed_type = td;
106 erval.structure_ptr = sptr;
107 return erval;
108 }
109
110 if(cb) {
111 uint8_t bool_value;
112 ssize_t ret;
113
Lev Walkin958d7a82004-08-19 13:26:36 +0000114 bool_value = *st?0xff:0; /* 0xff mandated by DER */
Lev Walkinf15320b2004-06-03 03:38:44 +0000115 ret = cb(&bool_value, 1, app_key);
116 if(ret == -1) {
117 erval.encoded = -1;
118 erval.failed_type = td;
119 erval.structure_ptr = sptr;
120 return erval;
121 }
122 }
123
124 erval.encoded += 1;
125
126 return erval;
127}
128
129int
130BOOLEAN_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
131 asn_app_consume_bytes_f *cb, void *app_key) {
Lev Walkinc2346572004-08-11 09:07:36 +0000132 const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
Lev Walkinf15320b2004-06-03 03:38:44 +0000133
Lev Walkind9bd7752004-06-05 08:17:50 +0000134 (void)td; /* Unused argument */
135 (void)ilevel; /* Unused argument */
136
Lev Walkinf15320b2004-06-03 03:38:44 +0000137 if(st) {
Lev Walkin958d7a82004-08-19 13:26:36 +0000138 if(*st)
Lev Walkinf15320b2004-06-03 03:38:44 +0000139 return cb("TRUE", 4, app_key);
140 else
141 return cb("FALSE", 5, app_key);
142 } else {
143 return cb("<absent>", 8, app_key);
144 }
145}
146
147void
148BOOLEAN_free(asn1_TYPE_descriptor_t *td, void *ptr, int contents_only) {
149 if(td && ptr && !contents_only) {
150 FREEMEM(ptr);
151 }
152}
153