blob: a4f556ca52e482ede4bf9c064c0e464d298c5c4c [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 <functional>
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080021#include <memory>
22#include <string>
Adam Lesinskicacb28f2016-10-19 12:18:14 -070023#include <unordered_map>
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080024#include <vector>
25
Adam Lesinskice5e56e2016-10-21 17:56:45 -070026#include "ConfigDescription.h"
27#include "util/BigBuffer.h"
28#include "util/StringPiece.h"
29
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080030namespace aapt {
31
32struct Span {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070033 std::string name;
Adam Lesinskice5e56e2016-10-21 17:56:45 -070034 uint32_t first_char;
35 uint32_t last_char;
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:
Adam Lesinskib54ef102016-10-21 13:38:42 -070045 class Context {
46 public:
47 enum : uint32_t {
48 kStylePriority = 0u,
49 kHighPriority = 1u,
50 kNormalPriority = 0x7fffffffu,
51 kLowPriority = 0xffffffffu,
52 };
53 uint32_t priority = kNormalPriority;
Adam Lesinskicacb28f2016-10-19 12:18:14 -070054 ConfigDescription config;
Adam Lesinskib54ef102016-10-21 13:38:42 -070055
56 Context() = default;
57 Context(uint32_t p, const ConfigDescription& c) : priority(p), config(c) {}
58 explicit Context(uint32_t p) : priority(p) {}
59 explicit Context(const ConfigDescription& c)
60 : priority(kNormalPriority), config(c) {}
Adam Lesinskicacb28f2016-10-19 12:18:14 -070061 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080062
Adam Lesinskicacb28f2016-10-19 12:18:14 -070063 class Entry;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080064
Adam Lesinskicacb28f2016-10-19 12:18:14 -070065 class Ref {
66 public:
67 Ref();
68 Ref(const Ref&);
69 ~Ref();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080070
Adam Lesinskicacb28f2016-10-19 12:18:14 -070071 Ref& operator=(const Ref& rhs);
72 const std::string* operator->() const;
73 const std::string& operator*() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080074
Adam Lesinskice5e56e2016-10-21 17:56:45 -070075 size_t index() const;
76 const Context& GetContext() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080077
Adam Lesinskicacb28f2016-10-19 12:18:14 -070078 private:
79 friend class StringPool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080080
Adam Lesinskicacb28f2016-10-19 12:18:14 -070081 explicit Ref(Entry* entry);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080082
Adam Lesinskice5e56e2016-10-21 17:56:45 -070083 Entry* entry_;
Adam Lesinskicacb28f2016-10-19 12:18:14 -070084 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080085
Adam Lesinskicacb28f2016-10-19 12:18:14 -070086 class StyleEntry;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080087
Adam Lesinskicacb28f2016-10-19 12:18:14 -070088 class StyleRef {
89 public:
90 StyleRef();
91 StyleRef(const StyleRef&);
92 ~StyleRef();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080093
Adam Lesinskicacb28f2016-10-19 12:18:14 -070094 StyleRef& operator=(const StyleRef& rhs);
95 const StyleEntry* operator->() const;
96 const StyleEntry& operator*() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080097
Adam Lesinskice5e56e2016-10-21 17:56:45 -070098 size_t index() const;
99 const Context& GetContext() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800100
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700101 private:
102 friend class StringPool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800103
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700104 explicit StyleRef(StyleEntry* entry);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800105
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700106 StyleEntry* entry_;
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700107 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800108
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700109 class Entry {
110 public:
111 std::string value;
112 Context context;
113 size_t index;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800114
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700115 private:
116 friend class StringPool;
117 friend class Ref;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800118
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700119 int ref_;
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700120 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800121
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700122 struct Span {
123 Ref name;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700124 uint32_t first_char;
125 uint32_t last_char;
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700126 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800127
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700128 class StyleEntry {
129 public:
130 Ref str;
131 std::vector<Span> spans;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800132
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700133 private:
134 friend class StringPool;
135 friend class StyleRef;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800136
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700137 int ref_;
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700138 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800139
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700140 using const_iterator = std::vector<std::unique_ptr<Entry>>::const_iterator;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800141
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700142 static bool FlattenUtf8(BigBuffer* out, const StringPool& pool);
143 static bool FlattenUtf16(BigBuffer* out, const StringPool& pool);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800144
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700145 StringPool() = default;
146 StringPool(const StringPool&) = delete;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800147
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700148 /**
149 * Adds a string to the pool, unless it already exists. Returns
150 * a reference to the string in the pool.
151 */
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700152 Ref MakeRef(const StringPiece& str);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800153
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700154 /**
155 * Adds a string to the pool, unless it already exists, with a context
156 * object that can be used when sorting the string pool. Returns
157 * a reference to the string in the pool.
158 */
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700159 Ref MakeRef(const StringPiece& str, const Context& context);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800160
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700161 /**
162 * Adds a style to the string pool and returns a reference to it.
163 */
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700164 StyleRef MakeRef(const StyleString& str);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800165
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700166 /**
167 * Adds a style to the string pool with a context object that
168 * can be used when sorting the string pool. Returns a reference
169 * to the style in the string pool.
170 */
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700171 StyleRef MakeRef(const StyleString& str, const Context& context);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800172
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700173 /**
174 * Adds a style from another string pool. Returns a reference to the
175 * style in the string pool.
176 */
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700177 StyleRef MakeRef(const StyleRef& ref);
Adam Lesinski769de982015-04-10 19:43:55 -0700178
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700179 /**
180 * Moves pool into this one without coalescing strings. When this
181 * function returns, pool will be empty.
182 */
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700183 void Merge(StringPool&& pool);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800184
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700185 /**
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700186 * Returns the number of strings in the table.
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700187 */
188 inline size_t size() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800189
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700190 /**
191 * Reserves space for strings and styles as an optimization.
192 */
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700193 void HintWillAdd(size_t string_count, size_t style_count);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800194
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700195 /**
196 * Sorts the strings according to some comparison function.
197 */
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700198 void Sort(const std::function<bool(const Entry&, const Entry&)>& cmp);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800199
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700200 /**
201 * Removes any strings that have no references.
202 */
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700203 void Prune();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800204
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700205 private:
206 friend const_iterator begin(const StringPool& pool);
207 friend const_iterator end(const StringPool& pool);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800208
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700209 static bool Flatten(BigBuffer* out, const StringPool& pool, bool utf8);
Adam Lesinski24aad162015-04-24 19:19:30 -0700210
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700211 Ref MakeRefImpl(const StringPiece& str, const Context& context, bool unique);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800212
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700213 std::vector<std::unique_ptr<Entry>> strings_;
214 std::vector<std::unique_ptr<StyleEntry>> styles_;
215 std::unordered_multimap<StringPiece, Entry*> indexed_strings_;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800216};
217
218//
219// Inline implementation
220//
221
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700222inline size_t StringPool::size() const { return strings_.size(); }
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800223
224inline StringPool::const_iterator begin(const StringPool& pool) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700225 return pool.strings_.begin();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800226}
227
228inline StringPool::const_iterator end(const StringPool& pool) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700229 return pool.strings_.end();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800230}
231
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700232} // namespace aapt
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800233
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700234#endif // AAPT_STRING_POOL_H