16f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/* 26f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Copyright (C) 2015 The Android Open Source Project 36f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * 46f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 56f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * you may not use this file except in compliance with the License. 66f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * You may obtain a copy of the License at 76f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * 86f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 96f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * 106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Unless required by applicable law or agreed to in writing, software 116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * See the License for the specific language governing permissions and 146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * limitations under the License. 156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 171ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/BigBuffer.h" 186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <algorithm> 206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <memory> 216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#include <vector> 226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 23ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "android-base/logging.h" 24ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskinamespace aapt { 266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 27ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskivoid* BigBuffer::NextBlockImpl(size_t size) { 28ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (!blocks_.empty()) { 29ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski Block& block = blocks_.back(); 30ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (block.block_size_ - block.size >= size) { 31ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski void* out_buffer = block.buffer.get() + block.size; 32ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski block.size += size; 33ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski size_ += size; 34ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return out_buffer; 356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 36ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 38ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const size_t actual_size = std::max(block_size_, size); 396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 40ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski Block block = {}; 416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 42ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski // Zero-allocate the block's buffer. 43ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski block.buffer = std::unique_ptr<uint8_t[]>(new uint8_t[actual_size]()); 44ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski CHECK(block.buffer); 456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 46ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski block.size = size; 47ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski block.block_size_ = actual_size; 486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 49ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski blocks_.push_back(std::move(block)); 50ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski size_ += size; 51ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return blocks_.back().buffer.get(); 526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 54ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskivoid* BigBuffer::NextBlock(size_t* out_size) { 55ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (!blocks_.empty()) { 56ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski Block& block = blocks_.back(); 57ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (block.size != block.block_size_) { 58ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski void* out_buffer = block.buffer.get() + block.size; 59ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski size_t size = block.block_size_ - block.size; 60ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski block.size = block.block_size_; 61ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski size_ += size; 62ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski *out_size = size; 63ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return out_buffer; 6421efb6827cede06c2ab708de6cdb64d052dddcceAdam Lesinski } 65ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 6621efb6827cede06c2ab708de6cdb64d052dddcceAdam Lesinski 67ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski // Zero-allocate the block's buffer. 68ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski Block block = {}; 69ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski block.buffer = std::unique_ptr<uint8_t[]>(new uint8_t[block_size_]()); 70ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski CHECK(block.buffer); 71ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski block.size = block_size_; 72ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski block.block_size_ = block_size_; 73ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski blocks_.push_back(std::move(block)); 74ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski size_ += block_size_; 75ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski *out_size = block_size_; 76ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return blocks_.back().buffer.get(); 7721efb6827cede06c2ab708de6cdb64d052dddcceAdam Lesinski} 7821efb6827cede06c2ab708de6cdb64d052dddcceAdam Lesinski 79c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinskistd::string BigBuffer::to_string() const { 80c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski std::string result; 81c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski for (const Block& block : blocks_) { 82c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski result.append(block.buffer.get(), block.buffer.get() + block.size); 83c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski } 84c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski return result; 85c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski} 86c8f71aa67ea599cb80205496cb67e9e7a121299cAdam Lesinski 87ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski} // namespace aapt 88