1 /*
2 * Copyright (c) 2014-2019 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 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 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
cbor_float_ctrl_is_ctrl(const cbor_item_t * item)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
cbor_float_get_float2(const cbor_item_t * item)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
cbor_float_get_float4(const cbor_item_t * item)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
cbor_float_get_float8(const cbor_item_t * item)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
cbor_float_get_float(const cbor_item_t * item)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
cbor_set_float2(cbor_item_t * item,float value)61 void cbor_set_float2(cbor_item_t *item, float value) {
62 assert(cbor_is_float(item));
63 assert(cbor_float_get_width(item) == CBOR_FLOAT_16);
64 *((float *)item->data) = value;
65 }
66
cbor_set_float4(cbor_item_t * item,float value)67 void cbor_set_float4(cbor_item_t *item, float value) {
68 assert(cbor_is_float(item));
69 assert(cbor_float_get_width(item) == CBOR_FLOAT_32);
70 *((float *)item->data) = value;
71 }
72
cbor_set_float8(cbor_item_t * item,double value)73 void cbor_set_float8(cbor_item_t *item, double value) {
74 assert(cbor_is_float(item));
75 assert(cbor_float_get_width(item) == CBOR_FLOAT_64);
76 *((double *)item->data) = value;
77 }
78
cbor_set_ctrl(cbor_item_t * item,uint8_t value)79 void cbor_set_ctrl(cbor_item_t *item, uint8_t value) {
80 assert(cbor_isa_float_ctrl(item));
81 assert(cbor_float_get_width(item) == CBOR_FLOAT_0);
82 item->metadata.float_ctrl_metadata.ctrl = value;
83 }
84
cbor_ctrl_is_bool(const cbor_item_t * item)85 bool cbor_ctrl_is_bool(const cbor_item_t *item) {
86 assert(cbor_is_bool(item));
87 return item->metadata.float_ctrl_metadata.ctrl == CBOR_CTRL_TRUE;
88 }
89
cbor_new_ctrl()90 cbor_item_t *cbor_new_ctrl() {
91 cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t));
92 _CBOR_NOTNULL(item);
93
94 *item = (cbor_item_t){
95 .type = CBOR_TYPE_FLOAT_CTRL,
96 .data = NULL,
97 .refcount = 1,
98 .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_0,
99 .ctrl = CBOR_CTRL_NONE}}};
100 return item;
101 }
102
cbor_new_float2()103 cbor_item_t *cbor_new_float2() {
104 cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 4);
105 _CBOR_NOTNULL(item);
106
107 *item = (cbor_item_t){
108 .type = CBOR_TYPE_FLOAT_CTRL,
109 .data = (unsigned char *)item + sizeof(cbor_item_t),
110 .refcount = 1,
111 .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_16}}};
112 return item;
113 }
114
cbor_new_float4()115 cbor_item_t *cbor_new_float4() {
116 cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 4);
117 _CBOR_NOTNULL(item);
118
119 *item = (cbor_item_t){
120 .type = CBOR_TYPE_FLOAT_CTRL,
121 .data = (unsigned char *)item + sizeof(cbor_item_t),
122 .refcount = 1,
123 .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_32}}};
124 return item;
125 }
126
cbor_new_float8()127 cbor_item_t *cbor_new_float8() {
128 cbor_item_t *item = _CBOR_MALLOC(sizeof(cbor_item_t) + 8);
129 _CBOR_NOTNULL(item);
130
131 *item = (cbor_item_t){
132 .type = CBOR_TYPE_FLOAT_CTRL,
133 .data = (unsigned char *)item + sizeof(cbor_item_t),
134 .refcount = 1,
135 .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_64}}};
136 return item;
137 }
138
cbor_new_null()139 cbor_item_t *cbor_new_null() {
140 cbor_item_t *item = cbor_new_ctrl();
141 _CBOR_NOTNULL(item);
142 cbor_set_ctrl(item, CBOR_CTRL_NULL);
143 return item;
144 }
145
cbor_new_undef()146 cbor_item_t *cbor_new_undef() {
147 cbor_item_t *item = cbor_new_ctrl();
148 _CBOR_NOTNULL(item);
149 cbor_set_ctrl(item, CBOR_CTRL_UNDEF);
150 return item;
151 }
152
cbor_build_bool(bool value)153 cbor_item_t *cbor_build_bool(bool value) {
154 return cbor_build_ctrl(value ? CBOR_CTRL_TRUE : CBOR_CTRL_FALSE);
155 }
156
cbor_build_float2(float value)157 cbor_item_t *cbor_build_float2(float value) {
158 cbor_item_t *item = cbor_new_float2();
159 _CBOR_NOTNULL(item);
160 cbor_set_float2(item, value);
161 return item;
162 }
163
cbor_build_float4(float value)164 cbor_item_t *cbor_build_float4(float value) {
165 cbor_item_t *item = cbor_new_float4();
166 _CBOR_NOTNULL(item);
167 cbor_set_float4(item, value);
168 return item;
169 }
170
cbor_build_float8(double value)171 cbor_item_t *cbor_build_float8(double value) {
172 cbor_item_t *item = cbor_new_float8();
173 _CBOR_NOTNULL(item);
174 cbor_set_float8(item, value);
175 return item;
176 }
177
cbor_build_ctrl(uint8_t value)178 cbor_item_t *cbor_build_ctrl(uint8_t value) {
179 cbor_item_t *item = cbor_new_ctrl();
180 _CBOR_NOTNULL(item);
181 cbor_set_ctrl(item, value);
182 return item;
183 }
184