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