194 satır
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* buf, uint32_t value) {
  7. if (port::kLittleEndian) {
  8. memcpy(buf, &value, sizeof(value));
  9. } else {
  10. buf[0] = value & 0xff;
  11. buf[1] = (value >> 8) & 0xff;
  12. buf[2] = (value >> 16) & 0xff;
  13. buf[3] = (value >> 24) & 0xff;
  14. }
  15. }
  16. void EncodeFixed64(char* buf, uint64_t value) {
  17. if (port::kLittleEndian) {
  18. memcpy(buf, &value, sizeof(value));
  19. } else {
  20. buf[0] = value & 0xff;
  21. buf[1] = (value >> 8) & 0xff;
  22. buf[2] = (value >> 16) & 0xff;
  23. buf[3] = (value >> 24) & 0xff;
  24. buf[4] = (value >> 32) & 0xff;
  25. buf[5] = (value >> 40) & 0xff;
  26. buf[6] = (value >> 48) & 0xff;
  27. buf[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-1)) | 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,
  100. const char* limit,
  101. uint32_t* value) {
  102. uint32_t result = 0;
  103. for (uint32_t shift = 0; shift <= 28 && p < limit; shift += 7) {
  104. uint32_t byte = *(reinterpret_cast<const unsigned char*>(p));
  105. p++;
  106. if (byte & 128) {
  107. // More bytes are present
  108. result |= ((byte & 127) << shift);
  109. } else {
  110. result |= (byte << shift);
  111. *value = result;
  112. return reinterpret_cast<const char*>(p);
  113. }
  114. }
  115. return NULL;
  116. }
  117. bool GetVarint32(Slice* input, uint32_t* value) {
  118. const char* p = input->data();
  119. const char* limit = p + input->size();
  120. const char* q = GetVarint32Ptr(p, limit, value);
  121. if (q == NULL) {
  122. return false;
  123. } else {
  124. *input = Slice(q, limit - q);
  125. return true;
  126. }
  127. }
  128. const char* GetVarint64Ptr(const char* p, const char* limit, uint64_t* value) {
  129. uint64_t result = 0;
  130. for (uint32_t shift = 0; shift <= 63 && p < limit; shift += 7) {
  131. uint64_t byte = *(reinterpret_cast<const unsigned char*>(p));
  132. p++;
  133. if (byte & 128) {
  134. // More bytes are present
  135. result |= ((byte & 127) << shift);
  136. } else {
  137. result |= (byte << shift);
  138. *value = result;
  139. return reinterpret_cast<const char*>(p);
  140. }
  141. }
  142. return NULL;
  143. }
  144. bool GetVarint64(Slice* input, uint64_t* value) {
  145. const char* p = input->data();
  146. const char* limit = p + input->size();
  147. const char* q = GetVarint64Ptr(p, limit, value);
  148. if (q == NULL) {
  149. return false;
  150. } else {
  151. *input = Slice(q, limit - q);
  152. return true;
  153. }
  154. }
  155. const char* GetLengthPrefixedSlice(const char* p, const char* limit,
  156. Slice* result) {
  157. uint32_t len;
  158. p = GetVarint32Ptr(p, limit, &len);
  159. if (p == NULL) return NULL;
  160. if (p + len > limit) return NULL;
  161. *result = Slice(p, len);
  162. return p + len;
  163. }
  164. bool GetLengthPrefixedSlice(Slice* input, Slice* result) {
  165. uint32_t len;
  166. if (GetVarint32(input, &len) &&
  167. input->size() >= len) {
  168. *result = Slice(input->data(), len);
  169. input->remove_prefix(len);
  170. return true;
  171. } else {
  172. return false;
  173. }
  174. }
  175. } // namespace leveldb