AAPT2: Fix overlay support
Supports the <add-resource> tag and mimics old AAPT behavior of
not allowing new resources defined unless <add-resource> was used
or --auto-add-overlay was specified.
Change-Id: I9b461137357617ade37fd7045b418b8e6450b9c4
diff --git a/tools/aapt2/io/ZipArchive.h b/tools/aapt2/io/ZipArchive.h
index 98afc49..5ad119d 100644
--- a/tools/aapt2/io/ZipArchive.h
+++ b/tools/aapt2/io/ZipArchive.h
@@ -20,7 +20,7 @@
#include "io/File.h"
#include "util/StringPiece.h"
-#include <utils/FileMap.h>
+#include <map>
#include <ziparchive/zip_archive.h>
namespace aapt {
@@ -32,37 +32,10 @@
*/
class ZipFile : public IFile {
public:
- ZipFile(ZipArchiveHandle handle, const ZipEntry& entry, const Source& source) :
- mZipHandle(handle), mZipEntry(entry), mSource(source) {
- }
+ ZipFile(ZipArchiveHandle handle, const ZipEntry& entry, const Source& source);
- std::unique_ptr<IData> openAsData() override {
- if (mZipEntry.method == kCompressStored) {
- int fd = GetFileDescriptor(mZipHandle);
-
- android::FileMap fileMap;
- bool result = fileMap.create(nullptr, fd, mZipEntry.offset,
- mZipEntry.uncompressed_length, true);
- if (!result) {
- return {};
- }
- return util::make_unique<MmappedData>(std::move(fileMap));
-
- } else {
- std::unique_ptr<uint8_t[]> data = std::unique_ptr<uint8_t[]>(
- new uint8_t[mZipEntry.uncompressed_length]);
- int32_t result = ExtractToMemory(mZipHandle, &mZipEntry, data.get(),
- static_cast<uint32_t>(mZipEntry.uncompressed_length));
- if (result != 0) {
- return {};
- }
- return util::make_unique<MallocData>(std::move(data), mZipEntry.uncompressed_length);
- }
- }
-
- const Source& getSource() const override {
- return mSource;
- }
+ std::unique_ptr<IData> openAsData() override;
+ const Source& getSource() const override;
private:
ZipArchiveHandle mZipHandle;
@@ -70,71 +43,38 @@
Source mSource;
};
+class ZipFileCollection;
+
+class ZipFileCollectionIterator : public IFileCollectionIterator {
+public:
+ ZipFileCollectionIterator(ZipFileCollection* collection);
+
+ bool hasNext() override;
+ io::IFile* next() override;
+
+private:
+ std::map<std::string, std::unique_ptr<IFile>>::const_iterator mCurrent, mEnd;
+};
+
/**
* An IFileCollection that represents a ZIP archive and the entries within it.
*/
class ZipFileCollection : public IFileCollection {
public:
static std::unique_ptr<ZipFileCollection> create(const StringPiece& path,
- std::string* outError) {
- std::unique_ptr<ZipFileCollection> collection = std::unique_ptr<ZipFileCollection>(
- new ZipFileCollection());
+ std::string* outError);
- int32_t result = OpenArchive(path.data(), &collection->mHandle);
- if (result != 0) {
- if (outError) *outError = ErrorCodeString(result);
- return {};
- }
+ io::IFile* findFile(const StringPiece& path) override;
+ std::unique_ptr<IFileCollectionIterator> iterator() override;
- ZipString suffix(".flat");
- void* cookie = nullptr;
- result = StartIteration(collection->mHandle, &cookie, nullptr, &suffix);
- if (result != 0) {
- if (outError) *outError = ErrorCodeString(result);
- return {};
- }
-
- using IterationEnder = std::unique_ptr<void, decltype(EndIteration)*>;
- IterationEnder iterationEnder(cookie, EndIteration);
-
- ZipString zipEntryName;
- ZipEntry zipData;
- while ((result = Next(cookie, &zipData, &zipEntryName)) == 0) {
- std::string nestedPath = path.toString();
- nestedPath += "@" + std::string(reinterpret_cast<const char*>(zipEntryName.name),
- zipEntryName.name_length);
- collection->mFiles.push_back(util::make_unique<ZipFile>(collection->mHandle,
- zipData,
- Source(nestedPath)));
- }
-
- if (result != -1) {
- if (outError) *outError = ErrorCodeString(result);
- return {};
- }
- return collection;
- }
-
- const_iterator begin() const override {
- return mFiles.begin();
- }
-
- const_iterator end() const override {
- return mFiles.end();
- }
-
- ~ZipFileCollection() override {
- if (mHandle) {
- CloseArchive(mHandle);
- }
- }
+ ~ZipFileCollection() override;
private:
- ZipFileCollection() : mHandle(nullptr) {
- }
+ friend class ZipFileCollectionIterator;
+ ZipFileCollection();
ZipArchiveHandle mHandle;
- std::vector<std::unique_ptr<IFile>> mFiles;
+ std::map<std::string, std::unique_ptr<IFile>> mFiles;
};
} // namespace io