big_endian.cc 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Copyright 2014 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. #include "base/big_endian.h"
  5. #include <string.h>
  6. #include "base/numerics/checked_math.h"
  7. #include "base/strings/string_piece.h"
  8. namespace base {
  9. BigEndianReader BigEndianReader::FromStringPiece(
  10. base::StringPiece string_piece) {
  11. return BigEndianReader(base::as_bytes(base::make_span(string_piece)));
  12. }
  13. BigEndianReader::BigEndianReader(const uint8_t* buf, size_t len)
  14. : ptr_(buf), end_(ptr_ + len) {
  15. // Ensure `len` does not cause `end_` to wrap around.
  16. CHECK_GE(end_, ptr_);
  17. }
  18. BigEndianReader::BigEndianReader(base::span<const uint8_t> buf)
  19. : ptr_(buf.data()), end_(buf.data() + buf.size()) {}
  20. bool BigEndianReader::Skip(size_t len) {
  21. if (len > remaining())
  22. return false;
  23. ptr_ += len;
  24. return true;
  25. }
  26. bool BigEndianReader::ReadBytes(void* out, size_t len) {
  27. if (len > remaining())
  28. return false;
  29. memcpy(out, ptr_, len);
  30. ptr_ += len;
  31. return true;
  32. }
  33. bool BigEndianReader::ReadPiece(base::StringPiece* out, size_t len) {
  34. if (len > remaining())
  35. return false;
  36. *out = base::StringPiece(reinterpret_cast<const char*>(ptr_), len);
  37. ptr_ += len;
  38. return true;
  39. }
  40. bool BigEndianReader::ReadSpan(base::span<const uint8_t>* out, size_t len) {
  41. if (len > remaining())
  42. return false;
  43. *out = base::make_span(ptr_, len);
  44. ptr_ += len;
  45. return true;
  46. }
  47. template<typename T>
  48. bool BigEndianReader::Read(T* value) {
  49. if (sizeof(T) > remaining())
  50. return false;
  51. ReadBigEndian<T>(ptr_, value);
  52. ptr_ += sizeof(T);
  53. return true;
  54. }
  55. bool BigEndianReader::ReadU8(uint8_t* value) {
  56. return Read(value);
  57. }
  58. bool BigEndianReader::ReadU16(uint16_t* value) {
  59. return Read(value);
  60. }
  61. bool BigEndianReader::ReadU32(uint32_t* value) {
  62. return Read(value);
  63. }
  64. bool BigEndianReader::ReadU64(uint64_t* value) {
  65. return Read(value);
  66. }
  67. template <typename T>
  68. bool BigEndianReader::ReadLengthPrefixed(base::StringPiece* out) {
  69. T t_len;
  70. if (!Read(&t_len))
  71. return false;
  72. size_t len = strict_cast<size_t>(t_len);
  73. const uint8_t* original_ptr = ptr_;
  74. if (!Skip(len)) {
  75. ptr_ -= sizeof(T);
  76. return false;
  77. }
  78. *out = base::StringPiece(reinterpret_cast<const char*>(original_ptr), len);
  79. return true;
  80. }
  81. bool BigEndianReader::ReadU8LengthPrefixed(base::StringPiece* out) {
  82. return ReadLengthPrefixed<uint8_t>(out);
  83. }
  84. bool BigEndianReader::ReadU16LengthPrefixed(base::StringPiece* out) {
  85. return ReadLengthPrefixed<uint16_t>(out);
  86. }
  87. BigEndianWriter::BigEndianWriter(char* buf, size_t len)
  88. : ptr_(buf), end_(ptr_ + len) {
  89. // Ensure `len` does not cause `end_` to wrap around.
  90. CHECK_GE(end_, ptr_);
  91. }
  92. bool BigEndianWriter::Skip(size_t len) {
  93. if (len > remaining())
  94. return false;
  95. ptr_ += len;
  96. return true;
  97. }
  98. bool BigEndianWriter::WriteBytes(const void* buf, size_t len) {
  99. if (len > remaining())
  100. return false;
  101. memcpy(ptr_, buf, len);
  102. ptr_ += len;
  103. return true;
  104. }
  105. template<typename T>
  106. bool BigEndianWriter::Write(T value) {
  107. if (sizeof(T) > remaining())
  108. return false;
  109. WriteBigEndian<T>(ptr_, value);
  110. ptr_ += sizeof(T);
  111. return true;
  112. }
  113. bool BigEndianWriter::WriteU8(uint8_t value) {
  114. return Write(value);
  115. }
  116. bool BigEndianWriter::WriteU16(uint16_t value) {
  117. return Write(value);
  118. }
  119. bool BigEndianWriter::WriteU32(uint32_t value) {
  120. return Write(value);
  121. }
  122. bool BigEndianWriter::WriteU64(uint64_t value) {
  123. return Write(value);
  124. }
  125. } // namespace base