| /* |
| * Copyright (C) 2018 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "chre/util/dynamic_vector_base.h" |
| |
| #include <cstdint> |
| #include <cstring> |
| |
| #include "chre/util/container_support.h" |
| |
| namespace chre { |
| |
| DynamicVectorBase::DynamicVectorBase(DynamicVectorBase &&other) |
| : mData(other.mData), mSize(other.mSize), mCapacity(other.mCapacity) { |
| other.mData = nullptr; |
| other.mSize = 0; |
| other.mCapacity = 0; |
| } |
| |
| bool DynamicVectorBase::doReserve(size_t newCapacity, size_t elementSize) { |
| bool success = (newCapacity <= mCapacity); |
| if (!success) { |
| void *newData = memoryAlloc(newCapacity * elementSize); |
| if (newData != nullptr) { |
| if (mData != nullptr) { |
| memcpy(newData, mData, mSize * elementSize); |
| memoryFree(mData); |
| } |
| mData = newData; |
| mCapacity = newCapacity; |
| success = true; |
| } |
| } |
| |
| return success; |
| } |
| |
| bool DynamicVectorBase::doPrepareForPush(size_t elementSize) { |
| return doReserve(getNextGrowthCapacity(), elementSize); |
| } |
| |
| size_t DynamicVectorBase::getNextGrowthCapacity() const { |
| size_t newCapacity; |
| if (mCapacity == 0) { |
| newCapacity = 1; |
| } else if (mSize == mCapacity) { |
| newCapacity = mCapacity * 2; |
| } else { |
| newCapacity = mCapacity; |
| } |
| |
| return newCapacity; |
| } |
| |
| void DynamicVectorBase::doErase(size_t index, size_t elementSize) { |
| mSize--; |
| size_t moveAmount = (mSize - index) * elementSize; |
| memmove(static_cast<uint8_t *>(mData) + (index * elementSize), |
| static_cast<uint8_t *>(mData) + ((index + 1) * elementSize), |
| moveAmount); |
| } |
| |
| bool DynamicVectorBase::doPushBack(const void *element, size_t elementSize) { |
| bool spaceAvailable = doPrepareForPush(elementSize); |
| if (spaceAvailable) { |
| memcpy(static_cast<uint8_t *>(mData) + (mSize * elementSize), element, |
| elementSize); |
| mSize++; |
| } |
| |
| return spaceAvailable; |
| } |
| |
| } // namespace chre |