Sat, 03 Jan 2015 20:18:00 +0100
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 2011 Google Inc. |
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 | |
michael@0 | 11 | #ifndef SkTLazy_DEFINED |
michael@0 | 12 | #define SkTLazy_DEFINED |
michael@0 | 13 | |
michael@0 | 14 | #include "SkTypes.h" |
michael@0 | 15 | #include <new> |
michael@0 | 16 | |
michael@0 | 17 | template <typename T> class SkTLazy; |
michael@0 | 18 | template <typename T> void* operator new(size_t, SkTLazy<T>* lazy); |
michael@0 | 19 | |
michael@0 | 20 | /** |
michael@0 | 21 | * Efficient way to defer allocating/initializing a class until it is needed |
michael@0 | 22 | * (if ever). |
michael@0 | 23 | */ |
michael@0 | 24 | template <typename T> class SkTLazy { |
michael@0 | 25 | public: |
michael@0 | 26 | SkTLazy() : fPtr(NULL) {} |
michael@0 | 27 | |
michael@0 | 28 | explicit SkTLazy(const T* src) : fPtr(NULL) { |
michael@0 | 29 | if (src) { |
michael@0 | 30 | fPtr = new (fStorage) T(*src); |
michael@0 | 31 | } |
michael@0 | 32 | } |
michael@0 | 33 | |
michael@0 | 34 | SkTLazy(const SkTLazy<T>& src) : fPtr(NULL) { |
michael@0 | 35 | if (src.isValid()) { |
michael@0 | 36 | fPtr = new (fStorage) T(*src->get()); |
michael@0 | 37 | } else { |
michael@0 | 38 | fPtr = NULL; |
michael@0 | 39 | } |
michael@0 | 40 | } |
michael@0 | 41 | |
michael@0 | 42 | ~SkTLazy() { |
michael@0 | 43 | if (this->isValid()) { |
michael@0 | 44 | fPtr->~T(); |
michael@0 | 45 | } |
michael@0 | 46 | } |
michael@0 | 47 | |
michael@0 | 48 | /** |
michael@0 | 49 | * Return a pointer to a default-initialized instance of the class. If a |
michael@0 | 50 | * previous instance had been initialized (either from init() or set()) it |
michael@0 | 51 | * will first be destroyed, so that a freshly initialized instance is |
michael@0 | 52 | * always returned. |
michael@0 | 53 | */ |
michael@0 | 54 | T* init() { |
michael@0 | 55 | if (this->isValid()) { |
michael@0 | 56 | fPtr->~T(); |
michael@0 | 57 | } |
michael@0 | 58 | fPtr = new (SkTCast<T*>(fStorage)) T; |
michael@0 | 59 | return fPtr; |
michael@0 | 60 | } |
michael@0 | 61 | |
michael@0 | 62 | /** |
michael@0 | 63 | * Copy src into this, and return a pointer to a copy of it. Note this |
michael@0 | 64 | * will always return the same pointer, so if it is called on a lazy that |
michael@0 | 65 | * has already been initialized, then this will copy over the previous |
michael@0 | 66 | * contents. |
michael@0 | 67 | */ |
michael@0 | 68 | T* set(const T& src) { |
michael@0 | 69 | if (this->isValid()) { |
michael@0 | 70 | *fPtr = src; |
michael@0 | 71 | } else { |
michael@0 | 72 | fPtr = new (SkTCast<T*>(fStorage)) T(src); |
michael@0 | 73 | } |
michael@0 | 74 | return fPtr; |
michael@0 | 75 | } |
michael@0 | 76 | |
michael@0 | 77 | /** |
michael@0 | 78 | * Destroy the lazy object (if it was created via init() or set()) |
michael@0 | 79 | */ |
michael@0 | 80 | void reset() { |
michael@0 | 81 | if (this->isValid()) { |
michael@0 | 82 | fPtr->~T(); |
michael@0 | 83 | fPtr = NULL; |
michael@0 | 84 | } |
michael@0 | 85 | } |
michael@0 | 86 | |
michael@0 | 87 | /** |
michael@0 | 88 | * Returns true if a valid object has been initialized in the SkTLazy, |
michael@0 | 89 | * false otherwise. |
michael@0 | 90 | */ |
michael@0 | 91 | bool isValid() const { return NULL != fPtr; } |
michael@0 | 92 | |
michael@0 | 93 | /** |
michael@0 | 94 | * Returns the object. This version should only be called when the caller |
michael@0 | 95 | * knows that the object has been initialized. |
michael@0 | 96 | */ |
michael@0 | 97 | T* get() const { SkASSERT(this->isValid()); return fPtr; } |
michael@0 | 98 | |
michael@0 | 99 | /** |
michael@0 | 100 | * Like above but doesn't assert if object isn't initialized (in which case |
michael@0 | 101 | * NULL is returned). |
michael@0 | 102 | */ |
michael@0 | 103 | T* getMaybeNull() const { return fPtr; } |
michael@0 | 104 | |
michael@0 | 105 | private: |
michael@0 | 106 | friend void* operator new<T>(size_t, SkTLazy* lazy); |
michael@0 | 107 | |
michael@0 | 108 | T* fPtr; // NULL or fStorage |
michael@0 | 109 | char fStorage[sizeof(T)]; |
michael@0 | 110 | }; |
michael@0 | 111 | |
michael@0 | 112 | // Use the below macro (SkNEW_IN_TLAZY) rather than calling this directly |
michael@0 | 113 | template <typename T> void* operator new(size_t, SkTLazy<T>* lazy) { |
michael@0 | 114 | SkASSERT(!lazy->isValid()); |
michael@0 | 115 | lazy->fPtr = reinterpret_cast<T*>(lazy->fStorage); |
michael@0 | 116 | return lazy->fPtr; |
michael@0 | 117 | } |
michael@0 | 118 | |
michael@0 | 119 | // Skia doesn't use C++ exceptions but it may be compiled with them enabled. Having an op delete |
michael@0 | 120 | // to match the op new silences warnings about missing op delete when a constructor throws an |
michael@0 | 121 | // exception. |
michael@0 | 122 | template <typename T> void operator delete(void*, SkTLazy<T>*) { SK_CRASH(); } |
michael@0 | 123 | |
michael@0 | 124 | // Use this to construct a T inside an SkTLazy using a non-default constructor. |
michael@0 | 125 | #define SkNEW_IN_TLAZY(tlazy_ptr, type_name, args) (new (tlazy_ptr) type_name args) |
michael@0 | 126 | |
michael@0 | 127 | /** |
michael@0 | 128 | * A helper built on top of SkTLazy to do copy-on-first-write. The object is initialized |
michael@0 | 129 | * with a const pointer but provides a non-const pointer accessor. The first time the |
michael@0 | 130 | * accessor is called (if ever) the object is cloned. |
michael@0 | 131 | * |
michael@0 | 132 | * In the following example at most one copy of constThing is made: |
michael@0 | 133 | * |
michael@0 | 134 | * SkTCopyOnFirstWrite<Thing> thing(&constThing); |
michael@0 | 135 | * ... |
michael@0 | 136 | * function_that_takes_a_const_thing_ptr(thing); // constThing is passed |
michael@0 | 137 | * ... |
michael@0 | 138 | * if (need_to_modify_thing()) { |
michael@0 | 139 | * thing.writable()->modifyMe(); // makes a copy of constThing |
michael@0 | 140 | * } |
michael@0 | 141 | * ... |
michael@0 | 142 | * x = thing->readSomething(); |
michael@0 | 143 | * ... |
michael@0 | 144 | * if (need_to_modify_thing_now()) { |
michael@0 | 145 | * thing.writable()->changeMe(); // makes a copy of constThing if we didn't call modifyMe() |
michael@0 | 146 | * } |
michael@0 | 147 | * |
michael@0 | 148 | * consume_a_thing(thing); // could be constThing or a modified copy. |
michael@0 | 149 | */ |
michael@0 | 150 | template <typename T> |
michael@0 | 151 | class SkTCopyOnFirstWrite { |
michael@0 | 152 | public: |
michael@0 | 153 | SkTCopyOnFirstWrite(const T& initial) : fObj(&initial) {} |
michael@0 | 154 | |
michael@0 | 155 | // Constructor for delayed initialization. |
michael@0 | 156 | SkTCopyOnFirstWrite() : fObj(NULL) {} |
michael@0 | 157 | |
michael@0 | 158 | // Should only be called once, and only if the default constructor was used. |
michael@0 | 159 | void init(const T& initial) { |
michael@0 | 160 | SkASSERT(NULL == fObj); |
michael@0 | 161 | SkASSERT(!fLazy.isValid()); |
michael@0 | 162 | fObj = &initial; |
michael@0 | 163 | } |
michael@0 | 164 | |
michael@0 | 165 | /** |
michael@0 | 166 | * Returns a writable T*. The first time this is called the initial object is cloned. |
michael@0 | 167 | */ |
michael@0 | 168 | T* writable() { |
michael@0 | 169 | SkASSERT(NULL != fObj); |
michael@0 | 170 | if (!fLazy.isValid()) { |
michael@0 | 171 | fLazy.set(*fObj); |
michael@0 | 172 | fObj = fLazy.get(); |
michael@0 | 173 | } |
michael@0 | 174 | return const_cast<T*>(fObj); |
michael@0 | 175 | } |
michael@0 | 176 | |
michael@0 | 177 | /** |
michael@0 | 178 | * Operators for treating this as though it were a const pointer. |
michael@0 | 179 | */ |
michael@0 | 180 | |
michael@0 | 181 | const T *operator->() const { return fObj; } |
michael@0 | 182 | |
michael@0 | 183 | operator const T*() const { return fObj; } |
michael@0 | 184 | |
michael@0 | 185 | const T& operator *() const { return *fObj; } |
michael@0 | 186 | |
michael@0 | 187 | private: |
michael@0 | 188 | const T* fObj; |
michael@0 | 189 | SkTLazy<T> fLazy; |
michael@0 | 190 | }; |
michael@0 | 191 | |
michael@0 | 192 | #endif |