libcbor  0.5.0
libcbor is a C library for parsing and generating CBOR, the general-purpose schema-less binary data format.
loaders.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2017 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 "loaders.h"
9 #include <math.h>
10 
11 #ifdef HAVE_ENDIAN_H
12 #include <endian.h>
13 #endif
14 
15 uint8_t _cbor_load_uint8(cbor_data source)
16 {
17  return (uint8_t) *source;
18 }
19 
20 uint16_t _cbor_load_uint16(const unsigned char *source)
21 {
22 #ifdef HAVE_ENDIAN_H
23  return be16toh(*(uint16_t *) source);
24 #else
25  #ifdef IS_BIG_ENDIAN
26  return *(uint16_t *) source;
27  #else
28  return ((uint16_t) *(source + 0) << 8) +
29  (uint8_t) *(source + 1);
30  #endif
31 #endif
32 }
33 
34 uint32_t _cbor_load_uint32(const unsigned char *source)
35 {
36 #ifdef HAVE_ENDIAN_H
37  return be32toh(*(uint32_t *) source);
38 #else
39  #ifdef IS_BIG_ENDIAN
40  return *(uint32_t *) source;
41  #else
42  return ((uint32_t) *(source + 0) << 0x18) +
43  ((uint32_t) *(source + 1) << 0x10) +
44  ((uint16_t) *(source + 2) << 0x08) +
45  (uint8_t) *(source + 3);
46  #endif
47 #endif
48 }
49 
50 uint64_t _cbor_load_uint64(const unsigned char *source)
51 {
52 #ifdef HAVE_ENDIAN_H
53  return be64toh(*(uint64_t *) source);
54 #else
55  #ifdef IS_BIG_ENDIAN
56  return *(uint64_t *) source;
57  #else
58  return ((uint64_t) *(source + 0) << 0x38) +
59  ((uint64_t) *(source + 1) << 0x30) +
60  ((uint64_t) *(source + 2) << 0x28) +
61  ((uint64_t) *(source + 3) << 0x20) +
62  ((uint32_t) *(source + 4) << 0x18) +
63  ((uint32_t) *(source + 5) << 0x10) +
64  ((uint16_t) *(source + 6) << 0x08) +
65  (uint8_t) *(source + 7);
66  #endif
67 #endif
68 }
69 
70 /* As per http://tools.ietf.org/html/rfc7049#appendix-D */
71 float _cbor_decode_half(unsigned char *halfp)
72 {
73  int half = (halfp[0] << 8) + halfp[1];
74  int exp = (half >> 10) & 0x1f;
75  int mant = half & 0x3ff;
76  double val;
77  if (exp == 0) val = ldexp(mant, -24);
78  else if (exp != 31) val = ldexp(mant + 1024, exp - 25);
79  else val = mant == 0 ? INFINITY : NAN;
80  return (float) (half & 0x8000 ? -val : val);
81 }
82 
83 double _cbor_load_half(cbor_data source)
84 {
85  /* Discard const */
86  return _cbor_decode_half((unsigned char *) source);
87 }
88 
90 {
91  union _cbor_float_helper helper = {.as_uint = _cbor_load_uint32(source)};
92  return helper.as_float;
93 }
94 
96 {
97  union _cbor_double_helper helper = {.as_uint = _cbor_load_uint64(source)};
98  return helper.as_double;
99 }
double _cbor_load_double(cbor_data source)
Definition: loaders.c:95
float as_float
Definition: data.h:127
float _cbor_load_float(cbor_data source)
Definition: loaders.c:89
uint32_t as_uint
Definition: data.h:128
double _cbor_load_half(cbor_data source)
Definition: loaders.c:83
uint16_t _cbor_load_uint16(const unsigned char *source)
Definition: loaders.c:20
uint8_t _cbor_load_uint8(cbor_data source)
Definition: loaders.c:15
float _cbor_decode_half(unsigned char *halfp)
Definition: loaders.c:71
uint32_t _cbor_load_uint32(const unsigned char *source)
Definition: loaders.c:34
uint64_t as_uint
Definition: data.h:134
const unsigned char * cbor_data
Definition: data.h:20
double as_double
Definition: data.h:133
Raw memory casts helper.
Definition: data.h:126
Raw memory casts helper.
Definition: data.h:132
uint64_t _cbor_load_uint64(const unsigned char *source)
Definition: loaders.c:50