libcbor  0.5.0
libcbor is a C library for parsing and generating CBOR, the general-purpose schema-less binary data format.
encoding.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 "encoding.h"
9 #include "internal/encoders.h"
10 
11 size_t cbor_encode_uint8(uint8_t value, unsigned char *buffer, size_t buffer_size)
12 {
13  return _cbor_encode_uint8(value, buffer, buffer_size, 0x00);
14 }
15 
16 size_t cbor_encode_uint16(uint16_t value, unsigned char *buffer, size_t buffer_size)
17 {
18  return _cbor_encode_uint16(value, buffer, buffer_size, 0x00);
19 }
20 
21 size_t cbor_encode_uint32(uint32_t value, unsigned char *buffer, size_t buffer_size)
22 {
23  return _cbor_encode_uint32(value, buffer, buffer_size, 0x00);
24 }
25 
26 size_t cbor_encode_uint64(uint64_t value, unsigned char *buffer, size_t buffer_size)
27 {
28  return _cbor_encode_uint64(value, buffer, buffer_size, 0x00);
29 }
30 
31 size_t cbor_encode_uint(uint64_t value, unsigned char *buffer, size_t buffer_size)
32 {
33  return _cbor_encode_uint(value, buffer, buffer_size, 0x00);
34 }
35 
36 
37 size_t cbor_encode_negint8(uint8_t value, unsigned char *buffer, size_t buffer_size)
38 {
39  return _cbor_encode_uint8(value, buffer, buffer_size, 0x20);
40 }
41 
42 size_t cbor_encode_negint16(uint16_t value, unsigned char *buffer, size_t buffer_size)
43 {
44  return _cbor_encode_uint16(value, buffer, buffer_size, 0x20);
45 }
46 
47 size_t cbor_encode_negint32(uint32_t value, unsigned char *buffer, size_t buffer_size)
48 {
49  return _cbor_encode_uint32(value, buffer, buffer_size, 0x20);
50 }
51 
52 size_t cbor_encode_negint64(uint64_t value, unsigned char *buffer, size_t buffer_size)
53 {
54  return _cbor_encode_uint64(value, buffer, buffer_size, 0x20);
55 }
56 
57 size_t cbor_encode_negint(uint64_t value, unsigned char *buffer, size_t buffer_size)
58 {
59  return _cbor_encode_uint(value, buffer, buffer_size, 0x20);
60 }
61 
62 size_t cbor_encode_bytestring_start(size_t length, unsigned char *buffer, size_t buffer_size)
63 {
64  return _cbor_encode_uint((size_t) length, buffer, buffer_size, 0x40);
65 }
66 
67 size_t _cbor_encode_byte(uint8_t value, unsigned char *buffer, size_t buffer_size)
68 {
69  if (buffer_size >= 1) {
70  buffer[0] = value;
71  return 1;
72  } else
73  return 0;
74 }
75 
76 size_t cbor_encode_indef_bytestring_start(unsigned char *buffer, size_t buffer_size)
77 {
78  return _cbor_encode_byte(0x5F, buffer, buffer_size);
79 }
80 
81 size_t cbor_encode_string_start(size_t length, unsigned char *buffer, size_t buffer_size)
82 {
83  return _cbor_encode_uint((size_t) length, buffer, buffer_size, 0x60);
84 }
85 
86 size_t cbor_encode_indef_string_start(unsigned char *buffer, size_t buffer_size)
87 {
88  return _cbor_encode_byte(0x7F, buffer, buffer_size);
89 }
90 
91 size_t cbor_encode_array_start(size_t length, unsigned char *buffer, size_t buffer_size)
92 {
93  return _cbor_encode_uint((size_t) length, buffer, buffer_size, 0x80);
94 }
95 
96 size_t cbor_encode_indef_array_start(unsigned char *buffer, size_t buffer_size)
97 {
98  return _cbor_encode_byte(0x9F, buffer, buffer_size);
99 }
100 
101 size_t cbor_encode_map_start(size_t length, unsigned char *buffer, size_t buffer_size)
102 {
103  return _cbor_encode_uint((size_t) length, buffer, buffer_size, 0xA0);
104 }
105 
106 size_t cbor_encode_indef_map_start(unsigned char *buffer, size_t buffer_size)
107 {
108  return _cbor_encode_byte(0xBF, buffer, buffer_size);
109 }
110 
111 size_t cbor_encode_tag(uint64_t value, unsigned char *buffer, size_t buffer_size)
112 {
113  return _cbor_encode_uint(value, buffer, buffer_size, 0xC0);
114 }
115 
116 size_t cbor_encode_bool(bool value, unsigned char *buffer, size_t buffer_size)
117 {
118  return value ? _cbor_encode_byte(0xF5, buffer, buffer_size) : _cbor_encode_byte(0xF4, buffer, buffer_size);
119 }
120 
121 size_t cbor_encode_null(unsigned char *buffer, size_t buffer_size)
122 {
123  return _cbor_encode_byte(0xF6, buffer, buffer_size);
124 }
125 
126 size_t cbor_encode_undef(unsigned char *buffer, size_t buffer_size)
127 {
128  return _cbor_encode_byte(0xF7, buffer, buffer_size);
129 }
130 
131 size_t cbor_encode_half(float value, unsigned char *buffer, size_t buffer_size)
132 {
133  /* Assuming value is normalized */
134  uint32_t val = ((union _cbor_float_helper) {.as_float = value}).as_uint;
135  uint16_t res;
136  uint8_t exp = (uint8_t) ((val & 0x7F800000) >> 23); /* 0b0111_1111_1000_0000_0000_0000_0000_0000 */
137  uint32_t mant = val & 0x7FFFFF; /* 0b0000_0000_0111_1111_1111_1111_1111_1111 */
138  if (exp == 0xFF) { /* Infinity or NaNs */
139  if (value != value) {
140  res = (uint16_t) 0x00e700; /* Not IEEE semantics - required by CBOR [s. 3.9] */
141  } else {
142  res = (uint16_t) ((val & 0x80000000) >> 16 | 0x7C00 | (mant ? 1 : 0) << 15);
143  }
144  } else if (exp == 0x00) { /* Zeroes or subnorms */
145  res = (uint16_t) ((val & 0x80000000) >> 16 | mant >> 13);
146  } else { /* Normal numbers */
147  int8_t logical_exp = (int8_t) (exp - 127);
148  assert(logical_exp == exp - 127);
149 
150  // Now we know that 2^exp <= 0 logically
151  if (logical_exp < -24) {
152  /* No unambiguous representation exists, this float is not a half float and is too small to
153  be represented using a half, round off to zero. Consistent with the reference implementation. */
154  res = 0;
155  } else if (logical_exp < -14) {
156  /* Offset the remaining decimal places by shifting the significand, the value is lost.
157  This is an implementation decision that works around the absence of standard half-float
158  in the language. */
159  res = (uint16_t) (val & 0x80000000) >> 16 | (uint16_t) (1 << (24 + logical_exp));
160  } else {
161  res = (uint16_t) ((val & 0x80000000) >> 16 | ((((uint8_t) logical_exp) + 15) << 10) | (uint16_t) (mant >> 13));
162  }
163  }
164  return _cbor_encode_uint16(res, buffer, buffer_size, 0xE0);
165 }
166 
167 size_t cbor_encode_single(float value, unsigned char *buffer, size_t buffer_size)
168 {
169 
170  return _cbor_encode_uint32(((union _cbor_float_helper) {.as_float = value}).as_uint, buffer, buffer_size, 0xE0);
171 }
172 
173 size_t cbor_encode_double(double value, unsigned char *buffer, size_t buffer_size)
174 {
175  return _cbor_encode_uint64(((union _cbor_double_helper) {.as_double = value}).as_uint, buffer, buffer_size, 0xE0);
176 }
177 
178 size_t cbor_encode_break(unsigned char *buffer, size_t buffer_size)
179 {
180  return _cbor_encode_byte(0xFF, buffer, buffer_size);
181 }
182 
183 size_t cbor_encode_ctrl(uint8_t value, unsigned char * buffer, size_t buffer_size)
184 {
185  return _cbor_encode_uint8(value, buffer, buffer_size, 0xE0);
186 }
size_t cbor_encode_map_start(size_t length, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:101
size_t cbor_encode_break(unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:178
size_t cbor_encode_half(float value, unsigned char *buffer, size_t buffer_size)
Encodes a half-precision float.
Definition: encoding.c:131
size_t cbor_encode_indef_array_start(unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:96
size_t cbor_encode_string_start(size_t length, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:81
size_t cbor_encode_negint32(uint32_t value, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:47
uint32_t as_uint
Definition: data.h:128
size_t cbor_encode_ctrl(uint8_t value, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:183
size_t _cbor_encode_uint16(uint16_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset)
Definition: encoders.c:31
size_t _cbor_encode_uint64(uint64_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset)
Definition: encoders.c:75
size_t cbor_encode_negint8(uint8_t value, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:37
size_t cbor_encode_uint64(uint64_t value, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:26
size_t _cbor_encode_byte(uint8_t value, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:67
size_t cbor_encode_single(float value, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:167
size_t cbor_encode_null(unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:121
size_t cbor_encode_bool(bool value, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:116
size_t cbor_encode_indef_map_start(unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:106
size_t _cbor_encode_uint32(uint32_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset)
Definition: encoders.c:52
size_t cbor_encode_double(double value, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:173
size_t _cbor_encode_uint(uint64_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset)
Definition: encoders.c:102
size_t cbor_encode_array_start(size_t length, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:91
size_t cbor_encode_uint8(uint8_t value, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:11
size_t cbor_encode_uint16(uint16_t value, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:16
size_t cbor_encode_negint64(uint64_t value, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:52
size_t cbor_encode_uint32(uint32_t value, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:21
size_t cbor_encode_undef(unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:126
size_t cbor_encode_negint(uint64_t value, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:57
size_t cbor_encode_indef_string_start(unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:86
size_t cbor_encode_uint(uint64_t value, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:31
size_t _cbor_encode_uint8(uint8_t value, unsigned char *buffer, size_t buffer_size, uint8_t offset)
Definition: encoders.c:14
size_t cbor_encode_bytestring_start(size_t length, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:62
size_t cbor_encode_indef_bytestring_start(unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:76
size_t cbor_encode_negint16(uint16_t value, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:42
Raw memory casts helper.
Definition: data.h:126
Raw memory casts helper.
Definition: data.h:132
size_t cbor_encode_tag(uint64_t value, unsigned char *buffer, size_t buffer_size)
Definition: encoding.c:111