GeoDesk for C++
Fast and storage-efficient spatial database engine for OpenStreetMap features
Loading...
Searching...
No Matches
varint.h
Go to the documentation of this file.
1// Copyright (c) 2024 Clarisma / GeoDesk contributors
2// SPDX-License-Identifier: LGPL-3.0-only
3
4#pragma once
5
6#include <cassert>
7#include <cstdint>
8#include <string_view>
10
11namespace clarisma {
12
13inline uint64_t readVarint35(const uint8_t*& p)
14{
15 uint32_t val;
16 uint8_t b;
17 b = *p++;
18 val = b & 0x7f;
19 if ((b & 0x80) == 0) return val;
20 b = *p++;
21 val |= static_cast<uint32_t>(b & 0x7f) << 7;
22 if ((b & 0x80) == 0) return val;
23 b = *p++;
24 val |= static_cast<uint32_t>(b & 0x7f) << 14;
25 if ((b & 0x80) == 0) return val;
26 b = *p++;
27 val |= static_cast<uint32_t>(b & 0x7f) << 21;
28 if ((b & 0x80) == 0) return val;
29 b = *p++;
30 val |= static_cast<uint32_t>(b & 0x7f) << 28;
31 assert((b & 0x80) == 0);
32 return val;
33}
34
35inline uint32_t readVarint32(const uint8_t*& p)
36{
37 return static_cast<uint32_t>(readVarint35(p));
38}
39
40// TODO: Read 9 bytes max, last byte does not need a continuation bit
41// 8 x 7 bits = 56 bits, plus final 8 bits means we can store 64 bits
42// in 9 bytes
43
44inline uint64_t readVarint64(const uint8_t*& p)
45{
46 uint64_t val;
47 uint8_t b;
48 b = *p++;
49 val = b & 0x7f;
50 if ((b & 0x80) == 0) return val;
51 b = *p++;
52 val |= static_cast<uint64_t>(b & 0x7f) << 7;
53 if ((b & 0x80) == 0) return val;
54 b = *p++;
55 val |= static_cast<uint64_t>(b & 0x7f) << 14;
56 if ((b & 0x80) == 0) return val;
57 b = *p++;
58 val |= static_cast<uint64_t>(b & 0x7f) << 21;
59 if ((b & 0x80) == 0) return val;
60 b = *p++;
61 val |= static_cast<uint64_t>(b & 0x7f) << 28;
62 if ((b & 0x80) == 0) return val;
63 b = *p++;
64 val |= static_cast<uint64_t>(b & 0x7f) << 35;
65 if ((b & 0x80) == 0) return val;
66 b = *p++;
67 val |= static_cast<uint64_t>(b & 0x7f) << 42;
68 if ((b & 0x80) == 0) return val;
69 b = *p++;
70 val |= static_cast<uint64_t>(b & 0x7f) << 49;
71 if ((b & 0x80) == 0) return val;
72 b = *p++;
73 val |= static_cast<uint64_t>(b & 0x7f) << 56;
74 if ((b & 0x80) == 0) return val;
75 b = *p++;
76 val |= static_cast<uint64_t>(b & 0x7f) << 63;
77 assert((b & 0x80) == 0);
78 return val;
79}
80
81inline int64_t readSignedVarint35(const uint8_t*& p)
82{
83 int64_t val = static_cast<int64_t>(readVarint35(p));
84 return (val >> 1) ^ -(val & 1);
85}
86
87inline int32_t readSignedVarint32(const uint8_t*& p)
88{
89 int64_t val = static_cast<int64_t>(readVarint35(p));
90 return static_cast<int32_t>((val >> 1) ^ -(val & 1));
91}
92
93inline int64_t readSignedVarint64(const uint8_t*& p)
94{
95 int64_t val = static_cast<int64_t>(readVarint64(p));
96 return (val >> 1) ^ -(val & 1);
97}
98
99
100inline std::string_view readStringView(const uint8_t*& p)
101{
102 uint32_t len = readVarint32(p);
103 std::string_view sv(reinterpret_cast<const char*>(p), len);
104 p += len;
105 return sv;
106}
107
108inline int countVarints(const void* pStart, const void* pEnd)
109{
110 int count = 0;
111 const char* p = reinterpret_cast<const char*>(pStart);
112 while (p < pEnd)
113 {
114 if (*p++ >= 0) count++;
115 }
116 return count;
117}
118
119inline void skipVarints(const uint8_t*& p, int count)
120{
121 do
122 {
123 uint8_t b = *p++;
124 count -= (b >> 7) ^ 1;
125 }
126 while (count);
127}
128
129
136inline void skipVarintsBackwardUnsafe(const uint8_t*& p, int count)
137{
138 do
139 {
140 p--;
141 uint8_t b = *(p-1);
142 count -= (b >> 7) ^ 1;
143 }
144 while (count);
145}
146
147// TODO: modify so we can write 64 bits in 9 bytes, no continuation bit in final
148
149inline void writeVarint(uint8_t*& p, uint64_t val)
150{
151 while (val >= 0x80)
152 {
153 *p++ = (val & 0x7f) | 0x80;
154 val >>= 7;
155 }
156 *p++ = static_cast<uint8_t>(val);
157}
158
159
160inline void writeSignedVarint(uint8_t*& p, int64_t val)
161{
162 writeVarint(p, (val << 1) ^ (val >> 63));
163}
164
170inline unsigned int varintSize(uint64_t v)
171{
172 return (64 - Bits::countLeadingZerosInNonZero64(v | 1) + 6) / 7;
173}
174
175
176inline uint64_t toZigzag(int64_t v)
177{
178 return (v << 1) ^ (v >> 63);
179}
180
181inline uint32_t toZigzag(int32_t v)
182{
183 return (v << 1) ^ (v >> 31);
184}
185
186inline int64_t fromZigzag(uint64_t v)
187{
188 return static_cast<int64_t>((v >> 1) ^ -static_cast<int64_t>(v & 1));
189}
190
191inline int32_t fromZigzag(uint32_t v)
192{
193 return static_cast<int32_t>((v >> 1) ^ -static_cast<int32_t>(v & 1));
194}
195
196/*
197
198class Varint
199{
200public:
201 explicit Varint(uint64_t value) : value_(value) {}
202 uint64_t value() const { return value_; }
203
204private:
205 uint64_t value_;
206};
207
208class SignedVarint
209{
210public:
211 explicit SignedVarint(int64_t value) : value_(value) {}
212 int64_t value() const { return value_; }
213
214private:
215 int64_t value_;
216};
217
218template<typename Stream>
219Stream& operator<<(Stream& out, Varint v)
220{
221 uint8_t buf[16];
222 uint8_t* p = buf;
223 writeVarint(p, v.value());
224 out.write(reinterpret_cast<const char*>(buf), p-buf);
225 return static_cast<Stream&>(out);
226}
227
228template<typename Stream>
229Stream& operator<<(Stream& out, SignedVarint v)
230{
231 uint8_t buf[16];
232 uint8_t* p = buf;
233 writeSignedVarint(p, v.value());
234 out.write(reinterpret_cast<const char*>(buf), p-buf);
235 return static_cast<Stream&>(out);
236}
237
238*/
239
240
241
242} // namespace clarisma
Definition Arena.h:17
int countVarints(const void *pStart, const void *pEnd)
Definition varint.h:108
uint64_t readVarint35(const uint8_t *&p)
Definition varint.h:13
void skipVarints(const uint8_t *&p, int count)
Definition varint.h:119
std::string_view readStringView(const uint8_t *&p)
Definition varint.h:100
uint64_t toZigzag(int64_t v)
Definition varint.h:176
void writeSignedVarint(uint8_t *&p, int64_t val)
Definition varint.h:160
int64_t readSignedVarint64(const uint8_t *&p)
Definition varint.h:93
int32_t readSignedVarint32(const uint8_t *&p)
Definition varint.h:87
uint64_t readVarint64(const uint8_t *&p)
Definition varint.h:44
int64_t fromZigzag(uint64_t v)
Definition varint.h:186
unsigned int varintSize(uint64_t v)
Returns the number of bytes required to encode the given unsigned value as a varint (A varint require...
Definition varint.h:170
int64_t readSignedVarint35(const uint8_t *&p)
Definition varint.h:81
uint32_t readVarint32(const uint8_t *&p)
Definition varint.h:35
void skipVarintsBackwardUnsafe(const uint8_t *&p, int count)
Moves pointer backward, skipping over the specified numbers of varints.
Definition varint.h:136
void writeVarint(uint8_t *&p, uint64_t val)
Definition varint.h:149