2 * Copyright 2013 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "folly/GroupVarint.h"
20 #include <gtest/gtest.h>
22 using namespace folly;
26 class StringAppender {
28 /* implicit */ StringAppender(std::string& s) : s_(s) { }
29 void operator()(StringPiece sp) {
30 s_.append(sp.data(), sp.size());
36 typedef GroupVarintEncoder<uint32_t, StringAppender> GroupVarint32Encoder;
37 typedef GroupVarintEncoder<uint64_t, StringAppender> GroupVarint64Encoder;
38 typedef GroupVarintDecoder<uint32_t> GroupVarint32Decoder;
39 typedef GroupVarintDecoder<uint32_t> GroupVarint64Decoder;
41 // Expected bytes follow, terminate with -1
42 void testGroupVarint32(uint32_t a, uint32_t b, uint32_t c, uint32_t d, ...) {
45 std::vector<char> expectedBytes;
47 while ((byte = va_arg(ap, int)) != -1) {
48 expectedBytes.push_back(byte);
52 size_t size = GroupVarint32::size(a, b, c, d);
53 EXPECT_EQ(expectedBytes.size(), size);
55 std::vector<char> foundBytes;
56 foundBytes.resize(size + 4);
57 char* start = &(foundBytes.front());
58 char* p = GroupVarint32::encode(start, a, b, c, d);
59 EXPECT_EQ((void*)(start + size), (void*)p);
61 for (size_t i = 0; i < size; i++) {
62 EXPECT_EQ(0xff & expectedBytes[i], 0xff & foundBytes[i]);
66 EXPECT_EQ(size, GroupVarint32::encodedSize(start));
68 uint32_t fa, fb, fc, fd;
69 const char* r = GroupVarint32::decode(start, &fa, &fb, &fc, &fd);
70 EXPECT_EQ((void*)(start + size), (void*)r);
78 void testGroupVarint64(uint64_t a, uint64_t b, uint64_t c, uint64_t d,
82 std::vector<char> expectedBytes;
84 while ((byte = va_arg(ap, int)) != -1) {
85 expectedBytes.push_back(byte);
89 size_t size = GroupVarint64::size(a, b, c, d, e);
90 EXPECT_EQ(expectedBytes.size(), size);
92 std::vector<char> foundBytes;
93 foundBytes.resize(size + 8);
94 char* start = &(foundBytes.front());
95 char* p = GroupVarint64::encode(start, a, b, c, d, e);
96 EXPECT_EQ((void*)(start + size), (void*)p);
98 for (size_t i = 0; i < size; i++) {
99 EXPECT_EQ(0xff & expectedBytes[i], 0xff & foundBytes[i]);
103 EXPECT_EQ(size, GroupVarint64::encodedSize(start));
105 uint64_t fa, fb, fc, fd, fe;
106 const char* r = GroupVarint64::decode(start, &fa, &fb, &fc, &fd, &fe);
107 EXPECT_EQ((void*)(start + size), (void*)r);
118 TEST(GroupVarint, GroupVarint32) {
119 EXPECT_EQ(0, GroupVarint32::maxSize(0));
120 EXPECT_EQ(5, GroupVarint32::maxSize(1));
121 EXPECT_EQ(9, GroupVarint32::maxSize(2));
122 EXPECT_EQ(13, GroupVarint32::maxSize(3));
123 EXPECT_EQ(17, GroupVarint32::maxSize(4));
124 EXPECT_EQ(22, GroupVarint32::maxSize(5));
125 EXPECT_EQ(26, GroupVarint32::maxSize(6));
126 testGroupVarint32(0, 0, 0, 0,
128 testGroupVarint32(1, 2, 3, 4,
130 testGroupVarint32(1 << 8, (2 << 16) + 3, (4 << 24) + (5 << 8) + 6, 7,
131 0x39, 0, 1, 3, 0, 2, 6, 5, 0, 4, 7, -1);
134 TEST(GroupVarint, GroupVarint64) {
135 EXPECT_EQ(0, GroupVarint64::maxSize(0));
136 EXPECT_EQ(10, GroupVarint64::maxSize(1));
137 EXPECT_EQ(18, GroupVarint64::maxSize(2));
138 EXPECT_EQ(26, GroupVarint64::maxSize(3));
139 EXPECT_EQ(34, GroupVarint64::maxSize(4));
140 EXPECT_EQ(42, GroupVarint64::maxSize(5));
141 EXPECT_EQ(52, GroupVarint64::maxSize(6));
142 testGroupVarint64(0, 0, 0, 0, 0,
143 0, 0, 0, 0, 0, 0, 0, -1);
144 testGroupVarint64(1, 2, 3, 4, 5,
145 0, 0, 1, 2, 3, 4, 5, -1);
146 testGroupVarint64(1 << 8, (2 << 16) + 3, (4 << 24) + (5 << 8) + 6,
147 (7ULL << 32) + (8 << 16),
148 (9ULL << 56) + (10ULL << 40) + 11,
154 11, 0, 0, 0, 0, 10, 0, 9,
158 TEST(GroupVarint, GroupVarintEncoder) {
161 GroupVarint32Encoder gv(s);
165 EXPECT_EQ(2, s.size());
166 EXPECT_EQ(std::string("\x00\x00", 2), s);
169 GroupVarint32Encoder gv(s);
176 EXPECT_EQ(5, s.size());
177 EXPECT_EQ(std::string("\x00\x01\x02\x03\x04", 5), s);
181 TEST(GroupVarint, GroupVarintDecoder) {
182 // Make sure we don't read out of bounds
183 std::string padding(17, 'X');
186 std::string s("\x00\x00", 2);
188 StringPiece p(s.data(), 2);
190 GroupVarint32Decoder gv(p);
192 EXPECT_TRUE(gv.next(&v));
194 EXPECT_FALSE(gv.next(&v));
195 EXPECT_TRUE(gv.rest().empty());
199 std::string s("\x00\x01\x02\x03\x04\x01\x02\x03\x04", 9);
201 StringPiece p(s.data(), 9);
203 GroupVarint32Decoder gv(p);
205 EXPECT_TRUE(gv.next(&v));
207 EXPECT_TRUE(gv.next(&v));
209 EXPECT_TRUE(gv.next(&v));
211 EXPECT_TRUE(gv.next(&v));
213 EXPECT_TRUE(gv.next(&v));
214 EXPECT_EQ(0x0302, v);
215 EXPECT_TRUE(gv.next(&v));
217 EXPECT_FALSE(gv.next(&v));
218 EXPECT_TRUE(gv.rest().empty());
222 // Limit max count when reading a full block
223 std::string s("\x00\x01\x02\x03\x04\x01\x02\x03\x04", 9);
225 StringPiece p(s.data(), 9);
227 GroupVarint32Decoder gv(p, 3);
229 EXPECT_TRUE(gv.next(&v));
231 EXPECT_TRUE(gv.next(&v));
233 EXPECT_TRUE(gv.next(&v));
235 EXPECT_FALSE(gv.next(&v));
236 EXPECT_EQ(std::string("\x04\x01\x02\x03\x04", 5), gv.rest().toString());
240 // Limit max count when reading a partial block
241 std::string s("\x00\x01\x02\x03\x04\x01\x02\x03\x04", 9);
243 StringPiece p(s.data(), 9);
245 GroupVarint32Decoder gv(p, 5);
247 EXPECT_TRUE(gv.next(&v));
249 EXPECT_TRUE(gv.next(&v));
251 EXPECT_TRUE(gv.next(&v));
253 EXPECT_TRUE(gv.next(&v));
255 EXPECT_TRUE(gv.next(&v));
256 EXPECT_EQ(0x0302, v);
257 EXPECT_FALSE(gv.next(&v));
258 EXPECT_EQ(std::string("\x04", 1), gv.rest().toString());