Line data Source code
1 : /*
2 : * Copyright (C) 2005 The Android Open Source Project
3 : *
4 : * Licensed under the Apache License, Version 2.0 (the "License");
5 : * you may not use this file except in compliance with the License.
6 : * You may obtain a copy of the License at
7 : *
8 : * http://www.apache.org/licenses/LICENSE-2.0
9 : *
10 : * Unless required by applicable law or agreed to in writing, software
11 : * distributed under the License is distributed on an "AS IS" BASIS,
12 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : * See the License for the specific language governing permissions and
14 : * limitations under the License.
15 : */
16 :
17 : #ifndef ANDROID_KEYED_VECTOR_H
18 : #define ANDROID_KEYED_VECTOR_H
19 :
20 : #include <assert.h>
21 : #include <stdint.h>
22 : #include <sys/types.h>
23 :
24 : #include <cutils/log.h>
25 :
26 : #include <utils/SortedVector.h>
27 : #include <utils/TypeHelpers.h>
28 : #include <utils/Errors.h>
29 :
30 : // ---------------------------------------------------------------------------
31 :
32 : namespace stagefright {
33 :
34 : template <typename KEY, typename VALUE>
35 0 : class KeyedVector
36 : {
37 : public:
38 : typedef KEY key_type;
39 : typedef VALUE value_type;
40 :
41 : inline KeyedVector();
42 :
43 : /*
44 : * empty the vector
45 : */
46 :
47 0 : inline void clear() { mVector.clear(); }
48 :
49 : /*!
50 : * vector stats
51 : */
52 :
53 : //! returns number of items in the vector
54 0 : inline size_t size() const { return mVector.size(); }
55 : //! returns whether or not the vector is empty
56 : inline bool isEmpty() const { return mVector.isEmpty(); }
57 : //! returns how many items can be stored without reallocating the backing store
58 : inline size_t capacity() const { return mVector.capacity(); }
59 : //! sets the capacity. capacity can never be reduced less than size()
60 : inline ssize_t setCapacity(size_t size) { return mVector.setCapacity(size); }
61 :
62 : // returns true if the arguments is known to be identical to this vector
63 : inline bool isIdenticalTo(const KeyedVector& rhs) const;
64 :
65 : /*!
66 : * accessors
67 : */
68 : const VALUE& valueFor(const KEY& key) const;
69 : const VALUE& valueAt(size_t index) const;
70 : const KEY& keyAt(size_t index) const;
71 : ssize_t indexOfKey(const KEY& key) const;
72 : const VALUE& operator[] (size_t index) const;
73 :
74 : /*!
75 : * modifying the array
76 : */
77 :
78 : VALUE& editValueFor(const KEY& key);
79 : VALUE& editValueAt(size_t index);
80 :
81 : /*!
82 : * add/insert/replace items
83 : */
84 :
85 : ssize_t add(const KEY& key, const VALUE& item);
86 : ssize_t replaceValueFor(const KEY& key, const VALUE& item);
87 : ssize_t replaceValueAt(size_t index, const VALUE& item);
88 :
89 : /*!
90 : * remove items
91 : */
92 :
93 : ssize_t removeItem(const KEY& key);
94 : ssize_t removeItemsAt(size_t index, size_t count = 1);
95 :
96 : private:
97 : SortedVector< key_value_pair_t<KEY, VALUE> > mVector;
98 : };
99 :
100 : // KeyedVector<KEY, VALUE> can be trivially moved using memcpy() because its
101 : // underlying SortedVector can be trivially moved.
102 : template<typename KEY, typename VALUE> struct trait_trivial_move<KeyedVector<KEY, VALUE> > {
103 : enum { value = trait_trivial_move<SortedVector< key_value_pair_t<KEY, VALUE> > >::value };
104 : };
105 :
106 :
107 : // ---------------------------------------------------------------------------
108 :
109 : /**
110 : * Variation of KeyedVector that holds a default value to return when
111 : * valueFor() is called with a key that doesn't exist.
112 : */
113 : template <typename KEY, typename VALUE>
114 : class DefaultKeyedVector : public KeyedVector<KEY, VALUE>
115 : {
116 : public:
117 : inline DefaultKeyedVector(const VALUE& defValue = VALUE());
118 : const VALUE& valueFor(const KEY& key) const;
119 :
120 : private:
121 : VALUE mDefault;
122 : };
123 :
124 : // ---------------------------------------------------------------------------
125 :
126 : template<typename KEY, typename VALUE> inline
127 0 : KeyedVector<KEY,VALUE>::KeyedVector()
128 : {
129 0 : }
130 :
131 : template<typename KEY, typename VALUE> inline
132 : bool KeyedVector<KEY,VALUE>::isIdenticalTo(const KeyedVector<KEY,VALUE>& rhs) const {
133 : return mVector.array() == rhs.mVector.array();
134 : }
135 :
136 : template<typename KEY, typename VALUE> inline
137 0 : ssize_t KeyedVector<KEY,VALUE>::indexOfKey(const KEY& key) const {
138 0 : return mVector.indexOf( key_value_pair_t<KEY,VALUE>(key) );
139 : }
140 :
141 : template<typename KEY, typename VALUE> inline
142 : const VALUE& KeyedVector<KEY,VALUE>::valueFor(const KEY& key) const {
143 : ssize_t i = this->indexOfKey(key);
144 : LOG_ALWAYS_FATAL_IF(i<0, "%s: key not found", __PRETTY_FUNCTION__);
145 : return mVector.itemAt(i).value;
146 : }
147 :
148 : template<typename KEY, typename VALUE> inline
149 0 : const VALUE& KeyedVector<KEY,VALUE>::valueAt(size_t index) const {
150 0 : return mVector.itemAt(index).value;
151 : }
152 :
153 : template<typename KEY, typename VALUE> inline
154 : const VALUE& KeyedVector<KEY,VALUE>::operator[] (size_t index) const {
155 : return valueAt(index);
156 : }
157 :
158 : template<typename KEY, typename VALUE> inline
159 0 : const KEY& KeyedVector<KEY,VALUE>::keyAt(size_t index) const {
160 0 : return mVector.itemAt(index).key;
161 : }
162 :
163 : template<typename KEY, typename VALUE> inline
164 : VALUE& KeyedVector<KEY,VALUE>::editValueFor(const KEY& key) {
165 : ssize_t i = this->indexOfKey(key);
166 : LOG_ALWAYS_FATAL_IF(i<0, "%s: key not found", __PRETTY_FUNCTION__);
167 : return mVector.editItemAt(i).value;
168 : }
169 :
170 : template<typename KEY, typename VALUE> inline
171 0 : VALUE& KeyedVector<KEY,VALUE>::editValueAt(size_t index) {
172 0 : return mVector.editItemAt(index).value;
173 : }
174 :
175 : template<typename KEY, typename VALUE> inline
176 0 : ssize_t KeyedVector<KEY,VALUE>::add(const KEY& key, const VALUE& value) {
177 0 : return mVector.add( key_value_pair_t<KEY,VALUE>(key, value) );
178 : }
179 :
180 : template<typename KEY, typename VALUE> inline
181 : ssize_t KeyedVector<KEY,VALUE>::replaceValueFor(const KEY& key, const VALUE& value) {
182 : key_value_pair_t<KEY,VALUE> pair(key, value);
183 : mVector.remove(pair);
184 : return mVector.add(pair);
185 : }
186 :
187 : template<typename KEY, typename VALUE> inline
188 : ssize_t KeyedVector<KEY,VALUE>::replaceValueAt(size_t index, const VALUE& item) {
189 : if (index<size()) {
190 : mVector.editItemAt(index).value = item;
191 : return index;
192 : }
193 : return BAD_INDEX;
194 : }
195 :
196 : template<typename KEY, typename VALUE> inline
197 : ssize_t KeyedVector<KEY,VALUE>::removeItem(const KEY& key) {
198 : return mVector.remove(key_value_pair_t<KEY,VALUE>(key));
199 : }
200 :
201 : template<typename KEY, typename VALUE> inline
202 0 : ssize_t KeyedVector<KEY, VALUE>::removeItemsAt(size_t index, size_t count) {
203 0 : return mVector.removeItemsAt(index, count);
204 : }
205 :
206 : // ---------------------------------------------------------------------------
207 :
208 : template<typename KEY, typename VALUE> inline
209 : DefaultKeyedVector<KEY,VALUE>::DefaultKeyedVector(const VALUE& defValue)
210 : : mDefault(defValue)
211 : {
212 : }
213 :
214 : template<typename KEY, typename VALUE> inline
215 : const VALUE& DefaultKeyedVector<KEY,VALUE>::valueFor(const KEY& key) const {
216 : ssize_t i = this->indexOfKey(key);
217 : return i >= 0 ? KeyedVector<KEY,VALUE>::valueAt(i) : mDefault;
218 : }
219 :
220 : }; // namespace stagefright
221 :
222 : // ---------------------------------------------------------------------------
223 :
224 : #endif // ANDROID_KEYED_VECTOR_H
|