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 "androidfw/Streams.h" 23 #include "format/Archive.h" 24 #include "google/protobuf/io/coded_stream.h" 25 #include "google/protobuf/message.h" 26 #include "io/File.h" 27 #include "process/IResourceTableConsumer.h" 28 29 namespace aapt { 30 namespace io { 31 32 bool CopyInputStreamToArchive(IAaptContext* context, android::InputStream* in, 33 std::string_view out_path, uint32_t compression_flags, 34 IArchiveWriter* writer); 35 36 bool CopyFileToArchive(IAaptContext* context, IFile* file, std::string_view out_path, 37 uint32_t compression_flags, IArchiveWriter* writer); 38 39 bool CopyFileToArchivePreserveCompression(IAaptContext* context, IFile* file, 40 std::string_view out_path, IArchiveWriter* writer); 41 42 bool CopyProtoToArchive(IAaptContext* context, ::google::protobuf::Message* proto_msg, 43 std::string_view out_path, uint32_t compression_flags, 44 IArchiveWriter* writer); 45 46 // Copies the data from in to out. Returns false if there was an error. 47 // If there was an error, check the individual streams' HadError/GetError methods. 48 bool Copy(android::OutputStream* out, android::InputStream* in); 49 bool Copy(android::OutputStream* out, android::StringPiece in); 50 bool Copy(::google::protobuf::io::ZeroCopyOutputStream* out, android::InputStream* in); 51 52 class OutputStreamAdaptor : public android::OutputStream { 53 public: OutputStreamAdaptor(::google::protobuf::io::ZeroCopyOutputStream * out)54 explicit OutputStreamAdaptor(::google::protobuf::io::ZeroCopyOutputStream* out) : out_(out) { 55 } 56 Next(void ** data,size_t * size)57 bool Next(void** data, size_t* size) override { 58 int out_size; 59 bool result = out_->Next(data, &out_size); 60 *size = static_cast<size_t>(out_size); 61 if (!result) { 62 error_ocurred_ = true; 63 } 64 return result; 65 } 66 BackUp(size_t count)67 void BackUp(size_t count) override { 68 out_->BackUp(static_cast<int>(count)); 69 } 70 ByteCount()71 size_t ByteCount() const override { 72 return static_cast<size_t>(out_->ByteCount()); 73 } 74 HadError()75 bool HadError() const override { 76 return error_ocurred_; 77 } 78 79 private: 80 DISALLOW_COPY_AND_ASSIGN(OutputStreamAdaptor); 81 82 ::google::protobuf::io::ZeroCopyOutputStream* out_; 83 bool error_ocurred_ = false; 84 }; 85 86 class ZeroCopyInputAdaptor : public ::google::protobuf::io::ZeroCopyInputStream { 87 public: ZeroCopyInputAdaptor(android::InputStream * in)88 explicit ZeroCopyInputAdaptor(android::InputStream* in) : in_(in) { 89 } 90 Next(const void ** data,int * size)91 bool Next(const void** data, int* size) override { 92 size_t out_size; 93 bool result = in_->Next(data, &out_size); 94 *size = static_cast<int>(out_size); 95 return result; 96 } 97 BackUp(int count)98 void BackUp(int count) override { 99 in_->BackUp(static_cast<size_t>(count)); 100 } 101 Skip(int count)102 bool Skip(int count) override { 103 const void* data; 104 int size; 105 while (Next(&data, &size)) { 106 if (size > count) { 107 BackUp(size - count); 108 return true; 109 } else { 110 count -= size; 111 } 112 } 113 return false; 114 } 115 ByteCount()116 ::google::protobuf::int64 ByteCount() const override { 117 return static_cast<::google::protobuf::int64>(in_->ByteCount()); 118 } 119 120 private: 121 DISALLOW_COPY_AND_ASSIGN(ZeroCopyInputAdaptor); 122 123 android::InputStream* in_; 124 }; 125 126 class ProtoInputStreamReader { 127 public: ProtoInputStreamReader(android::InputStream * in)128 explicit ProtoInputStreamReader(android::InputStream* in) : in_(in) { 129 } 130 131 /** Deserializes a Message proto from the current position in the input stream.*/ ReadMessage(T * message)132 template <typename T> bool ReadMessage(T *message) { 133 ZeroCopyInputAdaptor adapter(in_); 134 google::protobuf::io::CodedInputStream coded_stream(&adapter); 135 coded_stream.SetTotalBytesLimit(std::numeric_limits<int32_t>::max()); 136 return message->ParseFromCodedStream(&coded_stream); 137 } 138 139 private: 140 android::InputStream* in_; 141 }; 142 143 } // namespace io 144 } // namespace aapt 145 146 #endif /* AAPT_IO_UTIL_H */ 147