blob: ef6926a6faa29935455d6fe52231ca8881e5655c [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 */
Lev Walkina9cc46e2004-09-22 16:06:28 +00005#include <asn_internal.h>
Lev Walkinf15320b2004-06-03 03:38:44 +00006#include <BOOLEAN.h>
7
8/*
9 * BOOLEAN basic type description.
10 */
11static ber_tlv_tag_t asn1_DEF_BOOLEAN_tags[] = {
12 (ASN_TAG_CLASS_UNIVERSAL | (1 << 2))
13};
14asn1_TYPE_descriptor_t asn1_DEF_BOOLEAN = {
15 "BOOLEAN",
Lev Walkina9cc46e2004-09-22 16:06:28 +000016 BOOLEAN_free,
17 BOOLEAN_print,
Lev Walkinf15320b2004-06-03 03:38:44 +000018 asn_generic_no_constraint,
19 BOOLEAN_decode_ber,
20 BOOLEAN_encode_der,
Lev Walkina9cc46e2004-09-22 16:06:28 +000021 0, /* Not implemented yet */
22 BOOLEAN_encode_xer,
Lev Walkinf15320b2004-06-03 03:38:44 +000023 0, /* Use generic outmost tag fetcher */
24 asn1_DEF_BOOLEAN_tags,
Lev Walkin188ed2c2004-09-13 08:31:01 +000025 sizeof(asn1_DEF_BOOLEAN_tags) / sizeof(asn1_DEF_BOOLEAN_tags[0]),
26 asn1_DEF_BOOLEAN_tags, /* Same as above */
27 sizeof(asn1_DEF_BOOLEAN_tags) / sizeof(asn1_DEF_BOOLEAN_tags[0]),
Lev Walkin449f8322004-08-20 13:23:42 +000028 0, 0, /* No members */
Lev Walkind9bd7752004-06-05 08:17:50 +000029 0 /* No specifics */
Lev Walkinf15320b2004-06-03 03:38:44 +000030};
31
32/*
33 * Decode BOOLEAN type.
34 */
35ber_dec_rval_t
36BOOLEAN_decode_ber(asn1_TYPE_descriptor_t *td,
Lev Walkin958d7a82004-08-19 13:26:36 +000037 void **bool_value, void *buf_ptr, size_t size,
Lev Walkinf15320b2004-06-03 03:38:44 +000038 int tag_mode) {
Lev Walkin958d7a82004-08-19 13:26:36 +000039 BOOLEAN_t *st = (BOOLEAN_t *)*bool_value;
Lev Walkinf15320b2004-06-03 03:38:44 +000040 ber_dec_rval_t rval;
Lev Walkinf15320b2004-06-03 03:38:44 +000041 ber_tlv_len_t length;
42 ber_tlv_len_t lidx;
43
44 if(st == NULL) {
Lev Walkin8e8078a2004-09-26 13:10:40 +000045 st = (BOOLEAN_t *)(*bool_value = CALLOC(1, sizeof(*st)));
Lev Walkinf15320b2004-06-03 03:38:44 +000046 if(st == NULL) {
47 rval.code = RC_FAIL;
48 rval.consumed = 0;
49 return rval;
50 }
51 }
52
53 ASN_DEBUG("Decoding %s as BOOLEAN (tm=%d)",
54 td->name, tag_mode);
55
56 /*
57 * Check tags.
58 */
Lev Walkin8e8078a2004-09-26 13:10:40 +000059 rval = ber_check_tags(td, 0, buf_ptr, size, tag_mode, 0, &length, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +000060 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
Lev Walkina9cc46e2004-09-22 16:06:28 +000096asn_enc_rval_t
Lev Walkinf15320b2004-06-03 03:38:44 +000097BOOLEAN_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) {
Lev Walkina9cc46e2004-09-22 16:06:28 +0000100 asn_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
Lev Walkin8e8078a2004-09-26 13:10:40 +0000103 erval.encoded = der_write_tags(td, 1, tag_mode, 0, tag, cb, app_key);
Lev Walkinf15320b2004-06-03 03:38:44 +0000104 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;
Lev Walkinf15320b2004-06-03 03:38:44 +0000112
Lev Walkin8e8078a2004-09-26 13:10:40 +0000113 bool_value = *st ? 0xff : 0; /* 0xff mandated by DER */
114
115 if(cb(&bool_value, 1, app_key) < 0) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000116 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
Lev Walkina9cc46e2004-09-22 16:06:28 +0000128asn_enc_rval_t
129BOOLEAN_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
130 int ilevel, enum xer_encoder_flags_e flags,
131 asn_app_consume_bytes_f *cb, void *app_key) {
132 const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
133 asn_enc_rval_t er;
134
135 (void)ilevel;
136 (void)flags;
137
138 if(!st) _ASN_ENCODE_FAILED;
139
140 if(*st) {
141 _ASN_CALLBACK("<true/>", 7);
142 er.encoded = 7;
143 } else {
144 _ASN_CALLBACK("<false/>", 8);
145 er.encoded = 8;
146 }
147
148 return er;
149}
150
Lev Walkinf15320b2004-06-03 03:38:44 +0000151int
152BOOLEAN_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
153 asn_app_consume_bytes_f *cb, void *app_key) {
Lev Walkinc2346572004-08-11 09:07:36 +0000154 const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
Lev Walkin8e8078a2004-09-26 13:10:40 +0000155 const char *buf;
156 size_t buflen;
Lev Walkinf15320b2004-06-03 03:38:44 +0000157
Lev Walkind9bd7752004-06-05 08:17:50 +0000158 (void)td; /* Unused argument */
159 (void)ilevel; /* Unused argument */
160
Lev Walkinf15320b2004-06-03 03:38:44 +0000161 if(st) {
Lev Walkin8e8078a2004-09-26 13:10:40 +0000162 if(*st) {
163 buf = "TRUE";
164 buflen = 4;
165 } else {
166 buf = "FALSE";
167 buflen = 5;
168 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000169 } else {
Lev Walkin8e8078a2004-09-26 13:10:40 +0000170 buf = "<absent>";
171 buflen = 8;
Lev Walkinf15320b2004-06-03 03:38:44 +0000172 }
Lev Walkin8e8078a2004-09-26 13:10:40 +0000173
174 return (cb(buf, buflen, app_key) < 0) ? -1 : 0;
Lev Walkinf15320b2004-06-03 03:38:44 +0000175}
176
177void
178BOOLEAN_free(asn1_TYPE_descriptor_t *td, void *ptr, int contents_only) {
179 if(td && ptr && !contents_only) {
180 FREEMEM(ptr);
181 }
182}
183