Home | History | Annotate | Line # | Download | only in cbor
      1 /*
      2  * Copyright (c) 2014-2019 Pavel Kalvoda <me (at) 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   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   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 
     23 bool 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 
     28 float 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 
     34 float 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 
     40 double 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 
     46 double 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 
     61 void 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 
     67 void 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 
     73 void 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 
     79 void 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 
     85 bool 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 
     90 cbor_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 
    103 cbor_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 
    115 cbor_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 
    127 cbor_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 
    139 cbor_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 
    146 cbor_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 
    153 cbor_item_t *cbor_build_bool(bool value) {
    154   return cbor_build_ctrl(value ? CBOR_CTRL_TRUE : CBOR_CTRL_FALSE);
    155 }
    156 
    157 cbor_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 
    164 cbor_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 
    171 cbor_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 
    178 cbor_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