Embedded SDK
Embedded SDK
Loading...
Searching...
No Matches
buffer.c
Go to the documentation of this file.
1/*****************************************************************************
2 * (c) 2020 Ledger SAS.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
17#include <stdint.h> // uint*_t
18#include <stddef.h> // size_t
19#include <stdbool.h> // bool
20#include <string.h> // memmove
21
22#include "buffer.h"
23#include "read.h"
24#include "varint.h"
25#include "bip32.h"
26#include "write.h"
27
28bool buffer_can_read(const buffer_t *buffer, size_t n)
29{
30 return buffer->size - buffer->offset >= n;
31}
32
33#define buffer_has_space buffer_can_read
34
35bool buffer_seek_set(buffer_t *buffer, size_t offset)
36{
37 if (offset > buffer->size) {
38 return false;
39 }
40
41 buffer->offset = offset;
42
43 return true;
44}
45
46bool buffer_seek_cur(buffer_t *buffer, size_t offset)
47{
48 if (buffer->offset + offset < buffer->offset || // overflow
49 buffer->offset + offset > buffer->size) { // exceed buffer size
50 return false;
51 }
52
53 buffer->offset += offset;
54
55 return true;
56}
57
58bool buffer_seek_end(buffer_t *buffer, size_t offset)
59{
60 if (offset > buffer->size) {
61 return false;
62 }
63
64 buffer->offset = buffer->size - offset;
65
66 return true;
67}
68
69bool buffer_read_u8(buffer_t *buffer, uint8_t *value)
70{
71 if (!buffer_can_read(buffer, 1)) {
72 *value = 0;
73
74 return false;
75 }
76
77 *value = buffer->ptr[buffer->offset];
78 buffer_seek_cur(buffer, 1);
79
80 return true;
81}
82
83bool buffer_read_u16(buffer_t *buffer, uint16_t *value, endianness_t endianness)
84{
85 if (!buffer_can_read(buffer, 2)) {
86 *value = 0;
87
88 return false;
89 }
90
91 *value = ((endianness == BE) ? read_u16_be(buffer->ptr, buffer->offset)
92 : read_u16_le(buffer->ptr, buffer->offset));
93
94 buffer_seek_cur(buffer, 2);
95
96 return true;
97}
98
99bool buffer_read_u32(buffer_t *buffer, uint32_t *value, endianness_t endianness)
100{
101 if (!buffer_can_read(buffer, 4)) {
102 *value = 0;
103
104 return false;
105 }
106
107 *value = ((endianness == BE) ? read_u32_be(buffer->ptr, buffer->offset)
108 : read_u32_le(buffer->ptr, buffer->offset));
109
110 buffer_seek_cur(buffer, 4);
111
112 return true;
113}
114
115bool buffer_read_u64(buffer_t *buffer, uint64_t *value, endianness_t endianness)
116{
117 if (!buffer_can_read(buffer, 8)) {
118 *value = 0;
119
120 return false;
121 }
122
123 *value = ((endianness == BE) ? read_u64_be(buffer->ptr, buffer->offset)
124 : read_u64_le(buffer->ptr, buffer->offset));
125
126 buffer_seek_cur(buffer, 8);
127
128 return true;
129}
130
131bool buffer_read_varint(buffer_t *buffer, uint64_t *value)
132{
133 int length = varint_read(buffer->ptr + buffer->offset, buffer->size - buffer->offset, value);
134
135 if (length < 0) {
136 *value = 0;
137
138 return false;
139 }
140
141 return buffer_seek_cur(buffer, (size_t) length);
142}
143
144bool buffer_read_bip32_path(buffer_t *buffer, uint32_t *out, size_t out_len)
145{
146 if (!bip32_path_read(
147 buffer->ptr + buffer->offset, buffer->size - buffer->offset, out, out_len)) {
148 return false;
149 }
150
151 buffer_seek_cur(buffer, sizeof(*out) * out_len);
152
153 return true;
154}
155
156bool buffer_copy(const buffer_t *buffer, uint8_t *out, size_t out_len)
157{
158 if (buffer->size - buffer->offset > out_len) {
159 return false;
160 }
161
162 memmove(out, buffer->ptr + buffer->offset, buffer->size - buffer->offset);
163
164 return true;
165}
166
167bool buffer_move(buffer_t *buffer, uint8_t *out, size_t out_len)
168{
169 if (!buffer_copy(buffer, out, out_len)) {
170 return false;
171 }
172
173 buffer_seek_cur(buffer, out_len);
174
175 return true;
176}
177
178bool buffer_peek(const buffer_t *buffer, uint8_t *value)
179{
180 return buffer_peek_n(buffer, 0, value);
181}
182
183bool buffer_peek_n(const buffer_t *buffer, size_t n, uint8_t *value)
184{
185 if (buffer->size - buffer->offset < n + 1) {
186 return false;
187 }
188
189 *value = buffer->ptr[buffer->offset + n];
190
191 return true;
192}
193
194WEAK bool buffer_read_bytes(buffer_t *buffer, uint8_t *out, size_t n)
195{
196 if (buffer->size - buffer->offset < n) {
197 return false;
198 }
199
200 memmove(out, buffer->ptr + buffer->offset, n);
201 buffer_seek_cur(buffer, n);
202
203 return true;
204}
205
206bool buffer_write_u8(buffer_t *buffer, uint8_t value)
207{
208 if (!buffer_has_space(buffer, 1)) {
209 return false;
210 }
211
212 (buffer->ptr)[buffer->offset] = value;
213 buffer_seek_cur(buffer, 1);
214
215 return true;
216}
217
218bool buffer_write_u16(buffer_t *buffer, uint16_t value, endianness_t endianness)
219{
220 if (!buffer_has_space(buffer, 2)) {
221 return false;
222 }
223
224 if (endianness == BE) {
225 write_u16_be(buffer->ptr, buffer->offset, value);
226 }
227 else {
228 write_u16_le(buffer->ptr, buffer->offset, value);
229 }
230 buffer_seek_cur(buffer, 2);
231
232 return true;
233}
234
235bool buffer_write_u32(buffer_t *buffer, uint32_t value, endianness_t endianness)
236{
237 if (!buffer_has_space(buffer, 4)) {
238 return false;
239 }
240
241 if (endianness == BE) {
242 write_u32_be(buffer->ptr, buffer->offset, value);
243 }
244 else {
245 write_u32_le(buffer->ptr, buffer->offset, value);
246 }
247 buffer_seek_cur(buffer, 4);
248
249 return true;
250}
251
252bool buffer_write_u64(buffer_t *buffer, uint64_t value, endianness_t endianness)
253{
254 if (!buffer_has_space(buffer, 8)) {
255 return false;
256 }
257
258 if (endianness == BE) {
259 write_u64_be(buffer->ptr, buffer->offset, value);
260 }
261 else {
262 write_u64_le(buffer->ptr, buffer->offset, value);
263 }
264
265 buffer_seek_cur(buffer, 8);
266
267 return true;
268}
269
270bool buffer_write_bytes(buffer_t *buffer, const uint8_t *data, size_t n)
271{
272 if (!buffer_has_space(buffer, n)) {
273 return false;
274 }
275
276 memmove(buffer->ptr + buffer->offset, data, n);
277 buffer_seek_cur(buffer, n);
278 return true;
279}
bool bip32_path_read(const uint8_t *in, size_t in_len, uint32_t *out, size_t out_len)
Definition bip32.c:26
bool buffer_read_varint(buffer_t *buffer, uint64_t *value)
Definition buffer.c:131
bool buffer_seek_end(buffer_t *buffer, size_t offset)
Definition buffer.c:58
bool buffer_read_u16(buffer_t *buffer, uint16_t *value, endianness_t endianness)
Definition buffer.c:83
bool buffer_write_u16(buffer_t *buffer, uint16_t value, endianness_t endianness)
Definition buffer.c:218
bool buffer_copy(const buffer_t *buffer, uint8_t *out, size_t out_len)
Definition buffer.c:156
bool buffer_seek_cur(buffer_t *buffer, size_t offset)
Definition buffer.c:46
bool buffer_read_bip32_path(buffer_t *buffer, uint32_t *out, size_t out_len)
Definition buffer.c:144
bool buffer_write_bytes(buffer_t *buffer, const uint8_t *data, size_t n)
Definition buffer.c:270
bool buffer_seek_set(buffer_t *buffer, size_t offset)
Definition buffer.c:35
bool buffer_can_read(const buffer_t *buffer, size_t n)
Definition buffer.c:28
bool buffer_write_u64(buffer_t *buffer, uint64_t value, endianness_t endianness)
Definition buffer.c:252
bool buffer_peek(const buffer_t *buffer, uint8_t *value)
Definition buffer.c:178
bool buffer_write_u32(buffer_t *buffer, uint32_t value, endianness_t endianness)
Definition buffer.c:235
#define buffer_has_space
Definition buffer.c:33
bool buffer_write_u8(buffer_t *buffer, uint8_t value)
Definition buffer.c:206
bool buffer_read_u64(buffer_t *buffer, uint64_t *value, endianness_t endianness)
Definition buffer.c:115
WEAK bool buffer_read_bytes(buffer_t *buffer, uint8_t *out, size_t n)
Definition buffer.c:194
bool buffer_peek_n(const buffer_t *buffer, size_t n, uint8_t *value)
Definition buffer.c:183
bool buffer_move(buffer_t *buffer, uint8_t *out, size_t out_len)
Definition buffer.c:167
bool buffer_read_u32(buffer_t *buffer, uint32_t *value, endianness_t endianness)
Definition buffer.c:99
bool buffer_read_u8(buffer_t *buffer, uint8_t *value)
Definition buffer.c:69
endianness_t
Definition buffer.h:12
@ BE
Definition buffer.h:13
#define WEAK
Definition macros.h:8
uint32_t read_u32_le(const uint8_t *ptr, size_t offset)
Definition read.c:52
uint64_t read_u64_le(const uint8_t *ptr, size_t offset)
Definition read.c:60
uint16_t read_u16_le(const uint8_t *ptr, size_t offset)
Definition read.c:46
uint32_t read_u32_be(const uint8_t *ptr, size_t offset)
Definition read.c:26
uint64_t read_u64_be(const uint8_t *ptr, size_t offset)
Definition read.c:34
uint16_t read_u16_be(const uint8_t *ptr, size_t offset)
Definition read.c:20
uint8_t * ptr
Definition buffer.h:21
size_t size
Pointer to byte buffer.
Definition buffer.h:22
size_t offset
Size of byte buffer.
Definition buffer.h:23
int varint_read(const uint8_t *in, size_t in_len, uint64_t *value)
Definition varint.c:42
void write_u16_le(uint8_t *ptr, size_t offset, uint16_t value)
Definition write.c:46
void write_u32_be(uint8_t *ptr, size_t offset, uint32_t value)
Definition write.c:26
void write_u16_be(uint8_t *ptr, size_t offset, uint16_t value)
Definition write.c:20
void write_u64_be(uint8_t *ptr, size_t offset, uint64_t value)
Definition write.c:34
void write_u64_le(uint8_t *ptr, size_t offset, uint64_t value)
Definition write.c:60
void write_u32_le(uint8_t *ptr, size_t offset, uint32_t value)
Definition write.c:52