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
18namespace android {
19namespace base {
20
21StringVector::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
31StringVector& 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
40StringVector::~StringVector() {
41    reserve(0U);
42}
43
44void 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
56void 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
68void 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
76String* 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
86void StringVector::append(const String& str) {
87    *(this->emplace(this->size())) = str;
88}
89
90void StringVector::prepend(const String& str) {
91    *(this->emplace(0U)) = str;
92}
93
94void StringVector::insert(size_t index, const String& str) {
95    *(this->emplace(index)) = str;
96}
97
98void StringVector::append(const StringView& view) {
99    *(this->emplace(this->size())) = view;
100}
101
102void StringVector::prepend(const StringView& view) {
103    *(this->emplace(0U)) = view;
104}
105
106void StringVector::insert(size_t index, const StringView& view) {
107    *(this->emplace(index)) = view;
108}
109
110void 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