// 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 #include #include 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::max() <= std::numeric_limits::max(), "The value may overflow the return type"); return (static_cast(buffer[0]) << 8) | static_cast(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(buffer[0]) << 24) | (static_cast(buffer[1]) << 16) | (static_cast(buffer[2]) << 8) | static_cast(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(buffer[0]) << 56) | (static_cast(buffer[1]) << 48) | (static_cast(buffer[2]) << 40) | (static_cast(buffer[3]) << 32) | (static_cast(buffer[4]) << 24) | (static_cast(buffer[5]) << 16) | (static_cast(buffer[6]) << 8) | static_cast(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 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_