blob: 05c26e7e4ea1fbd7be8e0022cae9a2a9518c29e3 [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#ifndef AAPT_STRING_POOL_H
18#define AAPT_STRING_POOL_H
19
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080020#include "ConfigDescription.h"
Adam Lesinskicacb28f2016-10-19 12:18:14 -070021#include "util/BigBuffer.h"
Adam Lesinski1ab598f2015-08-14 14:26:04 -070022#include "util/StringPiece.h"
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080023
24#include <functional>
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080025#include <memory>
26#include <string>
Adam Lesinskicacb28f2016-10-19 12:18:14 -070027#include <unordered_map>
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080028#include <vector>
29
30namespace aapt {
31
32struct Span {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070033 std::string name;
34 uint32_t firstChar;
35 uint32_t lastChar;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080036};
37
38struct StyleString {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070039 std::string str;
40 std::vector<Span> spans;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080041};
42
43class StringPool {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070044 public:
45 struct Context {
46 uint32_t priority;
47 ConfigDescription config;
48 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080049
Adam Lesinskicacb28f2016-10-19 12:18:14 -070050 class Entry;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080051
Adam Lesinskicacb28f2016-10-19 12:18:14 -070052 class Ref {
53 public:
54 Ref();
55 Ref(const Ref&);
56 ~Ref();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080057
Adam Lesinskicacb28f2016-10-19 12:18:14 -070058 Ref& operator=(const Ref& rhs);
59 const std::string* operator->() const;
60 const std::string& operator*() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080061
Adam Lesinskicacb28f2016-10-19 12:18:14 -070062 size_t getIndex() const;
63 const Context& getContext() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080064
Adam Lesinskicacb28f2016-10-19 12:18:14 -070065 private:
66 friend class StringPool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080067
Adam Lesinskicacb28f2016-10-19 12:18:14 -070068 explicit Ref(Entry* entry);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080069
Adam Lesinskicacb28f2016-10-19 12:18:14 -070070 Entry* mEntry;
71 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080072
Adam Lesinskicacb28f2016-10-19 12:18:14 -070073 class StyleEntry;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080074
Adam Lesinskicacb28f2016-10-19 12:18:14 -070075 class StyleRef {
76 public:
77 StyleRef();
78 StyleRef(const StyleRef&);
79 ~StyleRef();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080080
Adam Lesinskicacb28f2016-10-19 12:18:14 -070081 StyleRef& operator=(const StyleRef& rhs);
82 const StyleEntry* operator->() const;
83 const StyleEntry& operator*() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080084
Adam Lesinskicacb28f2016-10-19 12:18:14 -070085 size_t getIndex() const;
86 const Context& getContext() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080087
Adam Lesinskicacb28f2016-10-19 12:18:14 -070088 private:
89 friend class StringPool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080090
Adam Lesinskicacb28f2016-10-19 12:18:14 -070091 explicit StyleRef(StyleEntry* entry);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080092
Adam Lesinskicacb28f2016-10-19 12:18:14 -070093 StyleEntry* mEntry;
94 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080095
Adam Lesinskicacb28f2016-10-19 12:18:14 -070096 class Entry {
97 public:
98 std::string value;
99 Context context;
100 size_t index;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800101
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700102 private:
103 friend class StringPool;
104 friend class Ref;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800105
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700106 int ref;
107 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800108
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700109 struct Span {
110 Ref name;
111 uint32_t firstChar;
112 uint32_t lastChar;
113 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800114
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700115 class StyleEntry {
116 public:
117 Ref str;
118 std::vector<Span> spans;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800119
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700120 private:
121 friend class StringPool;
122 friend class StyleRef;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800123
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700124 int ref;
125 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800126
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700127 using const_iterator = std::vector<std::unique_ptr<Entry>>::const_iterator;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800128
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700129 static bool flattenUtf8(BigBuffer* out, const StringPool& pool);
130 static bool flattenUtf16(BigBuffer* out, const StringPool& pool);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800131
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700132 StringPool() = default;
133 StringPool(const StringPool&) = delete;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800134
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700135 /**
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 StringPiece& str);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800140
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700141 /**
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 StringPiece& str, const Context& context);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800147
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700148 /**
149 * Adds a style to the string pool and returns a reference to it.
150 */
151 StyleRef makeRef(const StyleString& str);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800152
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700153 /**
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);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800159
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700160 /**
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);
Adam Lesinski769de982015-04-10 19:43:55 -0700165
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700166 /**
167 * Moves pool into this one without coalescing strings. When this
168 * function returns, pool will be empty.
169 */
170 void merge(StringPool&& pool);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800171
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700172 /**
173 * Retuns the number of strings in the table.
174 */
175 inline size_t size() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800176
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700177 /**
178 * Reserves space for strings and styles as an optimization.
179 */
180 void hintWillAdd(size_t stringCount, size_t styleCount);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800181
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700182 /**
183 * Sorts the strings according to some comparison function.
184 */
185 void sort(const std::function<bool(const Entry&, const Entry&)>& cmp);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800186
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700187 /**
188 * Removes any strings that have no references.
189 */
190 void prune();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800191
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700192 private:
193 friend const_iterator begin(const StringPool& pool);
194 friend const_iterator end(const StringPool& pool);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800195
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700196 static bool flatten(BigBuffer* out, const StringPool& pool, bool utf8);
Adam Lesinski24aad162015-04-24 19:19:30 -0700197
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700198 Ref makeRefImpl(const StringPiece& str, const Context& context, bool unique);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800199
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700200 std::vector<std::unique_ptr<Entry>> mStrings;
201 std::vector<std::unique_ptr<StyleEntry>> mStyles;
202 std::unordered_multimap<StringPiece, Entry*> mIndexedStrings;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800203};
204
205//
206// Inline implementation
207//
208
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700209inline size_t StringPool::size() const { return mStrings.size(); }
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800210
211inline StringPool::const_iterator begin(const StringPool& pool) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700212 return pool.mStrings.begin();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800213}
214
215inline StringPool::const_iterator end(const StringPool& pool) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700216 return pool.mStrings.end();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800217}
218
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700219} // namespace aapt
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800220
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700221#endif // AAPT_STRING_POOL_H