Home | History | Annotate | Download | only in io
      1 /*
      2  * Copyright (C) 2015 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_DATA_H
     18 #define AAPT_IO_DATA_H
     19 
     20 #include <memory>
     21 
     22 #include "android-base/macros.h"
     23 #include "utils/FileMap.h"
     24 
     25 #include "io/Io.h"
     26 
     27 namespace aapt {
     28 namespace io {
     29 
     30 // Interface for a block of contiguous memory. An instance of this interface owns the data.
     31 class IData : public KnownSizeInputStream {
     32  public:
     33   virtual ~IData() = default;
     34 
     35   virtual const void* data() const = 0;
     36   virtual size_t size() const = 0;
     37 
     38   virtual size_t TotalSize() const override {
     39     return size();
     40   }
     41 };
     42 
     43 class DataSegment : public IData {
     44  public:
     45   explicit DataSegment(std::unique_ptr<IData> data, size_t offset, size_t len)
     46       : data_(std::move(data)), offset_(offset), len_(len), next_read_(offset) {}
     47   virtual ~DataSegment() = default;
     48 
     49   const void* data() const override {
     50     return static_cast<const uint8_t*>(data_->data()) + offset_;
     51   }
     52 
     53   size_t size() const override { return len_; }
     54 
     55   bool Next(const void** data, size_t* size) override {
     56     if (next_read_ == offset_ + len_) {
     57       return false;
     58     }
     59     *data = static_cast<const uint8_t*>(data_->data()) + next_read_;
     60     *size = len_ - (next_read_ - offset_);
     61     next_read_ = offset_ + len_;
     62     return true;
     63   }
     64 
     65   void BackUp(size_t count) override {
     66     if (count > next_read_ - offset_) {
     67       next_read_ = offset_;
     68     } else {
     69       next_read_ -= count;
     70     }
     71   }
     72 
     73   bool CanRewind() const override { return true; }
     74 
     75   bool Rewind() override {
     76     next_read_ = offset_;
     77     return true;
     78   }
     79 
     80   size_t ByteCount() const override { return next_read_ - offset_; }
     81 
     82   bool HadError() const override { return false; }
     83 
     84  private:
     85   DISALLOW_COPY_AND_ASSIGN(DataSegment);
     86 
     87   std::unique_ptr<IData> data_;
     88   size_t offset_;
     89   size_t len_;
     90   size_t next_read_;
     91 };
     92 
     93 // Implementation of IData that exposes a memory mapped file.
     94 // The mmapped file is owned by this object.
     95 class MmappedData : public IData {
     96  public:
     97   explicit MmappedData(android::FileMap&& map) : map_(std::forward<android::FileMap>(map)) {}
     98   virtual ~MmappedData() = default;
     99 
    100   const void* data() const override { return map_.getDataPtr(); }
    101 
    102   size_t size() const override { return map_.getDataLength(); }
    103 
    104   bool Next(const void** data, size_t* size) override {
    105     if (next_read_ == map_.getDataLength()) {
    106       return false;
    107     }
    108     *data = reinterpret_cast<const uint8_t*>(map_.getDataPtr()) + next_read_;
    109     *size = map_.getDataLength() - next_read_;
    110     next_read_ = map_.getDataLength();
    111     return true;
    112   }
    113 
    114   void BackUp(size_t count) override {
    115     if (count > next_read_) {
    116       next_read_ = 0;
    117     } else {
    118       next_read_ -= count;
    119     }
    120   }
    121 
    122   bool CanRewind() const override { return true; }
    123 
    124   bool Rewind() override {
    125     next_read_ = 0;
    126     return true;
    127   }
    128 
    129   size_t ByteCount() const override { return next_read_; }
    130 
    131   bool HadError() const override { return false; }
    132 
    133  private:
    134   DISALLOW_COPY_AND_ASSIGN(MmappedData);
    135 
    136   android::FileMap map_;
    137   size_t next_read_ = 0;
    138 };
    139 
    140 // Implementation of IData that exposes a block of memory that was malloc'ed (new'ed).
    141 // The memory is owned by this object.
    142 class MallocData : public IData {
    143  public:
    144   MallocData(std::unique_ptr<const uint8_t[]> data, size_t size)
    145       : data_(std::move(data)), size_(size) {}
    146   virtual ~MallocData() = default;
    147 
    148   const void* data() const override { return data_.get(); }
    149 
    150   size_t size() const override { return size_; }
    151 
    152   bool Next(const void** data, size_t* size) override {
    153     if (next_read_ == size_) {
    154       return false;
    155     }
    156     *data = data_.get() + next_read_;
    157     *size = size_ - next_read_;
    158     next_read_ = size_;
    159     return true;
    160   }
    161 
    162   void BackUp(size_t count) override {
    163     if (count > next_read_) {
    164       next_read_ = 0;
    165     } else {
    166       next_read_ -= count;
    167     }
    168   }
    169 
    170   bool CanRewind() const override { return true; }
    171 
    172   bool Rewind() override {
    173     next_read_ = 0;
    174     return true;
    175   }
    176 
    177   size_t ByteCount() const override { return next_read_; }
    178 
    179   bool HadError() const override { return false; }
    180 
    181  private:
    182   DISALLOW_COPY_AND_ASSIGN(MallocData);
    183 
    184   std::unique_ptr<const uint8_t[]> data_;
    185   size_t size_;
    186   size_t next_read_ = 0;
    187 };
    188 
    189 // When mmap fails because the file has length 0, we use the EmptyData to simulate data of length 0.
    190 class EmptyData : public IData {
    191  public:
    192   virtual ~EmptyData() = default;
    193 
    194   const void* data() const override {
    195     static const uint8_t d = 0;
    196     return &d;
    197   }
    198 
    199   size_t size() const override { return 0u; }
    200 
    201   bool Next(const void** /*data*/, size_t* /*size*/) override { return false; }
    202 
    203   void BackUp(size_t /*count*/) override {}
    204 
    205   bool CanRewind() const override { return true; }
    206 
    207   bool Rewind() override { return true; }
    208 
    209   size_t ByteCount() const override { return 0u; }
    210 
    211   bool HadError() const override { return false; }
    212 };
    213 
    214 }  // namespace io
    215 }  // namespace aapt
    216 
    217 #endif /* AAPT_IO_DATA_H */
    218