integers.h 3.0 KB

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