小组成员:谢瑞阳、徐翔宇
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

192 line
4.8 KiB

  1. // Copyright (c) 2011 The LevelDB 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. See the AUTHORS file for names of contributors.
  4. #include "util/coding.h"
  5. namespace leveldb {
  6. void EncodeFixed32(char* dst, uint32_t value) {
  7. if (port::kLittleEndian) {
  8. memcpy(dst, &value, sizeof(value));
  9. } else {
  10. dst[0] = value & 0xff;
  11. dst[1] = (value >> 8) & 0xff;
  12. dst[2] = (value >> 16) & 0xff;
  13. dst[3] = (value >> 24) & 0xff;
  14. }
  15. }
  16. void EncodeFixed64(char* dst, uint64_t value) {
  17. if (port::kLittleEndian) {
  18. memcpy(dst, &value, sizeof(value));
  19. } else {
  20. dst[0] = value & 0xff;
  21. dst[1] = (value >> 8) & 0xff;
  22. dst[2] = (value >> 16) & 0xff;
  23. dst[3] = (value >> 24) & 0xff;
  24. dst[4] = (value >> 32) & 0xff;
  25. dst[5] = (value >> 40) & 0xff;
  26. dst[6] = (value >> 48) & 0xff;
  27. dst[7] = (value >> 56) & 0xff;
  28. }
  29. }
  30. void PutFixed32(std::string* dst, uint32_t value) {
  31. char buf[sizeof(value)];
  32. EncodeFixed32(buf, value);
  33. dst->append(buf, sizeof(buf));
  34. }
  35. void PutFixed64(std::string* dst, uint64_t value) {
  36. char buf[sizeof(value)];
  37. EncodeFixed64(buf, value);
  38. dst->append(buf, sizeof(buf));
  39. }
  40. char* EncodeVarint32(char* dst, uint32_t v) {
  41. // Operate on characters as unsigneds
  42. unsigned char* ptr = reinterpret_cast<unsigned char*>(dst);
  43. static const int B = 128;
  44. if (v < (1 << 7)) {
  45. *(ptr++) = v;
  46. } else if (v < (1 << 14)) {
  47. *(ptr++) = v | B;
  48. *(ptr++) = v >> 7;
  49. } else if (v < (1 << 21)) {
  50. *(ptr++) = v | B;
  51. *(ptr++) = (v >> 7) | B;
  52. *(ptr++) = v >> 14;
  53. } else if (v < (1 << 28)) {
  54. *(ptr++) = v | B;
  55. *(ptr++) = (v >> 7) | B;
  56. *(ptr++) = (v >> 14) | B;
  57. *(ptr++) = v >> 21;
  58. } else {
  59. *(ptr++) = v | B;
  60. *(ptr++) = (v >> 7) | B;
  61. *(ptr++) = (v >> 14) | B;
  62. *(ptr++) = (v >> 21) | B;
  63. *(ptr++) = v >> 28;
  64. }
  65. return reinterpret_cast<char*>(ptr);
  66. }
  67. void PutVarint32(std::string* dst, uint32_t v) {
  68. char buf[5];
  69. char* ptr = EncodeVarint32(buf, v);
  70. dst->append(buf, ptr - buf);
  71. }
  72. char* EncodeVarint64(char* dst, uint64_t v) {
  73. static const int B = 128;
  74. unsigned char* ptr = reinterpret_cast<unsigned char*>(dst);
  75. while (v >= B) {
  76. *(ptr++) = v | B;
  77. v >>= 7;
  78. }
  79. *(ptr++) = static_cast<unsigned char>(v);
  80. return reinterpret_cast<char*>(ptr);
  81. }
  82. void PutVarint64(std::string* dst, uint64_t v) {
  83. char buf[10];
  84. char* ptr = EncodeVarint64(buf, v);
  85. dst->append(buf, ptr - buf);
  86. }
  87. void PutLengthPrefixedSlice(std::string* dst, const Slice& value) {
  88. PutVarint32(dst, value.size());
  89. dst->append(value.data(), value.size());
  90. }
  91. int VarintLength(uint64_t v) {
  92. int len = 1;
  93. while (v >= 128) {
  94. v >>= 7;
  95. len++;
  96. }
  97. return len;
  98. }
  99. const char* GetVarint32PtrFallback(const char* p, const char* limit,
  100. uint32_t* value) {
  101. uint32_t result = 0;
  102. for (uint32_t shift = 0; shift <= 28 && p < limit; shift += 7) {
  103. uint32_t byte = *(reinterpret_cast<const unsigned char*>(p));
  104. p++;
  105. if (byte & 128) {
  106. // More bytes are present
  107. result |= ((byte & 127) << shift);
  108. } else {
  109. result |= (byte << shift);
  110. *value = result;
  111. return reinterpret_cast<const char*>(p);
  112. }
  113. }
  114. return nullptr;
  115. }
  116. bool GetVarint32(Slice* input, uint32_t* value) {
  117. const char* p = input->data();
  118. const char* limit = p + input->size();
  119. const char* q = GetVarint32Ptr(p, limit, value);
  120. if (q == nullptr) {
  121. return false;
  122. } else {
  123. *input = Slice(q, limit - q);
  124. return true;
  125. }
  126. }
  127. const char* GetVarint64Ptr(const char* p, const char* limit, uint64_t* value) {
  128. uint64_t result = 0;
  129. for (uint32_t shift = 0; shift <= 63 && p < limit; shift += 7) {
  130. uint64_t byte = *(reinterpret_cast<const unsigned char*>(p));
  131. p++;
  132. if (byte & 128) {
  133. // More bytes are present
  134. result |= ((byte & 127) << shift);
  135. } else {
  136. result |= (byte << shift);
  137. *value = result;
  138. return reinterpret_cast<const char*>(p);
  139. }
  140. }
  141. return nullptr;
  142. }
  143. bool GetVarint64(Slice* input, uint64_t* value) {
  144. const char* p = input->data();
  145. const char* limit = p + input->size();
  146. const char* q = GetVarint64Ptr(p, limit, value);
  147. if (q == nullptr) {
  148. return false;
  149. } else {
  150. *input = Slice(q, limit - q);
  151. return true;
  152. }
  153. }
  154. const char* GetLengthPrefixedSlice(const char* p, const char* limit,
  155. Slice* result) {
  156. uint32_t len;
  157. p = GetVarint32Ptr(p, limit, &len);
  158. if (p == nullptr) return nullptr;
  159. if (p + len > limit) return nullptr;
  160. *result = Slice(p, len);
  161. return p + len;
  162. }
  163. bool GetLengthPrefixedSlice(Slice* input, Slice* result) {
  164. uint32_t len;
  165. if (GetVarint32(input, &len) && input->size() >= len) {
  166. *result = Slice(input->data(), len);
  167. input->remove_prefix(len);
  168. return true;
  169. } else {
  170. return false;
  171. }
  172. }
  173. } // namespace leveldb