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