Home | History | Annotate | Download | only in io
      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 #include "google/protobuf/io/coded_stream.h"
     24 
     25 #include "format/Archive.h"
     26 #include "io/File.h"
     27 #include "io/Io.h"
     28 #include "process/IResourceTableConsumer.h"
     29 
     30 namespace aapt {
     31 namespace io {
     32 
     33 bool CopyInputStreamToArchive(IAaptContext* context, InputStream* in, const std::string& out_path,
     34                               uint32_t compression_flags, IArchiveWriter* writer);
     35 
     36 bool CopyFileToArchive(IAaptContext* context, IFile* file, const std::string& out_path,
     37                        uint32_t compression_flags, IArchiveWriter* writer);
     38 
     39 bool CopyFileToArchivePreserveCompression(IAaptContext* context, IFile* file,
     40                                           const std::string& out_path, IArchiveWriter* writer);
     41 
     42 bool CopyProtoToArchive(IAaptContext* context, ::google::protobuf::MessageLite* proto_msg,
     43                         const std::string& 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(OutputStream* out, InputStream* in);
     49 bool Copy(OutputStream* out, const ::android::StringPiece& in);
     50 bool Copy(::google::protobuf::io::ZeroCopyOutputStream* out, InputStream* in);
     51 
     52 class OutputStreamAdaptor : public io::OutputStream {
     53  public:
     54   explicit OutputStreamAdaptor(::google::protobuf::io::ZeroCopyOutputStream* out) : out_(out) {
     55   }
     56 
     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 
     67   void BackUp(size_t count) override {
     68     out_->BackUp(static_cast<int>(count));
     69   }
     70 
     71   size_t ByteCount() const override {
     72     return static_cast<size_t>(out_->ByteCount());
     73   }
     74 
     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:
     88   explicit ZeroCopyInputAdaptor(io::InputStream* in) : in_(in) {
     89   }
     90 
     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 
     98   void BackUp(int count) override {
     99     in_->BackUp(static_cast<size_t>(count));
    100   }
    101 
    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 
    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   io::InputStream* in_;
    124 };
    125 
    126 class ProtoInputStreamReader {
    127  public:
    128   explicit ProtoInputStreamReader(io::InputStream* in) : in_(in) { }
    129 
    130   /** Deserializes a MessageLite proto from the current position in the input stream.*/
    131   template <typename T> bool ReadMessage(T *message_lite) {
    132     ZeroCopyInputAdaptor adapter(in_);
    133     google::protobuf::io::CodedInputStream coded_stream(&adapter);
    134     coded_stream.SetTotalBytesLimit(std::numeric_limits<int32_t>::max(),
    135                                     coded_stream.BytesUntilTotalBytesLimit());
    136     return message_lite->ParseFromCodedStream(&coded_stream);
    137   }
    138 
    139  private:
    140   io::InputStream* in_;
    141 };
    142 
    143 }  // namespace io
    144 }  // namespace aapt
    145 
    146 #endif /* AAPT_IO_UTIL_H */
    147