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