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 CBOR_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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 163 cbor_item_t* cbor_build_bool(bool value) { 164 return cbor_build_ctrl(value ? CBOR_CTRL_TRUE : CBOR_CTRL_FALSE); 165 } 166 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 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 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 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