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 <functional> 216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <memory> 226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <ostream> 236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <string> 246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <vector> 256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 26ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "androidfw/ResourceTypes.h" 27d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski#include "androidfw/StringPiece.h" 28ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "utils/ByteOrder.h" 29ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 30ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "util/BigBuffer.h" 31ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "util/Maybe.h" 32ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 33ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#ifdef _WIN32 34ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski// TODO(adamlesinski): remove once http://b/32447322 is resolved. 35ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski// utils/ByteOrder.h includes winsock2.h on WIN32, 36ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski// which will pull in the ERROR definition. This conflicts 37ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski// with android-base/logging.h, which takes care of undefining 38ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski// ERROR, but it gets included too early (before winsock2.h). 39ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#ifdef ERROR 40ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#undef ERROR 41ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#endif 42ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#endif 43ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskinamespace aapt { 456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskinamespace util { 466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 47c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinskitemplate <typename T> 48c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinskistruct Range { 49c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski T start; 50c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski T end; 51c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski}; 52c744ae8aca97edfb2422598ea620e8219449fa9bAdam Lesinski 53d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskistd::vector<std::string> Split(const android::StringPiece& str, char sep); 54d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskistd::vector<std::string> SplitAndLowercase(const android::StringPiece& str, char sep); 556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 574d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinski * Returns true if the string starts with prefix. 584d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinski */ 59d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskibool StartsWith(const android::StringPiece& str, const android::StringPiece& prefix); 604d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinski 614d3a987694f6f6b95d8a0f1542618223ce253e6dAdam Lesinski/** 626f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Returns true if the string ends with suffix. 636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 64d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskibool EndsWith(const android::StringPiece& str, const android::StringPiece& suffix); 656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 666f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Creates a new StringPiece16 that points to a substring 686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * of the original string without leading or trailing whitespace. 696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 70d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiandroid::StringPiece TrimWhitespace(const android::StringPiece& str); 713b4cd94034ff3e5567a2ba6da35d640ff61db4b9Adam Lesinski 726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * UTF-16 isspace(). It basically checks for lower range characters that are 746f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * whitespace. 756f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 76cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskiinline bool isspace16(char16_t c) { return c < 0x0080 && isspace(c); } 776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Returns an iterator to the first character that is not alpha-numeric and that 806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * is not in the allowedChars set. 816f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 82d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiandroid::StringPiece::const_iterator FindNonAlphaNumericAndNotInSet( 83d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski const android::StringPiece& str, const android::StringPiece& allowed_chars); 846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 86a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski * Tests that the string is a valid Java class name. 87a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski */ 88d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskibool IsJavaClassName(const android::StringPiece& str); 89a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 90a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski/** 911ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Tests that the string is a valid Java package name. 921ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */ 93d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskibool IsJavaPackageName(const android::StringPiece& str); 941ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 951ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/** 96cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * Converts the class name to a fully qualified class name from the given 97cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * `package`. Ex: 98a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski * 99a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski * asdf --> package.asdf 100a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski * .asdf --> package.asdf 101a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski * .a.b --> package.a.b 102a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski * asdf.adsf --> asdf.adsf 103a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski */ 104d5083f6f6b9bc76bbe64052bcec639eee752a321Adam LesinskiMaybe<std::string> GetFullyQualifiedClassName(const android::StringPiece& package, 105d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski const android::StringPiece& class_name); 106a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 107a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski/** 108d0f492db038c6210c1138865d816bfb134376538Adam Lesinski * Makes a std::unique_ptr<> with the template parameter inferred by the compiler. 1096f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * This will be present in C++14 and can be removed then. 1106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 1116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename T, class... Args> 1126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskistd::unique_ptr<T> make_unique(Args&&... args) { 113cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return std::unique_ptr<T>(new T{std::forward<Args>(args)...}); 1146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 117cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * Writes a set of items to the std::ostream, joining the times with the 118cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * provided 1196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * separator. 1206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 12136c73a595910e96f3552f938eeb81d46356067a1Adam Lesinskitemplate <typename Container> 122ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski::std::function<::std::ostream&(::std::ostream&)> Joiner( 123cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const Container& container, const char* sep) { 124cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski using std::begin; 125cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski using std::end; 126ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const auto begin_iter = begin(container); 127ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const auto end_iter = end(container); 128ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return [begin_iter, end_iter, sep](::std::ostream& out) -> ::std::ostream& { 129ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski for (auto iter = begin_iter; iter != end_iter; ++iter) { 130ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (iter != begin_iter) { 131cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski out << sep; 132cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 133cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski out << *iter; 134cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 135cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return out; 136cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski }; 1376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 140cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * Helper method to extract a UTF-16 string from a StringPool. If the string is 141cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * stored as UTF-8, 142d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski * the conversion to UTF-16 happens within ResStringPool. 1436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 144d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiandroid::StringPiece16 GetString16(const android::ResStringPool& pool, size_t idx); 1456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 146d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski/** 147cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * Helper method to extract a UTF-8 string from a StringPool. If the string is 148cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * stored as UTF-16, 149cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * the conversion from UTF-16 to UTF-8 does not happen in ResStringPool and is 150cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * done by this method, 151cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * which maintains no state or cache. This means we must return an std::string 152cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * copy. 153d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski */ 154ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskistd::string GetString(const android::ResStringPool& pool, size_t idx); 15528cacf091ad2b1c2749e77f590e9523e58735252Adam Lesinski 156b23f1e077b02a1d62bcf5e34655e8dc979e124faAdam Lesinski/** 157cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * Checks that the Java string format contains no non-positional arguments 158cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * (arguments without 159cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * explicitly specifying an index) when there are more than one argument. This 160cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * is an error 161cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * because translations may rearrange the order of the arguments in the string, 162cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * which will 163b23f1e077b02a1d62bcf5e34655e8dc979e124faAdam Lesinski * break the string interpolation. 164b23f1e077b02a1d62bcf5e34655e8dc979e124faAdam Lesinski */ 165d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskibool VerifyJavaStringFormat(const android::StringPiece& str); 166b23f1e077b02a1d62bcf5e34655e8dc979e124faAdam Lesinski 1676f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiclass StringBuilder { 168cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public: 169d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski StringBuilder& Append(const android::StringPiece& str); 170ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const std::string& ToString() const; 171ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const std::string& Error() const; 172ac6edc501b61e14e3b70ccbbd4d8ed112d92b96cAdam Lesinski bool IsEmpty() const; 173cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 174cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski // When building StyledStrings, we need UTF-16 indices into the string, 175cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski // which is what the Java layer expects when dealing with java 176cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski // String.charAt(). 177ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski size_t Utf16Len() const; 178cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 179ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski explicit operator bool() const; 180cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 181cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski private: 182ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::string str_; 183ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski size_t utf16_len_ = 0; 184ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool quote_ = false; 185ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool trailing_space_ = false; 186ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool last_char_was_escape_ = false; 187ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::string error_; 1886f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}; 1896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 190ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline const std::string& StringBuilder::ToString() const { return str_; } 1916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 192ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline const std::string& StringBuilder::Error() const { return error_; } 1936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 194ac6edc501b61e14e3b70ccbbd4d8ed112d92b96cAdam Lesinskiinline bool StringBuilder::IsEmpty() const { return str_.empty(); } 195ac6edc501b61e14e3b70ccbbd4d8ed112d92b96cAdam Lesinski 196ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline size_t StringBuilder::Utf16Len() const { return utf16_len_; } 1978c3f31f022f7e094fd227ef0c2987e0846cb3e43Adam Lesinski 198ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline StringBuilder::operator bool() const { return error_.empty(); } 1996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2006f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 2016f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Converts a UTF8 string to a UTF16 string. 2026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 203d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskistd::u16string Utf8ToUtf16(const android::StringPiece& utf8); 204d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskistd::string Utf16ToUtf8(const android::StringPiece16& utf16); 2056f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 2076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Writes the entire BigBuffer to the output stream. 2086f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 209ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskibool WriteAll(std::ostream& out, const BigBuffer& buffer); 2106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/* 2126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Copies the entire BigBuffer into a single buffer. 2136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 214ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskistd::unique_ptr<uint8_t[]> Copy(const BigBuffer& buffer); 2156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 2176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * A Tokenizer implemented as an iterable collection. It does not allocate 2186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * any memory on the heap nor use standard containers. 2196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 2206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiclass Tokenizer { 221cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public: 222cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski class iterator { 223cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public: 224cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski iterator(const iterator&) = default; 225cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski iterator& operator=(const iterator&) = default; 2266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 227cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski iterator& operator++(); 228d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski 229d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski android::StringPiece operator*() { return token_; } 230cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski bool operator==(const iterator& rhs) const; 231cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski bool operator!=(const iterator& rhs) const; 2326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 233cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski private: 234cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski friend class Tokenizer; 2356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 236d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski iterator(android::StringPiece s, char sep, android::StringPiece tok, bool end); 2376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 238d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski android::StringPiece str_; 239ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski char separator_; 240d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski android::StringPiece token_; 241ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool end_; 242cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski }; 2436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 244d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski Tokenizer(android::StringPiece str, char sep); 2456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 246ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski iterator begin() { return begin_; } 2476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 248ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski iterator end() { return end_; } 2496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 250cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski private: 251ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const iterator begin_; 252ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const iterator end_; 253d0f116b619feede0cfdb647157ce5ab4d50a1c46Adam Lesinski}; 2546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 255d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline Tokenizer Tokenize(const android::StringPiece& str, char sep) { return Tokenizer(str, sep); } 2566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 257ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline uint16_t HostToDevice16(uint16_t value) { return htods(value); } 2581ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 259ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline uint32_t HostToDevice32(uint32_t value) { return htodl(value); } 2601ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 261ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline uint16_t DeviceToHost16(uint16_t value) { return dtohs(value); } 2621ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 263ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiinline uint32_t DeviceToHost32(uint32_t value) { return dtohl(value); } 2641ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 26524aad163bc88cb10d2275385e9afc3de7f342d65Adam Lesinski/** 2661ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Given a path like: res/xml-sw600dp/foo.xml 2671ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * 2681ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Extracts "res/xml-sw600dp/" into outPrefix. 2691ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Extracts "foo" into outEntry. 2701ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Extracts ".xml" into outSuffix. 2711ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * 2721ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Returns true if successful. 2731ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */ 274d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskibool ExtractResFilePathParts(const android::StringPiece& path, android::StringPiece* out_prefix, 275d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski android::StringPiece* out_entry, android::StringPiece* out_suffix); 2761ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 277cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski} // namespace util 2786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/** 280cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * Stream operator for functions. Calls the function with the stream as an 281cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski * argument. 2826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * In the aapt namespace for lookup. 2836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 284cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskiinline ::std::ostream& operator<<( 285cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski ::std::ostream& out, 286cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const ::std::function<::std::ostream&(::std::ostream&)>& f) { 287cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return f(out); 2886f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2896f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 290cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski} // namespace aapt 2916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 292cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski#endif // AAPT_UTIL_H 293