blob: c7a1cac2b44993ca404a995b85461f13c0d00bb9 [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 Walkind9bd7752004-06-05 08:17:50 +000028 0, /* Always in primitive form */
Lev Walkin449f8322004-08-20 13:23:42 +000029 0, 0, /* No members */
Lev Walkind9bd7752004-06-05 08:17:50 +000030 0 /* No specifics */
Lev Walkinf15320b2004-06-03 03:38:44 +000031};
32
33/*
34 * Decode BOOLEAN type.
35 */
36ber_dec_rval_t
37BOOLEAN_decode_ber(asn1_TYPE_descriptor_t *td,
Lev Walkin958d7a82004-08-19 13:26:36 +000038 void **bool_value, void *buf_ptr, size_t size,
Lev Walkinf15320b2004-06-03 03:38:44 +000039 int tag_mode) {
Lev Walkin958d7a82004-08-19 13:26:36 +000040 BOOLEAN_t *st = (BOOLEAN_t *)*bool_value;
Lev Walkinf15320b2004-06-03 03:38:44 +000041 ber_dec_rval_t rval;
Lev Walkinf15320b2004-06-03 03:38:44 +000042 ber_tlv_len_t length;
43 ber_tlv_len_t lidx;
44
45 if(st == NULL) {
Lev Walkin958d7a82004-08-19 13:26:36 +000046 (void *)st = *bool_value = CALLOC(1, sizeof(*st));
Lev Walkinf15320b2004-06-03 03:38:44 +000047 if(st == NULL) {
48 rval.code = RC_FAIL;
49 rval.consumed = 0;
50 return rval;
51 }
52 }
53
54 ASN_DEBUG("Decoding %s as BOOLEAN (tm=%d)",
55 td->name, tag_mode);
56
57 /*
58 * Check tags.
59 */
Lev Walkin5ccf1eb2004-09-24 20:58:47 +000060 rval = ber_check_tags(td, 0, buf_ptr, size, tag_mode, &length, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +000061 if(rval.code != RC_OK)
62 return rval;
63
64 ASN_DEBUG("Boolean length is %d bytes", (int)length);
65
Lev Walkin4ce78ca2004-08-25 01:34:11 +000066 buf_ptr = ((char *)buf_ptr) + rval.consumed;
Lev Walkinf15320b2004-06-03 03:38:44 +000067 size -= rval.consumed;
Lev Walkind9bd7752004-06-05 08:17:50 +000068 if(length > (ber_tlv_len_t)size) {
Lev Walkinf15320b2004-06-03 03:38:44 +000069 rval.code = RC_WMORE;
70 rval.consumed = 0;
71 return rval;
72 }
73
74 /*
75 * Compute boolean value.
76 */
Lev Walkin958d7a82004-08-19 13:26:36 +000077 for(*st = 0, lidx = 0;
78 (lidx < length) && *st == 0; lidx++) {
Lev Walkinf15320b2004-06-03 03:38:44 +000079 /*
80 * Very simple approach: read bytes until the end or
81 * value is already TRUE.
82 * BOOLEAN is not supposed to contain meaningful data anyway.
83 */
Lev Walkin958d7a82004-08-19 13:26:36 +000084 *st |= ((uint8_t *)buf_ptr)[lidx];
Lev Walkinf15320b2004-06-03 03:38:44 +000085 }
86
87 rval.code = RC_OK;
88 rval.consumed += length;
89
Lev Walkin958d7a82004-08-19 13:26:36 +000090 ASN_DEBUG("Took %ld/%ld bytes to encode %s, value=%d",
Lev Walkinf15320b2004-06-03 03:38:44 +000091 (long)rval.consumed, (long)length,
Lev Walkin958d7a82004-08-19 13:26:36 +000092 td->name, *st);
Lev Walkinf15320b2004-06-03 03:38:44 +000093
94 return rval;
95}
96
Lev Walkina9cc46e2004-09-22 16:06:28 +000097asn_enc_rval_t
Lev Walkinf15320b2004-06-03 03:38:44 +000098BOOLEAN_encode_der(asn1_TYPE_descriptor_t *td, void *sptr,
99 int tag_mode, ber_tlv_tag_t tag,
100 asn_app_consume_bytes_f *cb, void *app_key) {
Lev Walkina9cc46e2004-09-22 16:06:28 +0000101 asn_enc_rval_t erval;
Lev Walkinc2346572004-08-11 09:07:36 +0000102 BOOLEAN_t *st = (BOOLEAN_t *)sptr;
Lev Walkinf15320b2004-06-03 03:38:44 +0000103
104 erval.encoded = der_write_tags(td, 1, tag_mode, tag, cb, app_key);
105 if(erval.encoded == -1) {
106 erval.failed_type = td;
107 erval.structure_ptr = sptr;
108 return erval;
109 }
110
111 if(cb) {
112 uint8_t bool_value;
113 ssize_t ret;
114
Lev Walkin958d7a82004-08-19 13:26:36 +0000115 bool_value = *st?0xff:0; /* 0xff mandated by DER */
Lev Walkinf15320b2004-06-03 03:38:44 +0000116 ret = cb(&bool_value, 1, app_key);
117 if(ret == -1) {
118 erval.encoded = -1;
119 erval.failed_type = td;
120 erval.structure_ptr = sptr;
121 return erval;
122 }
123 }
124
125 erval.encoded += 1;
126
127 return erval;
128}
129
Lev Walkina9cc46e2004-09-22 16:06:28 +0000130asn_enc_rval_t
131BOOLEAN_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
132 int ilevel, enum xer_encoder_flags_e flags,
133 asn_app_consume_bytes_f *cb, void *app_key) {
134 const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
135 asn_enc_rval_t er;
136
137 (void)ilevel;
138 (void)flags;
139
140 if(!st) _ASN_ENCODE_FAILED;
141
142 if(*st) {
143 _ASN_CALLBACK("<true/>", 7);
144 er.encoded = 7;
145 } else {
146 _ASN_CALLBACK("<false/>", 8);
147 er.encoded = 8;
148 }
149
150 return er;
151}
152
Lev Walkinf15320b2004-06-03 03:38:44 +0000153int
154BOOLEAN_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
155 asn_app_consume_bytes_f *cb, void *app_key) {
Lev Walkinc2346572004-08-11 09:07:36 +0000156 const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
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 Walkin958d7a82004-08-19 13:26:36 +0000162 if(*st)
Lev Walkinf15320b2004-06-03 03:38:44 +0000163 return cb("TRUE", 4, app_key);
164 else
165 return cb("FALSE", 5, app_key);
166 } else {
167 return cb("<absent>", 8, app_key);
168 }
169}
170
171void
172BOOLEAN_free(asn1_TYPE_descriptor_t *td, void *ptr, int contents_only) {
173 if(td && ptr && !contents_only) {
174 FREEMEM(ptr);
175 }
176}
177