1 /* 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 #ifndef AAPT_STRING_POOL_H 18 #define AAPT_STRING_POOL_H 19 20 #include "util/BigBuffer.h" 21 #include "ConfigDescription.h" 22 #include "util/StringPiece.h" 23 24 #include <functional> 25 #include <map> 26 #include <memory> 27 #include <string> 28 #include <vector> 29 30 namespace aapt { 31 32 struct Span { 33 std::u16string name; 34 uint32_t firstChar; 35 uint32_t lastChar; 36 }; 37 38 struct StyleString { 39 std::u16string str; 40 std::vector<Span> spans; 41 }; 42 43 class StringPool { 44 public: 45 struct Context { 46 uint32_t priority; 47 ConfigDescription config; 48 }; 49 50 class Entry; 51 52 class Ref { 53 public: 54 Ref(); 55 Ref(const Ref&); 56 ~Ref(); 57 58 Ref& operator=(const Ref& rhs); 59 const std::u16string* operator->() const; 60 const std::u16string& operator*() const; 61 62 size_t getIndex() const; 63 const Context& getContext() const; 64 65 private: 66 friend class StringPool; 67 68 Ref(Entry* entry); 69 70 Entry* mEntry; 71 }; 72 73 class StyleEntry; 74 75 class StyleRef { 76 public: 77 StyleRef(); 78 StyleRef(const StyleRef&); 79 ~StyleRef(); 80 81 StyleRef& operator=(const StyleRef& rhs); 82 const StyleEntry* operator->() const; 83 const StyleEntry& operator*() const; 84 85 size_t getIndex() const; 86 const Context& getContext() const; 87 88 private: 89 friend class StringPool; 90 91 StyleRef(StyleEntry* entry); 92 93 StyleEntry* mEntry; 94 }; 95 96 class Entry { 97 public: 98 std::u16string value; 99 Context context; 100 size_t index; 101 102 private: 103 friend class StringPool; 104 friend class Ref; 105 106 int ref; 107 }; 108 109 struct Span { 110 Ref name; 111 uint32_t firstChar; 112 uint32_t lastChar; 113 }; 114 115 class StyleEntry { 116 public: 117 Ref str; 118 std::vector<Span> spans; 119 120 private: 121 friend class StringPool; 122 friend class StyleRef; 123 124 int ref; 125 }; 126 127 using const_iterator = std::vector<std::unique_ptr<Entry>>::const_iterator; 128 129 static bool flattenUtf8(BigBuffer* out, const StringPool& pool); 130 static bool flattenUtf16(BigBuffer* out, const StringPool& pool); 131 132 StringPool() = default; 133 StringPool(const StringPool&) = delete; 134 135 /** 136 * Adds a string to the pool, unless it already exists. Returns 137 * a reference to the string in the pool. 138 */ 139 Ref makeRef(const StringPiece16& str); 140 141 /** 142 * Adds a string to the pool, unless it already exists, with a context 143 * object that can be used when sorting the string pool. Returns 144 * a reference to the string in the pool. 145 */ 146 Ref makeRef(const StringPiece16& str, const Context& context); 147 148 /** 149 * Adds a style to the string pool and returns a reference to it. 150 */ 151 StyleRef makeRef(const StyleString& str); 152 153 /** 154 * Adds a style to the string pool with a context object that 155 * can be used when sorting the string pool. Returns a reference 156 * to the style in the string pool. 157 */ 158 StyleRef makeRef(const StyleString& str, const Context& context); 159 160 /** 161 * Adds a style from another string pool. Returns a reference to the 162 * style in the string pool. 163 */ 164 StyleRef makeRef(const StyleRef& ref); 165 166 /** 167 * Moves pool into this one without coalescing strings. When this 168 * function returns, pool will be empty. 169 */ 170 void merge(StringPool&& pool); 171 172 /** 173 * Retuns the number of strings in the table. 174 */ 175 inline size_t size() const; 176 177 /** 178 * Reserves space for strings and styles as an optimization. 179 */ 180 void hintWillAdd(size_t stringCount, size_t styleCount); 181 182 /** 183 * Sorts the strings according to some comparison function. 184 */ 185 void sort(const std::function<bool(const Entry&, const Entry&)>& cmp); 186 187 /** 188 * Removes any strings that have no references. 189 */ 190 void prune(); 191 192 private: 193 friend const_iterator begin(const StringPool& pool); 194 friend const_iterator end(const StringPool& pool); 195 196 static bool flatten(BigBuffer* out, const StringPool& pool, bool utf8); 197 198 Ref makeRefImpl(const StringPiece16& str, const Context& context, bool unique); 199 200 std::vector<std::unique_ptr<Entry>> mStrings; 201 std::vector<std::unique_ptr<StyleEntry>> mStyles; 202 std::multimap<StringPiece16, Entry*> mIndexedStrings; 203 }; 204 205 // 206 // Inline implementation 207 // 208 209 inline size_t StringPool::size() const { 210 return mStrings.size(); 211 } 212 213 inline StringPool::const_iterator begin(const StringPool& pool) { 214 return pool.mStrings.begin(); 215 } 216 217 inline StringPool::const_iterator end(const StringPool& pool) { 218 return pool.mStrings.end(); 219 } 220 221 } // namespace aapt 222 223 #endif // AAPT_STRING_POOL_H 224