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