1 // Copyright 2014 The Android Open Source Project 2 // 3 // This software is licensed under the terms of the GNU General Public 4 // License version 2, as published by the Free Software Foundation, and 5 // may be copied, distributed, and modified under those terms. 6 // 7 // This program is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 // GNU General Public License for more details. 11 12 #include "android/base/containers/StringVector.h" 13 14 #include "android/base/StringView.h" 15 16 #include <stdio.h> 17 18 namespace android { 19 namespace base { 20 21 StringVector::StringVector(const StringVector& other) : PodVector<String>() { 22 size_t count = other.size(); 23 // We rely on the fact that an all-0 String instance is properly 24 // initialized to the empty string. 25 resize(count); 26 for (size_t n = 0; n < count; ++n) { 27 (*this) [n] = other[n]; 28 } 29 } 30 31 StringVector& StringVector::operator=(const StringVector& other) { 32 reserve(0U); 33 resize(other.size()); 34 for (size_t n = 0; n < other.size(); ++n) { 35 (*this)[n] = other[n]; 36 } 37 return *this; 38 } 39 40 StringVector::~StringVector() { 41 reserve(0U); 42 } 43 44 void StringVector::resize(size_t newSize) { 45 size_t oldSize = size(); 46 String* oldStrings = begin(); 47 if (newSize < oldSize) { 48 String::finalizeSlice(oldStrings + newSize, oldSize - newSize); 49 } 50 PodVectorBase::resize(newSize, sizeof(String)); 51 if (oldStrings != begin()) { 52 String::adjustMovedSlice(oldStrings, begin(), newSize); 53 } 54 } 55 56 void StringVector::reserve(size_t newSize) { 57 size_t oldSize = size(); 58 String* oldStrings = begin(); 59 if (newSize < oldSize) { 60 String::finalizeSlice(oldStrings + newSize, oldSize - newSize); 61 } 62 PodVectorBase::reserve(newSize, sizeof(String)); 63 if (oldStrings != begin()) { 64 String::adjustMovedSlice(oldStrings, begin(), newSize); 65 } 66 } 67 68 void StringVector::remove(size_t index) { 69 size_t oldSize = size(); 70 if (index >= oldSize) 71 return; 72 String::finalizeSlice(begin(), 1U); 73 String::moveSlice(begin(), index + 1, index, oldSize - index); 74 } 75 76 String* StringVector::emplace(size_t index) { 77 size_t oldSize = size(); 78 DCHECK(index <= oldSize); 79 resize(oldSize + 1U); 80 String::moveSlice(begin(), index, index + 1, oldSize - index); 81 String* result = begin() + index; 82 ::memset(result, 0, sizeof(String)); 83 return result; 84 } 85 86 void StringVector::append(const String& str) { 87 *(this->emplace(this->size())) = str; 88 } 89 90 void StringVector::prepend(const String& str) { 91 *(this->emplace(0U)) = str; 92 } 93 94 void StringVector::insert(size_t index, const String& str) { 95 *(this->emplace(index)) = str; 96 } 97 98 void StringVector::append(const StringView& view) { 99 *(this->emplace(this->size())) = view; 100 } 101 102 void StringVector::prepend(const StringView& view) { 103 *(this->emplace(0U)) = view; 104 } 105 106 void StringVector::insert(size_t index, const StringView& view) { 107 *(this->emplace(index)) = view; 108 } 109 110 void StringVector::swap(StringVector* other) { 111 size_t mySize = size(); 112 size_t otherSize = other->size(); 113 PodVectorBase::swapAll(other); 114 String::adjustMovedSlice(this->begin(), other->begin(), mySize); 115 String::adjustMovedSlice(other->begin(), this->begin(), otherSize); 116 } 117 118 } // namespace base 119 } // namespace android 120