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 
TotalSize()38   virtual size_t TotalSize() const override {
39     return size();
40   }
41 };
42 
43 class DataSegment : public IData {
44  public:
DataSegment(std::unique_ptr<IData> data,size_t offset,size_t len)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 
data()49   const void* data() const override {
50     return static_cast<const uint8_t*>(data_->data()) + offset_;
51   }
52 
size()53   size_t size() const override { return len_; }
54 
Next(const void ** data,size_t * size)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 
BackUp(size_t count)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 
CanRewind()73   bool CanRewind() const override { return true; }
74 
Rewind()75   bool Rewind() override {
76     next_read_ = offset_;
77     return true;
78   }
79 
ByteCount()80   size_t ByteCount() const override { return next_read_ - offset_; }
81 
HadError()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:
MmappedData(android::FileMap && map)97   explicit MmappedData(android::FileMap&& map) : map_(std::forward<android::FileMap>(map)) {}
98   virtual ~MmappedData() = default;
99 
data()100   const void* data() const override { return map_.getDataPtr(); }
101 
size()102   size_t size() const override { return map_.getDataLength(); }
103 
Next(const void ** data,size_t * size)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 
BackUp(size_t count)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 
CanRewind()122   bool CanRewind() const override { return true; }
123 
Rewind()124   bool Rewind() override {
125     next_read_ = 0;
126     return true;
127   }
128 
ByteCount()129   size_t ByteCount() const override { return next_read_; }
130 
HadError()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:
MallocData(std::unique_ptr<const uint8_t[]> data,size_t size)144   MallocData(std::unique_ptr<const uint8_t[]> data, size_t size)
145       : data_(std::move(data)), size_(size) {}
146   virtual ~MallocData() = default;
147 
data()148   const void* data() const override { return data_.get(); }
149 
size()150   size_t size() const override { return size_; }
151 
Next(const void ** data,size_t * size)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 
BackUp(size_t count)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 
CanRewind()170   bool CanRewind() const override { return true; }
171 
Rewind()172   bool Rewind() override {
173     next_read_ = 0;
174     return true;
175   }
176 
ByteCount()177   size_t ByteCount() const override { return next_read_; }
178 
HadError()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 
data()194   const void* data() const override {
195     static const uint8_t d = 0;
196     return &d;
197   }
198 
size()199   size_t size() const override { return 0u; }
200 
Next(const void **,size_t *)201   bool Next(const void** /*data*/, size_t* /*size*/) override { return false; }
202 
BackUp(size_t)203   void BackUp(size_t /*count*/) override {}
204 
CanRewind()205   bool CanRewind() const override { return true; }
206 
Rewind()207   bool Rewind() override { return true; }
208 
ByteCount()209   size_t ByteCount() const override { return 0u; }
210 
HadError()211   bool HadError() const override { return false; }
212 };
213 
214 }  // namespace io
215 }  // namespace aapt
216 
217 #endif /* AAPT_IO_DATA_H */
218