gfx/skia/trunk/include/core/SkTDArray.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1
michael@0 2 /*
michael@0 3 * Copyright 2006 The Android Open Source Project
michael@0 4 *
michael@0 5 * Use of this source code is governed by a BSD-style license that can be
michael@0 6 * found in the LICENSE file.
michael@0 7 */
michael@0 8
michael@0 9
michael@0 10 #ifndef SkTDArray_DEFINED
michael@0 11 #define SkTDArray_DEFINED
michael@0 12
michael@0 13 #include "SkTypes.h"
michael@0 14
michael@0 15 template <typename T> class SK_API SkTDArray {
michael@0 16 public:
michael@0 17 SkTDArray() {
michael@0 18 fReserve = fCount = 0;
michael@0 19 fArray = NULL;
michael@0 20 #ifdef SK_DEBUG
michael@0 21 fData = NULL;
michael@0 22 #endif
michael@0 23 }
michael@0 24 SkTDArray(const T src[], int count) {
michael@0 25 SkASSERT(src || count == 0);
michael@0 26
michael@0 27 fReserve = fCount = 0;
michael@0 28 fArray = NULL;
michael@0 29 #ifdef SK_DEBUG
michael@0 30 fData = NULL;
michael@0 31 #endif
michael@0 32 if (count) {
michael@0 33 fArray = (T*)sk_malloc_throw(count * sizeof(T));
michael@0 34 #ifdef SK_DEBUG
michael@0 35 fData = (ArrayT*)fArray;
michael@0 36 #endif
michael@0 37 memcpy(fArray, src, sizeof(T) * count);
michael@0 38 fReserve = fCount = count;
michael@0 39 }
michael@0 40 }
michael@0 41 SkTDArray(const SkTDArray<T>& src) {
michael@0 42 fReserve = fCount = 0;
michael@0 43 fArray = NULL;
michael@0 44 #ifdef SK_DEBUG
michael@0 45 fData = NULL;
michael@0 46 #endif
michael@0 47 SkTDArray<T> tmp(src.fArray, src.fCount);
michael@0 48 this->swap(tmp);
michael@0 49 }
michael@0 50 ~SkTDArray() {
michael@0 51 sk_free(fArray);
michael@0 52 }
michael@0 53
michael@0 54 SkTDArray<T>& operator=(const SkTDArray<T>& src) {
michael@0 55 if (this != &src) {
michael@0 56 if (src.fCount > fReserve) {
michael@0 57 SkTDArray<T> tmp(src.fArray, src.fCount);
michael@0 58 this->swap(tmp);
michael@0 59 } else {
michael@0 60 memcpy(fArray, src.fArray, sizeof(T) * src.fCount);
michael@0 61 fCount = src.fCount;
michael@0 62 }
michael@0 63 }
michael@0 64 return *this;
michael@0 65 }
michael@0 66
michael@0 67 friend bool operator==(const SkTDArray<T>& a, const SkTDArray<T>& b) {
michael@0 68 return a.fCount == b.fCount &&
michael@0 69 (a.fCount == 0 ||
michael@0 70 !memcmp(a.fArray, b.fArray, a.fCount * sizeof(T)));
michael@0 71 }
michael@0 72 friend bool operator!=(const SkTDArray<T>& a, const SkTDArray<T>& b) {
michael@0 73 return !(a == b);
michael@0 74 }
michael@0 75
michael@0 76 void swap(SkTDArray<T>& other) {
michael@0 77 SkTSwap(fArray, other.fArray);
michael@0 78 #ifdef SK_DEBUG
michael@0 79 SkTSwap(fData, other.fData);
michael@0 80 #endif
michael@0 81 SkTSwap(fReserve, other.fReserve);
michael@0 82 SkTSwap(fCount, other.fCount);
michael@0 83 }
michael@0 84
michael@0 85 /** Return a ptr to the array of data, to be freed with sk_free. This also
michael@0 86 resets the SkTDArray to be empty.
michael@0 87 */
michael@0 88 T* detach() {
michael@0 89 T* array = fArray;
michael@0 90 fArray = NULL;
michael@0 91 fReserve = fCount = 0;
michael@0 92 SkDEBUGCODE(fData = NULL;)
michael@0 93 return array;
michael@0 94 }
michael@0 95
michael@0 96 bool isEmpty() const { return fCount == 0; }
michael@0 97
michael@0 98 /**
michael@0 99 * Return the number of elements in the array
michael@0 100 */
michael@0 101 int count() const { return fCount; }
michael@0 102
michael@0 103 /**
michael@0 104 * Return the total number of elements allocated.
michael@0 105 * reserved() - count() gives you the number of elements you can add
michael@0 106 * without causing an allocation.
michael@0 107 */
michael@0 108 int reserved() const { return fReserve; }
michael@0 109
michael@0 110 /**
michael@0 111 * return the number of bytes in the array: count * sizeof(T)
michael@0 112 */
michael@0 113 size_t bytes() const { return fCount * sizeof(T); }
michael@0 114
michael@0 115 T* begin() { return fArray; }
michael@0 116 const T* begin() const { return fArray; }
michael@0 117 T* end() { return fArray ? fArray + fCount : NULL; }
michael@0 118 const T* end() const { return fArray ? fArray + fCount : NULL; }
michael@0 119
michael@0 120 T& operator[](int index) {
michael@0 121 SkASSERT(index < fCount);
michael@0 122 return fArray[index];
michael@0 123 }
michael@0 124 const T& operator[](int index) const {
michael@0 125 SkASSERT(index < fCount);
michael@0 126 return fArray[index];
michael@0 127 }
michael@0 128
michael@0 129 T& getAt(int index) {
michael@0 130 return (*this)[index];
michael@0 131 }
michael@0 132 const T& getAt(int index) const {
michael@0 133 return (*this)[index];
michael@0 134 }
michael@0 135
michael@0 136 void reset() {
michael@0 137 if (fArray) {
michael@0 138 sk_free(fArray);
michael@0 139 fArray = NULL;
michael@0 140 #ifdef SK_DEBUG
michael@0 141 fData = NULL;
michael@0 142 #endif
michael@0 143 fReserve = fCount = 0;
michael@0 144 } else {
michael@0 145 SkASSERT(fReserve == 0 && fCount == 0);
michael@0 146 }
michael@0 147 }
michael@0 148
michael@0 149 void rewind() {
michael@0 150 // same as setCount(0)
michael@0 151 fCount = 0;
michael@0 152 }
michael@0 153
michael@0 154 /**
michael@0 155 * Sets the number of elements in the array.
michael@0 156 * If the array does not have space for count elements, it will increase
michael@0 157 * the storage allocated to some amount greater than that required.
michael@0 158 * It will never shrink the shrink the storage.
michael@0 159 */
michael@0 160 void setCount(int count) {
michael@0 161 SkASSERT(count >= 0);
michael@0 162 if (count > fReserve) {
michael@0 163 this->resizeStorageToAtLeast(count);
michael@0 164 }
michael@0 165 fCount = count;
michael@0 166 }
michael@0 167
michael@0 168 void setReserve(int reserve) {
michael@0 169 if (reserve > fReserve) {
michael@0 170 this->resizeStorageToAtLeast(reserve);
michael@0 171 }
michael@0 172 }
michael@0 173
michael@0 174 T* prepend() {
michael@0 175 this->adjustCount(1);
michael@0 176 memmove(fArray + 1, fArray, (fCount - 1) * sizeof(T));
michael@0 177 return fArray;
michael@0 178 }
michael@0 179
michael@0 180 T* append() {
michael@0 181 return this->append(1, NULL);
michael@0 182 }
michael@0 183 T* append(int count, const T* src = NULL) {
michael@0 184 int oldCount = fCount;
michael@0 185 if (count) {
michael@0 186 SkASSERT(src == NULL || fArray == NULL ||
michael@0 187 src + count <= fArray || fArray + oldCount <= src);
michael@0 188
michael@0 189 this->adjustCount(count);
michael@0 190 if (src) {
michael@0 191 memcpy(fArray + oldCount, src, sizeof(T) * count);
michael@0 192 }
michael@0 193 }
michael@0 194 return fArray + oldCount;
michael@0 195 }
michael@0 196
michael@0 197 T* appendClear() {
michael@0 198 T* result = this->append();
michael@0 199 *result = 0;
michael@0 200 return result;
michael@0 201 }
michael@0 202
michael@0 203 T* insert(int index) {
michael@0 204 return this->insert(index, 1, NULL);
michael@0 205 }
michael@0 206 T* insert(int index, int count, const T* src = NULL) {
michael@0 207 SkASSERT(count);
michael@0 208 SkASSERT(index <= fCount);
michael@0 209 size_t oldCount = fCount;
michael@0 210 this->adjustCount(count);
michael@0 211 T* dst = fArray + index;
michael@0 212 memmove(dst + count, dst, sizeof(T) * (oldCount - index));
michael@0 213 if (src) {
michael@0 214 memcpy(dst, src, sizeof(T) * count);
michael@0 215 }
michael@0 216 return dst;
michael@0 217 }
michael@0 218
michael@0 219 void remove(int index, int count = 1) {
michael@0 220 SkASSERT(index + count <= fCount);
michael@0 221 fCount = fCount - count;
michael@0 222 memmove(fArray + index, fArray + index + count, sizeof(T) * (fCount - index));
michael@0 223 }
michael@0 224
michael@0 225 void removeShuffle(int index) {
michael@0 226 SkASSERT(index < fCount);
michael@0 227 int newCount = fCount - 1;
michael@0 228 fCount = newCount;
michael@0 229 if (index != newCount) {
michael@0 230 memcpy(fArray + index, fArray + newCount, sizeof(T));
michael@0 231 }
michael@0 232 }
michael@0 233
michael@0 234 int find(const T& elem) const {
michael@0 235 const T* iter = fArray;
michael@0 236 const T* stop = fArray + fCount;
michael@0 237
michael@0 238 for (; iter < stop; iter++) {
michael@0 239 if (*iter == elem) {
michael@0 240 return (int) (iter - fArray);
michael@0 241 }
michael@0 242 }
michael@0 243 return -1;
michael@0 244 }
michael@0 245
michael@0 246 int rfind(const T& elem) const {
michael@0 247 const T* iter = fArray + fCount;
michael@0 248 const T* stop = fArray;
michael@0 249
michael@0 250 while (iter > stop) {
michael@0 251 if (*--iter == elem) {
michael@0 252 return SkToInt(iter - stop);
michael@0 253 }
michael@0 254 }
michael@0 255 return -1;
michael@0 256 }
michael@0 257
michael@0 258 /**
michael@0 259 * Returns true iff the array contains this element.
michael@0 260 */
michael@0 261 bool contains(const T& elem) const {
michael@0 262 return (this->find(elem) >= 0);
michael@0 263 }
michael@0 264
michael@0 265 /**
michael@0 266 * Copies up to max elements into dst. The number of items copied is
michael@0 267 * capped by count - index. The actual number copied is returned.
michael@0 268 */
michael@0 269 int copyRange(T* dst, int index, int max) const {
michael@0 270 SkASSERT(max >= 0);
michael@0 271 SkASSERT(!max || dst);
michael@0 272 if (index >= fCount) {
michael@0 273 return 0;
michael@0 274 }
michael@0 275 int count = SkMin32(max, fCount - index);
michael@0 276 memcpy(dst, fArray + index, sizeof(T) * count);
michael@0 277 return count;
michael@0 278 }
michael@0 279
michael@0 280 void copy(T* dst) const {
michael@0 281 this->copyRange(dst, 0, fCount);
michael@0 282 }
michael@0 283
michael@0 284 // routines to treat the array like a stack
michael@0 285 T* push() { return this->append(); }
michael@0 286 void push(const T& elem) { *this->append() = elem; }
michael@0 287 const T& top() const { return (*this)[fCount - 1]; }
michael@0 288 T& top() { return (*this)[fCount - 1]; }
michael@0 289 void pop(T* elem) { if (elem) *elem = (*this)[fCount - 1]; --fCount; }
michael@0 290 void pop() { --fCount; }
michael@0 291
michael@0 292 void deleteAll() {
michael@0 293 T* iter = fArray;
michael@0 294 T* stop = fArray + fCount;
michael@0 295 while (iter < stop) {
michael@0 296 SkDELETE (*iter);
michael@0 297 iter += 1;
michael@0 298 }
michael@0 299 this->reset();
michael@0 300 }
michael@0 301
michael@0 302 void freeAll() {
michael@0 303 T* iter = fArray;
michael@0 304 T* stop = fArray + fCount;
michael@0 305 while (iter < stop) {
michael@0 306 sk_free(*iter);
michael@0 307 iter += 1;
michael@0 308 }
michael@0 309 this->reset();
michael@0 310 }
michael@0 311
michael@0 312 void unrefAll() {
michael@0 313 T* iter = fArray;
michael@0 314 T* stop = fArray + fCount;
michael@0 315 while (iter < stop) {
michael@0 316 (*iter)->unref();
michael@0 317 iter += 1;
michael@0 318 }
michael@0 319 this->reset();
michael@0 320 }
michael@0 321
michael@0 322 void safeUnrefAll() {
michael@0 323 T* iter = fArray;
michael@0 324 T* stop = fArray + fCount;
michael@0 325 while (iter < stop) {
michael@0 326 SkSafeUnref(*iter);
michael@0 327 iter += 1;
michael@0 328 }
michael@0 329 this->reset();
michael@0 330 }
michael@0 331
michael@0 332 void visitAll(void visitor(T&)) {
michael@0 333 T* stop = this->end();
michael@0 334 for (T* curr = this->begin(); curr < stop; curr++) {
michael@0 335 if (*curr) {
michael@0 336 visitor(*curr);
michael@0 337 }
michael@0 338 }
michael@0 339 }
michael@0 340
michael@0 341 #ifdef SK_DEBUG
michael@0 342 void validate() const {
michael@0 343 SkASSERT((fReserve == 0 && fArray == NULL) ||
michael@0 344 (fReserve > 0 && fArray != NULL));
michael@0 345 SkASSERT(fCount <= fReserve);
michael@0 346 SkASSERT(fData == (ArrayT*)fArray);
michael@0 347 }
michael@0 348 #endif
michael@0 349
michael@0 350 private:
michael@0 351 #ifdef SK_DEBUG
michael@0 352 enum {
michael@0 353 kDebugArraySize = 16
michael@0 354 };
michael@0 355 typedef T ArrayT[kDebugArraySize];
michael@0 356 ArrayT* fData;
michael@0 357 #endif
michael@0 358 T* fArray;
michael@0 359 int fReserve;
michael@0 360 int fCount;
michael@0 361
michael@0 362 /**
michael@0 363 * Adjusts the number of elements in the array.
michael@0 364 * This is the same as calling setCount(count() + delta).
michael@0 365 */
michael@0 366 void adjustCount(int delta) {
michael@0 367 this->setCount(fCount + delta);
michael@0 368 }
michael@0 369
michael@0 370 /**
michael@0 371 * Increase the storage allocation such that it can hold (fCount + extra)
michael@0 372 * elements.
michael@0 373 * It never shrinks the allocation, and it may increase the allocation by
michael@0 374 * more than is strictly required, based on a private growth heuristic.
michael@0 375 *
michael@0 376 * note: does NOT modify fCount
michael@0 377 */
michael@0 378 void resizeStorageToAtLeast(int count) {
michael@0 379 SkASSERT(count > fReserve);
michael@0 380 fReserve = count + 4;
michael@0 381 fReserve += fReserve / 4;
michael@0 382 fArray = (T*)sk_realloc_throw(fArray, fReserve * sizeof(T));
michael@0 383 #ifdef SK_DEBUG
michael@0 384 fData = (ArrayT*)fArray;
michael@0 385 #endif
michael@0 386 }
michael@0 387 };
michael@0 388
michael@0 389 #endif

mercurial