xref: /freebsd/contrib/libcbor/src/cbor/floats_ctrls.c (revision b5b9517bfe394e55088f5a05882eabae7e9b7b29)
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