Home | History | Annotate | Download | only in aapt2
      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