Util.h revision 24aad163bc88cb10d2275385e9afc3de7f342d65
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_UTIL_H 186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#define AAPT_UTIL_H 196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include "BigBuffer.h" 2124aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski#include "Maybe.h" 226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include "StringPiece.h" 236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <androidfw/ResourceTypes.h> 256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <functional> 266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <memory> 276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <ostream> 286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <string> 296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <vector> 306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskinamespace aapt { 326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskinamespace util { 336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistd::vector<std::string> split(const StringPiece& str, char sep); 356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistd::vector<std::string> splitAndLowercase(const StringPiece& str, char sep); 366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 384d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinski * Returns true if the string starts with prefix. 394d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinski */ 404d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinskitemplate <typename T> 414d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinskibool stringStartsWith(const BasicStringPiece<T>& str, const BasicStringPiece<T>& prefix) { 424d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinski if (str.size() < prefix.size()) { 434d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinski return false; 444d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinski } 454d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinski return str.substr(0, prefix.size()) == prefix; 464d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinski} 474d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinski 484d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinski/** 496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Returns true if the string ends with suffix. 506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 514d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinskitemplate <typename T> 524d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinskibool stringEndsWith(const BasicStringPiece<T>& str, const BasicStringPiece<T>& suffix) { 534d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinski if (str.size() < suffix.size()) { 544d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinski return false; 554d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinski } 564d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinski return str.substr(str.size() - suffix.size(), suffix.size()) == suffix; 574d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinski} 586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Creates a new StringPiece16 that points to a substring 616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * of the original string without leading or trailing whitespace. 626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam LesinskiStringPiece16 trimWhitespace(const StringPiece16& str); 646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * UTF-16 isspace(). It basically checks for lower range characters that are 676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * whitespace. 686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool isspace16(char16_t c) { 706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return c < 0x0080 && isspace(c); 716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Returns an iterator to the first character that is not alpha-numeric and that 756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * is not in the allowedChars set. 766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam LesinskiStringPiece16::const_iterator findNonAlphaNumericAndNotInSet(const StringPiece16& str, 786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski const StringPiece16& allowedChars); 796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 816f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Makes a std::unique_ptr<> with the template parameter inferred by the compiler. 826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * This will be present in C++14 and can be removed then. 836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename T, class... Args> 856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistd::unique_ptr<T> make_unique(Args&&... args) { 866f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return std::unique_ptr<T>(new T{std::forward<Args>(args)...}); 876f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 886f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Writes a set of items to the std::ostream, joining the times with the provided 916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * separator. 926f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename Iterator> 946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski::std::function<::std::ostream&(::std::ostream&)> joiner(Iterator begin, Iterator end, 956f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski const char* sep) { 966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return [begin, end, sep](::std::ostream& out) -> ::std::ostream& { 976f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski for (auto iter = begin; iter != end; ++iter) { 986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski if (iter != begin) { 996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski out << sep; 1006f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 1016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski out << *iter; 1026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 1036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return out; 1046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski }; 1056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline ::std::function<::std::ostream&(::std::ostream&)> formatSize(size_t size) { 1086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return [size](::std::ostream& out) -> ::std::ostream& { 109ca2fc353c2b07e24e297fdc8426c7abd601d908bAdam Lesinski constexpr size_t K = 1024u; 1106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski constexpr size_t M = K * K; 1111fce4f9c898d8053f4721e0f6ed85c9d07589f24Greg Hackmann constexpr size_t G = M * K; 1126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski if (size < K) { 1136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski out << size << "B"; 1146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } else if (size < M) { 1156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski out << (double(size) / K) << " KiB"; 1166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } else if (size < G) { 1176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski out << (double(size) / M) << " MiB"; 1186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } else { 1196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski out << (double(size) / G) << " GiB"; 1206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 1216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return out; 1226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski }; 1236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 1266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Helper method to extract a string from a StringPool. 1276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 1286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline StringPiece16 getString(const android::ResStringPool& pool, size_t idx) { 1296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski size_t len; 1306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski const char16_t* str = pool.stringAt(idx, &len); 1316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski if (str != nullptr) { 1326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return StringPiece16(str, len); 1336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 1346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return StringPiece16(); 1356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiclass StringBuilder { 1386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskipublic: 1396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski StringBuilder& append(const StringPiece16& str); 1406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski const std::u16string& str() const; 1416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski const std::string& error() const; 1426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski operator bool() const; 1436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprivate: 1456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski std::u16string mStr; 1466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski bool mQuote = false; 1476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski bool mTrailingSpace = false; 1486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski std::string mError; 1496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}; 1506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline const std::u16string& StringBuilder::str() const { 1526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return mStr; 1536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline const std::string& StringBuilder::error() const { 1566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return mError; 1576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline StringBuilder::operator bool() const { 1606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return mError.empty(); 1616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 1646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Converts a UTF8 string to a UTF16 string. 1656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 1666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistd::u16string utf8ToUtf16(const StringPiece& utf8); 1676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistd::string utf16ToUtf8(const StringPiece16& utf8); 1686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 1706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Writes the entire BigBuffer to the output stream. 1716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 1726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskibool writeAll(std::ostream& out, const BigBuffer& buffer); 1736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/* 1756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Copies the entire BigBuffer into a single buffer. 1766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 1776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistd::unique_ptr<uint8_t[]> copy(const BigBuffer& buffer); 1786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 1806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * A Tokenizer implemented as an iterable collection. It does not allocate 1816f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * any memory on the heap nor use standard containers. 1826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 1836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename Char> 1846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiclass Tokenizer { 1856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskipublic: 1866f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski class iterator { 1876f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski public: 1886f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski iterator(const iterator&) = default; 1896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski iterator& operator=(const iterator&) = default; 1906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski iterator& operator++(); 1926f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski BasicStringPiece<Char> operator*(); 1936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski bool operator==(const iterator& rhs) const; 1946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski bool operator!=(const iterator& rhs) const; 1956f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski private: 1976f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski friend class Tokenizer<Char>; 1986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski iterator(BasicStringPiece<Char> s, Char sep, BasicStringPiece<Char> tok); 2006f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski BasicStringPiece<Char> str; 2026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski Char separator; 2036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski BasicStringPiece<Char> token; 2046f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski }; 2056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski Tokenizer(BasicStringPiece<Char> str, Char sep); 2076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski iterator begin(); 2086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski iterator end(); 2096f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprivate: 2116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski const iterator mBegin; 2126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski const iterator mEnd; 2136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}; 2146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename Char> 2166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline Tokenizer<Char> tokenize(BasicStringPiece<Char> str, Char sep) { 2176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return Tokenizer<Char>(str, sep); 2186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename Char> 2216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitypename Tokenizer<Char>::iterator& Tokenizer<Char>::iterator::operator++() { 2226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski const Char* start = token.end(); 2236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski const Char* end = str.end(); 2246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski if (start == end) { 2256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski token.assign(token.end(), 0); 2266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return *this; 2276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 2286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski start += 1; 2306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski const Char* current = start; 2316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski while (current != end) { 2326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski if (*current == separator) { 2336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski token.assign(start, current - start); 2346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return *this; 2356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 2366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski ++current; 2376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 2386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski token.assign(start, end - start); 2396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return *this; 2406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename Char> 2436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline BasicStringPiece<Char> Tokenizer<Char>::iterator::operator*() { 2446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return token; 2456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename Char> 2486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool Tokenizer<Char>::iterator::operator==(const iterator& rhs) const { 2496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski // We check equality here a bit differently. 2506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski // We need to know that the addresses are the same. 2516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return token.begin() == rhs.token.begin() && token.end() == rhs.token.end(); 2526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename Char> 2556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool Tokenizer<Char>::iterator::operator!=(const iterator& rhs) const { 2566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return !(*this == rhs); 2576f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename Char> 2606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline Tokenizer<Char>::iterator::iterator(BasicStringPiece<Char> s, Char sep, 2616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski BasicStringPiece<Char> tok) : 2626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski str(s), separator(sep), token(tok) { 2636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename Char> 2666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline typename Tokenizer<Char>::iterator Tokenizer<Char>::begin() { 2676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return mBegin; 2686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename Char> 2716f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline typename Tokenizer<Char>::iterator Tokenizer<Char>::end() { 2726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return mEnd; 2736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename Char> 2766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline Tokenizer<Char>::Tokenizer(BasicStringPiece<Char> str, Char sep) : 2776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski mBegin(++iterator(str, sep, BasicStringPiece<Char>(str.begin() - 1, 0))), 2786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski mEnd(str, sep, BasicStringPiece<Char>(str.end(), 0)) { 2796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 28124aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski/** 28224aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski * Returns a package name if the namespace URI is of the form: 28324aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski * http://schemas.android.com/apk/res/<package> 28424aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski * 28524aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski * Special case: if namespaceUri is http://schemas.android.com/apk/res-auto, 28624aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski * returns an empty package name. 28724aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski */ 28824aad163bc88cb10d2275385e9afc3de7f342d65Adam LesinskiMaybe<std::u16string> extractPackageFromNamespace(const std::u16string& namespaceUri); 28924aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski 2906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} // namespace util 2916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2926f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 2936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Stream operator for functions. Calls the function with the stream as an argument. 2946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * In the aapt namespace for lookup. 2956f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 2966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline ::std::ostream& operator<<(::std::ostream& out, 2976f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski ::std::function<::std::ostream&(::std::ostream&)> f) { 2986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski return f(out); 2996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 3006f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 3016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} // namespace aapt 3026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 3036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#endif // AAPT_UTIL_H 304