blob: 09dc7ea5b1c480b09110b4e3ae0fdc56b9dce25d [file] [log] [blame]
Adam Lesinskia40e9722015-11-24 19:11:46 -08001/*
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
Adam Lesinskicacb28f2016-10-19 12:18:14 -070020#include <memory>
Adam Lesinskia40e9722015-11-24 19:11:46 -080021
Adam Lesinskice5e56e2016-10-21 17:56:45 -070022#include "android-base/macros.h"
23#include "utils/FileMap.h"
24
Adam Lesinski06460ef2017-03-14 18:52:13 -070025#include "io/Io.h"
26
Adam Lesinskia40e9722015-11-24 19:11:46 -080027namespace aapt {
28namespace io {
29
Adam Lesinski06460ef2017-03-14 18:52:13 -070030// Interface for a block of contiguous memory. An instance of this interface owns the data.
31class IData : public InputStream {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070032 public:
33 virtual ~IData() = default;
Adam Lesinskia40e9722015-11-24 19:11:46 -080034
Adam Lesinskicacb28f2016-10-19 12:18:14 -070035 virtual const void* data() const = 0;
36 virtual size_t size() const = 0;
Adam Lesinskia40e9722015-11-24 19:11:46 -080037};
38
Adam Lesinski5eeaadd2016-08-25 12:26:56 -070039class DataSegment : public IData {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070040 public:
41 explicit DataSegment(std::unique_ptr<IData> data, size_t offset, size_t len)
Adam Lesinski06460ef2017-03-14 18:52:13 -070042 : data_(std::move(data)), offset_(offset), len_(len), next_read_(offset) {}
43 virtual ~DataSegment() = default;
Adam Lesinski5eeaadd2016-08-25 12:26:56 -070044
Adam Lesinskicacb28f2016-10-19 12:18:14 -070045 const void* data() const override {
Adam Lesinskice5e56e2016-10-21 17:56:45 -070046 return static_cast<const uint8_t*>(data_->data()) + offset_;
Adam Lesinskicacb28f2016-10-19 12:18:14 -070047 }
Adam Lesinski5eeaadd2016-08-25 12:26:56 -070048
Adam Lesinskice5e56e2016-10-21 17:56:45 -070049 size_t size() const override { return len_; }
Adam Lesinski5eeaadd2016-08-25 12:26:56 -070050
Adam Lesinski06460ef2017-03-14 18:52:13 -070051 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
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
69 bool CanRewind() const override { return true; }
70
71 bool Rewind() override {
72 next_read_ = offset_;
73 return true;
74 }
75
76 size_t ByteCount() const override { return next_read_ - offset_; }
77
78 bool HadError() const override { return false; }
79
Adam Lesinskicacb28f2016-10-19 12:18:14 -070080 private:
81 DISALLOW_COPY_AND_ASSIGN(DataSegment);
Adam Lesinski5eeaadd2016-08-25 12:26:56 -070082
Adam Lesinskice5e56e2016-10-21 17:56:45 -070083 std::unique_ptr<IData> data_;
84 size_t offset_;
85 size_t len_;
Adam Lesinski06460ef2017-03-14 18:52:13 -070086 size_t next_read_;
Adam Lesinski5eeaadd2016-08-25 12:26:56 -070087};
88
Adam Lesinski06460ef2017-03-14 18:52:13 -070089// Implementation of IData that exposes a memory mapped file.
90// The mmapped file is owned by this object.
Adam Lesinskia40e9722015-11-24 19:11:46 -080091class MmappedData : public IData {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070092 public:
Adam Lesinski06460ef2017-03-14 18:52:13 -070093 explicit MmappedData(android::FileMap&& map) : map_(std::forward<android::FileMap>(map)) {}
94 virtual ~MmappedData() = default;
Adam Lesinskia40e9722015-11-24 19:11:46 -080095
Adam Lesinskice5e56e2016-10-21 17:56:45 -070096 const void* data() const override { return map_.getDataPtr(); }
Adam Lesinskia40e9722015-11-24 19:11:46 -080097
Adam Lesinskice5e56e2016-10-21 17:56:45 -070098 size_t size() const override { return map_.getDataLength(); }
Adam Lesinskia40e9722015-11-24 19:11:46 -080099
Adam Lesinski06460ef2017-03-14 18:52:13 -0700100 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
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
118 bool CanRewind() const override { return true; }
119
120 bool Rewind() override {
121 next_read_ = 0;
122 return true;
123 }
124
125 size_t ByteCount() const override { return next_read_; }
126
127 bool HadError() const override { return false; }
128
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700129 private:
Adam Lesinski06460ef2017-03-14 18:52:13 -0700130 DISALLOW_COPY_AND_ASSIGN(MmappedData);
131
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700132 android::FileMap map_;
Adam Lesinski06460ef2017-03-14 18:52:13 -0700133 size_t next_read_ = 0;
Adam Lesinskia40e9722015-11-24 19:11:46 -0800134};
135
Adam Lesinski06460ef2017-03-14 18:52:13 -0700136// Implementation of IData that exposes a block of memory that was malloc'ed (new'ed).
137// The memory is owned by this object.
Adam Lesinskia40e9722015-11-24 19:11:46 -0800138class MallocData : public IData {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700139 public:
140 MallocData(std::unique_ptr<const uint8_t[]> data, size_t size)
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700141 : data_(std::move(data)), size_(size) {}
Adam Lesinski06460ef2017-03-14 18:52:13 -0700142 virtual ~MallocData() = default;
Adam Lesinskia40e9722015-11-24 19:11:46 -0800143
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700144 const void* data() const override { return data_.get(); }
Adam Lesinskia40e9722015-11-24 19:11:46 -0800145
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700146 size_t size() const override { return size_; }
Adam Lesinskia40e9722015-11-24 19:11:46 -0800147
Adam Lesinski06460ef2017-03-14 18:52:13 -0700148 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
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
166 bool CanRewind() const override { return true; }
167
168 bool Rewind() override {
169 next_read_ = 0;
170 return true;
171 }
172
173 size_t ByteCount() const override { return next_read_; }
174
175 bool HadError() const override { return false; }
176
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700177 private:
Adam Lesinski06460ef2017-03-14 18:52:13 -0700178 DISALLOW_COPY_AND_ASSIGN(MallocData);
179
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700180 std::unique_ptr<const uint8_t[]> data_;
181 size_t size_;
Adam Lesinski06460ef2017-03-14 18:52:13 -0700182 size_t next_read_ = 0;
Adam Lesinskia40e9722015-11-24 19:11:46 -0800183};
184
Adam Lesinski06460ef2017-03-14 18:52:13 -0700185// When mmap fails because the file has length 0, we use the EmptyData to simulate data of length 0.
Adam Lesinski52364f72016-01-11 13:10:24 -0800186class EmptyData : public IData {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700187 public:
Adam Lesinski06460ef2017-03-14 18:52:13 -0700188 virtual ~EmptyData() = default;
189
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700190 const void* data() const override {
191 static const uint8_t d = 0;
192 return &d;
193 }
Adam Lesinski52364f72016-01-11 13:10:24 -0800194
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700195 size_t size() const override { return 0u; }
Adam Lesinski06460ef2017-03-14 18:52:13 -0700196
197 bool Next(const void** /*data*/, size_t* /*size*/) override { return false; }
198
199 void BackUp(size_t /*count*/) override {}
200
201 bool CanRewind() const override { return true; }
202
203 bool Rewind() override { return true; }
204
205 size_t ByteCount() const override { return 0u; }
206
207 bool HadError() const override { return false; }
Adam Lesinski52364f72016-01-11 13:10:24 -0800208};
209
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700210} // namespace io
211} // namespace aapt
Adam Lesinskia40e9722015-11-24 19:11:46 -0800212
213#endif /* AAPT_IO_DATA_H */