1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef AAPT_IO_UTIL_H 18 #define AAPT_IO_UTIL_H 19 20 #include <string_view> 21 22 #include "format/Archive.h" 23 #include "google/protobuf/io/coded_stream.h" 24 #include "google/protobuf/message.h" 25 #include "io/File.h" 26 #include "io/Io.h" 27 #include "process/IResourceTableConsumer.h" 28 29 namespace aapt { 30 namespace io { 31 32 bool CopyInputStreamToArchive(IAaptContext* context, InputStream* in, std::string_view out_path, 33 uint32_t compression_flags, IArchiveWriter* writer); 34 35 bool CopyFileToArchive(IAaptContext* context, IFile* file, std::string_view out_path, 36 uint32_t compression_flags, IArchiveWriter* writer); 37 38 bool CopyFileToArchivePreserveCompression(IAaptContext* context, IFile* file, 39 std::string_view out_path, IArchiveWriter* writer); 40 41 bool CopyProtoToArchive(IAaptContext* context, ::google::protobuf::Message* proto_msg, 42 std::string_view out_path, uint32_t compression_flags, 43 IArchiveWriter* writer); 44 45 // Copies the data from in to out. Returns false if there was an error. 46 // If there was an error, check the individual streams' HadError/GetError methods. 47 bool Copy(OutputStream* out, InputStream* in); 48 bool Copy(OutputStream* out, android::StringPiece in); 49 bool Copy(::google::protobuf::io::ZeroCopyOutputStream* out, InputStream* in); 50 51 class OutputStreamAdaptor : public io::OutputStream { 52 public: OutputStreamAdaptor(::google::protobuf::io::ZeroCopyOutputStream * out)53 explicit OutputStreamAdaptor(::google::protobuf::io::ZeroCopyOutputStream* out) : out_(out) { 54 } 55 Next(void ** data,size_t * size)56 bool Next(void** data, size_t* size) override { 57 int out_size; 58 bool result = out_->Next(data, &out_size); 59 *size = static_cast<size_t>(out_size); 60 if (!result) { 61 error_ocurred_ = true; 62 } 63 return result; 64 } 65 BackUp(size_t count)66 void BackUp(size_t count) override { 67 out_->BackUp(static_cast<int>(count)); 68 } 69 ByteCount()70 size_t ByteCount() const override { 71 return static_cast<size_t>(out_->ByteCount()); 72 } 73 HadError()74 bool HadError() const override { 75 return error_ocurred_; 76 } 77 78 private: 79 DISALLOW_COPY_AND_ASSIGN(OutputStreamAdaptor); 80 81 ::google::protobuf::io::ZeroCopyOutputStream* out_; 82 bool error_ocurred_ = false; 83 }; 84 85 class ZeroCopyInputAdaptor : public ::google::protobuf::io::ZeroCopyInputStream { 86 public: ZeroCopyInputAdaptor(io::InputStream * in)87 explicit ZeroCopyInputAdaptor(io::InputStream* in) : in_(in) { 88 } 89 Next(const void ** data,int * size)90 bool Next(const void** data, int* size) override { 91 size_t out_size; 92 bool result = in_->Next(data, &out_size); 93 *size = static_cast<int>(out_size); 94 return result; 95 } 96 BackUp(int count)97 void BackUp(int count) override { 98 in_->BackUp(static_cast<size_t>(count)); 99 } 100 Skip(int count)101 bool Skip(int count) override { 102 const void* data; 103 int size; 104 while (Next(&data, &size)) { 105 if (size > count) { 106 BackUp(size - count); 107 return true; 108 } else { 109 count -= size; 110 } 111 } 112 return false; 113 } 114 ByteCount()115 ::google::protobuf::int64 ByteCount() const override { 116 return static_cast<::google::protobuf::int64>(in_->ByteCount()); 117 } 118 119 private: 120 DISALLOW_COPY_AND_ASSIGN(ZeroCopyInputAdaptor); 121 122 io::InputStream* in_; 123 }; 124 125 class ProtoInputStreamReader { 126 public: ProtoInputStreamReader(io::InputStream * in)127 explicit ProtoInputStreamReader(io::InputStream* in) : in_(in) { } 128 129 /** Deserializes a Message proto from the current position in the input stream.*/ ReadMessage(T * message)130 template <typename T> bool ReadMessage(T *message) { 131 ZeroCopyInputAdaptor adapter(in_); 132 google::protobuf::io::CodedInputStream coded_stream(&adapter); 133 coded_stream.SetTotalBytesLimit(std::numeric_limits<int32_t>::max()); 134 return message->ParseFromCodedStream(&coded_stream); 135 } 136 137 private: 138 io::InputStream* in_; 139 }; 140 141 } // namespace io 142 } // namespace aapt 143 144 #endif /* AAPT_IO_UTIL_H */ 145