libosmscout 1.1.1
Loading...
Searching...
No Matches
Number.h
Go to the documentation of this file.
1#ifndef OSMSCOUT_NUMBER_H
2#define OSMSCOUT_NUMBER_H
3
4/*
5 This source is part of the libosmscout library
6 Copyright (C) 2009 Tim Teulings
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/
22
24
25#include <array>
26#include <limits>
27#include <cstddef>
28#include <cassert>
29
31
32namespace osmscout {
33
49 template<typename N>
50 inline unsigned int EncodeNumberSigned(N number,
51 char* buffer)
52 {
53 unsigned int bytes=1;
54 char val;
55
56 if (number<0) {
57 number^=static_cast<N>(-1);
58 val=static_cast<char>((number & 0x3fu) << 1 | 0x01u);
59 }
60 else {
61 val=static_cast<char>((number & 0x3fu) << 1);
62 }
63
64 number>>=6;
65
66 while (number!=0) {
67 *(buffer++)=val | 0x80u;
68 val=static_cast<char>(number & 0x7fu);
69 number>>=7;
70 bytes++;
71 }
72
73 *buffer=val;
74 return bytes;
75 }
76
91 template<typename N>
92 inline unsigned int EncodeNumberUnsigned(N number,
93 char* buffer)
94 {
95 unsigned int bytes=0;
96
97 while (number>0x7f) {
98 buffer[bytes]=static_cast<char>((number & 0x7f) | 0x80);
99 number>>=7;
100 bytes++;
101 }
102
103 buffer[bytes]=static_cast<char>(number);
104 bytes++;
105
106 return bytes;
107 }
108
109 template<bool is_signed, typename N>
111 {
112 };
113
114 template<typename N>
115 struct EncodeNumberTemplated<true, N>
116 {
117 static inline unsigned int f(N number,char* buffer)
118 {
119 return EncodeNumberSigned<N>(number,buffer);
120 }
121 };
122
123 template<typename N>
124 struct EncodeNumberTemplated<false, N>
125 {
126 static inline unsigned int f(N number,char* buffer)
127 {
128 return EncodeNumberUnsigned<N>(number,buffer);
129 }
130 };
131
144 template<typename N>
145 inline unsigned int EncodeNumber(N number,
146 char* buffer)
147 {
149 ::f(number,buffer);
150 }
151
164 template<typename N, size_t S>
165 inline unsigned int EncodeNumber(N number,
166 std::array<char, S> &buffer)
167 {
168 if constexpr (std::numeric_limits<N>::is_signed) {
169 static_assert(sizeof(N) * 64 + 7 <= S * 56, "Not enough big buffer for encoding signed number");
170 } else {
171 static_assert(sizeof(N) * 64 <= S * 56, "Not enough big buffer for encoding unsigned number");
172 }
174 ::f(number,buffer.data());
175 assert(dataWritten<=S);
176 return dataWritten;
177 }
178
186 template<typename N>
187 inline unsigned int DecodeNumberSigned(const char* buffer,
188 N& number)
189 {
190 unsigned int shift=0;
191 unsigned int nextShift=0;
192 unsigned int bytes=1;
193
194 // negative form
195 if ((*buffer & 0x01u)!=0) {
196 N val=(*buffer & 0x7eu) >> 1;
197
198 number=-1;
199 nextShift=6;
200
201 while ((*(buffer++) & 0x80u)!=0) {
202 number^=(val << shift);
203 val=*buffer & 0x7fu;
204 shift=nextShift;
205 nextShift+=7;
206 bytes++;
207 }
208
209 number^=static_cast<N>(val) << shift;
210 }
211 else {
212 N val=(*buffer & 0x7eu) >> 1;
213
214 number=0;
215 nextShift=6;
216
217 while ((*(buffer++) & 0x80u)!=0) {
218 number|=(val << shift);
219 val=*buffer & 0x7fu;
220 shift=nextShift;
221 nextShift+=7;
222 bytes++;
223 }
224
225 number|=static_cast<N>(val) << shift;
226 }
227
228 return bytes;
229 }
230
238 template<typename N>
239 inline unsigned int DecodeNumberUnsigned(const char* buffer,
240 N& number)
241 {
242 unsigned int shift=0;
243 unsigned int bytes=1;
244
245 number=0;
246
247 while (true) {
248 number|=static_cast<N>(*buffer & 0x7f) << shift;
249
250 if (((*buffer) & 0x80)==0) {
251 return bytes;
252 }
253
254 bytes++;
255 buffer++;
256 shift+=7;
257 }
258
259 // Only for the compiler...
260 return bytes;
261 }
262
263 template<bool is_signed, typename N>
265 {
266 };
267
268 template<typename N>
269 struct DecodeNumberTemplated<true, N>
270 {
271 static inline unsigned int f(const char* buffer, N& number)
272 {
273 return DecodeNumberSigned<N>(buffer,number);
274 }
275 };
276
277 template<typename N>
278 struct DecodeNumberTemplated<false, N>
279 {
280 static inline unsigned int f(const char* buffer, N& number)
281 {
282 return DecodeNumberUnsigned<N>(buffer,number);
283 }
284 };
285
293 template<typename N>
294 inline unsigned int DecodeNumber(const char* buffer,
295 N& number)
296 {
298 ::f(buffer,number);
299 }
300
305 template<typename N>
306 inline N BitsToBytes(N bits)
307 {
308 return bits%8==0 ? bits/8 : bits/8+1;
309 }
310
317 template<typename N>
319 {
320 uint8_t bytes=0;
321
322 while (number!=0) {
323 number=number/256;
324 bytes++;
325 }
326
327 if (bytes==0) {
328 bytes=1;
329 }
330
331 return bytes;
332 }
333
340 template<typename N>
341 uint8_t BitsNeededToEncodeNumber(N number)
342 {
343 uint8_t bits=0;
344
345 while (number!=0) {
346 number=number/2;
347 bits++;
348 }
349
350 if (bits==0) {
351 bits=1;
352 }
353
354 return bits;
355 }
356
366 extern OSMSCOUT_API uint64_t InterleaveNumbers(uint32_t a,
367 uint32_t b);
368}
369
370#endif
#define OSMSCOUT_API
Definition CoreImportExport.h:45
unsigned int DecodeNumber(const char *buffer, N &number)
Definition Number.h:294
unsigned int DecodeNumberUnsigned(const char *buffer, N &number)
Definition Number.h:239
uint8_t BytesNeededToEncodeNumber(N number)
Definition Number.h:318
N BitsToBytes(N bits)
Definition Number.h:306
unsigned int EncodeNumberUnsigned(N number, char *buffer)
Definition Number.h:92
OSMSCOUT_API uint64_t InterleaveNumbers(uint32_t a, uint32_t b)
unsigned int EncodeNumber(N number, char *buffer)
Definition Number.h:145
unsigned int DecodeNumberSigned(const char *buffer, N &number)
Definition Number.h:187
unsigned int EncodeNumberSigned(N number, char *buffer)
Definition Number.h:50
uint8_t BitsNeededToEncodeNumber(N number)
Definition Number.h:341
Definition Area.h:39
static unsigned int f(const char *buffer, N &number)
Definition Number.h:280
static unsigned int f(const char *buffer, N &number)
Definition Number.h:271
Definition Number.h:265
static unsigned int f(N number, char *buffer)
Definition Number.h:126
static unsigned int f(N number, char *buffer)
Definition Number.h:117
Definition Number.h:111