16f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/*
26f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Copyright (C) 2015 The Android Open Source Project
36f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
46f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
56f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * you may not use this file except in compliance with the License.
66f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * You may obtain a copy of the License at
76f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
86f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
96f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski *
106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Unless required by applicable law or agreed to in writing, software
116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * See the License for the specific language governing permissions and
146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * limitations under the License.
156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */
166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#ifndef AAPT_STRING_POOL_H
186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#define AAPT_STRING_POOL_H
196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include "BigBuffer.h"
216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include "ConfigDescription.h"
226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include "StringPiece.h"
236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <functional>
256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <map>
266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <memory>
276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <string>
286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <vector>
296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskinamespace aapt {
316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct Span {
336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    std::u16string name;
346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    uint32_t firstChar;
356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    uint32_t lastChar;
366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistruct StyleString {
396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    std::u16string str;
406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    std::vector<Span> spans;
416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiclass StringPool {
446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskipublic:
456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    struct Context {
466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        uint32_t priority;
476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ConfigDescription config;
486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    };
496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    class Entry;
516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    class Ref {
536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    public:
546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        Ref();
556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        Ref(const Ref&);
566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ~Ref();
576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        Ref& operator=(const Ref& rhs);
596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        const std::u16string* operator->() const;
606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        const std::u16string& operator*() const;
616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        size_t getIndex() const;
636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        const Context& getContext() const;
646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    private:
666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        friend class StringPool;
676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        Ref(Entry* entry);
696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        Entry* mEntry;
716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    };
726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    class StyleEntry;
746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    class StyleRef {
766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    public:
776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        StyleRef();
786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        StyleRef(const StyleRef&);
796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        ~StyleRef();
806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
816f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        StyleRef& operator=(const StyleRef& rhs);
826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        const StyleEntry* operator->() const;
836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        const StyleEntry& operator*() const;
846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        size_t getIndex() const;
866f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        const Context& getContext() const;
876f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
886f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    private:
896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        friend class StringPool;
906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        StyleRef(StyleEntry* entry);
926f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        StyleEntry* mEntry;
946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    };
956f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    class Entry {
976f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    public:
986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        std::u16string value;
996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        Context context;
1006f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        size_t index;
1016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    private:
1036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        friend class StringPool;
1046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        friend class Ref;
1056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        int ref;
1076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    };
1086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1096f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    struct Span {
1106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        Ref name;
1116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        uint32_t firstChar;
1126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        uint32_t lastChar;
1136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    };
1146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    class StyleEntry {
1166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    public:
1176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        Ref str;
1186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        std::vector<Span> spans;
1196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    private:
1216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        friend class StringPool;
1226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        friend class StyleRef;
1236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        int ref;
1256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    };
1266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    using const_iterator = std::vector<std::unique_ptr<Entry>>::const_iterator;
1286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    static bool flattenUtf8(BigBuffer* out, const StringPool& pool);
13024aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski    static bool flattenUtf16(BigBuffer* out, const StringPool& pool);
1316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    StringPool() = default;
1336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    StringPool(const StringPool&) = delete;
1346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    /**
1366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     * Adds a string to the pool, unless it already exists. Returns
1376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     * a reference to the string in the pool.
1386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     */
1396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    Ref makeRef(const StringPiece16& str);
1406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    /**
1426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     * Adds a string to the pool, unless it already exists, with a context
1436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     * object that can be used when sorting the string pool. Returns
1446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     * a reference to the string in the pool.
1456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     */
1466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    Ref makeRef(const StringPiece16& str, const Context& context);
1476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    /**
1496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     * Adds a style to the string pool and returns a reference to it.
1506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     */
1516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    StyleRef makeRef(const StyleString& str);
1526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    /**
1546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     * Adds a style to the string pool with a context object that
1556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     * can be used when sorting the string pool. Returns a reference
1566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     * to the style in the string pool.
1576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     */
1586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    StyleRef makeRef(const StyleString& str, const Context& context);
1596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    /**
161769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * Adds a style from another string pool. Returns a reference to the
162769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     * style in the string pool.
163769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski     */
164769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    StyleRef makeRef(const StyleRef& ref);
165769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski
166769de98f2dd41bfe39a1c9f76aefd1ad58942733Adam Lesinski    /**
1676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     * Moves pool into this one without coalescing strings. When this
1686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     * function returns, pool will be empty.
1696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     */
1706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    void merge(StringPool&& pool);
1716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    /**
1736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     * Retuns the number of strings in the table.
1746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     */
1756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    inline size_t size() const;
1766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    /**
1786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     * Reserves space for strings and styles as an optimization.
1796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     */
1806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    void hintWillAdd(size_t stringCount, size_t styleCount);
1816f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    /**
1836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     * Sorts the strings according to some comparison function.
1846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     */
1856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    void sort(const std::function<bool(const Entry&, const Entry&)>& cmp);
1866f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1876f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    /**
1886f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     * Removes any strings that have no references.
1896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski     */
1906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    void prune();
1916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
1926f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprivate:
1936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    friend const_iterator begin(const StringPool& pool);
1946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    friend const_iterator end(const StringPool& pool);
1956f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
19624aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski    static bool flatten(BigBuffer* out, const StringPool& pool, bool utf8);
19724aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski
1986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    Ref makeRefImpl(const StringPiece16& str, const Context& context, bool unique);
1996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2006f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    std::vector<std::unique_ptr<Entry>> mStrings;
2016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    std::vector<std::unique_ptr<StyleEntry>> mStyles;
2026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    std::multimap<StringPiece16, Entry*> mIndexedStrings;
2036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski};
2046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski//
2066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski// Inline implementation
2076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski//
2086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2096f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline size_t StringPool::size() const {
2106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return mStrings.size();
2116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline StringPool::const_iterator begin(const StringPool& pool) {
2146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return pool.mStrings.begin();
2156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline StringPool::const_iterator end(const StringPool& pool) {
2186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return pool.mStrings.end();
2196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}
2206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} // namespace aapt
2226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
2236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#endif // AAPT_STRING_POOL_H
224