CodedOutputData.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * Tencent is pleased to support the open source community by making
  3. * MMKV available.
  4. *
  5. * Copyright (C) 2018 THL A29 Limited, a Tencent company.
  6. * All rights reserved.
  7. *
  8. * Licensed under the BSD 3-Clause License (the "License"); you may not use
  9. * this file except in compliance with the License. You may obtain a copy of
  10. * the License at
  11. *
  12. * https://opensource.org/licenses/BSD-3-Clause
  13. *
  14. * Unless required by applicable law or agreed to in writing, software
  15. * distributed under the License is distributed on an "AS IS" BASIS,
  16. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. * See the License for the specific language governing permissions and
  18. * limitations under the License.
  19. */
  20. #include "CodedOutputData.h"
  21. #include "PBUtility.h"
  22. #include <cstring>
  23. #include <stdexcept>
  24. #ifdef MMKV_APPLE
  25. # if __has_feature(objc_arc)
  26. # error This file must be compiled with MRC. Use -fno-objc-arc flag.
  27. # endif
  28. #endif // MMKV_APPLE
  29. using namespace std;
  30. namespace mmkv {
  31. CodedOutputData::CodedOutputData(void *ptr, size_t len) : m_ptr((uint8_t *) ptr), m_size(len), m_position(0) {
  32. MMKV_ASSERT(m_ptr);
  33. }
  34. uint8_t *CodedOutputData::curWritePointer() {
  35. return m_ptr + m_position;
  36. }
  37. void CodedOutputData::writeDouble(double value) {
  38. this->writeRawLittleEndian64(Float64ToInt64(value));
  39. }
  40. void CodedOutputData::writeFloat(float value) {
  41. this->writeRawLittleEndian32(Float32ToInt32(value));
  42. }
  43. void CodedOutputData::writeInt64(int64_t value) {
  44. this->writeRawVarint64(value);
  45. }
  46. void CodedOutputData::writeUInt64(uint64_t value) {
  47. writeRawVarint64(static_cast<int64_t>(value));
  48. }
  49. void CodedOutputData::writeInt32(int32_t value) {
  50. if (value >= 0) {
  51. this->writeRawVarint32(value);
  52. } else {
  53. this->writeRawVarint64(value);
  54. }
  55. }
  56. void CodedOutputData::writeUInt32(uint32_t value) {
  57. writeRawVarint32(static_cast<int32_t>(value));
  58. }
  59. void CodedOutputData::writeBool(bool value) {
  60. this->writeRawByte(static_cast<uint8_t>(value ? 1 : 0));
  61. }
  62. void CodedOutputData::writeData(const MMBuffer &value) {
  63. this->writeRawVarint32((int32_t) value.length());
  64. this->writeRawData(value);
  65. }
  66. #ifndef MMKV_APPLE
  67. void CodedOutputData::writeString(const string &value) {
  68. size_t numberOfBytes = value.size();
  69. this->writeRawVarint32((int32_t) numberOfBytes);
  70. if (m_position + numberOfBytes > m_size) {
  71. auto msg = "m_position: " + to_string(m_position) + ", numberOfBytes: " + to_string(numberOfBytes) +
  72. ", m_size: " + to_string(m_size);
  73. throw out_of_range(msg);
  74. }
  75. memcpy(m_ptr + m_position, ((uint8_t *) value.data()), numberOfBytes);
  76. m_position += numberOfBytes;
  77. }
  78. #endif // MMKV_APPLE
  79. size_t CodedOutputData::spaceLeft() {
  80. if (m_size <= m_position) {
  81. return 0;
  82. }
  83. return m_size - m_position;
  84. }
  85. void CodedOutputData::seek(size_t addedSize) {
  86. m_position += addedSize;
  87. if (m_position > m_size) {
  88. throw out_of_range("OutOfSpace");
  89. }
  90. }
  91. void CodedOutputData::writeRawByte(uint8_t value) {
  92. if (m_position == m_size) {
  93. throw out_of_range("m_position: " + to_string(m_position) + " m_size: " + to_string(m_size));
  94. return;
  95. }
  96. m_ptr[m_position++] = value;
  97. }
  98. void CodedOutputData::writeRawData(const MMBuffer &data) {
  99. size_t numberOfBytes = data.length();
  100. if (m_position + numberOfBytes > m_size) {
  101. auto msg = "m_position: " + to_string(m_position) + ", numberOfBytes: " + to_string(numberOfBytes) +
  102. ", m_size: " + to_string(m_size);
  103. throw out_of_range(msg);
  104. }
  105. memcpy(m_ptr + m_position, data.getPtr(), numberOfBytes);
  106. m_position += numberOfBytes;
  107. }
  108. void CodedOutputData::writeRawVarint32(int32_t value) {
  109. while (true) {
  110. if ((value & ~0x7f) == 0) {
  111. this->writeRawByte(static_cast<uint8_t>(value));
  112. return;
  113. } else {
  114. this->writeRawByte(static_cast<uint8_t>((value & 0x7F) | 0x80));
  115. value = logicalRightShift32(value, 7);
  116. }
  117. }
  118. }
  119. void CodedOutputData::writeRawVarint64(int64_t value) {
  120. while (true) {
  121. if ((value & ~0x7f) == 0) {
  122. this->writeRawByte(static_cast<uint8_t>(value));
  123. return;
  124. } else {
  125. this->writeRawByte(static_cast<uint8_t>((value & 0x7f) | 0x80));
  126. value = logicalRightShift64(value, 7);
  127. }
  128. }
  129. }
  130. void CodedOutputData::writeRawLittleEndian32(int32_t value) {
  131. this->writeRawByte(static_cast<uint8_t>((value) &0xff));
  132. this->writeRawByte(static_cast<uint8_t>((value >> 8) & 0xff));
  133. this->writeRawByte(static_cast<uint8_t>((value >> 16) & 0xff));
  134. this->writeRawByte(static_cast<uint8_t>((value >> 24) & 0xff));
  135. }
  136. void CodedOutputData::writeRawLittleEndian64(int64_t value) {
  137. this->writeRawByte(static_cast<uint8_t>((value) &0xff));
  138. this->writeRawByte(static_cast<uint8_t>((value >> 8) & 0xff));
  139. this->writeRawByte(static_cast<uint8_t>((value >> 16) & 0xff));
  140. this->writeRawByte(static_cast<uint8_t>((value >> 24) & 0xff));
  141. this->writeRawByte(static_cast<uint8_t>((value >> 32) & 0xff));
  142. this->writeRawByte(static_cast<uint8_t>((value >> 40) & 0xff));
  143. this->writeRawByte(static_cast<uint8_t>((value >> 48) & 0xff));
  144. this->writeRawByte(static_cast<uint8_t>((value >> 56) & 0xff));
  145. }
  146. } // namespace mmkv