blob: b0ae1786cb0c56255cccbbf8d3b48b02138873a4 [file] [log] [blame]
vlmfa67ddc2004-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,
22 sizeof(asn1_DEF_BOOLEAN_tags)/sizeof(asn1_DEF_BOOLEAN_tags[0]),
23 1, /* Single UNIVERSAL tag may be implicitly overriden */
vlmb42843a2004-06-05 08:17:50 +000024 0, /* Always in primitive form */
vlme413c122004-08-20 13:23:42 +000025 0, 0, /* No members */
vlmb42843a2004-06-05 08:17:50 +000026 0 /* No specifics */
vlmfa67ddc2004-06-03 03:38:44 +000027};
28
29/*
30 * Decode BOOLEAN type.
31 */
32ber_dec_rval_t
33BOOLEAN_decode_ber(asn1_TYPE_descriptor_t *td,
vlmaf9cf132004-08-19 13:26:36 +000034 void **bool_value, void *buf_ptr, size_t size,
vlmfa67ddc2004-06-03 03:38:44 +000035 int tag_mode) {
vlmaf9cf132004-08-19 13:26:36 +000036 BOOLEAN_t *st = (BOOLEAN_t *)*bool_value;
vlmfa67ddc2004-06-03 03:38:44 +000037 ber_dec_rval_t rval;
vlmb42843a2004-06-05 08:17:50 +000038 ber_dec_ctx_t ctx = { 0, 0, 0, 0 };
vlmfa67ddc2004-06-03 03:38:44 +000039 ber_tlv_len_t length;
40 ber_tlv_len_t lidx;
41
42 if(st == NULL) {
vlmaf9cf132004-08-19 13:26:36 +000043 (void *)st = *bool_value = CALLOC(1, sizeof(*st));
vlmfa67ddc2004-06-03 03:38:44 +000044 if(st == NULL) {
45 rval.code = RC_FAIL;
46 rval.consumed = 0;
47 return rval;
48 }
49 }
50
51 ASN_DEBUG("Decoding %s as BOOLEAN (tm=%d)",
52 td->name, tag_mode);
53
54 /*
55 * Check tags.
56 */
57 rval = ber_check_tags(td, &ctx,
58 buf_ptr, size, tag_mode, &length, 0);
59 if(rval.code != RC_OK)
60 return rval;
61
62 ASN_DEBUG("Boolean length is %d bytes", (int)length);
63
vlmd86c9252004-08-25 01:34:11 +000064 buf_ptr = ((char *)buf_ptr) + rval.consumed;
vlmfa67ddc2004-06-03 03:38:44 +000065 size -= rval.consumed;
vlmb42843a2004-06-05 08:17:50 +000066 if(length > (ber_tlv_len_t)size) {
vlmfa67ddc2004-06-03 03:38:44 +000067 rval.code = RC_WMORE;
68 rval.consumed = 0;
69 return rval;
70 }
71
72 /*
73 * Compute boolean value.
74 */
vlmaf9cf132004-08-19 13:26:36 +000075 for(*st = 0, lidx = 0;
76 (lidx < length) && *st == 0; lidx++) {
vlmfa67ddc2004-06-03 03:38:44 +000077 /*
78 * Very simple approach: read bytes until the end or
79 * value is already TRUE.
80 * BOOLEAN is not supposed to contain meaningful data anyway.
81 */
vlmaf9cf132004-08-19 13:26:36 +000082 *st |= ((uint8_t *)buf_ptr)[lidx];
vlmfa67ddc2004-06-03 03:38:44 +000083 }
84
85 rval.code = RC_OK;
86 rval.consumed += length;
87
vlmaf9cf132004-08-19 13:26:36 +000088 ASN_DEBUG("Took %ld/%ld bytes to encode %s, value=%d",
vlmfa67ddc2004-06-03 03:38:44 +000089 (long)rval.consumed, (long)length,
vlmaf9cf132004-08-19 13:26:36 +000090 td->name, *st);
vlmfa67ddc2004-06-03 03:38:44 +000091
92 return rval;
93}
94
95der_enc_rval_t
96BOOLEAN_encode_der(asn1_TYPE_descriptor_t *td, void *sptr,
97 int tag_mode, ber_tlv_tag_t tag,
98 asn_app_consume_bytes_f *cb, void *app_key) {
99 der_enc_rval_t erval;
vlmda674682004-08-11 09:07:36 +0000100 BOOLEAN_t *st = (BOOLEAN_t *)sptr;
vlmfa67ddc2004-06-03 03:38:44 +0000101
102 erval.encoded = der_write_tags(td, 1, tag_mode, tag, cb, app_key);
103 if(erval.encoded == -1) {
104 erval.failed_type = td;
105 erval.structure_ptr = sptr;
106 return erval;
107 }
108
109 if(cb) {
110 uint8_t bool_value;
111 ssize_t ret;
112
vlmaf9cf132004-08-19 13:26:36 +0000113 bool_value = *st?0xff:0; /* 0xff mandated by DER */
vlmfa67ddc2004-06-03 03:38:44 +0000114 ret = cb(&bool_value, 1, app_key);
115 if(ret == -1) {
116 erval.encoded = -1;
117 erval.failed_type = td;
118 erval.structure_ptr = sptr;
119 return erval;
120 }
121 }
122
123 erval.encoded += 1;
124
125 return erval;
126}
127
128int
129BOOLEAN_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
130 asn_app_consume_bytes_f *cb, void *app_key) {
vlmda674682004-08-11 09:07:36 +0000131 const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
vlmfa67ddc2004-06-03 03:38:44 +0000132
vlmb42843a2004-06-05 08:17:50 +0000133 (void)td; /* Unused argument */
134 (void)ilevel; /* Unused argument */
135
vlmfa67ddc2004-06-03 03:38:44 +0000136 if(st) {
vlmaf9cf132004-08-19 13:26:36 +0000137 if(*st)
vlmfa67ddc2004-06-03 03:38:44 +0000138 return cb("TRUE", 4, app_key);
139 else
140 return cb("FALSE", 5, app_key);
141 } else {
142 return cb("<absent>", 8, app_key);
143 }
144}
145
146void
147BOOLEAN_free(asn1_TYPE_descriptor_t *td, void *ptr, int contents_only) {
148 if(td && ptr && !contents_only) {
149 FREEMEM(ptr);
150 }
151}
152