1 /*
2 * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
3 *
4 * libcbor is free software; you can redistribute it and/or modify
5 * it under the terms of the MIT license. See LICENSE for details.
6 */
7
8 #include "floats_ctrls.h"
9 #include <math.h>
10 #include "assert.h"
11
cbor_float_get_width(const cbor_item_t * item)12 cbor_float_width cbor_float_get_width(const cbor_item_t* item) {
13 CBOR_ASSERT(cbor_isa_float_ctrl(item));
14 return item->metadata.float_ctrl_metadata.width;
15 }
16
cbor_ctrl_value(const cbor_item_t * item)17 uint8_t cbor_ctrl_value(const cbor_item_t* item) {
18 CBOR_ASSERT(cbor_isa_float_ctrl(item));
19 CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_0);
20 return item->metadata.float_ctrl_metadata.ctrl;
21 }
22
cbor_float_ctrl_is_ctrl(const cbor_item_t * item)23 bool cbor_float_ctrl_is_ctrl(const cbor_item_t* item) {
24 CBOR_ASSERT(cbor_isa_float_ctrl(item));
25 return cbor_float_get_width(item) == CBOR_FLOAT_0;
26 }
27
cbor_float_get_float2(const cbor_item_t * item)28 float cbor_float_get_float2(const cbor_item_t* item) {
29 CBOR_ASSERT(cbor_is_float(item));
30 CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_16);
31 return *(float*)item->data;
32 }
33
cbor_float_get_float4(const cbor_item_t * item)34 float cbor_float_get_float4(const cbor_item_t* item) {
35 CBOR_ASSERT(cbor_is_float(item));
36 CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_32);
37 return *(float*)item->data;
38 }
39
cbor_float_get_float8(const cbor_item_t * item)40 double cbor_float_get_float8(const cbor_item_t* item) {
41 CBOR_ASSERT(cbor_is_float(item));
42 CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_64);
43 return *(double*)item->data;
44 }
45
cbor_float_get_float(const cbor_item_t * item)46 double cbor_float_get_float(const cbor_item_t* item) {
47 CBOR_ASSERT(cbor_isa_float_ctrl(item));
48 CBOR_ASSERT(cbor_float_get_width(item) >= CBOR_FLOAT_0 &&
49 cbor_float_get_width(item) <= CBOR_FLOAT_64);
50 switch (cbor_float_get_width(item)) {
51 case CBOR_FLOAT_0:
52 return NAN;
53 case CBOR_FLOAT_16:
54 return cbor_float_get_float2(item);
55 case CBOR_FLOAT_32:
56 return cbor_float_get_float4(item);
57 case CBOR_FLOAT_64:
58 return cbor_float_get_float8(item);
59 default: // LCOV_EXCL_START
60 _CBOR_UNREACHABLE;
61 return 0; // LCOV_EXCL_STOP
62 }
63 }
64
cbor_get_bool(const cbor_item_t * item)65 bool cbor_get_bool(const cbor_item_t* item) {
66 CBOR_ASSERT(cbor_is_bool(item));
67 return item->metadata.float_ctrl_metadata.ctrl == CBOR_CTRL_TRUE;
68 }
69
cbor_set_float2(cbor_item_t * item,float value)70 void cbor_set_float2(cbor_item_t* item, float value) {
71 CBOR_ASSERT(cbor_is_float(item));
72 CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_16);
73 *((float*)item->data) = value;
74 }
75
cbor_set_float4(cbor_item_t * item,float value)76 void cbor_set_float4(cbor_item_t* item, float value) {
77 CBOR_ASSERT(cbor_is_float(item));
78 CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_32);
79 *((float*)item->data) = value;
80 }
81
cbor_set_float8(cbor_item_t * item,double value)82 void cbor_set_float8(cbor_item_t* item, double value) {
83 CBOR_ASSERT(cbor_is_float(item));
84 CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_64);
85 *((double*)item->data) = value;
86 }
87
cbor_set_ctrl(cbor_item_t * item,uint8_t value)88 void cbor_set_ctrl(cbor_item_t* item, uint8_t value) {
89 CBOR_ASSERT(cbor_isa_float_ctrl(item));
90 CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_0);
91 item->metadata.float_ctrl_metadata.ctrl = value;
92 }
93
cbor_set_bool(cbor_item_t * item,bool value)94 void cbor_set_bool(cbor_item_t* item, bool value) {
95 CBOR_ASSERT(cbor_is_bool(item));
96 item->metadata.float_ctrl_metadata.ctrl =
97 value ? CBOR_CTRL_TRUE : CBOR_CTRL_FALSE;
98 }
99
cbor_new_ctrl(void)100 cbor_item_t* cbor_new_ctrl(void) {
101 cbor_item_t* item = _cbor_malloc(sizeof(cbor_item_t));
102 _CBOR_NOTNULL(item);
103
104 *item = (cbor_item_t){
105 .type = CBOR_TYPE_FLOAT_CTRL,
106 .data = NULL,
107 .refcount = 1,
108 .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_0,
109 .ctrl = CBOR_CTRL_NONE}}};
110 return item;
111 }
112
cbor_new_float2(void)113 cbor_item_t* cbor_new_float2(void) {
114 cbor_item_t* item = _cbor_malloc(sizeof(cbor_item_t) + 4);
115 _CBOR_NOTNULL(item);
116
117 *item = (cbor_item_t){
118 .type = CBOR_TYPE_FLOAT_CTRL,
119 .data = (unsigned char*)item + sizeof(cbor_item_t),
120 .refcount = 1,
121 .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_16}}};
122 return item;
123 }
124
cbor_new_float4(void)125 cbor_item_t* cbor_new_float4(void) {
126 cbor_item_t* item = _cbor_malloc(sizeof(cbor_item_t) + 4);
127 _CBOR_NOTNULL(item);
128
129 *item = (cbor_item_t){
130 .type = CBOR_TYPE_FLOAT_CTRL,
131 .data = (unsigned char*)item + sizeof(cbor_item_t),
132 .refcount = 1,
133 .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_32}}};
134 return item;
135 }
136
cbor_new_float8(void)137 cbor_item_t* cbor_new_float8(void) {
138 cbor_item_t* item = _cbor_malloc(sizeof(cbor_item_t) + 8);
139 _CBOR_NOTNULL(item);
140
141 *item = (cbor_item_t){
142 .type = CBOR_TYPE_FLOAT_CTRL,
143 .data = (unsigned char*)item + sizeof(cbor_item_t),
144 .refcount = 1,
145 .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_64}}};
146 return item;
147 }
148
cbor_new_null(void)149 cbor_item_t* cbor_new_null(void) {
150 cbor_item_t* item = cbor_new_ctrl();
151 _CBOR_NOTNULL(item);
152 cbor_set_ctrl(item, CBOR_CTRL_NULL);
153 return item;
154 }
155
cbor_new_undef(void)156 cbor_item_t* cbor_new_undef(void) {
157 cbor_item_t* item = cbor_new_ctrl();
158 _CBOR_NOTNULL(item);
159 cbor_set_ctrl(item, CBOR_CTRL_UNDEF);
160 return item;
161 }
162
cbor_build_bool(bool value)163 cbor_item_t* cbor_build_bool(bool value) {
164 return cbor_build_ctrl(value ? CBOR_CTRL_TRUE : CBOR_CTRL_FALSE);
165 }
166
cbor_build_float2(float value)167 cbor_item_t* cbor_build_float2(float value) {
168 cbor_item_t* item = cbor_new_float2();
169 _CBOR_NOTNULL(item);
170 cbor_set_float2(item, value);
171 return item;
172 }
173
cbor_build_float4(float value)174 cbor_item_t* cbor_build_float4(float value) {
175 cbor_item_t* item = cbor_new_float4();
176 _CBOR_NOTNULL(item);
177 cbor_set_float4(item, value);
178 return item;
179 }
180
cbor_build_float8(double value)181 cbor_item_t* cbor_build_float8(double value) {
182 cbor_item_t* item = cbor_new_float8();
183 _CBOR_NOTNULL(item);
184 cbor_set_float8(item, value);
185 return item;
186 }
187
cbor_build_ctrl(uint8_t value)188 cbor_item_t* cbor_build_ctrl(uint8_t value) {
189 cbor_item_t* item = cbor_new_ctrl();
190 _CBOR_NOTNULL(item);
191 cbor_set_ctrl(item, value);
192 return item;
193 }
194