1da0d961cSdjm /*
2d3425be1Sdjm * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
3da0d961cSdjm *
4da0d961cSdjm * libcbor is free software; you can redistribute it and/or modify
5da0d961cSdjm * it under the terms of the MIT license. See LICENSE for details.
6da0d961cSdjm */
7da0d961cSdjm
8da0d961cSdjm #include "floats_ctrls.h"
9da0d961cSdjm #include <math.h>
109e5c2ddcSdjm #include "assert.h"
11da0d961cSdjm
cbor_float_get_width(const cbor_item_t * item)129e5c2ddcSdjm cbor_float_width cbor_float_get_width(const cbor_item_t *item) {
13*4dcc46c4Sdjm CBOR_ASSERT(cbor_isa_float_ctrl(item));
14da0d961cSdjm return item->metadata.float_ctrl_metadata.width;
15da0d961cSdjm }
16da0d961cSdjm
cbor_ctrl_value(const cbor_item_t * item)179e5c2ddcSdjm uint8_t cbor_ctrl_value(const cbor_item_t *item) {
18*4dcc46c4Sdjm CBOR_ASSERT(cbor_isa_float_ctrl(item));
19*4dcc46c4Sdjm CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_0);
20da0d961cSdjm return item->metadata.float_ctrl_metadata.ctrl;
21da0d961cSdjm }
22da0d961cSdjm
cbor_float_ctrl_is_ctrl(const cbor_item_t * item)239e5c2ddcSdjm bool cbor_float_ctrl_is_ctrl(const cbor_item_t *item) {
24*4dcc46c4Sdjm CBOR_ASSERT(cbor_isa_float_ctrl(item));
25da0d961cSdjm return cbor_float_get_width(item) == CBOR_FLOAT_0;
26da0d961cSdjm }
27da0d961cSdjm
cbor_float_get_float2(const cbor_item_t * item)289e5c2ddcSdjm float cbor_float_get_float2(const cbor_item_t *item) {
29*4dcc46c4Sdjm CBOR_ASSERT(cbor_is_float(item));
30*4dcc46c4Sdjm CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_16);
31da0d961cSdjm return *(float *)item->data;
32da0d961cSdjm }
33da0d961cSdjm
cbor_float_get_float4(const cbor_item_t * item)349e5c2ddcSdjm float cbor_float_get_float4(const cbor_item_t *item) {
35*4dcc46c4Sdjm CBOR_ASSERT(cbor_is_float(item));
36*4dcc46c4Sdjm CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_32);
37da0d961cSdjm return *(float *)item->data;
38da0d961cSdjm }
39da0d961cSdjm
cbor_float_get_float8(const cbor_item_t * item)409e5c2ddcSdjm double cbor_float_get_float8(const cbor_item_t *item) {
41*4dcc46c4Sdjm CBOR_ASSERT(cbor_is_float(item));
42*4dcc46c4Sdjm CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_64);
43da0d961cSdjm return *(double *)item->data;
44da0d961cSdjm }
45da0d961cSdjm
cbor_float_get_float(const cbor_item_t * item)469e5c2ddcSdjm double cbor_float_get_float(const cbor_item_t *item) {
47*4dcc46c4Sdjm CBOR_ASSERT(cbor_is_float(item));
48*4dcc46c4Sdjm // cppcheck-suppress missingReturn
49da0d961cSdjm switch (cbor_float_get_width(item)) {
509e5c2ddcSdjm case CBOR_FLOAT_0:
519e5c2ddcSdjm return NAN;
529e5c2ddcSdjm case CBOR_FLOAT_16:
539e5c2ddcSdjm return cbor_float_get_float2(item);
549e5c2ddcSdjm case CBOR_FLOAT_32:
559e5c2ddcSdjm return cbor_float_get_float4(item);
569e5c2ddcSdjm case CBOR_FLOAT_64:
579e5c2ddcSdjm return cbor_float_get_float8(item);
58da0d961cSdjm }
59da0d961cSdjm }
60da0d961cSdjm
cbor_get_bool(const cbor_item_t * item)61d3425be1Sdjm bool cbor_get_bool(const cbor_item_t *item) {
62*4dcc46c4Sdjm CBOR_ASSERT(cbor_is_bool(item));
63d3425be1Sdjm return item->metadata.float_ctrl_metadata.ctrl == CBOR_CTRL_TRUE;
64d3425be1Sdjm }
65d3425be1Sdjm
cbor_set_float2(cbor_item_t * item,float value)669e5c2ddcSdjm void cbor_set_float2(cbor_item_t *item, float value) {
67*4dcc46c4Sdjm CBOR_ASSERT(cbor_is_float(item));
68*4dcc46c4Sdjm CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_16);
69da0d961cSdjm *((float *)item->data) = value;
70da0d961cSdjm }
71da0d961cSdjm
cbor_set_float4(cbor_item_t * item,float value)729e5c2ddcSdjm void cbor_set_float4(cbor_item_t *item, float value) {
73*4dcc46c4Sdjm CBOR_ASSERT(cbor_is_float(item));
74*4dcc46c4Sdjm CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_32);
75da0d961cSdjm *((float *)item->data) = value;
76da0d961cSdjm }
77da0d961cSdjm
cbor_set_float8(cbor_item_t * item,double value)789e5c2ddcSdjm void cbor_set_float8(cbor_item_t *item, double value) {
79*4dcc46c4Sdjm CBOR_ASSERT(cbor_is_float(item));
80*4dcc46c4Sdjm CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_64);
81da0d961cSdjm *((double *)item->data) = value;
82da0d961cSdjm }
83da0d961cSdjm
cbor_set_ctrl(cbor_item_t * item,uint8_t value)849e5c2ddcSdjm void cbor_set_ctrl(cbor_item_t *item, uint8_t value) {
85*4dcc46c4Sdjm CBOR_ASSERT(cbor_isa_float_ctrl(item));
86*4dcc46c4Sdjm CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_0);
87da0d961cSdjm item->metadata.float_ctrl_metadata.ctrl = value;
88da0d961cSdjm }
89da0d961cSdjm
cbor_set_bool(cbor_item_t * item,bool value)90d3425be1Sdjm void cbor_set_bool(cbor_item_t *item, bool value) {
91*4dcc46c4Sdjm CBOR_ASSERT(cbor_is_bool(item));
92d3425be1Sdjm item->metadata.float_ctrl_metadata.ctrl =
93d3425be1Sdjm value ? CBOR_CTRL_TRUE : CBOR_CTRL_FALSE;
94da0d961cSdjm }
95da0d961cSdjm
cbor_new_ctrl(void)96*4dcc46c4Sdjm cbor_item_t *cbor_new_ctrl(void) {
97*4dcc46c4Sdjm cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t));
989e5c2ddcSdjm _CBOR_NOTNULL(item);
999e5c2ddcSdjm
100da0d961cSdjm *item = (cbor_item_t){
101da0d961cSdjm .type = CBOR_TYPE_FLOAT_CTRL,
102da0d961cSdjm .data = NULL,
103da0d961cSdjm .refcount = 1,
1049e5c2ddcSdjm .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_0,
1059e5c2ddcSdjm .ctrl = CBOR_CTRL_NONE}}};
106da0d961cSdjm return item;
107da0d961cSdjm }
108da0d961cSdjm
cbor_new_float2(void)109*4dcc46c4Sdjm cbor_item_t *cbor_new_float2(void) {
110*4dcc46c4Sdjm cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t) + 4);
1119e5c2ddcSdjm _CBOR_NOTNULL(item);
1129e5c2ddcSdjm
113da0d961cSdjm *item = (cbor_item_t){
114da0d961cSdjm .type = CBOR_TYPE_FLOAT_CTRL,
115da0d961cSdjm .data = (unsigned char *)item + sizeof(cbor_item_t),
116da0d961cSdjm .refcount = 1,
1179e5c2ddcSdjm .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_16}}};
118da0d961cSdjm return item;
119da0d961cSdjm }
120da0d961cSdjm
cbor_new_float4(void)121*4dcc46c4Sdjm cbor_item_t *cbor_new_float4(void) {
122*4dcc46c4Sdjm cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t) + 4);
1239e5c2ddcSdjm _CBOR_NOTNULL(item);
1249e5c2ddcSdjm
125da0d961cSdjm *item = (cbor_item_t){
126da0d961cSdjm .type = CBOR_TYPE_FLOAT_CTRL,
127da0d961cSdjm .data = (unsigned char *)item + sizeof(cbor_item_t),
128da0d961cSdjm .refcount = 1,
1299e5c2ddcSdjm .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_32}}};
130da0d961cSdjm return item;
131da0d961cSdjm }
132da0d961cSdjm
cbor_new_float8(void)133*4dcc46c4Sdjm cbor_item_t *cbor_new_float8(void) {
134*4dcc46c4Sdjm cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t) + 8);
1359e5c2ddcSdjm _CBOR_NOTNULL(item);
1369e5c2ddcSdjm
137da0d961cSdjm *item = (cbor_item_t){
138da0d961cSdjm .type = CBOR_TYPE_FLOAT_CTRL,
139da0d961cSdjm .data = (unsigned char *)item + sizeof(cbor_item_t),
140da0d961cSdjm .refcount = 1,
1419e5c2ddcSdjm .metadata = {.float_ctrl_metadata = {.width = CBOR_FLOAT_64}}};
142da0d961cSdjm return item;
143da0d961cSdjm }
144da0d961cSdjm
cbor_new_null(void)145*4dcc46c4Sdjm cbor_item_t *cbor_new_null(void) {
146da0d961cSdjm cbor_item_t *item = cbor_new_ctrl();
1479e5c2ddcSdjm _CBOR_NOTNULL(item);
148da0d961cSdjm cbor_set_ctrl(item, CBOR_CTRL_NULL);
149da0d961cSdjm return item;
150da0d961cSdjm }
151da0d961cSdjm
cbor_new_undef(void)152*4dcc46c4Sdjm cbor_item_t *cbor_new_undef(void) {
153da0d961cSdjm cbor_item_t *item = cbor_new_ctrl();
1549e5c2ddcSdjm _CBOR_NOTNULL(item);
155da0d961cSdjm cbor_set_ctrl(item, CBOR_CTRL_UNDEF);
156da0d961cSdjm return item;
157da0d961cSdjm }
158da0d961cSdjm
cbor_build_bool(bool value)1599e5c2ddcSdjm cbor_item_t *cbor_build_bool(bool value) {
160da0d961cSdjm return cbor_build_ctrl(value ? CBOR_CTRL_TRUE : CBOR_CTRL_FALSE);
161da0d961cSdjm }
162da0d961cSdjm
cbor_build_float2(float value)1639e5c2ddcSdjm cbor_item_t *cbor_build_float2(float value) {
164da0d961cSdjm cbor_item_t *item = cbor_new_float2();
1659e5c2ddcSdjm _CBOR_NOTNULL(item);
166da0d961cSdjm cbor_set_float2(item, value);
167da0d961cSdjm return item;
168da0d961cSdjm }
169da0d961cSdjm
cbor_build_float4(float value)1709e5c2ddcSdjm cbor_item_t *cbor_build_float4(float value) {
171da0d961cSdjm cbor_item_t *item = cbor_new_float4();
1729e5c2ddcSdjm _CBOR_NOTNULL(item);
173da0d961cSdjm cbor_set_float4(item, value);
174da0d961cSdjm return item;
175da0d961cSdjm }
176da0d961cSdjm
cbor_build_float8(double value)1779e5c2ddcSdjm cbor_item_t *cbor_build_float8(double value) {
178da0d961cSdjm cbor_item_t *item = cbor_new_float8();
1799e5c2ddcSdjm _CBOR_NOTNULL(item);
180da0d961cSdjm cbor_set_float8(item, value);
181da0d961cSdjm return item;
182da0d961cSdjm }
183da0d961cSdjm
cbor_build_ctrl(uint8_t value)1849e5c2ddcSdjm cbor_item_t *cbor_build_ctrl(uint8_t value) {
185da0d961cSdjm cbor_item_t *item = cbor_new_ctrl();
1869e5c2ddcSdjm _CBOR_NOTNULL(item);
187da0d961cSdjm cbor_set_ctrl(item, value);
188da0d961cSdjm return item;
189da0d961cSdjm }
190