forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
integers.h
77 lines (67 loc) · 3.04 KB
/
integers.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SQL_RECOVER_MODULE_INTEGERS_H_
#define SQL_RECOVER_MODULE_INTEGERS_H_
#include <cstdint>
#include <limits>
#include <utility>
namespace sql {
namespace recover {
// Reads an unsigned 16-bit big-endian integer from the given buffer.
//
// |buffer| must point to at least two consecutive bytes of valid memory.
//
// The return type was chosen because it suits the callers best.
inline int LoadBigEndianUint16(const uint8_t* buffer) {
static_assert(
std::numeric_limits<uint16_t>::max() <= std::numeric_limits<int>::max(),
"The value may overflow the return type");
return (static_cast<int>(buffer[0]) << 8) | static_cast<int>(buffer[1]);
}
// Reads a signed 32-bit big-endian integer from the given buffer.
//
// |buffer| must point to at least four consecutive bytes of valid memory.
inline int32_t LoadBigEndianInt32(const uint8_t* buffer) {
// The code gets optimized to mov + bswap on x86_64, and to ldr + rev on ARM.
return (static_cast<int32_t>(buffer[0]) << 24) |
(static_cast<int32_t>(buffer[1]) << 16) |
(static_cast<int32_t>(buffer[2]) << 8) |
static_cast<int32_t>(buffer[3]);
}
// Reads a signed 64-bit big-endian integer from the given buffer.
//
// |buffer| must point to at least eight consecutive bytes of valid memory.
inline int64_t LoadBigEndianInt64(const uint8_t* buffer) {
// The code gets optimized to mov + bswap on x86_64, and to ldr + rev on ARM.
return (static_cast<int64_t>(buffer[0]) << 56) |
(static_cast<int64_t>(buffer[1]) << 48) |
(static_cast<int64_t>(buffer[2]) << 40) |
(static_cast<int64_t>(buffer[3]) << 32) |
(static_cast<int64_t>(buffer[4]) << 24) |
(static_cast<int64_t>(buffer[5]) << 16) |
(static_cast<int64_t>(buffer[6]) << 8) |
static_cast<int64_t>(buffer[7]);
}
// Reads a SQLite varint.
//
// SQLite varints decode to 64-bit integers, and take up at most 9 bytes.
// If present, the 9th byte holds bits 56-63 of the integer. This deviates from
// Google (protobuf, leveldb) varint encoding, where the last varint byte's top
// bit is always 0.
//
// The implementation assumes that |buffer| and |buffer_end| point into the same
// array of bytes, and that |buffer| < |buffer_end|. The implementation will
// never compute a pointer value larger than |buffer_end|.
//
// Returns the parsed number and a pointer to the first byte past the number.
// Per the rules above, the returned pointer is guaranteed to be between
// |buffer| and |buffer_end|. The returned pointer is also guaranteed to be at
// most |kMaxVarintSize| bytes past |buffer|.
std::pair<int64_t, const uint8_t*> ParseVarint(const uint8_t* buffer,
const uint8_t* buffer_end);
// The maximum number of bytes used to store a SQLite varint.
constexpr int kMaxVarintSize = 9;
} // namespace recover
} // namespace sql
#endif // SQL_RECOVER_MODULE_INTEGERS_H_