floats_ctrls.c revision 1.4
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
12cbor_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
17uint8_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
23bool 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
28float 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
34float 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
40double 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
46double cbor_float_get_float(const cbor_item_t *item) {
47  CBOR_ASSERT(cbor_is_float(item));
48  // cppcheck-suppress missingReturn
49  switch (cbor_float_get_width(item)) {
50    case CBOR_FLOAT_0:
51      return NAN;
52    case CBOR_FLOAT_16:
53      return cbor_float_get_float2(item);
54    case CBOR_FLOAT_32:
55      return cbor_float_get_float4(item);
56    case CBOR_FLOAT_64:
57      return cbor_float_get_float8(item);
58  }
59}
60
61bool cbor_get_bool(const cbor_item_t *item) {
62  CBOR_ASSERT(cbor_is_bool(item));
63  return item->metadata.float_ctrl_metadata.ctrl == CBOR_CTRL_TRUE;
64}
65
66void cbor_set_float2(cbor_item_t *item, float value) {
67  CBOR_ASSERT(cbor_is_float(item));
68  CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_16);
69  *((float *)item->data) = value;
70}
71
72void cbor_set_float4(cbor_item_t *item, float value) {
73  CBOR_ASSERT(cbor_is_float(item));
74  CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_32);
75  *((float *)item->data) = value;
76}
77
78void cbor_set_float8(cbor_item_t *item, double value) {
79  CBOR_ASSERT(cbor_is_float(item));
80  CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_64);
81  *((double *)item->data) = value;
82}
83
84void cbor_set_ctrl(cbor_item_t *item, uint8_t value) {
85  CBOR_ASSERT(cbor_isa_float_ctrl(item));
86  CBOR_ASSERT(cbor_float_get_width(item) == CBOR_FLOAT_0);
87  item->metadata.float_ctrl_metadata.ctrl = value;
88}
89
90void cbor_set_bool(cbor_item_t *item, bool value) {
91  CBOR_ASSERT(cbor_is_bool(item));
92  item->metadata.float_ctrl_metadata.ctrl =
93      value ? CBOR_CTRL_TRUE : CBOR_CTRL_FALSE;
94}
95
96cbor_item_t *cbor_new_ctrl(void) {
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
109cbor_item_t *cbor_new_float2(void) {
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
121cbor_item_t *cbor_new_float4(void) {
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
133cbor_item_t *cbor_new_float8(void) {
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
145cbor_item_t *cbor_new_null(void) {
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
152cbor_item_t *cbor_new_undef(void) {
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
159cbor_item_t *cbor_build_bool(bool value) {
160  return cbor_build_ctrl(value ? CBOR_CTRL_TRUE : CBOR_CTRL_FALSE);
161}
162
163cbor_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
170cbor_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
177cbor_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
184cbor_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