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.
5 #include "util/coding.h"
9 void EncodeFixed32(char* buf
, uint32_t value
) {
10 if (port::kLittleEndian
) {
11 memcpy(buf
, &value
, sizeof(value
));
13 buf
[0] = value
& 0xff;
14 buf
[1] = (value
>> 8) & 0xff;
15 buf
[2] = (value
>> 16) & 0xff;
16 buf
[3] = (value
>> 24) & 0xff;
20 void EncodeFixed64(char* buf
, uint64_t value
) {
21 if (port::kLittleEndian
) {
22 memcpy(buf
, &value
, sizeof(value
));
24 buf
[0] = value
& 0xff;
25 buf
[1] = (value
>> 8) & 0xff;
26 buf
[2] = (value
>> 16) & 0xff;
27 buf
[3] = (value
>> 24) & 0xff;
28 buf
[4] = (value
>> 32) & 0xff;
29 buf
[5] = (value
>> 40) & 0xff;
30 buf
[6] = (value
>> 48) & 0xff;
31 buf
[7] = (value
>> 56) & 0xff;
35 void PutFixed32(std::string
* dst
, uint32_t value
) {
36 char buf
[sizeof(value
)];
37 EncodeFixed32(buf
, value
);
38 dst
->append(buf
, sizeof(buf
));
41 void PutFixed64(std::string
* dst
, uint64_t value
) {
42 char buf
[sizeof(value
)];
43 EncodeFixed64(buf
, value
);
44 dst
->append(buf
, sizeof(buf
));
47 char* EncodeVarint32(char* dst
, uint32_t v
) {
48 // Operate on characters as unsigneds
49 unsigned char* ptr
= reinterpret_cast<unsigned char*>(dst
);
50 static const int B
= 128;
53 } else if (v
< (1<<14)) {
56 } else if (v
< (1<<21)) {
58 *(ptr
++) = (v
>>7) | B
;
60 } else if (v
< (1<<28)) {
62 *(ptr
++) = (v
>>7) | B
;
63 *(ptr
++) = (v
>>14) | B
;
67 *(ptr
++) = (v
>>7) | B
;
68 *(ptr
++) = (v
>>14) | B
;
69 *(ptr
++) = (v
>>21) | B
;
72 return reinterpret_cast<char*>(ptr
);
75 void PutVarint32(std::string
* dst
, uint32_t v
) {
77 char* ptr
= EncodeVarint32(buf
, v
);
78 dst
->append(buf
, ptr
- buf
);
81 char* EncodeVarint64(char* dst
, uint64_t v
) {
82 static const int B
= 128;
83 unsigned char* ptr
= reinterpret_cast<unsigned char*>(dst
);
85 *(ptr
++) = (v
& (B
-1)) | B
;
88 *(ptr
++) = static_cast<unsigned char>(v
);
89 return reinterpret_cast<char*>(ptr
);
92 void PutVarint64(std::string
* dst
, uint64_t v
) {
94 char* ptr
= EncodeVarint64(buf
, v
);
95 dst
->append(buf
, ptr
- buf
);
98 void PutLengthPrefixedSlice(std::string
* dst
, const Slice
& value
) {
99 PutVarint32(dst
, value
.size());
100 dst
->append(value
.data(), value
.size());
103 int VarintLength(uint64_t v
) {
112 const char* GetVarint32PtrFallback(const char* p
,
116 for (uint32_t shift
= 0; shift
<= 28 && p
< limit
; shift
+= 7) {
117 uint32_t byte
= *(reinterpret_cast<const unsigned char*>(p
));
120 // More bytes are present
121 result
|= ((byte
& 127) << shift
);
123 result
|= (byte
<< shift
);
125 return reinterpret_cast<const char*>(p
);
131 bool GetVarint32(Slice
* input
, uint32_t* value
) {
132 const char* p
= input
->data();
133 const char* limit
= p
+ input
->size();
134 const char* q
= GetVarint32Ptr(p
, limit
, value
);
138 *input
= Slice(q
, limit
- q
);
143 const char* GetVarint64Ptr(const char* p
, const char* limit
, uint64_t* value
) {
145 for (uint32_t shift
= 0; shift
<= 63 && p
< limit
; shift
+= 7) {
146 uint64_t byte
= *(reinterpret_cast<const unsigned char*>(p
));
149 // More bytes are present
150 result
|= ((byte
& 127) << shift
);
152 result
|= (byte
<< shift
);
154 return reinterpret_cast<const char*>(p
);
160 bool GetVarint64(Slice
* input
, uint64_t* value
) {
161 const char* p
= input
->data();
162 const char* limit
= p
+ input
->size();
163 const char* q
= GetVarint64Ptr(p
, limit
, value
);
167 *input
= Slice(q
, limit
- q
);
172 const char* GetLengthPrefixedSlice(const char* p
, const char* limit
,
175 p
= GetVarint32Ptr(p
, limit
, &len
);
176 if (p
== NULL
) return NULL
;
177 if (p
+ len
> limit
) return NULL
;
178 *result
= Slice(p
, len
);
182 bool GetLengthPrefixedSlice(Slice
* input
, Slice
* result
) {
184 if (GetVarint32(input
, &len
) &&
185 input
->size() >= len
) {
186 *result
= Slice(input
->data(), len
);
187 input
->remove_prefix(len
);
194 } // namespace leveldb