blob: 9a7238b584ba9ee94e770eaf9e044728f9c9e0bc [file] [log] [blame]
Adam Lesinski6f6ceb72014-11-14 14:48:12 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17#include "StringPool.h"
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080018
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080019#include <string>
20
Adam Lesinskid5083f62017-01-16 15:07:21 -080021#include "androidfw/StringPiece.h"
22
Ryan Mitchell70414f22018-03-26 11:05:31 -070023#include "Diagnostics.h"
Adam Lesinskice5e56e2016-10-21 17:56:45 -070024#include "test/Test.h"
25#include "util/Util.h"
26
Adam Lesinski060b53d2017-07-28 17:10:35 -070027using ::android::StringPiece;
28using ::android::StringPiece16;
29using ::testing::Eq;
30using ::testing::Ne;
31using ::testing::NotNull;
32using ::testing::Pointee;
Adam Lesinskid5083f62017-01-16 15:07:21 -080033
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080034namespace aapt {
35
36TEST(StringPoolTest, InsertOneString) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070037 StringPool pool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080038
Adam Lesinskice5e56e2016-10-21 17:56:45 -070039 StringPool::Ref ref = pool.MakeRef("wut");
Adam Lesinski060b53d2017-07-28 17:10:35 -070040 EXPECT_THAT(*ref, Eq("wut"));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080041}
42
43TEST(StringPoolTest, InsertTwoUniqueStrings) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070044 StringPool pool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080045
Adam Lesinski060b53d2017-07-28 17:10:35 -070046 StringPool::Ref ref_a = pool.MakeRef("wut");
47 StringPool::Ref ref_b = pool.MakeRef("hey");
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080048
Adam Lesinski060b53d2017-07-28 17:10:35 -070049 EXPECT_THAT(*ref_a, Eq("wut"));
50 EXPECT_THAT(*ref_b, Eq("hey"));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080051}
52
53TEST(StringPoolTest, DoNotInsertNewDuplicateString) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070054 StringPool pool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080055
Adam Lesinski060b53d2017-07-28 17:10:35 -070056 StringPool::Ref ref_a = pool.MakeRef("wut");
57 StringPool::Ref ref_b = pool.MakeRef("wut");
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080058
Adam Lesinski060b53d2017-07-28 17:10:35 -070059 EXPECT_THAT(*ref_a, Eq("wut"));
60 EXPECT_THAT(*ref_b, Eq("wut"));
61 EXPECT_THAT(pool.size(), Eq(1u));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080062}
63
y46029262018-04-16 18:13:14 -070064TEST(StringPoolTest, DoNotDedupeSameStringDifferentPriority) {
65 StringPool pool;
66
67 StringPool::Ref ref_a = pool.MakeRef("wut", StringPool::Context(0x81010001));
68 StringPool::Ref ref_b = pool.MakeRef("wut", StringPool::Context(0x81010002));
69
70 EXPECT_THAT(*ref_a, Eq("wut"));
71 EXPECT_THAT(*ref_b, Eq("wut"));
72 EXPECT_THAT(pool.size(), Eq(2u));
73}
74
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080075TEST(StringPoolTest, MaintainInsertionOrderIndex) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070076 StringPool pool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080077
Adam Lesinski060b53d2017-07-28 17:10:35 -070078 StringPool::Ref ref_a = pool.MakeRef("z");
79 StringPool::Ref ref_b = pool.MakeRef("a");
80 StringPool::Ref ref_c = pool.MakeRef("m");
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080081
Adam Lesinski060b53d2017-07-28 17:10:35 -070082 EXPECT_THAT(ref_a.index(), Eq(0u));
83 EXPECT_THAT(ref_b.index(), Eq(1u));
84 EXPECT_THAT(ref_c.index(), Eq(2u));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080085}
86
87TEST(StringPoolTest, PruneStringsWithNoReferences) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070088 StringPool pool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080089
Adam Lesinski060b53d2017-07-28 17:10:35 -070090 StringPool::Ref ref_a = pool.MakeRef("foo");
Adam Lesinskicacb28f2016-10-19 12:18:14 -070091
Adam Lesinski060b53d2017-07-28 17:10:35 -070092 {
93 StringPool::Ref ref_b = pool.MakeRef("wut");
94 EXPECT_THAT(*ref_b, Eq("wut"));
95 EXPECT_THAT(pool.size(), Eq(2u));
96 pool.Prune();
97 EXPECT_THAT(pool.size(), Eq(2u));
98 }
99 EXPECT_THAT(pool.size(), Eq(2u));
100
101 {
102 StringPool::Ref ref_c = pool.MakeRef("bar");
103 EXPECT_THAT(pool.size(), Eq(3u));
104
105 pool.Prune();
106 EXPECT_THAT(pool.size(), Eq(2u));
107 }
108 EXPECT_THAT(pool.size(), Eq(2u));
109
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700110 pool.Prune();
Adam Lesinski060b53d2017-07-28 17:10:35 -0700111 EXPECT_THAT(pool.size(), Eq(1u));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800112}
113
Adam Lesinski060b53d2017-07-28 17:10:35 -0700114TEST(StringPoolTest, SortAndMaintainIndexesInStringReferences) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700115 StringPool pool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800116
Adam Lesinski060b53d2017-07-28 17:10:35 -0700117 StringPool::Ref ref_a = pool.MakeRef("z");
118 StringPool::Ref ref_b = pool.MakeRef("a");
119 StringPool::Ref ref_c = pool.MakeRef("m");
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800120
Adam Lesinski060b53d2017-07-28 17:10:35 -0700121 EXPECT_THAT(*ref_a, Eq("z"));
122 EXPECT_THAT(ref_a.index(), Eq(0u));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800123
Adam Lesinski060b53d2017-07-28 17:10:35 -0700124 EXPECT_THAT(*ref_b, Eq("a"));
125 EXPECT_THAT(ref_b.index(), Eq(1u));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800126
Adam Lesinski060b53d2017-07-28 17:10:35 -0700127 EXPECT_THAT(*ref_c, Eq("m"));
128 EXPECT_THAT(ref_c.index(), Eq(2u));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800129
Adam Lesinski060b53d2017-07-28 17:10:35 -0700130 pool.Sort();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800131
Adam Lesinski060b53d2017-07-28 17:10:35 -0700132 EXPECT_THAT(*ref_a, Eq("z"));
133 EXPECT_THAT(ref_a.index(), Eq(2u));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800134
Adam Lesinski060b53d2017-07-28 17:10:35 -0700135 EXPECT_THAT(*ref_b, Eq("a"));
136 EXPECT_THAT(ref_b.index(), Eq(0u));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800137
Adam Lesinski060b53d2017-07-28 17:10:35 -0700138 EXPECT_THAT(*ref_c, Eq("m"));
139 EXPECT_THAT(ref_c.index(), Eq(1u));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800140}
141
142TEST(StringPoolTest, SortAndStillDedupe) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700143 StringPool pool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800144
Adam Lesinski060b53d2017-07-28 17:10:35 -0700145 StringPool::Ref ref_a = pool.MakeRef("z");
146 StringPool::Ref ref_b = pool.MakeRef("a");
147 StringPool::Ref ref_c = pool.MakeRef("m");
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800148
Adam Lesinski060b53d2017-07-28 17:10:35 -0700149 pool.Sort();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800150
Adam Lesinski060b53d2017-07-28 17:10:35 -0700151 StringPool::Ref ref_d = pool.MakeRef("z");
152 StringPool::Ref ref_e = pool.MakeRef("a");
153 StringPool::Ref ref_f = pool.MakeRef("m");
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800154
Adam Lesinski060b53d2017-07-28 17:10:35 -0700155 EXPECT_THAT(ref_d.index(), Eq(ref_a.index()));
156 EXPECT_THAT(ref_e.index(), Eq(ref_b.index()));
157 EXPECT_THAT(ref_f.index(), Eq(ref_c.index()));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800158}
159
160TEST(StringPoolTest, AddStyles) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700161 StringPool pool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800162
Adam Lesinski060b53d2017-07-28 17:10:35 -0700163 StringPool::StyleRef ref = pool.MakeRef(StyleString{{"android"}, {Span{{"b"}, 2, 6}}});
164 EXPECT_THAT(ref.index(), Eq(0u));
165 EXPECT_THAT(ref->value, Eq("android"));
166 ASSERT_THAT(ref->spans.size(), Eq(1u));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800167
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700168 const StringPool::Span& span = ref->spans.front();
Adam Lesinski060b53d2017-07-28 17:10:35 -0700169 EXPECT_THAT(*span.name, Eq("b"));
170 EXPECT_THAT(span.first_char, Eq(2u));
171 EXPECT_THAT(span.last_char, Eq(6u));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800172}
173
174TEST(StringPoolTest, DoNotDedupeStyleWithSameStringAsNonStyle) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700175 StringPool pool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800176
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700177 StringPool::Ref ref = pool.MakeRef("android");
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800178
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700179 StyleString str{{"android"}};
Adam Lesinski060b53d2017-07-28 17:10:35 -0700180 StringPool::StyleRef style_ref = pool.MakeRef(StyleString{{"android"}});
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800181
Adam Lesinski060b53d2017-07-28 17:10:35 -0700182 EXPECT_THAT(ref.index(), Ne(style_ref.index()));
183}
184
185TEST(StringPoolTest, StylesAndStringsAreSeparateAfterSorting) {
186 StringPool pool;
187
188 StringPool::StyleRef ref_a = pool.MakeRef(StyleString{{"beta"}});
189 StringPool::Ref ref_b = pool.MakeRef("alpha");
190 StringPool::StyleRef ref_c = pool.MakeRef(StyleString{{"alpha"}});
191
192 EXPECT_THAT(ref_b.index(), Ne(ref_c.index()));
193
194 pool.Sort();
195
196 EXPECT_THAT(ref_c.index(), Eq(0u));
197 EXPECT_THAT(ref_a.index(), Eq(1u));
198 EXPECT_THAT(ref_b.index(), Eq(2u));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800199}
200
Adam Lesinski769de982015-04-10 19:43:55 -0700201TEST(StringPoolTest, FlattenEmptyStringPoolUtf8) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700202 using namespace android; // For NO_ERROR on Windows.
Ryan Mitchell70414f22018-03-26 11:05:31 -0700203 StdErrDiagnostics diag;
Adam Lesinski803c7c82016-04-06 16:09:43 -0700204
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700205 StringPool pool;
206 BigBuffer buffer(1024);
Ryan Mitchell70414f22018-03-26 11:05:31 -0700207 StringPool::FlattenUtf8(&buffer, pool, &diag);
Adam Lesinski769de982015-04-10 19:43:55 -0700208
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700209 std::unique_ptr<uint8_t[]> data = util::Copy(buffer);
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700210 ResStringPool test;
Adam Lesinski060b53d2017-07-28 17:10:35 -0700211 ASSERT_THAT(test.setTo(data.get(), buffer.size()), Eq(NO_ERROR));
Adam Lesinski769de982015-04-10 19:43:55 -0700212}
213
Adam Lesinski52364f72016-01-11 13:10:24 -0800214TEST(StringPoolTest, FlattenOddCharactersUtf16) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700215 using namespace android; // For NO_ERROR on Windows.
Ryan Mitchell70414f22018-03-26 11:05:31 -0700216 StdErrDiagnostics diag;
Adam Lesinski803c7c82016-04-06 16:09:43 -0700217
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700218 StringPool pool;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700219 pool.MakeRef("\u093f");
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700220 BigBuffer buffer(1024);
Ryan Mitchell70414f22018-03-26 11:05:31 -0700221 StringPool::FlattenUtf16(&buffer, pool, &diag);
Adam Lesinski52364f72016-01-11 13:10:24 -0800222
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700223 std::unique_ptr<uint8_t[]> data = util::Copy(buffer);
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700224 ResStringPool test;
225 ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
226 size_t len = 0;
227 const char16_t* str = test.stringAt(0, &len);
Adam Lesinski060b53d2017-07-28 17:10:35 -0700228 EXPECT_THAT(len, Eq(1u));
229 EXPECT_THAT(str, Pointee(Eq(u'\u093f')));
230 EXPECT_THAT(str[1], Eq(0u));
Adam Lesinski52364f72016-01-11 13:10:24 -0800231}
232
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700233constexpr const char* sLongString =
234 "バッテリーを長持ちさせるため、バッテリーセーバーは端末のパフォーマンスを抑"
235 "え、バイブレーション、位置情報サービス、大半のバックグラウンドデータを制限"
236 "します。メール、SMSや、同期を使 "
237 "用するその他のアプリは、起動しても更新されないことがあります。バッテリーセ"
238 "ーバーは端末の充電中は自動的にOFFになります。";
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800239
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700240TEST(StringPoolTest, Flatten) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700241 using namespace android; // For NO_ERROR on Windows.
Ryan Mitchell70414f22018-03-26 11:05:31 -0700242 StdErrDiagnostics diag;
Adam Lesinski803c7c82016-04-06 16:09:43 -0700243
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700244 StringPool pool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800245
Adam Lesinski060b53d2017-07-28 17:10:35 -0700246 StringPool::Ref ref_a = pool.MakeRef("hello");
247 StringPool::Ref ref_b = pool.MakeRef("goodbye");
248 StringPool::Ref ref_c = pool.MakeRef(sLongString);
249 StringPool::Ref ref_d = pool.MakeRef("");
250 StringPool::StyleRef ref_e =
251 pool.MakeRef(StyleString{{"style"}, {Span{{"b"}, 0, 1}, Span{{"i"}, 2, 3}}});
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800252
Adam Lesinski060b53d2017-07-28 17:10:35 -0700253 // Styles are always first.
254 EXPECT_THAT(ref_e.index(), Eq(0u));
255
256 EXPECT_THAT(ref_a.index(), Eq(1u));
257 EXPECT_THAT(ref_b.index(), Eq(2u));
258 EXPECT_THAT(ref_c.index(), Eq(3u));
259 EXPECT_THAT(ref_d.index(), Eq(4u));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800260
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700261 BigBuffer buffers[2] = {BigBuffer(1024), BigBuffer(1024)};
Ryan Mitchell70414f22018-03-26 11:05:31 -0700262 StringPool::FlattenUtf8(&buffers[0], pool, &diag);
263 StringPool::FlattenUtf16(&buffers[1], pool, &diag);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800264
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700265 // Test both UTF-8 and UTF-16 buffers.
266 for (const BigBuffer& buffer : buffers) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700267 std::unique_ptr<uint8_t[]> data = util::Copy(buffer);
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700268
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700269 ResStringPool test;
270 ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800271
Adam Lesinski060b53d2017-07-28 17:10:35 -0700272 EXPECT_THAT(util::GetString(test, 1), Eq("hello"));
273 EXPECT_THAT(util::GetString16(test, 1), Eq(u"hello"));
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700274
Adam Lesinski060b53d2017-07-28 17:10:35 -0700275 EXPECT_THAT(util::GetString(test, 2), Eq("goodbye"));
276 EXPECT_THAT(util::GetString16(test, 2), Eq(u"goodbye"));
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700277
Adam Lesinski060b53d2017-07-28 17:10:35 -0700278 EXPECT_THAT(util::GetString(test, 3), Eq(sLongString));
279 EXPECT_THAT(util::GetString16(test, 3), Eq(util::Utf8ToUtf16(sLongString)));
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700280
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700281 size_t len;
Adam Lesinski060b53d2017-07-28 17:10:35 -0700282 EXPECT_TRUE(test.stringAt(4, &len) != nullptr || test.string8At(4, &len) != nullptr);
Adam Lesinskid0f116b2016-07-08 15:00:32 -0700283
Adam Lesinski060b53d2017-07-28 17:10:35 -0700284 EXPECT_THAT(util::GetString(test, 0), Eq("style"));
285 EXPECT_THAT(util::GetString16(test, 0), Eq(u"style"));
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800286
Adam Lesinski060b53d2017-07-28 17:10:35 -0700287 const ResStringPool_span* span = test.styleAt(0);
288 ASSERT_THAT(span, NotNull());
289 EXPECT_THAT(util::GetString(test, span->name.index), Eq("b"));
290 EXPECT_THAT(util::GetString16(test, span->name.index), Eq(u"b"));
291 EXPECT_THAT(span->firstChar, Eq(0u));
292 EXPECT_THAT(span->lastChar, Eq(1u));
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700293 span++;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800294
Adam Lesinski060b53d2017-07-28 17:10:35 -0700295 ASSERT_THAT(span->name.index, Ne(ResStringPool_span::END));
296 EXPECT_THAT(util::GetString(test, span->name.index), Eq("i"));
297 EXPECT_THAT(util::GetString16(test, span->name.index), Eq(u"i"));
298 EXPECT_THAT(span->firstChar, Eq(2u));
299 EXPECT_THAT(span->lastChar, Eq(3u));
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700300 span++;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800301
Adam Lesinski060b53d2017-07-28 17:10:35 -0700302 EXPECT_THAT(span->name.index, Eq(ResStringPool_span::END));
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700303 }
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800304}
305
Ryan Mitchell4353d61b2018-09-10 17:09:12 -0700306TEST(StringPoolTest, ModifiedUTF8) {
Ryan Mitchelld86ea582018-06-27 11:57:18 -0700307 using namespace android; // For NO_ERROR on Windows.
308 StdErrDiagnostics diag;
309 StringPool pool;
310 StringPool::Ref ref_a = pool.MakeRef("\xF0\x90\x90\x80"); // 𐐀 (U+10400)
311 StringPool::Ref ref_b = pool.MakeRef("foo \xF0\x90\x90\xB7 bar"); // 𐐷 (U+10437)
312 StringPool::Ref ref_c = pool.MakeRef("\xF0\x90\x90\x80\xF0\x90\x90\xB7");
313
314 BigBuffer buffer(1024);
315 StringPool::FlattenUtf8(&buffer, pool, &diag);
316 std::unique_ptr<uint8_t[]> data = util::Copy(buffer);
317
Ryan Mitchell4353d61b2018-09-10 17:09:12 -0700318 // Check that the codepoints are encoded using two three-byte surrogate pairs
Ryan Mitchelld86ea582018-06-27 11:57:18 -0700319 ResStringPool test;
320 ASSERT_EQ(test.setTo(data.get(), buffer.size()), NO_ERROR);
Ryan Mitchell4353d61b2018-09-10 17:09:12 -0700321 size_t len;
322 const char* str = test.string8At(0, &len);
323 ASSERT_THAT(str, NotNull());
324 EXPECT_THAT(std::string(str, len), Eq("\xED\xA0\x81\xED\xB0\x80"));
325 str = test.string8At(1, &len);
326 ASSERT_THAT(str, NotNull());
327 EXPECT_THAT(std::string(str, len), Eq("foo \xED\xA0\x81\xED\xB0\xB7 bar"));
328 str = test.string8At(2, &len);
329 ASSERT_THAT(str, NotNull());
330 EXPECT_THAT(std::string(str, len), Eq("\xED\xA0\x81\xED\xB0\x80\xED\xA0\x81\xED\xB0\xB7"));
331
332 // Check that retrieving the strings returns the original UTF-8 character bytes
333 EXPECT_THAT(util::GetString(test, 0), Eq("\xF0\x90\x90\x80"));
334 EXPECT_THAT(util::GetString(test, 1), Eq("foo \xF0\x90\x90\xB7 bar"));
335 EXPECT_THAT(util::GetString(test, 2), Eq("\xF0\x90\x90\x80\xF0\x90\x90\xB7"));
Ryan Mitchelld86ea582018-06-27 11:57:18 -0700336}
Ryan Mitchell61ffd402018-04-16 18:21:14 +0000337
Ryan Mitchell70414f22018-03-26 11:05:31 -0700338TEST(StringPoolTest, MaxEncodingLength) {
339 StdErrDiagnostics diag;
340 using namespace android; // For NO_ERROR on Windows.
341 ResStringPool test;
342
343 StringPool pool;
344 pool.MakeRef("aaaaaaaaaa");
345 BigBuffer buffers[2] = {BigBuffer(1024), BigBuffer(1024)};
346
347 // Make sure a UTF-8 string under the maximum length does not produce an error
348 EXPECT_THAT(StringPool::FlattenUtf8(&buffers[0], pool, &diag), Eq(true));
349 std::unique_ptr<uint8_t[]> data = util::Copy(buffers[0]);
350 test.setTo(data.get(), buffers[0].size());
351 EXPECT_THAT(util::GetString(test, 0), Eq("aaaaaaaaaa"));
352
353 // Make sure a UTF-16 string under the maximum length does not produce an error
354 EXPECT_THAT(StringPool::FlattenUtf16(&buffers[1], pool, &diag), Eq(true));
355 data = util::Copy(buffers[1]);
356 test.setTo(data.get(), buffers[1].size());
357 EXPECT_THAT(util::GetString16(test, 0), Eq(u"aaaaaaaaaa"));
358
359 StringPool pool2;
360 std::string longStr(50000, 'a');
361 pool2.MakeRef("this fits1");
362 pool2.MakeRef(longStr);
363 pool2.MakeRef("this fits2");
364 BigBuffer buffers2[2] = {BigBuffer(1024), BigBuffer(1024)};
365
366 // Make sure a string that exceeds the maximum length of UTF-8 produces an
367 // error and writes a shorter error string instead
368 EXPECT_THAT(StringPool::FlattenUtf8(&buffers2[0], pool2, &diag), Eq(false));
369 data = util::Copy(buffers2[0]);
370 test.setTo(data.get(), buffers2[0].size());
371 EXPECT_THAT(util::GetString(test, 0), "this fits1");
372 EXPECT_THAT(util::GetString(test, 1), "STRING_TOO_LARGE");
373 EXPECT_THAT(util::GetString(test, 2), "this fits2");
374
375 // Make sure a string that a string that exceeds the maximum length of UTF-8
376 // but not UTF-16 does not error for UTF-16
377 StringPool pool3;
378 std::u16string longStr16(50000, 'a');
379 pool3.MakeRef(longStr);
380 EXPECT_THAT(StringPool::FlattenUtf16(&buffers2[1], pool3, &diag), Eq(true));
381 data = util::Copy(buffers2[1]);
382 test.setTo(data.get(), buffers2[1].size());
383 EXPECT_THAT(util::GetString16(test, 0), Eq(longStr16));
384}
385
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700386} // namespace aapt