Embedded SDK
Embedded SDK
Loading...
Searching...
No Matches
varint.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
21#include "varint.h"
22#include "write.h"
23#include "read.h"
24
25uint8_t varint_size(uint64_t value)
26{
27 if (value <= 0xFC) {
28 return 1;
29 }
30
31 if (value <= UINT16_MAX) {
32 return 3;
33 }
34
35 if (value <= UINT32_MAX) {
36 return 5;
37 }
38
39 return 9; // <= UINT64_MAX
40}
41
42int varint_read(const uint8_t *in, size_t in_len, uint64_t *value)
43{
44 if (in_len < 1) {
45 return -1;
46 }
47
48 uint8_t prefix = in[0];
49
50 if (prefix == 0xFD) {
51 if (in_len < 3) {
52 return -1;
53 }
54 *value = (uint64_t) read_u16_le(in, 1);
55 return 3;
56 }
57
58 if (prefix == 0xFE) {
59 if (in_len < 5) {
60 return -1;
61 }
62 *value = (uint64_t) read_u32_le(in, 1);
63 return 5;
64 }
65
66 if (prefix == 0xFF) {
67 if (in_len < 9) {
68 return -1;
69 }
70 *value = (uint64_t) read_u64_le(in, 1);
71 return 9;
72 }
73
74 *value = (uint64_t) prefix; // prefix <= 0xFC
75
76 return 1;
77}
78
79int varint_write(uint8_t *out, size_t offset, uint64_t value)
80{
81 uint8_t varint_len = varint_size(value);
82
83 switch (varint_len) {
84 case 1:
85 out[offset] = (uint8_t) value;
86 break;
87 case 3:
88 out[offset++] = 0xFD;
89 write_u16_le(out, offset, (uint16_t) value);
90 break;
91 case 5:
92 out[offset++] = 0xFE;
93 write_u32_le(out, offset, (uint32_t) value);
94 break;
95 case 9:
96 out[offset++] = 0xFF;
97 write_u64_le(out, offset, (uint64_t) value);
98 break;
99 default:
100 return -1;
101 }
102
103 return varint_len;
104}
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
unsigned short uint16_t
Definition usbd_conf.h:54
unsigned char uint8_t
Definition usbd_conf.h:53
uint8_t varint_size(uint64_t value)
Definition varint.c:25
int varint_write(uint8_t *out, size_t offset, uint64_t value)
Definition varint.c:79
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_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