blob: 4f9b32444a10ebd17c512276b36f9ad75fffc6ff [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 */
25 0 /* No specifics */
vlmfa67ddc2004-06-03 03:38:44 +000026};
27
28/*
29 * Decode BOOLEAN type.
30 */
31ber_dec_rval_t
32BOOLEAN_decode_ber(asn1_TYPE_descriptor_t *td,
vlmaf9cf132004-08-19 13:26:36 +000033 void **bool_value, void *buf_ptr, size_t size,
vlmfa67ddc2004-06-03 03:38:44 +000034 int tag_mode) {
vlmaf9cf132004-08-19 13:26:36 +000035 BOOLEAN_t *st = (BOOLEAN_t *)*bool_value;
vlmfa67ddc2004-06-03 03:38:44 +000036 ber_dec_rval_t rval;
vlmb42843a2004-06-05 08:17:50 +000037 ber_dec_ctx_t ctx = { 0, 0, 0, 0 };
vlmfa67ddc2004-06-03 03:38:44 +000038 ber_tlv_len_t length;
39 ber_tlv_len_t lidx;
40
41 if(st == NULL) {
vlmaf9cf132004-08-19 13:26:36 +000042 (void *)st = *bool_value = CALLOC(1, sizeof(*st));
vlmfa67ddc2004-06-03 03:38:44 +000043 if(st == NULL) {
44 rval.code = RC_FAIL;
45 rval.consumed = 0;
46 return rval;
47 }
48 }
49
50 ASN_DEBUG("Decoding %s as BOOLEAN (tm=%d)",
51 td->name, tag_mode);
52
53 /*
54 * Check tags.
55 */
56 rval = ber_check_tags(td, &ctx,
57 buf_ptr, size, tag_mode, &length, 0);
58 if(rval.code != RC_OK)
59 return rval;
60
61 ASN_DEBUG("Boolean length is %d bytes", (int)length);
62
vlm1ff928d2004-08-11 08:10:13 +000063 (char *)buf_ptr += rval.consumed;
vlmfa67ddc2004-06-03 03:38:44 +000064 size -= rval.consumed;
vlmb42843a2004-06-05 08:17:50 +000065 if(length > (ber_tlv_len_t)size) {
vlmfa67ddc2004-06-03 03:38:44 +000066 rval.code = RC_WMORE;
67 rval.consumed = 0;
68 return rval;
69 }
70
71 /*
72 * Compute boolean value.
73 */
vlmaf9cf132004-08-19 13:26:36 +000074 for(*st = 0, lidx = 0;
75 (lidx < length) && *st == 0; lidx++) {
vlmfa67ddc2004-06-03 03:38:44 +000076 /*
77 * Very simple approach: read bytes until the end or
78 * value is already TRUE.
79 * BOOLEAN is not supposed to contain meaningful data anyway.
80 */
vlmaf9cf132004-08-19 13:26:36 +000081 *st |= ((uint8_t *)buf_ptr)[lidx];
vlmfa67ddc2004-06-03 03:38:44 +000082 }
83
84 rval.code = RC_OK;
85 rval.consumed += length;
86
vlmaf9cf132004-08-19 13:26:36 +000087 ASN_DEBUG("Took %ld/%ld bytes to encode %s, value=%d",
vlmfa67ddc2004-06-03 03:38:44 +000088 (long)rval.consumed, (long)length,
vlmaf9cf132004-08-19 13:26:36 +000089 td->name, *st);
vlmfa67ddc2004-06-03 03:38:44 +000090
91 return rval;
92}
93
94der_enc_rval_t
95BOOLEAN_encode_der(asn1_TYPE_descriptor_t *td, void *sptr,
96 int tag_mode, ber_tlv_tag_t tag,
97 asn_app_consume_bytes_f *cb, void *app_key) {
98 der_enc_rval_t erval;
vlmda674682004-08-11 09:07:36 +000099 BOOLEAN_t *st = (BOOLEAN_t *)sptr;
vlmfa67ddc2004-06-03 03:38:44 +0000100
101 erval.encoded = der_write_tags(td, 1, tag_mode, tag, cb, app_key);
102 if(erval.encoded == -1) {
103 erval.failed_type = td;
104 erval.structure_ptr = sptr;
105 return erval;
106 }
107
108 if(cb) {
109 uint8_t bool_value;
110 ssize_t ret;
111
vlmaf9cf132004-08-19 13:26:36 +0000112 bool_value = *st?0xff:0; /* 0xff mandated by DER */
vlmfa67ddc2004-06-03 03:38:44 +0000113 ret = cb(&bool_value, 1, app_key);
114 if(ret == -1) {
115 erval.encoded = -1;
116 erval.failed_type = td;
117 erval.structure_ptr = sptr;
118 return erval;
119 }
120 }
121
122 erval.encoded += 1;
123
124 return erval;
125}
126
127int
128BOOLEAN_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
129 asn_app_consume_bytes_f *cb, void *app_key) {
vlmda674682004-08-11 09:07:36 +0000130 const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
vlmfa67ddc2004-06-03 03:38:44 +0000131
vlmb42843a2004-06-05 08:17:50 +0000132 (void)td; /* Unused argument */
133 (void)ilevel; /* Unused argument */
134
vlmfa67ddc2004-06-03 03:38:44 +0000135 if(st) {
vlmaf9cf132004-08-19 13:26:36 +0000136 if(*st)
vlmfa67ddc2004-06-03 03:38:44 +0000137 return cb("TRUE", 4, app_key);
138 else
139 return cb("FALSE", 5, app_key);
140 } else {
141 return cb("<absent>", 8, app_key);
142 }
143}
144
145void
146BOOLEAN_free(asn1_TYPE_descriptor_t *td, void *ptr, int contents_only) {
147 if(td && ptr && !contents_only) {
148 FREEMEM(ptr);
149 }
150}
151