OSDN Git Service

AAPT2: Ensure strings are sorted by configuration
authorAdam Lesinski <adamlesinski@google.com>
Wed, 18 Oct 2017 22:07:33 +0000 (15:07 -0700)
committerAdam Lesinski <adamlesinski@google.com>
Wed, 18 Oct 2017 22:12:42 +0000 (15:12 -0700)
Keep strings sorted by configuration so that strings likely
to be selected (all match the same locale, for instance) are
close together.

Bug: 67958501
Test: make aapt2_tests
Change-Id: Id17d93bf2e03ce408a6f619d3ea6dc313e393b76

tools/aapt2/ResourceValues.cpp
tools/aapt2/ResourceValues_test.cpp
tools/aapt2/StringPool.cpp
tools/aapt2/StringPool.h

index 1cba194..a5ddc52 100644 (file)
@@ -55,7 +55,7 @@ bool RawString::Equals(const Value* value) const {
 }
 
 RawString* RawString::Clone(StringPool* new_pool) const {
-  RawString* rs = new RawString(new_pool->MakeRef(*value));
+  RawString* rs = new RawString(new_pool->MakeRef(value));
   rs->comment_ = comment_;
   rs->source_ = source_;
   return rs;
@@ -197,7 +197,7 @@ bool String::Flatten(android::Res_value* out_value) const {
 }
 
 String* String::Clone(StringPool* new_pool) const {
-  String* str = new String(new_pool->MakeRef(*value));
+  String* str = new String(new_pool->MakeRef(value));
   str->comment_ = comment_;
   str->source_ = source_;
   str->untranslatable_sections = untranslatable_sections;
@@ -280,7 +280,7 @@ bool FileReference::Flatten(android::Res_value* out_value) const {
 }
 
 FileReference* FileReference::Clone(StringPool* new_pool) const {
-  FileReference* fr = new FileReference(new_pool->MakeRef(*path));
+  FileReference* fr = new FileReference(new_pool->MakeRef(path));
   fr->file = file;
   fr->comment_ = comment_;
   fr->source_ = source_;
index 10f9b55..a80a9dc 100644 (file)
 
 #include "test/Test.h"
 
+using ::testing::Eq;
+using ::testing::SizeIs;
+using ::testing::StrEq;
+
 namespace aapt {
 
 TEST(ResourceValuesTest, PluralEquals) {
@@ -148,6 +152,22 @@ TEST(ResourceValuesTest, StyleClone) {
   EXPECT_TRUE(a->Equals(b.get()));
 }
 
+TEST(ResourcesValuesTest, StringClones) {
+  StringPool pool_a;
+  StringPool pool_b;
+
+  String str_a(pool_a.MakeRef("hello", StringPool::Context(test::ParseConfigOrDie("en"))));
+
+  ASSERT_THAT(pool_a, SizeIs(1u));
+  EXPECT_THAT(pool_a.strings()[0]->context.config, Eq(test::ParseConfigOrDie("en")));
+  EXPECT_THAT(pool_a.strings()[0]->value, StrEq("hello"));
+
+  std::unique_ptr<String> str_b(str_a.Clone(&pool_b));
+  ASSERT_THAT(pool_b, SizeIs(1u));
+  EXPECT_THAT(pool_b.strings()[0]->context.config, Eq(test::ParseConfigOrDie("en")));
+  EXPECT_THAT(pool_b.strings()[0]->value, StrEq("hello"));
+}
+
 TEST(ResourceValuesTest, StyleMerges) {
   StringPool pool_a;
   StringPool pool_b;
index 705b1ab..3a1a18c 100644 (file)
@@ -191,6 +191,13 @@ StringPool::Ref StringPool::MakeRefImpl(const StringPiece& str, const Context& c
   return Ref(borrow);
 }
 
+StringPool::Ref StringPool::MakeRef(const Ref& ref) {
+  if (ref.entry_->pool_ == this) {
+    return ref;
+  }
+  return MakeRef(ref.entry_->value, ref.entry_->context);
+}
+
 StringPool::StyleRef StringPool::MakeRef(const StyleString& str) {
   return MakeRef(str, Context{});
 }
index 8350d0d..3c1f3dc 100644 (file)
@@ -49,6 +49,8 @@ struct StyleString {
 // Otherwise, the style data array would have to be sparse and take up more space.
 class StringPool {
  public:
+  using size_type = size_t;
+
   class Context {
    public:
     enum : uint32_t {
@@ -165,6 +167,9 @@ class StringPool {
   // when sorting the string pool. Returns a reference to the string in the pool.
   Ref MakeRef(const android::StringPiece& str, const Context& context);
 
+  // Adds a string from another string pool. Returns a reference to the string in the string pool.
+  Ref MakeRef(const Ref& ref);
+
   // Adds a style to the string pool and returns a reference to it.
   StyleRef MakeRef(const StyleString& str);