11ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/* 21ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Copyright (C) 2015 The Android Open Source Project 31ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * 41ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 51ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * you may not use this file except in compliance with the License. 61ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * You may obtain a copy of the License at 71ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * 81ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 91ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * 101ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Unless required by applicable law or agreed to in writing, software 111ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 121ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * See the License for the specific language governing permissions and 141ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * limitations under the License. 151ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */ 161ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 171ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "flatten/Archive.h" 181ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 19a40e972fdaa68fc486ff90a319195515819068b2Adam Lesinski#include <cstdio> 201ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include <memory> 211ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include <string> 221ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include <vector> 231ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 2406460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski#include "android-base/errors.h" 25ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "android-base/macros.h" 26d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski#include "androidfw/StringPiece.h" 27ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "ziparchive/zip_writer.h" 28ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 29ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "util/Files.h" 30d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski 31d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiusing android::StringPiece; 32ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 331ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskinamespace aapt { 341ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 351ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskinamespace { 361ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 37ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiclass DirectoryWriter : public IArchiveWriter { 38ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski public: 39ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski DirectoryWriter() = default; 40cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 4106460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski bool Open(const StringPiece& out_dir) { 42d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski dir_ = out_dir.to_string(); 43ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski file::FileType type = file::GetFileType(dir_); 44cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski if (type == file::FileType::kNonexistant) { 4506460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski error_ = "directory does not exist"; 46cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return false; 47cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } else if (type != file::FileType::kDirectory) { 4806460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski error_ = "not a directory"; 49cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return false; 50cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 51cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return true; 52cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 53cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 54ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool StartEntry(const StringPiece& path, uint32_t flags) override { 55ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (file_) { 56cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return false; 57cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 58cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 59ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::string full_path = dir_; 60ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski file::AppendPath(&full_path, path); 61ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski file::mkdirs(file::GetStem(full_path)); 62cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 63ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski file_ = {fopen(full_path.data(), "wb"), fclose}; 64ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (!file_) { 6506460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski error_ = android::base::SystemErrorCodeToString(errno); 66cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return false; 67cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 68cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return true; 69cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 70cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 7106460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski bool Write(const void* data, int len) override { 72ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (!file_) { 73cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return false; 74cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 75cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 7606460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski if (fwrite(data, 1, len, file_.get()) != static_cast<size_t>(len)) { 7706460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski error_ = android::base::SystemErrorCodeToString(errno); 78ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski file_.reset(nullptr); 79cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return false; 80cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 81cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return true; 82cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 83cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 84ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool FinishEntry() override { 85ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (!file_) { 86cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return false; 871ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 88ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski file_.reset(nullptr); 89cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return true; 90cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 91ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 9206460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski bool WriteFile(const StringPiece& path, uint32_t flags, io::InputStream* in) override { 9306460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski if (!StartEntry(path, flags)) { 9406460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski return false; 9506460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski } 9606460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski 9706460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski const void* data = nullptr; 9806460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski size_t len = 0; 9906460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski while (in->Next(&data, &len)) { 10006460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski if (!Write(data, static_cast<int>(len))) { 10106460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski return false; 10206460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski } 10306460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski } 10406460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski return !in->HadError(); 10506460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski } 10606460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski 10706460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski bool HadError() const override { return !error_.empty(); } 10806460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski 10906460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski std::string GetError() const override { return error_; } 11006460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski 111ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski private: 112ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski DISALLOW_COPY_AND_ASSIGN(DirectoryWriter); 113ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 114ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::string dir_; 115ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::unique_ptr<FILE, decltype(fclose)*> file_ = {nullptr, fclose}; 11606460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski std::string error_; 1171ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski}; 1181ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 119ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiclass ZipFileWriter : public IArchiveWriter { 120ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski public: 121ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski ZipFileWriter() = default; 122cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 12306460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski bool Open(const StringPiece& path) { 124ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski file_ = {fopen(path.data(), "w+b"), fclose}; 125ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (!file_) { 12606460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski error_ = android::base::SystemErrorCodeToString(errno); 127cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return false; 1281ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 129ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski writer_ = util::make_unique<ZipWriter>(file_.get()); 130cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return true; 131cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 1321ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 133ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool StartEntry(const StringPiece& path, uint32_t flags) override { 134ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (!writer_) { 135cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return false; 136cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 1371ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 138ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski size_t zip_flags = 0; 139cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski if (flags & ArchiveEntry::kCompress) { 140ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski zip_flags |= ZipWriter::kCompress; 141cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 142a40e972fdaa68fc486ff90a319195515819068b2Adam Lesinski 143cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski if (flags & ArchiveEntry::kAlign) { 144ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski zip_flags |= ZipWriter::kAlign32; 145a40e972fdaa68fc486ff90a319195515819068b2Adam Lesinski } 1461ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 147ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski int32_t result = writer_->StartEntry(path.data(), zip_flags); 148cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski if (result != 0) { 14906460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski error_ = ZipWriter::ErrorCodeString(result); 150cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return false; 151cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 152cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return true; 153cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 154cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 15506460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski bool Write(const void* data, int len) override { 156ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski int32_t result = writer_->WriteBytes(data, len); 157cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski if (result != 0) { 15806460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski error_ = ZipWriter::ErrorCodeString(result); 159cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return false; 160cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 161cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return true; 162cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 163cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 164ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool FinishEntry() override { 165ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski int32_t result = writer_->FinishEntry(); 166cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski if (result != 0) { 16706460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski error_ = ZipWriter::ErrorCodeString(result); 168cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return false; 169a40e972fdaa68fc486ff90a319195515819068b2Adam Lesinski } 170cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return true; 171cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 172cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 17306460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski bool WriteFile(const StringPiece& path, uint32_t flags, io::InputStream* in) override { 17406460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski while (true) { 17506460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski if (!StartEntry(path, flags)) { 17606460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski return false; 17706460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski } 17806460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski 17906460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski const void* data = nullptr; 18006460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski size_t len = 0; 18106460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski while (in->Next(&data, &len)) { 18206460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski if (!Write(data, static_cast<int>(len))) { 18306460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski return false; 18406460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski } 18506460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski } 18606460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski 18706460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski if (in->HadError()) { 18806460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski return false; 18906460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski } 19006460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski 19106460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski if (!FinishEntry()) { 19206460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski return false; 19306460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski } 19406460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski 19506460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski // Check to see if the file was compressed enough. This is preserving behavior of AAPT. 19606460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski if ((flags & ArchiveEntry::kCompress) != 0 && in->CanRewind()) { 19706460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski ZipWriter::FileEntry last_entry; 19806460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski int32_t result = writer_->GetLastEntry(&last_entry); 19906460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski CHECK(result == 0); 20006460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski if (last_entry.compressed_size + (last_entry.compressed_size / 10) > 20106460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski last_entry.uncompressed_size) { 20206460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski // The file was not compressed enough, rewind and store it uncompressed. 20306460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski if (!in->Rewind()) { 20406460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski // Well we tried, may as well keep what we had. 20506460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski return true; 20606460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski } 20706460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski 20806460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski int32_t result = writer_->DiscardLastEntry(); 20906460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski if (result != 0) { 21006460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski error_ = ZipWriter::ErrorCodeString(result); 21106460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski return false; 21206460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski } 21306460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski flags &= ~ArchiveEntry::kCompress; 21406460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski 21506460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski continue; 21606460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski } 21706460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski } 21806460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski return true; 21906460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski } 22006460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski } 22106460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski 22206460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski bool HadError() const override { return !error_.empty(); } 22306460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski 22406460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski std::string GetError() const override { return error_; } 22506460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski 226cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski virtual ~ZipFileWriter() { 227ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (writer_) { 228ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski writer_->Finish(); 229cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 230cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 231ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 232ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski private: 233ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski DISALLOW_COPY_AND_ASSIGN(ZipFileWriter); 234ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 235ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::unique_ptr<FILE, decltype(fclose)*> file_ = {nullptr, fclose}; 236ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::unique_ptr<ZipWriter> writer_; 23706460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski std::string error_; 238cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}; 239cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 240cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski} // namespace 241cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 24206460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinskistd::unique_ptr<IArchiveWriter> CreateDirectoryArchiveWriter(IDiagnostics* diag, 24306460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski const StringPiece& path) { 24406460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski std::unique_ptr<DirectoryWriter> writer = util::make_unique<DirectoryWriter>(); 24506460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski if (!writer->Open(path)) { 24606460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski diag->Error(DiagMessage(path) << writer->GetError()); 247cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return {}; 248cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 249cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return std::move(writer); 250cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski} 251cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 25206460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinskistd::unique_ptr<IArchiveWriter> CreateZipFileArchiveWriter(IDiagnostics* diag, 25306460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski const StringPiece& path) { 254cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski std::unique_ptr<ZipFileWriter> writer = util::make_unique<ZipFileWriter>(); 25506460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski if (!writer->Open(path)) { 25606460ef0d7072114ea3280e1650f77f55e7223f4Adam Lesinski diag->Error(DiagMessage(path) << writer->GetError()); 257cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return {}; 258cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 259cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return std::move(writer); 2601ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski} 2611ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 262cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski} // namespace aapt 263