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