blob: a626d375b62589dfe22b6b03aa8fe3734bbfd43f [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 Lesinskid5083f62017-01-16 15:07:21 -080026#include "androidfw/StringPiece.h"
27
Adam Lesinskice5e56e2016-10-21 17:56:45 -070028#include "ConfigDescription.h"
29#include "util/BigBuffer.h"
Adam Lesinskice5e56e2016-10-21 17:56:45 -070030
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080031namespace aapt {
32
33struct Span {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070034 std::string name;
Adam Lesinskice5e56e2016-10-21 17:56:45 -070035 uint32_t first_char;
36 uint32_t last_char;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080037};
38
39struct StyleString {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070040 std::string str;
41 std::vector<Span> spans;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080042};
43
44class StringPool {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070045 public:
Adam Lesinskib54ef102016-10-21 13:38:42 -070046 class Context {
47 public:
48 enum : uint32_t {
49 kStylePriority = 0u,
50 kHighPriority = 1u,
51 kNormalPriority = 0x7fffffffu,
52 kLowPriority = 0xffffffffu,
53 };
54 uint32_t priority = kNormalPriority;
Adam Lesinskicacb28f2016-10-19 12:18:14 -070055 ConfigDescription config;
Adam Lesinskib54ef102016-10-21 13:38:42 -070056
57 Context() = default;
58 Context(uint32_t p, const ConfigDescription& c) : priority(p), config(c) {}
59 explicit Context(uint32_t p) : priority(p) {}
60 explicit Context(const ConfigDescription& c)
61 : priority(kNormalPriority), config(c) {}
Adam Lesinskicacb28f2016-10-19 12:18:14 -070062 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080063
Adam Lesinskicacb28f2016-10-19 12:18:14 -070064 class Entry;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080065
Adam Lesinskicacb28f2016-10-19 12:18:14 -070066 class Ref {
67 public:
68 Ref();
69 Ref(const Ref&);
70 ~Ref();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080071
Adam Lesinskicacb28f2016-10-19 12:18:14 -070072 Ref& operator=(const Ref& rhs);
Adam Lesinski75421622017-01-06 15:20:04 -080073 bool operator==(const Ref& rhs) const;
74 bool operator!=(const Ref& rhs) const;
Adam Lesinskicacb28f2016-10-19 12:18:14 -070075 const std::string* operator->() const;
76 const std::string& operator*() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080077
Adam Lesinskice5e56e2016-10-21 17:56:45 -070078 size_t index() const;
79 const Context& GetContext() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080080
Adam Lesinskicacb28f2016-10-19 12:18:14 -070081 private:
82 friend class StringPool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080083
Adam Lesinskicacb28f2016-10-19 12:18:14 -070084 explicit Ref(Entry* entry);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080085
Adam Lesinskice5e56e2016-10-21 17:56:45 -070086 Entry* entry_;
Adam Lesinskicacb28f2016-10-19 12:18:14 -070087 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080088
Adam Lesinskicacb28f2016-10-19 12:18:14 -070089 class StyleEntry;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080090
Adam Lesinskicacb28f2016-10-19 12:18:14 -070091 class StyleRef {
92 public:
93 StyleRef();
94 StyleRef(const StyleRef&);
95 ~StyleRef();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080096
Adam Lesinskicacb28f2016-10-19 12:18:14 -070097 StyleRef& operator=(const StyleRef& rhs);
Adam Lesinski75421622017-01-06 15:20:04 -080098 bool operator==(const StyleRef& rhs) const;
99 bool operator!=(const StyleRef& rhs) const;
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700100 const StyleEntry* operator->() const;
101 const StyleEntry& operator*() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800102
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700103 size_t index() const;
104 const Context& GetContext() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800105
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700106 private:
107 friend class StringPool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800108
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700109 explicit StyleRef(StyleEntry* entry);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800110
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700111 StyleEntry* entry_;
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700112 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800113
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700114 class Entry {
115 public:
116 std::string value;
117 Context context;
118 size_t index;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800119
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700120 private:
121 friend class StringPool;
122 friend class Ref;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800123
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700124 int ref_;
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700125 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800126
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700127 struct Span {
128 Ref name;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700129 uint32_t first_char;
130 uint32_t last_char;
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700131 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800132
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700133 class StyleEntry {
134 public:
135 Ref str;
136 std::vector<Span> spans;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800137
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700138 private:
139 friend class StringPool;
140 friend class StyleRef;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800141
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700142 int ref_;
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700143 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800144
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700145 using const_iterator = std::vector<std::unique_ptr<Entry>>::const_iterator;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800146
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700147 static bool FlattenUtf8(BigBuffer* out, const StringPool& pool);
148 static bool FlattenUtf16(BigBuffer* out, const StringPool& pool);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800149
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700150 StringPool() = default;
151 StringPool(const StringPool&) = delete;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800152
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700153 /**
154 * Adds a string to the pool, unless it already exists. Returns
155 * a reference to the string in the pool.
156 */
Adam Lesinskid5083f62017-01-16 15:07:21 -0800157 Ref MakeRef(const android::StringPiece& str);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800158
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700159 /**
160 * Adds a string to the pool, unless it already exists, with a context
161 * object that can be used when sorting the string pool. Returns
162 * a reference to the string in the pool.
163 */
Adam Lesinskid5083f62017-01-16 15:07:21 -0800164 Ref MakeRef(const android::StringPiece& str, const Context& context);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800165
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700166 /**
167 * Adds a style to the string pool and returns a reference to it.
168 */
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700169 StyleRef MakeRef(const StyleString& str);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800170
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700171 /**
172 * Adds a style to the string pool with a context object that
173 * can be used when sorting the string pool. Returns a reference
174 * to the style in the string pool.
175 */
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700176 StyleRef MakeRef(const StyleString& str, const Context& context);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800177
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700178 /**
179 * Adds a style from another string pool. Returns a reference to the
180 * style in the string pool.
181 */
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700182 StyleRef MakeRef(const StyleRef& ref);
Adam Lesinski769de982015-04-10 19:43:55 -0700183
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700184 /**
185 * Moves pool into this one without coalescing strings. When this
186 * function returns, pool will be empty.
187 */
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700188 void Merge(StringPool&& pool);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800189
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700190 /**
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700191 * Returns the number of strings in the table.
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700192 */
193 inline size_t size() const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800194
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700195 /**
196 * Reserves space for strings and styles as an optimization.
197 */
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700198 void HintWillAdd(size_t string_count, size_t style_count);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800199
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700200 /**
201 * Sorts the strings according to some comparison function.
202 */
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700203 void Sort(const std::function<bool(const Entry&, const Entry&)>& cmp);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800204
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700205 /**
206 * Removes any strings that have no references.
207 */
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700208 void Prune();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800209
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700210 private:
211 friend const_iterator begin(const StringPool& pool);
212 friend const_iterator end(const StringPool& pool);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800213
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700214 static bool Flatten(BigBuffer* out, const StringPool& pool, bool utf8);
Adam Lesinski24aad162015-04-24 19:19:30 -0700215
Adam Lesinskid5083f62017-01-16 15:07:21 -0800216 Ref MakeRefImpl(const android::StringPiece& str, const Context& context, bool unique);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800217
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700218 std::vector<std::unique_ptr<Entry>> strings_;
219 std::vector<std::unique_ptr<StyleEntry>> styles_;
Adam Lesinskid5083f62017-01-16 15:07:21 -0800220 std::unordered_multimap<android::StringPiece, Entry*> indexed_strings_;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800221};
222
223//
224// Inline implementation
225//
226
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700227inline size_t StringPool::size() const { return strings_.size(); }
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800228
229inline StringPool::const_iterator begin(const StringPool& pool) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700230 return pool.strings_.begin();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800231}
232
233inline StringPool::const_iterator end(const StringPool& pool) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700234 return pool.strings_.end();
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800235}
236
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700237} // namespace aapt
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800238
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700239#endif // AAPT_STRING_POOL_H