• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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