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