libosmscout
1.1.1
Toggle main menu visibility
Loading...
Searching...
No Matches
libosmscout
include
osmscout
util
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
23
#include <
osmscout/lib/CoreImportExport.h
>
24
25
#include <array>
26
#include <limits>
27
#include <cstddef>
28
#include <cassert>
29
30
#include <
osmscout/system/SystemTypes.h
>
31
32
namespace
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>
110
struct
EncodeNumberTemplated
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
{
148
return
EncodeNumberTemplated<std::numeric_limits<N>::is_signed
, N>
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
}
173
auto
dataWritten =
EncodeNumberTemplated<std::numeric_limits<N>::is_signed
, N>
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>
264
struct
DecodeNumberTemplated
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
{
297
return
DecodeNumberTemplated<std::numeric_limits<N>::is_signed
, N>
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>
318
uint8_t
BytesNeededToEncodeNumber
(N number)
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
CoreImportExport.h
OSMSCOUT_API
#define OSMSCOUT_API
Definition
CoreImportExport.h:45
SystemTypes.h
osmscout::DecodeNumber
unsigned int DecodeNumber(const char *buffer, N &number)
Definition
Number.h:294
osmscout::DecodeNumberUnsigned
unsigned int DecodeNumberUnsigned(const char *buffer, N &number)
Definition
Number.h:239
osmscout::BytesNeededToEncodeNumber
uint8_t BytesNeededToEncodeNumber(N number)
Definition
Number.h:318
osmscout::BitsToBytes
N BitsToBytes(N bits)
Definition
Number.h:306
osmscout::EncodeNumberUnsigned
unsigned int EncodeNumberUnsigned(N number, char *buffer)
Definition
Number.h:92
osmscout::InterleaveNumbers
OSMSCOUT_API uint64_t InterleaveNumbers(uint32_t a, uint32_t b)
osmscout::EncodeNumber
unsigned int EncodeNumber(N number, char *buffer)
Definition
Number.h:145
osmscout::DecodeNumberSigned
unsigned int DecodeNumberSigned(const char *buffer, N &number)
Definition
Number.h:187
osmscout::EncodeNumberSigned
unsigned int EncodeNumberSigned(N number, char *buffer)
Definition
Number.h:50
osmscout::BitsNeededToEncodeNumber
uint8_t BitsNeededToEncodeNumber(N number)
Definition
Number.h:341
osmscout
Definition
Area.h:39
osmscout::DecodeNumberTemplated< false, N >::f
static unsigned int f(const char *buffer, N &number)
Definition
Number.h:280
osmscout::DecodeNumberTemplated< true, N >::f
static unsigned int f(const char *buffer, N &number)
Definition
Number.h:271
osmscout::DecodeNumberTemplated
Definition
Number.h:265
osmscout::EncodeNumberTemplated< false, N >::f
static unsigned int f(N number, char *buffer)
Definition
Number.h:126
osmscout::EncodeNumberTemplated< true, N >::f
static unsigned int f(N number, char *buffer)
Definition
Number.h:117
osmscout::EncodeNumberTemplated
Definition
Number.h:111
Generated by
1.17.0