AAPT2: Better debugging output
Test: make aapt2_tests
Change-Id: I7778b773201381538dc1f2e376abee4eb33e44c0
diff --git a/tools/aapt2/io/FileStream.cpp b/tools/aapt2/io/FileStream.cpp
index 2f7a4b3..4ff6d78 100644
--- a/tools/aapt2/io/FileStream.cpp
+++ b/tools/aapt2/io/FileStream.cpp
@@ -26,6 +26,7 @@
#include "android-base/utf8.h"
using ::android::base::SystemErrorCodeToString;
+using ::android::base::unique_fd;
namespace aapt {
namespace io {
@@ -100,7 +101,13 @@
}
FileOutputStream::FileOutputStream(const std::string& path, int mode, size_t buffer_capacity)
- : FileOutputStream(::android::base::utf8::open(path.c_str(), mode), buffer_capacity) {
+ : FileOutputStream(unique_fd(::android::base::utf8::open(path.c_str(), mode)),
+ buffer_capacity) {
+}
+
+FileOutputStream::FileOutputStream(unique_fd fd, size_t buffer_capacity)
+ : FileOutputStream(fd.get(), buffer_capacity) {
+ owned_fd_ = std::move(fd);
}
FileOutputStream::FileOutputStream(int fd, size_t buffer_capacity)
@@ -118,7 +125,7 @@
}
bool FileOutputStream::Next(void** data, size_t* size) {
- if (fd_ == -1 || HadError()) {
+ if (HadError()) {
return false;
}
@@ -159,7 +166,8 @@
ssize_t n = TEMP_FAILURE_RETRY(write(fd_, buffer_.get(), buffer_offset_));
if (n < 0) {
error_ = SystemErrorCodeToString(errno);
- fd_.reset();
+ owned_fd_.reset();
+ fd_ = -1;
buffer_.reset();
return false;
}
diff --git a/tools/aapt2/io/FileStream.h b/tools/aapt2/io/FileStream.h
index 3b07667..4ed1ad5 100644
--- a/tools/aapt2/io/FileStream.h
+++ b/tools/aapt2/io/FileStream.h
@@ -29,12 +29,15 @@
namespace aapt {
namespace io {
+constexpr size_t kDefaultBufferCapacity = 4096u;
+
class FileInputStream : public InputStream {
public:
- explicit FileInputStream(const std::string& path, size_t buffer_capacity = 4096);
+ explicit FileInputStream(const std::string& path,
+ size_t buffer_capacity = kDefaultBufferCapacity);
- // Takes ownership of `fd`.
- explicit FileInputStream(int fd, size_t buffer_capacity = 4096);
+ // Take ownership of `fd`.
+ explicit FileInputStream(int fd, size_t buffer_capacity = kDefaultBufferCapacity);
bool Next(const void** data, size_t* size) override;
@@ -61,10 +64,14 @@
class FileOutputStream : public OutputStream {
public:
explicit FileOutputStream(const std::string& path, int mode = O_RDWR | O_CREAT | O_BINARY,
- size_t buffer_capacity = 4096);
+ size_t buffer_capacity = kDefaultBufferCapacity);
+
+ // Does not take ownership of `fd`.
+ explicit FileOutputStream(int fd, size_t buffer_capacity = kDefaultBufferCapacity);
// Takes ownership of `fd`.
- explicit FileOutputStream(int fd, size_t buffer_capacity = 4096);
+ explicit FileOutputStream(android::base::unique_fd fd,
+ size_t buffer_capacity = kDefaultBufferCapacity);
~FileOutputStream();
@@ -86,7 +93,8 @@
bool FlushImpl();
- android::base::unique_fd fd_;
+ android::base::unique_fd owned_fd_;
+ int fd_;
std::string error_;
std::unique_ptr<uint8_t[]> buffer_;
size_t buffer_capacity_;
diff --git a/tools/aapt2/io/FileStream_test.cpp b/tools/aapt2/io/FileStream_test.cpp
index 68c3cb1..a6d58ca 100644
--- a/tools/aapt2/io/FileStream_test.cpp
+++ b/tools/aapt2/io/FileStream_test.cpp
@@ -87,10 +87,8 @@
const std::string input = "this is a cool string";
TemporaryFile file;
- int fd = file.release();
- // FileOutputStream takes ownership.
- FileOutputStream out(fd, 10u);
+ FileOutputStream out(file.fd, 10u);
ASSERT_FALSE(out.HadError());
EXPECT_THAT(out.ByteCount(), Eq(0u));
@@ -118,10 +116,10 @@
ASSERT_TRUE(out.Flush());
- lseek64(fd, 0, SEEK_SET);
+ lseek64(file.fd, 0, SEEK_SET);
std::string actual;
- ASSERT_TRUE(android::base::ReadFdToString(fd, &actual));
+ ASSERT_TRUE(android::base::ReadFdToString(file.fd, &actual));
EXPECT_THAT(actual, StrEq(input));
}
diff --git a/tools/aapt2/io/Util.cpp b/tools/aapt2/io/Util.cpp
index d270340..7ee1016 100644
--- a/tools/aapt2/io/Util.cpp
+++ b/tools/aapt2/io/Util.cpp
@@ -18,6 +18,7 @@
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
+using ::android::StringPiece;
using ::google::protobuf::io::ZeroCopyOutputStream;
namespace aapt {
@@ -93,6 +94,25 @@
return !in->HadError();
}
+bool Copy(OutputStream* out, const StringPiece& in) {
+ const char* in_buffer = in.data();
+ size_t in_len = in.size();
+ while (in_len != 0) {
+ void* out_buffer;
+ size_t out_len;
+ if (!out->Next(&out_buffer, &out_len)) {
+ return false;
+ }
+
+ const size_t bytes_to_copy = in_len < out_len ? in_len : out_len;
+ memcpy(out_buffer, in_buffer, bytes_to_copy);
+ out->BackUp(out_len - bytes_to_copy);
+ in_buffer += bytes_to_copy;
+ in_len -= bytes_to_copy;
+ }
+ return true;
+}
+
bool Copy(ZeroCopyOutputStream* out, InputStream* in) {
OutputStreamAdaptor adaptor(out);
return Copy(&adaptor, in);
diff --git a/tools/aapt2/io/Util.h b/tools/aapt2/io/Util.h
index 1e48508..de2ab39 100644
--- a/tools/aapt2/io/Util.h
+++ b/tools/aapt2/io/Util.h
@@ -42,6 +42,7 @@
// Copies the data from in to out. Returns false if there was an error.
// If there was an error, check the individual streams' HadError/GetError methods.
bool Copy(OutputStream* out, InputStream* in);
+bool Copy(OutputStream* out, const ::android::StringPiece& in);
bool Copy(::google::protobuf::io::ZeroCopyOutputStream* out, InputStream* in);
class OutputStreamAdaptor : public io::OutputStream {