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.
1 /*
2 * Copyright 2006 The Android Open Source Project
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
8 #ifndef SkRandom_DEFINED
9 #define SkRandom_DEFINED
11 #include "SkScalar.h"
13 /** \class SkLCGRandom
15 Utility class that implements pseudo random 32bit numbers using a fast
16 linear equation. Unlike rand(), this class holds its own seed (initially
17 set to 0), so that multiple instances can be used with no side-effects.
18 */
19 class SkLCGRandom {
20 public:
21 SkLCGRandom() : fSeed(0) {}
22 SkLCGRandom(uint32_t seed) : fSeed(seed) {}
24 /** Return the next pseudo random number as an unsigned 32bit value.
25 */
26 uint32_t nextU() { uint32_t r = fSeed * kMul + kAdd; fSeed = r; return r; }
28 /** Return the next pseudo random number as a signed 32bit value.
29 */
30 int32_t nextS() { return (int32_t)this->nextU(); }
32 /** Return the next pseudo random number as an unsigned 16bit value.
33 */
34 U16CPU nextU16() { return this->nextU() >> 16; }
36 /** Return the next pseudo random number as a signed 16bit value.
37 */
38 S16CPU nextS16() { return this->nextS() >> 16; }
40 /**
41 * Returns value [0...1) as a float
42 */
43 float nextF() {
44 // const is 1 / (2^32 - 1)
45 return (float)(this->nextU() * 2.32830644e-10);
46 }
48 /**
49 * Returns value [min...max) as a float
50 */
51 float nextRangeF(float min, float max) {
52 return min + this->nextF() * (max - min);
53 }
55 /** Return the next pseudo random number, as an unsigned value of
56 at most bitCount bits.
57 @param bitCount The maximum number of bits to be returned
58 */
59 uint32_t nextBits(unsigned bitCount) {
60 SkASSERT(bitCount > 0 && bitCount <= 32);
61 return this->nextU() >> (32 - bitCount);
62 }
64 /** Return the next pseudo random unsigned number, mapped to lie within
65 [min, max] inclusive.
66 */
67 uint32_t nextRangeU(uint32_t min, uint32_t max) {
68 SkASSERT(min <= max);
69 uint32_t range = max - min + 1;
70 if (0 == range) {
71 return this->nextU();
72 } else {
73 return min + this->nextU() % range;
74 }
75 }
77 /** Return the next pseudo random unsigned number, mapped to lie within
78 [0, count).
79 */
80 uint32_t nextULessThan(uint32_t count) {
81 SkASSERT(count > 0);
82 return this->nextRangeU(0, count - 1);
83 }
85 /** Return the next pseudo random number expressed as an unsigned SkFixed
86 in the range [0..SK_Fixed1).
87 */
88 SkFixed nextUFixed1() { return this->nextU() >> 16; }
90 /** Return the next pseudo random number expressed as a signed SkFixed
91 in the range (-SK_Fixed1..SK_Fixed1).
92 */
93 SkFixed nextSFixed1() { return this->nextS() >> 15; }
95 /** Return the next pseudo random number expressed as a SkScalar
96 in the range [0..SK_Scalar1).
97 */
98 SkScalar nextUScalar1() { return SkFixedToScalar(this->nextUFixed1()); }
100 /** Return the next pseudo random number expressed as a SkScalar
101 in the range [min..max).
102 */
103 SkScalar nextRangeScalar(SkScalar min, SkScalar max) {
104 return this->nextUScalar1() * (max - min) + min;
105 }
107 /** Return the next pseudo random number expressed as a SkScalar
108 in the range (-SK_Scalar1..SK_Scalar1).
109 */
110 SkScalar nextSScalar1() { return SkFixedToScalar(this->nextSFixed1()); }
112 /** Return the next pseudo random number as a bool.
113 */
114 bool nextBool() { return this->nextU() >= 0x80000000; }
116 /** A biased version of nextBool().
117 */
118 bool nextBiasedBool(SkScalar fractionTrue) {
119 SkASSERT(fractionTrue >= 0 && fractionTrue <= SK_Scalar1);
120 return this->nextUScalar1() <= fractionTrue;
121 }
123 /**
124 * Return the next pseudo random number as a signed 64bit value.
125 */
126 int64_t next64() {
127 int64_t hi = this->nextS();
128 return (hi << 32) | this->nextU();
129 }
131 /**
132 * Return the current seed. This allows the caller to later reset to the
133 * same seed (using setSeed) so it can generate the same sequence.
134 */
135 int32_t getSeed() const { return fSeed; }
137 /** Set the seed of the random object. The seed is initialized to 0 when the
138 object is first created, and is updated each time the next pseudo random
139 number is requested.
140 */
141 void setSeed(int32_t seed) { fSeed = (uint32_t)seed; }
143 private:
144 // See "Numerical Recipes in C", 1992 page 284 for these constants
145 enum {
146 kMul = 1664525,
147 kAdd = 1013904223
148 };
149 uint32_t fSeed;
150 };
152 /** \class SkRandom
154 Utility class that implements pseudo random 32bit numbers using Marsaglia's
155 multiply-with-carry "mother of all" algorithm. Unlike rand(), this class holds
156 its own state, so that multiple instances can be used with no side-effects.
158 Has a large period and all bits are well-randomized.
159 */
160 class SkRandom {
161 public:
162 SkRandom() { init(0); }
163 SkRandom(uint32_t seed) { init(seed); }
164 SkRandom(const SkRandom& rand) : fK(rand.fK), fJ(rand.fJ) {}
166 SkRandom& operator=(const SkRandom& rand) {
167 fK = rand.fK;
168 fJ = rand.fJ;
170 return *this;
171 }
173 /** Return the next pseudo random number as an unsigned 32bit value.
174 */
175 uint32_t nextU() {
176 fK = kKMul*(fK & 0xffff) + (fK >> 16);
177 fJ = kJMul*(fJ & 0xffff) + (fJ >> 16);
178 return (((fK << 16) | (fK >> 16)) + fJ);
179 }
181 /** Return the next pseudo random number as a signed 32bit value.
182 */
183 int32_t nextS() { return (int32_t)this->nextU(); }
185 /** Return the next pseudo random number as an unsigned 16bit value.
186 */
187 U16CPU nextU16() { return this->nextU() >> 16; }
189 /** Return the next pseudo random number as a signed 16bit value.
190 */
191 S16CPU nextS16() { return this->nextS() >> 16; }
193 /**
194 * Returns value [0...1) as an IEEE float
195 */
196 float nextF() {
197 unsigned int floatint = 0x3f800000 | (this->nextU() >> 9);
198 float f = SkBits2Float(floatint) - 1.0f;
199 return f;
200 }
202 /**
203 * Returns value [min...max) as a float
204 */
205 float nextRangeF(float min, float max) {
206 return min + this->nextF() * (max - min);
207 }
209 /** Return the next pseudo random number, as an unsigned value of
210 at most bitCount bits.
211 @param bitCount The maximum number of bits to be returned
212 */
213 uint32_t nextBits(unsigned bitCount) {
214 SkASSERT(bitCount > 0 && bitCount <= 32);
215 return this->nextU() >> (32 - bitCount);
216 }
218 /** Return the next pseudo random unsigned number, mapped to lie within
219 [min, max] inclusive.
220 */
221 uint32_t nextRangeU(uint32_t min, uint32_t max) {
222 SkASSERT(min <= max);
223 uint32_t range = max - min + 1;
224 if (0 == range) {
225 return this->nextU();
226 } else {
227 return min + this->nextU() % range;
228 }
229 }
231 /** Return the next pseudo random unsigned number, mapped to lie within
232 [0, count).
233 */
234 uint32_t nextULessThan(uint32_t count) {
235 SkASSERT(count > 0);
236 return this->nextRangeU(0, count - 1);
237 }
239 /** Return the next pseudo random number expressed as an unsigned SkFixed
240 in the range [0..SK_Fixed1).
241 */
242 SkFixed nextUFixed1() { return this->nextU() >> 16; }
244 /** Return the next pseudo random number expressed as a signed SkFixed
245 in the range (-SK_Fixed1..SK_Fixed1).
246 */
247 SkFixed nextSFixed1() { return this->nextS() >> 15; }
249 /** Return the next pseudo random number expressed as a SkScalar
250 in the range [0..SK_Scalar1).
251 */
252 SkScalar nextUScalar1() { return SkFixedToScalar(this->nextUFixed1()); }
254 /** Return the next pseudo random number expressed as a SkScalar
255 in the range [min..max).
256 */
257 SkScalar nextRangeScalar(SkScalar min, SkScalar max) {
258 return this->nextUScalar1() * (max - min) + min;
259 }
261 /** Return the next pseudo random number expressed as a SkScalar
262 in the range (-SK_Scalar1..SK_Scalar1).
263 */
264 SkScalar nextSScalar1() { return SkFixedToScalar(this->nextSFixed1()); }
266 /** Return the next pseudo random number as a bool.
267 */
268 bool nextBool() { return this->nextU() >= 0x80000000; }
270 /** A biased version of nextBool().
271 */
272 bool nextBiasedBool(SkScalar fractionTrue) {
273 SkASSERT(fractionTrue >= 0 && fractionTrue <= SK_Scalar1);
274 return this->nextUScalar1() <= fractionTrue;
275 }
277 /**
278 * Return the next pseudo random number as a signed 64bit value.
279 */
280 int64_t next64() {
281 int64_t hi = this->nextS();
282 return (hi << 32) | this->nextU();
283 }
285 /** Reset the random object.
286 */
287 void setSeed(uint32_t seed) { init(seed); }
289 private:
290 // Initialize state variables with LCG.
291 // We must ensure that both J and K are non-zero, otherwise the
292 // multiply-with-carry step will forevermore return zero.
293 void init(uint32_t seed) {
294 fK = NextLCG(seed);
295 if (0 == fK) {
296 fK = NextLCG(fK);
297 }
298 fJ = NextLCG(fK);
299 if (0 == fJ) {
300 fJ = NextLCG(fJ);
301 }
302 SkASSERT(0 != fK && 0 != fJ);
303 }
304 static uint32_t NextLCG(uint32_t seed) { return kMul*seed + kAdd; }
306 // See "Numerical Recipes in C", 1992 page 284 for these constants
307 // For the LCG that sets the initial state from a seed
308 enum {
309 kMul = 1664525,
310 kAdd = 1013904223
311 };
312 // Constants for the multiply-with-carry steps
313 enum {
314 kKMul = 30345,
315 kJMul = 18000,
316 };
318 uint32_t fK;
319 uint32_t fJ;
320 };
322 #endif