1 // Copyright (C) 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "icing/util/encode-util.h"
16
17 #include <cstdint>
18 #include <string>
19
20 #include "gmock/gmock.h"
21 #include "gtest/gtest.h"
22
23 namespace icing {
24 namespace lib {
25 namespace encode_util {
26
27 namespace {
28
29 using ::testing::Eq;
30 using ::testing::Gt;
31 using ::testing::SizeIs;
32
TEST(EncodeUtilTest,IntCStringZeroConversion)33 TEST(EncodeUtilTest, IntCStringZeroConversion) {
34 uint64_t value = 0;
35 std::string encoded_str = EncodeIntToCString(value);
36
37 EXPECT_THAT(encoded_str, SizeIs(Gt(0)));
38 EXPECT_THAT(DecodeIntFromCString(encoded_str), Eq(value));
39 }
40
TEST(EncodeUtilTest,IntCStringConversionIsReversible)41 TEST(EncodeUtilTest, IntCStringConversionIsReversible) {
42 uint64_t value = 123456;
43 std::string encoded_str = EncodeIntToCString(value);
44 EXPECT_THAT(DecodeIntFromCString(encoded_str), Eq(value));
45 }
46
TEST(EncodeUtilTest,MultipleIntCStringConversionsAreReversible)47 TEST(EncodeUtilTest, MultipleIntCStringConversionsAreReversible) {
48 EXPECT_THAT(DecodeIntFromCString(EncodeIntToCString(25)), Eq(25));
49 EXPECT_THAT(DecodeIntFromCString(EncodeIntToCString(766)), Eq(766));
50 EXPECT_THAT(DecodeIntFromCString(EncodeIntToCString(2305)), Eq(2305));
51 EXPECT_THAT(DecodeIntFromCString(EncodeIntToCString(6922)), Eq(6922));
52 EXPECT_THAT(DecodeIntFromCString(EncodeIntToCString(62326)), Eq(62326));
53 EXPECT_THAT(DecodeIntFromCString(EncodeIntToCString(186985)), Eq(186985));
54 EXPECT_THAT(DecodeIntFromCString(EncodeIntToCString(560962)), Eq(560962));
55 EXPECT_THAT(DecodeIntFromCString(EncodeIntToCString(1682893)), Eq(1682893));
56 EXPECT_THAT(DecodeIntFromCString(EncodeIntToCString(15146065)), Eq(15146065));
57 EXPECT_THAT(DecodeIntFromCString(EncodeIntToCString(136314613)),
58 Eq(136314613));
59 EXPECT_THAT(DecodeIntFromCString(EncodeIntToCString(1226831545)),
60 Eq(1226831545));
61 EXPECT_THAT(DecodeIntFromCString(EncodeIntToCString(11041483933)),
62 Eq(11041483933));
63 EXPECT_THAT(DecodeIntFromCString(EncodeIntToCString(2683080596566)),
64 Eq(2683080596566));
65 EXPECT_THAT(DecodeIntFromCString(EncodeIntToCString(72443176107373)),
66 Eq(72443176107373));
67 EXPECT_THAT(DecodeIntFromCString(EncodeIntToCString(1955965754899162)),
68 Eq(1955965754899162));
69 EXPECT_THAT(DecodeIntFromCString(EncodeIntToCString(52811075382277465)),
70 Eq(52811075382277465));
71 EXPECT_THAT(DecodeIntFromCString(EncodeIntToCString(4277697105964474945)),
72 Eq(4277697105964474945));
73 }
74
TEST(EncodeUtilTest,MultipleValidEncodedCStringIntConversionsAreReversible)75 TEST(EncodeUtilTest, MultipleValidEncodedCStringIntConversionsAreReversible) {
76 // Only valid encoded C string (no zero bytes, length is between 1 and 10) are
77 // reversible.
78 EXPECT_THAT(EncodeIntToCString(DecodeIntFromCString("foo")), Eq("foo"));
79 EXPECT_THAT(EncodeIntToCString(DecodeIntFromCString("bar")), Eq("bar"));
80 EXPECT_THAT(EncodeIntToCString(DecodeIntFromCString("baz")), Eq("baz"));
81 EXPECT_THAT(EncodeIntToCString(DecodeIntFromCString("Icing")), Eq("Icing"));
82 EXPECT_THAT(EncodeIntToCString(DecodeIntFromCString("Google")), Eq("Google"));
83 EXPECT_THAT(EncodeIntToCString(DecodeIntFromCString("Youtube")),
84 Eq("Youtube"));
85 }
86
TEST(EncodeUtilTest,EncodeStringToCString)87 TEST(EncodeUtilTest, EncodeStringToCString) {
88 std::string digest;
89 digest.push_back(0b00000000); // '\0'
90 digest.push_back(0b00000001); // '\1'
91 digest.push_back(0b00000010); // '\2'
92 digest.push_back(0b00000011); // '\3'
93 digest.push_back(0b00000100); // '\4'
94 digest.push_back(0b00000101); // '\5'
95 digest.push_back(0b00000110); // '\6'
96 digest.push_back(0b00000111); // '\7'
97 digest.push_back(0b00001000); // '\8'
98 digest.push_back(0b00001001); // '\9'
99 std::string encoded_digest;
100 // 1 + first 7 bits from '\0'
101 encoded_digest.push_back(0b10000000);
102 // 1 + last 1 bit from '\0' + first 6 bits from '\1'
103 encoded_digest.push_back(0b10000000);
104 // 1 + last 2 bits from '\1' + first 5 bits from '\2'
105 encoded_digest.push_back(0b10100000);
106 // 1 + last 3 bits from '\2' + first 4 bits from '\3'
107 encoded_digest.push_back(0b10100000);
108 // 1 + last 4 bits from '\3' + first 3 bits from '\4'
109 encoded_digest.push_back(0b10011000);
110 // 1 + last 5 bits from '\4' + first 2 bits from '\5'
111 encoded_digest.push_back(0b10010000);
112 // 1 + last 6 bits from '\5' + first 1 bits from '\6'
113 encoded_digest.push_back(0b10001010);
114 // 1 + last 7 bits from '\6'
115 encoded_digest.push_back(0b10000110);
116 // 1 + first 7 bits from '\7'
117 encoded_digest.push_back(0b10000011);
118 // 1 + last 1 bit from '\7' + first 6 bits from '\8'
119 encoded_digest.push_back(0b11000010);
120 // 1 + last 2 bit from '\8' + first 5 bits from '\9'
121 encoded_digest.push_back(0b10000001);
122 // 1 + last 3 bit from '\9' + filled with 0s
123 encoded_digest.push_back(0b10010000);
124
125 EXPECT_THAT(EncodeStringToCString(digest), Eq(encoded_digest));
126 }
127
TEST(EncodeUtilTest,EncodeEmptyStringToCString)128 TEST(EncodeUtilTest, EncodeEmptyStringToCString) {
129 std::string digest;
130 std::string encoded_digest;
131
132 EXPECT_THAT(EncodeStringToCString(digest), Eq(encoded_digest));
133 }
134
TEST(EncodeUtilTest,EncodeMiddle0ByteStringToCStringConversions)135 TEST(EncodeUtilTest, EncodeMiddle0ByteStringToCStringConversions) {
136 std::string digest;
137 digest.push_back(0b00000001); // '\1'
138 digest.push_back(0b00000010); // '\2'
139 digest.push_back(0b00000011); // '\3'
140 digest.push_back(0b00000000); // '\0'
141 digest.push_back(0b00000100); // '\4'
142 digest.push_back(0b00000101); // '\5'
143 digest.push_back(0b00000110); // '\6'
144 std::string encoded_digest;
145 // 1 + first 7 bits from '\1'
146 encoded_digest.push_back(0b10000000);
147 // 1 + last 1 bit from '\1' + first 6 bits from '\2'
148 encoded_digest.push_back(0b11000000);
149 // 1 + last 2 bits from '\2' + first 5 bits from '\3'
150 encoded_digest.push_back(0b11000000);
151 // 1 + last 3 bits from '\3' + first 4 bits from '\0'
152 encoded_digest.push_back(0b10110000);
153 // 1 + last 4 bits from '\0' + first 3 bits from '\4'
154 encoded_digest.push_back(0b10000000);
155 // 1 + last 5 bits from '\4' + first 2 bits from '\5'
156 encoded_digest.push_back(0b10010000);
157 // 1 + last 6 bits from '\5' + first 1 bits from '\6'
158 encoded_digest.push_back(0b10001010);
159 // 1 + last 7 bits from '\6'
160 encoded_digest.push_back(0b10000110);
161
162 EXPECT_THAT(EncodeStringToCString(digest), Eq(encoded_digest));
163 }
164
TEST(EncodeUtilTest,Encode32BytesDigestToCStringLength)165 TEST(EncodeUtilTest, Encode32BytesDigestToCStringLength) {
166 std::string digest(32, 0b00000000);
167 // 37 = ceil(32 / 7.0 * 8.0)
168 EXPECT_THAT(EncodeStringToCString(digest).size(), Eq(37));
169 }
170
171 } // namespace
172
173 } // namespace encode_util
174 } // namespace lib
175 } // namespace icing
176