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>
21 
22 #include "google/protobuf/message_lite.h"
23 
24 #include "format/Archive.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, const std::string& out_path,
33                               uint32_t compression_flags, IArchiveWriter* writer);
34 
35 bool CopyFileToArchive(IAaptContext* context, IFile* file, const std::string& out_path,
36                        uint32_t compression_flags, IArchiveWriter* writer);
37 
38 bool CopyFileToArchivePreserveCompression(IAaptContext* context, IFile* file,
39                                           const std::string& out_path, IArchiveWriter* writer);
40 
41 bool CopyProtoToArchive(IAaptContext* context, ::google::protobuf::MessageLite* proto_msg,
42                         const std::string& 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, const ::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 }  // namespace io
126 }  // namespace aapt
127 
128 #endif /* AAPT_IO_UTIL_H */
129