1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- // 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_
|