xref: /aosp_15_r20/frameworks/base/tools/aapt2/io/Data.h (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker  *
4*d57664e9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker  *
8*d57664e9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker  *
10*d57664e9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker  * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker  */
16*d57664e9SAndroid Build Coastguard Worker 
17*d57664e9SAndroid Build Coastguard Worker #ifndef AAPT_IO_DATA_H
18*d57664e9SAndroid Build Coastguard Worker #define AAPT_IO_DATA_H
19*d57664e9SAndroid Build Coastguard Worker 
20*d57664e9SAndroid Build Coastguard Worker #include <memory>
21*d57664e9SAndroid Build Coastguard Worker 
22*d57664e9SAndroid Build Coastguard Worker #include "android-base/macros.h"
23*d57664e9SAndroid Build Coastguard Worker #include "androidfw/Streams.h"
24*d57664e9SAndroid Build Coastguard Worker #include "utils/FileMap.h"
25*d57664e9SAndroid Build Coastguard Worker 
26*d57664e9SAndroid Build Coastguard Worker namespace aapt {
27*d57664e9SAndroid Build Coastguard Worker namespace io {
28*d57664e9SAndroid Build Coastguard Worker 
29*d57664e9SAndroid Build Coastguard Worker // Interface for a block of contiguous memory. An instance of this interface owns the data.
30*d57664e9SAndroid Build Coastguard Worker class IData : public android::KnownSizeInputStream {
31*d57664e9SAndroid Build Coastguard Worker  public:
32*d57664e9SAndroid Build Coastguard Worker   virtual ~IData() = default;
33*d57664e9SAndroid Build Coastguard Worker 
34*d57664e9SAndroid Build Coastguard Worker   virtual const void* data() const = 0;
35*d57664e9SAndroid Build Coastguard Worker   virtual size_t size() const = 0;
36*d57664e9SAndroid Build Coastguard Worker 
TotalSize()37*d57664e9SAndroid Build Coastguard Worker   virtual size_t TotalSize() const override {
38*d57664e9SAndroid Build Coastguard Worker     return size();
39*d57664e9SAndroid Build Coastguard Worker   }
40*d57664e9SAndroid Build Coastguard Worker };
41*d57664e9SAndroid Build Coastguard Worker 
42*d57664e9SAndroid Build Coastguard Worker class DataSegment : public IData {
43*d57664e9SAndroid Build Coastguard Worker  public:
DataSegment(std::unique_ptr<IData> data,size_t offset,size_t len)44*d57664e9SAndroid Build Coastguard Worker   explicit DataSegment(std::unique_ptr<IData> data, size_t offset, size_t len)
45*d57664e9SAndroid Build Coastguard Worker       : data_(std::move(data)), offset_(offset), len_(len), next_read_(offset) {}
46*d57664e9SAndroid Build Coastguard Worker   virtual ~DataSegment() = default;
47*d57664e9SAndroid Build Coastguard Worker 
data()48*d57664e9SAndroid Build Coastguard Worker   const void* data() const override {
49*d57664e9SAndroid Build Coastguard Worker     return static_cast<const uint8_t*>(data_->data()) + offset_;
50*d57664e9SAndroid Build Coastguard Worker   }
51*d57664e9SAndroid Build Coastguard Worker 
size()52*d57664e9SAndroid Build Coastguard Worker   size_t size() const override { return len_; }
53*d57664e9SAndroid Build Coastguard Worker 
Next(const void ** data,size_t * size)54*d57664e9SAndroid Build Coastguard Worker   bool Next(const void** data, size_t* size) override {
55*d57664e9SAndroid Build Coastguard Worker     if (next_read_ == offset_ + len_) {
56*d57664e9SAndroid Build Coastguard Worker       return false;
57*d57664e9SAndroid Build Coastguard Worker     }
58*d57664e9SAndroid Build Coastguard Worker     *data = static_cast<const uint8_t*>(data_->data()) + next_read_;
59*d57664e9SAndroid Build Coastguard Worker     *size = len_ - (next_read_ - offset_);
60*d57664e9SAndroid Build Coastguard Worker     next_read_ = offset_ + len_;
61*d57664e9SAndroid Build Coastguard Worker     return true;
62*d57664e9SAndroid Build Coastguard Worker   }
63*d57664e9SAndroid Build Coastguard Worker 
BackUp(size_t count)64*d57664e9SAndroid Build Coastguard Worker   void BackUp(size_t count) override {
65*d57664e9SAndroid Build Coastguard Worker     if (count > next_read_ - offset_) {
66*d57664e9SAndroid Build Coastguard Worker       next_read_ = offset_;
67*d57664e9SAndroid Build Coastguard Worker     } else {
68*d57664e9SAndroid Build Coastguard Worker       next_read_ -= count;
69*d57664e9SAndroid Build Coastguard Worker     }
70*d57664e9SAndroid Build Coastguard Worker   }
71*d57664e9SAndroid Build Coastguard Worker 
CanRewind()72*d57664e9SAndroid Build Coastguard Worker   bool CanRewind() const override { return true; }
73*d57664e9SAndroid Build Coastguard Worker 
Rewind()74*d57664e9SAndroid Build Coastguard Worker   bool Rewind() override {
75*d57664e9SAndroid Build Coastguard Worker     next_read_ = offset_;
76*d57664e9SAndroid Build Coastguard Worker     return true;
77*d57664e9SAndroid Build Coastguard Worker   }
78*d57664e9SAndroid Build Coastguard Worker 
ByteCount()79*d57664e9SAndroid Build Coastguard Worker   size_t ByteCount() const override { return next_read_ - offset_; }
80*d57664e9SAndroid Build Coastguard Worker 
HadError()81*d57664e9SAndroid Build Coastguard Worker   bool HadError() const override { return false; }
82*d57664e9SAndroid Build Coastguard Worker 
83*d57664e9SAndroid Build Coastguard Worker  private:
84*d57664e9SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(DataSegment);
85*d57664e9SAndroid Build Coastguard Worker 
86*d57664e9SAndroid Build Coastguard Worker   std::unique_ptr<IData> data_;
87*d57664e9SAndroid Build Coastguard Worker   size_t offset_;
88*d57664e9SAndroid Build Coastguard Worker   size_t len_;
89*d57664e9SAndroid Build Coastguard Worker   size_t next_read_;
90*d57664e9SAndroid Build Coastguard Worker };
91*d57664e9SAndroid Build Coastguard Worker 
92*d57664e9SAndroid Build Coastguard Worker // Implementation of IData that exposes a memory mapped file.
93*d57664e9SAndroid Build Coastguard Worker // The mmapped file is owned by this object.
94*d57664e9SAndroid Build Coastguard Worker class MmappedData : public IData {
95*d57664e9SAndroid Build Coastguard Worker  public:
MmappedData(android::FileMap && map)96*d57664e9SAndroid Build Coastguard Worker   explicit MmappedData(android::FileMap&& map) : map_(std::forward<android::FileMap>(map)) {}
97*d57664e9SAndroid Build Coastguard Worker   virtual ~MmappedData() = default;
98*d57664e9SAndroid Build Coastguard Worker 
data()99*d57664e9SAndroid Build Coastguard Worker   const void* data() const override { return map_.getDataPtr(); }
100*d57664e9SAndroid Build Coastguard Worker 
size()101*d57664e9SAndroid Build Coastguard Worker   size_t size() const override { return map_.getDataLength(); }
102*d57664e9SAndroid Build Coastguard Worker 
Next(const void ** data,size_t * size)103*d57664e9SAndroid Build Coastguard Worker   bool Next(const void** data, size_t* size) override {
104*d57664e9SAndroid Build Coastguard Worker     if (next_read_ == map_.getDataLength()) {
105*d57664e9SAndroid Build Coastguard Worker       return false;
106*d57664e9SAndroid Build Coastguard Worker     }
107*d57664e9SAndroid Build Coastguard Worker     *data = reinterpret_cast<const uint8_t*>(map_.getDataPtr()) + next_read_;
108*d57664e9SAndroid Build Coastguard Worker     *size = map_.getDataLength() - next_read_;
109*d57664e9SAndroid Build Coastguard Worker     next_read_ = map_.getDataLength();
110*d57664e9SAndroid Build Coastguard Worker     return true;
111*d57664e9SAndroid Build Coastguard Worker   }
112*d57664e9SAndroid Build Coastguard Worker 
BackUp(size_t count)113*d57664e9SAndroid Build Coastguard Worker   void BackUp(size_t count) override {
114*d57664e9SAndroid Build Coastguard Worker     if (count > next_read_) {
115*d57664e9SAndroid Build Coastguard Worker       next_read_ = 0;
116*d57664e9SAndroid Build Coastguard Worker     } else {
117*d57664e9SAndroid Build Coastguard Worker       next_read_ -= count;
118*d57664e9SAndroid Build Coastguard Worker     }
119*d57664e9SAndroid Build Coastguard Worker   }
120*d57664e9SAndroid Build Coastguard Worker 
CanRewind()121*d57664e9SAndroid Build Coastguard Worker   bool CanRewind() const override { return true; }
122*d57664e9SAndroid Build Coastguard Worker 
Rewind()123*d57664e9SAndroid Build Coastguard Worker   bool Rewind() override {
124*d57664e9SAndroid Build Coastguard Worker     next_read_ = 0;
125*d57664e9SAndroid Build Coastguard Worker     return true;
126*d57664e9SAndroid Build Coastguard Worker   }
127*d57664e9SAndroid Build Coastguard Worker 
ByteCount()128*d57664e9SAndroid Build Coastguard Worker   size_t ByteCount() const override { return next_read_; }
129*d57664e9SAndroid Build Coastguard Worker 
HadError()130*d57664e9SAndroid Build Coastguard Worker   bool HadError() const override { return false; }
131*d57664e9SAndroid Build Coastguard Worker 
132*d57664e9SAndroid Build Coastguard Worker  private:
133*d57664e9SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(MmappedData);
134*d57664e9SAndroid Build Coastguard Worker 
135*d57664e9SAndroid Build Coastguard Worker   android::FileMap map_;
136*d57664e9SAndroid Build Coastguard Worker   size_t next_read_ = 0;
137*d57664e9SAndroid Build Coastguard Worker };
138*d57664e9SAndroid Build Coastguard Worker 
139*d57664e9SAndroid Build Coastguard Worker // Implementation of IData that exposes a block of memory that was malloc'ed (new'ed).
140*d57664e9SAndroid Build Coastguard Worker // The memory is owned by this object.
141*d57664e9SAndroid Build Coastguard Worker class MallocData : public IData {
142*d57664e9SAndroid Build Coastguard Worker  public:
MallocData(std::unique_ptr<const uint8_t[]> data,size_t size)143*d57664e9SAndroid Build Coastguard Worker   MallocData(std::unique_ptr<const uint8_t[]> data, size_t size)
144*d57664e9SAndroid Build Coastguard Worker       : data_(std::move(data)), size_(size) {}
145*d57664e9SAndroid Build Coastguard Worker   virtual ~MallocData() = default;
146*d57664e9SAndroid Build Coastguard Worker 
data()147*d57664e9SAndroid Build Coastguard Worker   const void* data() const override { return data_.get(); }
148*d57664e9SAndroid Build Coastguard Worker 
size()149*d57664e9SAndroid Build Coastguard Worker   size_t size() const override { return size_; }
150*d57664e9SAndroid Build Coastguard Worker 
Next(const void ** data,size_t * size)151*d57664e9SAndroid Build Coastguard Worker   bool Next(const void** data, size_t* size) override {
152*d57664e9SAndroid Build Coastguard Worker     if (next_read_ == size_) {
153*d57664e9SAndroid Build Coastguard Worker       return false;
154*d57664e9SAndroid Build Coastguard Worker     }
155*d57664e9SAndroid Build Coastguard Worker     *data = data_.get() + next_read_;
156*d57664e9SAndroid Build Coastguard Worker     *size = size_ - next_read_;
157*d57664e9SAndroid Build Coastguard Worker     next_read_ = size_;
158*d57664e9SAndroid Build Coastguard Worker     return true;
159*d57664e9SAndroid Build Coastguard Worker   }
160*d57664e9SAndroid Build Coastguard Worker 
BackUp(size_t count)161*d57664e9SAndroid Build Coastguard Worker   void BackUp(size_t count) override {
162*d57664e9SAndroid Build Coastguard Worker     if (count > next_read_) {
163*d57664e9SAndroid Build Coastguard Worker       next_read_ = 0;
164*d57664e9SAndroid Build Coastguard Worker     } else {
165*d57664e9SAndroid Build Coastguard Worker       next_read_ -= count;
166*d57664e9SAndroid Build Coastguard Worker     }
167*d57664e9SAndroid Build Coastguard Worker   }
168*d57664e9SAndroid Build Coastguard Worker 
CanRewind()169*d57664e9SAndroid Build Coastguard Worker   bool CanRewind() const override { return true; }
170*d57664e9SAndroid Build Coastguard Worker 
Rewind()171*d57664e9SAndroid Build Coastguard Worker   bool Rewind() override {
172*d57664e9SAndroid Build Coastguard Worker     next_read_ = 0;
173*d57664e9SAndroid Build Coastguard Worker     return true;
174*d57664e9SAndroid Build Coastguard Worker   }
175*d57664e9SAndroid Build Coastguard Worker 
ByteCount()176*d57664e9SAndroid Build Coastguard Worker   size_t ByteCount() const override { return next_read_; }
177*d57664e9SAndroid Build Coastguard Worker 
HadError()178*d57664e9SAndroid Build Coastguard Worker   bool HadError() const override { return false; }
179*d57664e9SAndroid Build Coastguard Worker 
180*d57664e9SAndroid Build Coastguard Worker  private:
181*d57664e9SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(MallocData);
182*d57664e9SAndroid Build Coastguard Worker 
183*d57664e9SAndroid Build Coastguard Worker   std::unique_ptr<const uint8_t[]> data_;
184*d57664e9SAndroid Build Coastguard Worker   size_t size_;
185*d57664e9SAndroid Build Coastguard Worker   size_t next_read_ = 0;
186*d57664e9SAndroid Build Coastguard Worker };
187*d57664e9SAndroid Build Coastguard Worker 
188*d57664e9SAndroid Build Coastguard Worker // When mmap fails because the file has length 0, we use the EmptyData to simulate data of length 0.
189*d57664e9SAndroid Build Coastguard Worker class EmptyData : public IData {
190*d57664e9SAndroid Build Coastguard Worker  public:
191*d57664e9SAndroid Build Coastguard Worker   virtual ~EmptyData() = default;
192*d57664e9SAndroid Build Coastguard Worker 
data()193*d57664e9SAndroid Build Coastguard Worker   const void* data() const override {
194*d57664e9SAndroid Build Coastguard Worker     static const uint8_t d = 0;
195*d57664e9SAndroid Build Coastguard Worker     return &d;
196*d57664e9SAndroid Build Coastguard Worker   }
197*d57664e9SAndroid Build Coastguard Worker 
size()198*d57664e9SAndroid Build Coastguard Worker   size_t size() const override { return 0u; }
199*d57664e9SAndroid Build Coastguard Worker 
Next(const void **,size_t *)200*d57664e9SAndroid Build Coastguard Worker   bool Next(const void** /*data*/, size_t* /*size*/) override { return false; }
201*d57664e9SAndroid Build Coastguard Worker 
BackUp(size_t)202*d57664e9SAndroid Build Coastguard Worker   void BackUp(size_t /*count*/) override {}
203*d57664e9SAndroid Build Coastguard Worker 
CanRewind()204*d57664e9SAndroid Build Coastguard Worker   bool CanRewind() const override { return true; }
205*d57664e9SAndroid Build Coastguard Worker 
Rewind()206*d57664e9SAndroid Build Coastguard Worker   bool Rewind() override { return true; }
207*d57664e9SAndroid Build Coastguard Worker 
ByteCount()208*d57664e9SAndroid Build Coastguard Worker   size_t ByteCount() const override { return 0u; }
209*d57664e9SAndroid Build Coastguard Worker 
HadError()210*d57664e9SAndroid Build Coastguard Worker   bool HadError() const override { return false; }
211*d57664e9SAndroid Build Coastguard Worker };
212*d57664e9SAndroid Build Coastguard Worker 
213*d57664e9SAndroid Build Coastguard Worker }  // namespace io
214*d57664e9SAndroid Build Coastguard Worker }  // namespace aapt
215*d57664e9SAndroid Build Coastguard Worker 
216*d57664e9SAndroid Build Coastguard Worker #endif /* AAPT_IO_DATA_H */
217