blob: 43b890f2b71bbab0f650dd4888be6ef46dc5785e [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 */
Lev Walkin5e033762004-09-29 13:26:15 +000011static ber_tlv_tag_t asn_DEF_BOOLEAN_tags[] = {
Lev Walkinf15320b2004-06-03 03:38:44 +000012 (ASN_TAG_CLASS_UNIVERSAL | (1 << 2))
13};
Lev Walkin5e033762004-09-29 13:26:15 +000014asn_TYPE_descriptor_t asn_DEF_BOOLEAN = {
Lev Walkinf15320b2004-06-03 03:38:44 +000015 "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 */
Lev Walkin5e033762004-09-29 13:26:15 +000024 asn_DEF_BOOLEAN_tags,
25 sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]),
26 asn_DEF_BOOLEAN_tags, /* Same as above */
27 sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_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
Lev Walkin5e033762004-09-29 13:26:15 +000036BOOLEAN_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
37 asn_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 Walkin8e8078a2004-09-26 13:10:40 +000046 st = (BOOLEAN_t *)(*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 Walkin5e033762004-09-29 13:26:15 +000060 rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size,
61 tag_mode, 0, &length, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +000062 if(rval.code != RC_OK)
63 return rval;
64
65 ASN_DEBUG("Boolean length is %d bytes", (int)length);
66
Lev Walkin4ce78ca2004-08-25 01:34:11 +000067 buf_ptr = ((char *)buf_ptr) + rval.consumed;
Lev Walkinf15320b2004-06-03 03:38:44 +000068 size -= rval.consumed;
Lev Walkind9bd7752004-06-05 08:17:50 +000069 if(length > (ber_tlv_len_t)size) {
Lev Walkinf15320b2004-06-03 03:38:44 +000070 rval.code = RC_WMORE;
71 rval.consumed = 0;
72 return rval;
73 }
74
75 /*
76 * Compute boolean value.
77 */
Lev Walkin958d7a82004-08-19 13:26:36 +000078 for(*st = 0, lidx = 0;
79 (lidx < length) && *st == 0; lidx++) {
Lev Walkinf15320b2004-06-03 03:38:44 +000080 /*
81 * Very simple approach: read bytes until the end or
82 * value is already TRUE.
83 * BOOLEAN is not supposed to contain meaningful data anyway.
84 */
Lev Walkin958d7a82004-08-19 13:26:36 +000085 *st |= ((uint8_t *)buf_ptr)[lidx];
Lev Walkinf15320b2004-06-03 03:38:44 +000086 }
87
88 rval.code = RC_OK;
89 rval.consumed += length;
90
Lev Walkin958d7a82004-08-19 13:26:36 +000091 ASN_DEBUG("Took %ld/%ld bytes to encode %s, value=%d",
Lev Walkinf15320b2004-06-03 03:38:44 +000092 (long)rval.consumed, (long)length,
Lev Walkin958d7a82004-08-19 13:26:36 +000093 td->name, *st);
Lev Walkinf15320b2004-06-03 03:38:44 +000094
95 return rval;
96}
97
Lev Walkina9cc46e2004-09-22 16:06:28 +000098asn_enc_rval_t
Lev Walkin5e033762004-09-29 13:26:15 +000099BOOLEAN_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
Lev Walkinf15320b2004-06-03 03:38:44 +0000100 int tag_mode, ber_tlv_tag_t tag,
101 asn_app_consume_bytes_f *cb, void *app_key) {
Lev Walkina9cc46e2004-09-22 16:06:28 +0000102 asn_enc_rval_t erval;
Lev Walkinc2346572004-08-11 09:07:36 +0000103 BOOLEAN_t *st = (BOOLEAN_t *)sptr;
Lev Walkinf15320b2004-06-03 03:38:44 +0000104
Lev Walkin8e8078a2004-09-26 13:10:40 +0000105 erval.encoded = der_write_tags(td, 1, tag_mode, 0, tag, cb, app_key);
Lev Walkinf15320b2004-06-03 03:38:44 +0000106 if(erval.encoded == -1) {
107 erval.failed_type = td;
108 erval.structure_ptr = sptr;
109 return erval;
110 }
111
112 if(cb) {
113 uint8_t bool_value;
Lev Walkinf15320b2004-06-03 03:38:44 +0000114
Lev Walkin8e8078a2004-09-26 13:10:40 +0000115 bool_value = *st ? 0xff : 0; /* 0xff mandated by DER */
116
117 if(cb(&bool_value, 1, app_key) < 0) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000118 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
Lev Walkin5e033762004-09-29 13:26:15 +0000131BOOLEAN_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
Lev Walkina9cc46e2004-09-22 16:06:28 +0000132 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;
Lev Walkin942fd082004-10-03 09:13:02 +0000151cb_failed:
152 _ASN_ENCODE_FAILED;
Lev Walkina9cc46e2004-09-22 16:06:28 +0000153}
154
Lev Walkinf15320b2004-06-03 03:38:44 +0000155int
Lev Walkin5e033762004-09-29 13:26:15 +0000156BOOLEAN_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
Lev Walkinf15320b2004-06-03 03:38:44 +0000157 asn_app_consume_bytes_f *cb, void *app_key) {
Lev Walkinc2346572004-08-11 09:07:36 +0000158 const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
Lev Walkin8e8078a2004-09-26 13:10:40 +0000159 const char *buf;
160 size_t buflen;
Lev Walkinf15320b2004-06-03 03:38:44 +0000161
Lev Walkind9bd7752004-06-05 08:17:50 +0000162 (void)td; /* Unused argument */
163 (void)ilevel; /* Unused argument */
164
Lev Walkinf15320b2004-06-03 03:38:44 +0000165 if(st) {
Lev Walkin8e8078a2004-09-26 13:10:40 +0000166 if(*st) {
167 buf = "TRUE";
168 buflen = 4;
169 } else {
170 buf = "FALSE";
171 buflen = 5;
172 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000173 } else {
Lev Walkin8e8078a2004-09-26 13:10:40 +0000174 buf = "<absent>";
175 buflen = 8;
Lev Walkinf15320b2004-06-03 03:38:44 +0000176 }
Lev Walkin8e8078a2004-09-26 13:10:40 +0000177
178 return (cb(buf, buflen, app_key) < 0) ? -1 : 0;
Lev Walkinf15320b2004-06-03 03:38:44 +0000179}
180
181void
Lev Walkin5e033762004-09-29 13:26:15 +0000182BOOLEAN_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000183 if(td && ptr && !contents_only) {
184 FREEMEM(ptr);
185 }
186}
187