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 12cbor_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 17uint8_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 23bool 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 28float 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 34float 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 40double 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 46double 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 61void 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 67void 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 73void 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 79void 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 85bool 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 90cbor_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 103cbor_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 115cbor_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 127cbor_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 139cbor_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 146cbor_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 153cbor_item_t *cbor_build_bool(bool value) { 154 return cbor_build_ctrl(value ? CBOR_CTRL_TRUE : CBOR_CTRL_FALSE); 155} 156 157cbor_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 164cbor_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 171cbor_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 178cbor_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