blob: 9609a19efea2111a1937c93e83164b356734770e [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 Walkind9bd7752004-06-05 08:17:50 +000042 ber_dec_ctx_t ctx = { 0, 0, 0, 0 };
Lev Walkinf15320b2004-06-03 03:38:44 +000043 ber_tlv_len_t length;
44 ber_tlv_len_t lidx;
45
46 if(st == NULL) {
Lev Walkin958d7a82004-08-19 13:26:36 +000047 (void *)st = *bool_value = CALLOC(1, sizeof(*st));
Lev Walkinf15320b2004-06-03 03:38:44 +000048 if(st == NULL) {
49 rval.code = RC_FAIL;
50 rval.consumed = 0;
51 return rval;
52 }
53 }
54
55 ASN_DEBUG("Decoding %s as BOOLEAN (tm=%d)",
56 td->name, tag_mode);
57
58 /*
59 * Check tags.
60 */
61 rval = ber_check_tags(td, &ctx,
62 buf_ptr, size, tag_mode, &length, 0);
63 if(rval.code != RC_OK)
64 return rval;
65
66 ASN_DEBUG("Boolean length is %d bytes", (int)length);
67
Lev Walkin4ce78ca2004-08-25 01:34:11 +000068 buf_ptr = ((char *)buf_ptr) + rval.consumed;
Lev Walkinf15320b2004-06-03 03:38:44 +000069 size -= rval.consumed;
Lev Walkind9bd7752004-06-05 08:17:50 +000070 if(length > (ber_tlv_len_t)size) {
Lev Walkinf15320b2004-06-03 03:38:44 +000071 rval.code = RC_WMORE;
72 rval.consumed = 0;
73 return rval;
74 }
75
76 /*
77 * Compute boolean value.
78 */
Lev Walkin958d7a82004-08-19 13:26:36 +000079 for(*st = 0, lidx = 0;
80 (lidx < length) && *st == 0; lidx++) {
Lev Walkinf15320b2004-06-03 03:38:44 +000081 /*
82 * Very simple approach: read bytes until the end or
83 * value is already TRUE.
84 * BOOLEAN is not supposed to contain meaningful data anyway.
85 */
Lev Walkin958d7a82004-08-19 13:26:36 +000086 *st |= ((uint8_t *)buf_ptr)[lidx];
Lev Walkinf15320b2004-06-03 03:38:44 +000087 }
88
89 rval.code = RC_OK;
90 rval.consumed += length;
91
Lev Walkin958d7a82004-08-19 13:26:36 +000092 ASN_DEBUG("Took %ld/%ld bytes to encode %s, value=%d",
Lev Walkinf15320b2004-06-03 03:38:44 +000093 (long)rval.consumed, (long)length,
Lev Walkin958d7a82004-08-19 13:26:36 +000094 td->name, *st);
Lev Walkinf15320b2004-06-03 03:38:44 +000095
96 return rval;
97}
98
Lev Walkina9cc46e2004-09-22 16:06:28 +000099asn_enc_rval_t
Lev Walkinf15320b2004-06-03 03:38:44 +0000100BOOLEAN_encode_der(asn1_TYPE_descriptor_t *td, void *sptr,
101 int tag_mode, ber_tlv_tag_t tag,
102 asn_app_consume_bytes_f *cb, void *app_key) {
Lev Walkina9cc46e2004-09-22 16:06:28 +0000103 asn_enc_rval_t erval;
Lev Walkinc2346572004-08-11 09:07:36 +0000104 BOOLEAN_t *st = (BOOLEAN_t *)sptr;
Lev Walkinf15320b2004-06-03 03:38:44 +0000105
106 erval.encoded = der_write_tags(td, 1, tag_mode, tag, cb, app_key);
107 if(erval.encoded == -1) {
108 erval.failed_type = td;
109 erval.structure_ptr = sptr;
110 return erval;
111 }
112
113 if(cb) {
114 uint8_t bool_value;
115 ssize_t ret;
116
Lev Walkin958d7a82004-08-19 13:26:36 +0000117 bool_value = *st?0xff:0; /* 0xff mandated by DER */
Lev Walkinf15320b2004-06-03 03:38:44 +0000118 ret = cb(&bool_value, 1, app_key);
119 if(ret == -1) {
120 erval.encoded = -1;
121 erval.failed_type = td;
122 erval.structure_ptr = sptr;
123 return erval;
124 }
125 }
126
127 erval.encoded += 1;
128
129 return erval;
130}
131
Lev Walkina9cc46e2004-09-22 16:06:28 +0000132asn_enc_rval_t
133BOOLEAN_encode_xer(asn1_TYPE_descriptor_t *td, void *sptr,
134 int ilevel, enum xer_encoder_flags_e flags,
135 asn_app_consume_bytes_f *cb, void *app_key) {
136 const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
137 asn_enc_rval_t er;
138
139 (void)ilevel;
140 (void)flags;
141
142 if(!st) _ASN_ENCODE_FAILED;
143
144 if(*st) {
145 _ASN_CALLBACK("<true/>", 7);
146 er.encoded = 7;
147 } else {
148 _ASN_CALLBACK("<false/>", 8);
149 er.encoded = 8;
150 }
151
152 return er;
153}
154
Lev Walkinf15320b2004-06-03 03:38:44 +0000155int
156BOOLEAN_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
157 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 Walkinf15320b2004-06-03 03:38:44 +0000159
Lev Walkind9bd7752004-06-05 08:17:50 +0000160 (void)td; /* Unused argument */
161 (void)ilevel; /* Unused argument */
162
Lev Walkinf15320b2004-06-03 03:38:44 +0000163 if(st) {
Lev Walkin958d7a82004-08-19 13:26:36 +0000164 if(*st)
Lev Walkinf15320b2004-06-03 03:38:44 +0000165 return cb("TRUE", 4, app_key);
166 else
167 return cb("FALSE", 5, app_key);
168 } else {
169 return cb("<absent>", 8, app_key);
170 }
171}
172
173void
174BOOLEAN_free(asn1_TYPE_descriptor_t *td, void *ptr, int contents_only) {
175 if(td && ptr && !contents_only) {
176 FREEMEM(ptr);
177 }
178}
179