AAPT2
First checking of AAPT2. The individual phases of AAPT2 work, but there
are some missing pieces.
For early testing we are missing:
- Need to properly mark file references and include them in package
- Need to package into zip
Final AAPT for apps we are missing:
- Need to crush PNGs
- Need to parse 9-patches
- Need to validate all of AndroidManifest.xml
- Need to write align method to align resource tables for splits.
Final AAPT for apps + system we are missing:
- Need to handle overlays
- Need to store comments for R file
- Need to handle --shared-lib (dynamic references too).
New AAPT features coming:
- Need to import compiled libraries
- Name mangling
- R file generation for library code
Change-Id: I95f8a63581b81a1f424ae6fb2c373c883b72c18d
diff --git a/tools/aapt2/Util.h b/tools/aapt2/Util.h
new file mode 100644
index 0000000..4c5249be
--- /dev/null
+++ b/tools/aapt2/Util.h
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AAPT_UTIL_H
+#define AAPT_UTIL_H
+
+#include "BigBuffer.h"
+#include "StringPiece.h"
+
+#include <androidfw/ResourceTypes.h>
+#include <functional>
+#include <memory>
+#include <ostream>
+#include <string>
+#include <vector>
+
+namespace aapt {
+namespace util {
+
+std::vector<std::string> split(const StringPiece& str, char sep);
+std::vector<std::string> splitAndLowercase(const StringPiece& str, char sep);
+
+/**
+ * Returns true if the string ends with suffix.
+ */
+bool stringEndsWith(const StringPiece& str, const StringPiece& suffix);
+
+/**
+ * Creates a new StringPiece16 that points to a substring
+ * of the original string without leading or trailing whitespace.
+ */
+StringPiece16 trimWhitespace(const StringPiece16& str);
+
+/**
+ * UTF-16 isspace(). It basically checks for lower range characters that are
+ * whitespace.
+ */
+inline bool isspace16(char16_t c) {
+ return c < 0x0080 && isspace(c);
+}
+
+/**
+ * Returns an iterator to the first character that is not alpha-numeric and that
+ * is not in the allowedChars set.
+ */
+StringPiece16::const_iterator findNonAlphaNumericAndNotInSet(const StringPiece16& str,
+ const StringPiece16& allowedChars);
+
+/**
+ * Makes a std::unique_ptr<> with the template parameter inferred by the compiler.
+ * This will be present in C++14 and can be removed then.
+ */
+template <typename T, class... Args>
+std::unique_ptr<T> make_unique(Args&&... args) {
+ return std::unique_ptr<T>(new T{std::forward<Args>(args)...});
+}
+
+/**
+ * Writes a set of items to the std::ostream, joining the times with the provided
+ * separator.
+ */
+template <typename Iterator>
+::std::function<::std::ostream&(::std::ostream&)> joiner(Iterator begin, Iterator end,
+ const char* sep) {
+ return [begin, end, sep](::std::ostream& out) -> ::std::ostream& {
+ for (auto iter = begin; iter != end; ++iter) {
+ if (iter != begin) {
+ out << sep;
+ }
+ out << *iter;
+ }
+ return out;
+ };
+}
+
+inline ::std::function<::std::ostream&(::std::ostream&)> formatSize(size_t size) {
+ return [size](::std::ostream& out) -> ::std::ostream& {
+ constexpr size_t K = 1024;
+ constexpr size_t M = K * K;
+ constexpr size_t G = M * M;
+ if (size < K) {
+ out << size << "B";
+ } else if (size < M) {
+ out << (double(size) / K) << " KiB";
+ } else if (size < G) {
+ out << (double(size) / M) << " MiB";
+ } else {
+ out << (double(size) / G) << " GiB";
+ }
+ return out;
+ };
+}
+
+/**
+ * Helper method to extract a string from a StringPool.
+ */
+inline StringPiece16 getString(const android::ResStringPool& pool, size_t idx) {
+ size_t len;
+ const char16_t* str = pool.stringAt(idx, &len);
+ if (str != nullptr) {
+ return StringPiece16(str, len);
+ }
+ return StringPiece16();
+}
+
+class StringBuilder {
+public:
+ StringBuilder& append(const StringPiece16& str);
+ const std::u16string& str() const;
+ const std::string& error() const;
+ operator bool() const;
+
+private:
+ std::u16string mStr;
+ bool mQuote = false;
+ bool mTrailingSpace = false;
+ std::string mError;
+};
+
+inline const std::u16string& StringBuilder::str() const {
+ return mStr;
+}
+
+inline const std::string& StringBuilder::error() const {
+ return mError;
+}
+
+inline StringBuilder::operator bool() const {
+ return mError.empty();
+}
+
+/**
+ * Converts a UTF8 string to a UTF16 string.
+ */
+std::u16string utf8ToUtf16(const StringPiece& utf8);
+std::string utf16ToUtf8(const StringPiece16& utf8);
+
+/**
+ * Writes the entire BigBuffer to the output stream.
+ */
+bool writeAll(std::ostream& out, const BigBuffer& buffer);
+
+/*
+ * Copies the entire BigBuffer into a single buffer.
+ */
+std::unique_ptr<uint8_t[]> copy(const BigBuffer& buffer);
+
+/**
+ * A Tokenizer implemented as an iterable collection. It does not allocate
+ * any memory on the heap nor use standard containers.
+ */
+template <typename Char>
+class Tokenizer {
+public:
+ class iterator {
+ public:
+ iterator(const iterator&) = default;
+ iterator& operator=(const iterator&) = default;
+
+ iterator& operator++();
+ BasicStringPiece<Char> operator*();
+ bool operator==(const iterator& rhs) const;
+ bool operator!=(const iterator& rhs) const;
+
+ private:
+ friend class Tokenizer<Char>;
+
+ iterator(BasicStringPiece<Char> s, Char sep, BasicStringPiece<Char> tok);
+
+ BasicStringPiece<Char> str;
+ Char separator;
+ BasicStringPiece<Char> token;
+ };
+
+ Tokenizer(BasicStringPiece<Char> str, Char sep);
+ iterator begin();
+ iterator end();
+
+private:
+ const iterator mBegin;
+ const iterator mEnd;
+};
+
+template <typename Char>
+inline Tokenizer<Char> tokenize(BasicStringPiece<Char> str, Char sep) {
+ return Tokenizer<Char>(str, sep);
+}
+
+template <typename Char>
+typename Tokenizer<Char>::iterator& Tokenizer<Char>::iterator::operator++() {
+ const Char* start = token.end();
+ const Char* end = str.end();
+ if (start == end) {
+ token.assign(token.end(), 0);
+ return *this;
+ }
+
+ start += 1;
+ const Char* current = start;
+ while (current != end) {
+ if (*current == separator) {
+ token.assign(start, current - start);
+ return *this;
+ }
+ ++current;
+ }
+ token.assign(start, end - start);
+ return *this;
+}
+
+template <typename Char>
+inline BasicStringPiece<Char> Tokenizer<Char>::iterator::operator*() {
+ return token;
+}
+
+template <typename Char>
+inline bool Tokenizer<Char>::iterator::operator==(const iterator& rhs) const {
+ // We check equality here a bit differently.
+ // We need to know that the addresses are the same.
+ return token.begin() == rhs.token.begin() && token.end() == rhs.token.end();
+}
+
+template <typename Char>
+inline bool Tokenizer<Char>::iterator::operator!=(const iterator& rhs) const {
+ return !(*this == rhs);
+}
+
+template <typename Char>
+inline Tokenizer<Char>::iterator::iterator(BasicStringPiece<Char> s, Char sep,
+ BasicStringPiece<Char> tok) :
+ str(s), separator(sep), token(tok) {
+}
+
+template <typename Char>
+inline typename Tokenizer<Char>::iterator Tokenizer<Char>::begin() {
+ return mBegin;
+}
+
+template <typename Char>
+inline typename Tokenizer<Char>::iterator Tokenizer<Char>::end() {
+ return mEnd;
+}
+
+template <typename Char>
+inline Tokenizer<Char>::Tokenizer(BasicStringPiece<Char> str, Char sep) :
+ mBegin(++iterator(str, sep, BasicStringPiece<Char>(str.begin() - 1, 0))),
+ mEnd(str, sep, BasicStringPiece<Char>(str.end(), 0)) {
+}
+
+} // namespace util
+
+/**
+ * Stream operator for functions. Calls the function with the stream as an argument.
+ * In the aapt namespace for lookup.
+ */
+inline ::std::ostream& operator<<(::std::ostream& out,
+ ::std::function<::std::ostream&(::std::ostream&)> f) {
+ return f(out);
+}
+
+} // namespace aapt
+
+#endif // AAPT_UTIL_H