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