Path: blob/main/contrib/libcbor/src/cbor/internal/loaders.c
39566 views
/*1* Copyright (c) 2014-2020 Pavel Kalvoda <[email protected]>2*3* libcbor is free software; you can redistribute it and/or modify4* it under the terms of the MIT license. See LICENSE for details.5*/67#include "loaders.h"8#include <math.h>9#include <string.h>1011uint8_t _cbor_load_uint8(cbor_data source) { return (uint8_t)*source; }1213uint16_t _cbor_load_uint16(const unsigned char *source) {14#ifdef IS_BIG_ENDIAN15uint16_t result;16memcpy(&result, source, 2);17return result;18#else19return ((uint16_t) * (source + 0) << 8) + (uint8_t) * (source + 1);20#endif21}2223uint32_t _cbor_load_uint32(const unsigned char *source) {24#ifdef IS_BIG_ENDIAN25uint32_t result;26memcpy(&result, source, 4);27return result;28#else29return ((uint32_t) * (source + 0) << 0x18) +30((uint32_t) * (source + 1) << 0x10) +31((uint16_t) * (source + 2) << 0x08) + (uint8_t) * (source + 3);32#endif33}3435uint64_t _cbor_load_uint64(const unsigned char *source) {36#ifdef IS_BIG_ENDIAN37uint64_t result;38memcpy(&result, source, 8);39return result;40#else41return ((uint64_t) * (source + 0) << 0x38) +42((uint64_t) * (source + 1) << 0x30) +43((uint64_t) * (source + 2) << 0x28) +44((uint64_t) * (source + 3) << 0x20) +45((uint32_t) * (source + 4) << 0x18) +46((uint32_t) * (source + 5) << 0x10) +47((uint16_t) * (source + 6) << 0x08) + (uint8_t) * (source + 7);48#endif49}5051/* As per https://www.rfc-editor.org/rfc/rfc8949.html#name-half-precision */52float _cbor_decode_half(unsigned char *halfp) {53int half = (halfp[0] << 8) + halfp[1];54int exp = (half >> 10) & 0x1f;55int mant = half & 0x3ff;56double val;57if (exp == 0)58val = ldexp(mant, -24);59else if (exp != 31)60val = ldexp(mant + 1024, exp - 25);61else62val = mant == 0 ? INFINITY : NAN;63return (float)(half & 0x8000 ? -val : val);64}6566float _cbor_load_half(cbor_data source) {67/* Discard const */68return _cbor_decode_half((unsigned char *)source);69}7071float _cbor_load_float(cbor_data source) {72union _cbor_float_helper helper = {.as_uint = _cbor_load_uint32(source)};73return helper.as_float;74}7576double _cbor_load_double(cbor_data source) {77union _cbor_double_helper helper = {.as_uint = _cbor_load_uint64(source)};78return helper.as_double;79}808182