xref: /freebsd/contrib/libcbor/src/cbor/floats_ctrls.c (revision 994297b01b98816bea1abf45ae4bac1bc69ee7a0)
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 
12 cbor_float_width cbor_float_get_width(const cbor_item_t *item) {
13   assert(cbor_isa_float_ctrl(item));
14   return item->metadata.float_ctrl_metadata.width;
15 }
16 
17 uint8_t cbor_ctrl_value(const cbor_item_t *item) {
18   assert(cbor_isa_float_ctrl(item));
19   assert(cbor_float_get_width(item) == CBOR_FLOAT_0);
20   return item->metadata.float_ctrl_metadata.ctrl;
21 }
22 
23 bool cbor_float_ctrl_is_ctrl(const cbor_item_t *item) {
24   assert(cbor_isa_float_ctrl(item));
25   return cbor_float_get_width(item) == CBOR_FLOAT_0;
26 }
27 
28 float cbor_float_get_float2(const cbor_item_t *item) {
29   assert(cbor_is_float(item));
30   assert(cbor_float_get_width(item) == CBOR_FLOAT_16);
31   return *(float *)item->data;
32 }
33 
34 float cbor_float_get_float4(const cbor_item_t *item) {
35   assert(cbor_is_float(item));
36   assert(cbor_float_get_width(item) == CBOR_FLOAT_32);
37   return *(float *)item->data;
38 }
39 
40 double cbor_float_get_float8(const cbor_item_t *item) {
41   assert(cbor_is_float(item));
42   assert(cbor_float_get_width(item) == CBOR_FLOAT_64);
43   return *(double *)item->data;
44 }
45 
46 double cbor_float_get_float(const cbor_item_t *item) {
47   assert(cbor_is_float(item));
48   switch (cbor_float_get_width(item)) {
49     case CBOR_FLOAT_0:
50       return NAN;
51     case CBOR_FLOAT_16:
52       return cbor_float_get_float2(item);
53     case CBOR_FLOAT_32:
54       return cbor_float_get_float4(item);
55     case CBOR_FLOAT_64:
56       return cbor_float_get_float8(item);
57   }
58   return NAN; /* Compiler complaints */
59 }
60 
61 bool cbor_get_bool(const cbor_item_t *item) {
62   assert(cbor_is_bool(item));
63   return item->metadata.float_ctrl_metadata.ctrl == CBOR_CTRL_TRUE;
64 }
65 
66 void cbor_set_float2(cbor_item_t *item, float value) {
67   assert(cbor_is_float(item));
68   assert(cbor_float_get_width(item) == CBOR_FLOAT_16);
69   *((float *)item->data) = value;
70 }
71 
72 void cbor_set_float4(cbor_item_t *item, float value) {
73   assert(cbor_is_float(item));
74   assert(cbor_float_get_width(item) == CBOR_FLOAT_32);
75   *((float *)item->data) = value;
76 }
77 
78 void cbor_set_float8(cbor_item_t *item, double value) {
79   assert(cbor_is_float(item));
80   assert(cbor_float_get_width(item) == CBOR_FLOAT_64);
81   *((double *)item->data) = value;
82 }
83 
84 void cbor_set_ctrl(cbor_item_t *item, uint8_t value) {
85   assert(cbor_isa_float_ctrl(item));
86   assert(cbor_float_get_width(item) == CBOR_FLOAT_0);
87   item->metadata.float_ctrl_metadata.ctrl = value;
88 }
89 
90 void cbor_set_bool(cbor_item_t *item, bool value) {
91   assert(cbor_is_bool(item));
92   item->metadata.float_ctrl_metadata.ctrl =
93       value ? CBOR_CTRL_TRUE : CBOR_CTRL_FALSE;
94 }
95 
96 cbor_item_t *cbor_new_ctrl() {
97   cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t));
98   _CBOR_NOTNULL(item);
99 
100   *item = (cbor_item_t){
101       .type = CBOR_TYPE_FLOAT_CTRL,
102       .data = NULL,
103       .refcount = 1,
104       .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_0,
105                                            .ctrl = CBOR_CTRL_NONE}}};
106   return item;
107 }
108 
109 cbor_item_t *cbor_new_float2() {
110   cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 4);
111   _CBOR_NOTNULL(item);
112 
113   *item = (cbor_item_t){
114       .type = CBOR_TYPE_FLOAT_CTRL,
115       .data = (unsigned char *)item + sizeof(cbor_item_t),
116       .refcount = 1,
117       .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_16}}};
118   return item;
119 }
120 
121 cbor_item_t *cbor_new_float4() {
122   cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 4);
123   _CBOR_NOTNULL(item);
124 
125   *item = (cbor_item_t){
126       .type = CBOR_TYPE_FLOAT_CTRL,
127       .data = (unsigned char *)item + sizeof(cbor_item_t),
128       .refcount = 1,
129       .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_32}}};
130   return item;
131 }
132 
133 cbor_item_t *cbor_new_float8() {
134   cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 8);
135   _CBOR_NOTNULL(item);
136 
137   *item = (cbor_item_t){
138       .type = CBOR_TYPE_FLOAT_CTRL,
139       .data = (unsigned char *)item + sizeof(cbor_item_t),
140       .refcount = 1,
141       .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_64}}};
142   return item;
143 }
144 
145 cbor_item_t *cbor_new_null() {
146   cbor_item_t *item = cbor_new_ctrl();
147   _CBOR_NOTNULL(item);
148   cbor_set_ctrl(item, CBOR_CTRL_NULL);
149   return item;
150 }
151 
152 cbor_item_t *cbor_new_undef() {
153   cbor_item_t *item = cbor_new_ctrl();
154   _CBOR_NOTNULL(item);
155   cbor_set_ctrl(item, CBOR_CTRL_UNDEF);
156   return item;
157 }
158 
159 cbor_item_t *cbor_build_bool(bool value) {
160   return cbor_build_ctrl(value ? CBOR_CTRL_TRUE : CBOR_CTRL_FALSE);
161 }
162 
163 cbor_item_t *cbor_build_float2(float value) {
164   cbor_item_t *item = cbor_new_float2();
165   _CBOR_NOTNULL(item);
166   cbor_set_float2(item, value);
167   return item;
168 }
169 
170 cbor_item_t *cbor_build_float4(float value) {
171   cbor_item_t *item = cbor_new_float4();
172   _CBOR_NOTNULL(item);
173   cbor_set_float4(item, value);
174   return item;
175 }
176 
177 cbor_item_t *cbor_build_float8(double value) {
178   cbor_item_t *item = cbor_new_float8();
179   _CBOR_NOTNULL(item);
180   cbor_set_float8(item, value);
181   return item;
182 }
183 
184 cbor_item_t *cbor_build_ctrl(uint8_t value) {
185   cbor_item_t *item = cbor_new_ctrl();
186   _CBOR_NOTNULL(item);
187   cbor_set_ctrl(item, value);
188   return item;
189 }
190