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 2012 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 | #include "SkWriteBuffer.h" |
michael@0 | 10 | #include "SkBitmap.h" |
michael@0 | 11 | #include "SkData.h" |
michael@0 | 12 | #include "SkPixelRef.h" |
michael@0 | 13 | #include "SkPtrRecorder.h" |
michael@0 | 14 | #include "SkStream.h" |
michael@0 | 15 | #include "SkTypeface.h" |
michael@0 | 16 | |
michael@0 | 17 | SkWriteBuffer::SkWriteBuffer(uint32_t flags) |
michael@0 | 18 | : fFlags(flags) |
michael@0 | 19 | , fFactorySet(NULL) |
michael@0 | 20 | , fNamedFactorySet(NULL) |
michael@0 | 21 | , fBitmapHeap(NULL) |
michael@0 | 22 | , fTFSet(NULL) |
michael@0 | 23 | , fBitmapEncoder(NULL) { |
michael@0 | 24 | } |
michael@0 | 25 | |
michael@0 | 26 | SkWriteBuffer::SkWriteBuffer(void* storage, size_t storageSize, uint32_t flags) |
michael@0 | 27 | : fFlags(flags) |
michael@0 | 28 | , fFactorySet(NULL) |
michael@0 | 29 | , fNamedFactorySet(NULL) |
michael@0 | 30 | , fWriter(storage, storageSize) |
michael@0 | 31 | , fBitmapHeap(NULL) |
michael@0 | 32 | , fTFSet(NULL) |
michael@0 | 33 | , fBitmapEncoder(NULL) { |
michael@0 | 34 | } |
michael@0 | 35 | |
michael@0 | 36 | SkWriteBuffer::~SkWriteBuffer() { |
michael@0 | 37 | SkSafeUnref(fFactorySet); |
michael@0 | 38 | SkSafeUnref(fNamedFactorySet); |
michael@0 | 39 | SkSafeUnref(fBitmapHeap); |
michael@0 | 40 | SkSafeUnref(fTFSet); |
michael@0 | 41 | } |
michael@0 | 42 | |
michael@0 | 43 | void SkWriteBuffer::writeByteArray(const void* data, size_t size) { |
michael@0 | 44 | fWriter.write32(SkToU32(size)); |
michael@0 | 45 | fWriter.writePad(data, size); |
michael@0 | 46 | } |
michael@0 | 47 | |
michael@0 | 48 | void SkWriteBuffer::writeBool(bool value) { |
michael@0 | 49 | fWriter.writeBool(value); |
michael@0 | 50 | } |
michael@0 | 51 | |
michael@0 | 52 | void SkWriteBuffer::writeFixed(SkFixed value) { |
michael@0 | 53 | fWriter.write32(value); |
michael@0 | 54 | } |
michael@0 | 55 | |
michael@0 | 56 | void SkWriteBuffer::writeScalar(SkScalar value) { |
michael@0 | 57 | fWriter.writeScalar(value); |
michael@0 | 58 | } |
michael@0 | 59 | |
michael@0 | 60 | void SkWriteBuffer::writeScalarArray(const SkScalar* value, uint32_t count) { |
michael@0 | 61 | fWriter.write32(count); |
michael@0 | 62 | fWriter.write(value, count * sizeof(SkScalar)); |
michael@0 | 63 | } |
michael@0 | 64 | |
michael@0 | 65 | void SkWriteBuffer::writeInt(int32_t value) { |
michael@0 | 66 | fWriter.write32(value); |
michael@0 | 67 | } |
michael@0 | 68 | |
michael@0 | 69 | void SkWriteBuffer::writeIntArray(const int32_t* value, uint32_t count) { |
michael@0 | 70 | fWriter.write32(count); |
michael@0 | 71 | fWriter.write(value, count * sizeof(int32_t)); |
michael@0 | 72 | } |
michael@0 | 73 | |
michael@0 | 74 | void SkWriteBuffer::writeUInt(uint32_t value) { |
michael@0 | 75 | fWriter.write32(value); |
michael@0 | 76 | } |
michael@0 | 77 | |
michael@0 | 78 | void SkWriteBuffer::write32(int32_t value) { |
michael@0 | 79 | fWriter.write32(value); |
michael@0 | 80 | } |
michael@0 | 81 | |
michael@0 | 82 | void SkWriteBuffer::writeString(const char* value) { |
michael@0 | 83 | fWriter.writeString(value); |
michael@0 | 84 | } |
michael@0 | 85 | |
michael@0 | 86 | void SkWriteBuffer::writeEncodedString(const void* value, size_t byteLength, |
michael@0 | 87 | SkPaint::TextEncoding encoding) { |
michael@0 | 88 | fWriter.writeInt(encoding); |
michael@0 | 89 | fWriter.writeInt(SkToU32(byteLength)); |
michael@0 | 90 | fWriter.write(value, byteLength); |
michael@0 | 91 | } |
michael@0 | 92 | |
michael@0 | 93 | |
michael@0 | 94 | void SkWriteBuffer::writeColor(const SkColor& color) { |
michael@0 | 95 | fWriter.write32(color); |
michael@0 | 96 | } |
michael@0 | 97 | |
michael@0 | 98 | void SkWriteBuffer::writeColorArray(const SkColor* color, uint32_t count) { |
michael@0 | 99 | fWriter.write32(count); |
michael@0 | 100 | fWriter.write(color, count * sizeof(SkColor)); |
michael@0 | 101 | } |
michael@0 | 102 | |
michael@0 | 103 | void SkWriteBuffer::writePoint(const SkPoint& point) { |
michael@0 | 104 | fWriter.writeScalar(point.fX); |
michael@0 | 105 | fWriter.writeScalar(point.fY); |
michael@0 | 106 | } |
michael@0 | 107 | |
michael@0 | 108 | void SkWriteBuffer::writePointArray(const SkPoint* point, uint32_t count) { |
michael@0 | 109 | fWriter.write32(count); |
michael@0 | 110 | fWriter.write(point, count * sizeof(SkPoint)); |
michael@0 | 111 | } |
michael@0 | 112 | |
michael@0 | 113 | void SkWriteBuffer::writeMatrix(const SkMatrix& matrix) { |
michael@0 | 114 | fWriter.writeMatrix(matrix); |
michael@0 | 115 | } |
michael@0 | 116 | |
michael@0 | 117 | void SkWriteBuffer::writeIRect(const SkIRect& rect) { |
michael@0 | 118 | fWriter.write(&rect, sizeof(SkIRect)); |
michael@0 | 119 | } |
michael@0 | 120 | |
michael@0 | 121 | void SkWriteBuffer::writeRect(const SkRect& rect) { |
michael@0 | 122 | fWriter.writeRect(rect); |
michael@0 | 123 | } |
michael@0 | 124 | |
michael@0 | 125 | void SkWriteBuffer::writeRegion(const SkRegion& region) { |
michael@0 | 126 | fWriter.writeRegion(region); |
michael@0 | 127 | } |
michael@0 | 128 | |
michael@0 | 129 | void SkWriteBuffer::writePath(const SkPath& path) { |
michael@0 | 130 | fWriter.writePath(path); |
michael@0 | 131 | } |
michael@0 | 132 | |
michael@0 | 133 | size_t SkWriteBuffer::writeStream(SkStream* stream, size_t length) { |
michael@0 | 134 | fWriter.write32(SkToU32(length)); |
michael@0 | 135 | size_t bytesWritten = fWriter.readFromStream(stream, length); |
michael@0 | 136 | if (bytesWritten < length) { |
michael@0 | 137 | fWriter.reservePad(length - bytesWritten); |
michael@0 | 138 | } |
michael@0 | 139 | return bytesWritten; |
michael@0 | 140 | } |
michael@0 | 141 | |
michael@0 | 142 | bool SkWriteBuffer::writeToStream(SkWStream* stream) { |
michael@0 | 143 | return fWriter.writeToStream(stream); |
michael@0 | 144 | } |
michael@0 | 145 | |
michael@0 | 146 | static void write_encoded_bitmap(SkWriteBuffer* buffer, SkData* data, |
michael@0 | 147 | const SkIPoint& origin) { |
michael@0 | 148 | buffer->writeUInt(SkToU32(data->size())); |
michael@0 | 149 | buffer->getWriter32()->writePad(data->data(), data->size()); |
michael@0 | 150 | buffer->write32(origin.fX); |
michael@0 | 151 | buffer->write32(origin.fY); |
michael@0 | 152 | } |
michael@0 | 153 | |
michael@0 | 154 | void SkWriteBuffer::writeBitmap(const SkBitmap& bitmap) { |
michael@0 | 155 | // Record the width and height. This way if readBitmap fails a dummy bitmap can be drawn at the |
michael@0 | 156 | // right size. |
michael@0 | 157 | this->writeInt(bitmap.width()); |
michael@0 | 158 | this->writeInt(bitmap.height()); |
michael@0 | 159 | |
michael@0 | 160 | // Record information about the bitmap in one of three ways, in order of priority: |
michael@0 | 161 | // 1. If there is an SkBitmapHeap, store it in the heap. The client can avoid serializing the |
michael@0 | 162 | // bitmap entirely or serialize it later as desired. A boolean value of true will be written |
michael@0 | 163 | // to the stream to signify that a heap was used. |
michael@0 | 164 | // 2. If there is a function for encoding bitmaps, use it to write an encoded version of the |
michael@0 | 165 | // bitmap. After writing a boolean value of false, signifying that a heap was not used, write |
michael@0 | 166 | // the size of the encoded data. A non-zero size signifies that encoded data was written. |
michael@0 | 167 | // 3. Call SkBitmap::flatten. After writing a boolean value of false, signifying that a heap was |
michael@0 | 168 | // not used, write a zero to signify that the data was not encoded. |
michael@0 | 169 | bool useBitmapHeap = fBitmapHeap != NULL; |
michael@0 | 170 | // Write a bool: true if the SkBitmapHeap is to be used, in which case the reader must use an |
michael@0 | 171 | // SkBitmapHeapReader to read the SkBitmap. False if the bitmap was serialized another way. |
michael@0 | 172 | this->writeBool(useBitmapHeap); |
michael@0 | 173 | if (useBitmapHeap) { |
michael@0 | 174 | SkASSERT(NULL == fBitmapEncoder); |
michael@0 | 175 | int32_t slot = fBitmapHeap->insert(bitmap); |
michael@0 | 176 | fWriter.write32(slot); |
michael@0 | 177 | // crbug.com/155875 |
michael@0 | 178 | // The generation ID is not required information. We write it to prevent collisions |
michael@0 | 179 | // in SkFlatDictionary. It is possible to get a collision when a previously |
michael@0 | 180 | // unflattened (i.e. stale) instance of a similar flattenable is in the dictionary |
michael@0 | 181 | // and the instance currently being written is re-using the same slot from the |
michael@0 | 182 | // bitmap heap. |
michael@0 | 183 | fWriter.write32(bitmap.getGenerationID()); |
michael@0 | 184 | return; |
michael@0 | 185 | } |
michael@0 | 186 | |
michael@0 | 187 | // see if the pixelref already has an encoded version |
michael@0 | 188 | if (bitmap.pixelRef()) { |
michael@0 | 189 | SkAutoDataUnref data(bitmap.pixelRef()->refEncodedData()); |
michael@0 | 190 | if (data.get() != NULL) { |
michael@0 | 191 | write_encoded_bitmap(this, data, bitmap.pixelRefOrigin()); |
michael@0 | 192 | return; |
michael@0 | 193 | } |
michael@0 | 194 | } |
michael@0 | 195 | |
michael@0 | 196 | // see if the caller wants to manually encode |
michael@0 | 197 | if (fBitmapEncoder != NULL) { |
michael@0 | 198 | SkASSERT(NULL == fBitmapHeap); |
michael@0 | 199 | size_t offset = 0; // this parameter is deprecated/ignored |
michael@0 | 200 | // if we have to "encode" the bitmap, then we assume there is no |
michael@0 | 201 | // offset to share, since we are effectively creating a new pixelref |
michael@0 | 202 | SkAutoDataUnref data(fBitmapEncoder(&offset, bitmap)); |
michael@0 | 203 | if (data.get() != NULL) { |
michael@0 | 204 | write_encoded_bitmap(this, data, SkIPoint::Make(0, 0)); |
michael@0 | 205 | return; |
michael@0 | 206 | } |
michael@0 | 207 | } |
michael@0 | 208 | |
michael@0 | 209 | // Bitmap was not encoded. Record a zero, implying that the reader need not decode. |
michael@0 | 210 | this->writeUInt(0); |
michael@0 | 211 | bitmap.flatten(*this); |
michael@0 | 212 | } |
michael@0 | 213 | |
michael@0 | 214 | void SkWriteBuffer::writeTypeface(SkTypeface* obj) { |
michael@0 | 215 | if (NULL == obj || NULL == fTFSet) { |
michael@0 | 216 | fWriter.write32(0); |
michael@0 | 217 | } else { |
michael@0 | 218 | fWriter.write32(fTFSet->add(obj)); |
michael@0 | 219 | } |
michael@0 | 220 | } |
michael@0 | 221 | |
michael@0 | 222 | SkFactorySet* SkWriteBuffer::setFactoryRecorder(SkFactorySet* rec) { |
michael@0 | 223 | SkRefCnt_SafeAssign(fFactorySet, rec); |
michael@0 | 224 | if (fNamedFactorySet != NULL) { |
michael@0 | 225 | fNamedFactorySet->unref(); |
michael@0 | 226 | fNamedFactorySet = NULL; |
michael@0 | 227 | } |
michael@0 | 228 | return rec; |
michael@0 | 229 | } |
michael@0 | 230 | |
michael@0 | 231 | SkNamedFactorySet* SkWriteBuffer::setNamedFactoryRecorder(SkNamedFactorySet* rec) { |
michael@0 | 232 | SkRefCnt_SafeAssign(fNamedFactorySet, rec); |
michael@0 | 233 | if (fFactorySet != NULL) { |
michael@0 | 234 | fFactorySet->unref(); |
michael@0 | 235 | fFactorySet = NULL; |
michael@0 | 236 | } |
michael@0 | 237 | return rec; |
michael@0 | 238 | } |
michael@0 | 239 | |
michael@0 | 240 | SkRefCntSet* SkWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) { |
michael@0 | 241 | SkRefCnt_SafeAssign(fTFSet, rec); |
michael@0 | 242 | return rec; |
michael@0 | 243 | } |
michael@0 | 244 | |
michael@0 | 245 | void SkWriteBuffer::setBitmapHeap(SkBitmapHeap* bitmapHeap) { |
michael@0 | 246 | SkRefCnt_SafeAssign(fBitmapHeap, bitmapHeap); |
michael@0 | 247 | if (bitmapHeap != NULL) { |
michael@0 | 248 | SkASSERT(NULL == fBitmapEncoder); |
michael@0 | 249 | fBitmapEncoder = NULL; |
michael@0 | 250 | } |
michael@0 | 251 | } |
michael@0 | 252 | |
michael@0 | 253 | void SkWriteBuffer::setBitmapEncoder(SkPicture::EncodeBitmap bitmapEncoder) { |
michael@0 | 254 | fBitmapEncoder = bitmapEncoder; |
michael@0 | 255 | if (bitmapEncoder != NULL) { |
michael@0 | 256 | SkASSERT(NULL == fBitmapHeap); |
michael@0 | 257 | SkSafeUnref(fBitmapHeap); |
michael@0 | 258 | fBitmapHeap = NULL; |
michael@0 | 259 | } |
michael@0 | 260 | } |
michael@0 | 261 | |
michael@0 | 262 | void SkWriteBuffer::writeFlattenable(const SkFlattenable* flattenable) { |
michael@0 | 263 | /* |
michael@0 | 264 | * If we have a factoryset, then the first 32bits tell us... |
michael@0 | 265 | * 0: failure to write the flattenable |
michael@0 | 266 | * >0: (1-based) index into the SkFactorySet or SkNamedFactorySet |
michael@0 | 267 | * If we don't have a factoryset, then the first "ptr" is either the |
michael@0 | 268 | * factory, or null for failure. |
michael@0 | 269 | * |
michael@0 | 270 | * The distinction is important, since 0-index is 32bits (always), but a |
michael@0 | 271 | * 0-functionptr might be 32 or 64 bits. |
michael@0 | 272 | */ |
michael@0 | 273 | if (NULL == flattenable) { |
michael@0 | 274 | if (this->isValidating()) { |
michael@0 | 275 | this->writeString(""); |
michael@0 | 276 | } else if (fFactorySet != NULL || fNamedFactorySet != NULL) { |
michael@0 | 277 | this->write32(0); |
michael@0 | 278 | } else { |
michael@0 | 279 | this->writeFunctionPtr(NULL); |
michael@0 | 280 | } |
michael@0 | 281 | return; |
michael@0 | 282 | } |
michael@0 | 283 | |
michael@0 | 284 | SkFlattenable::Factory factory = flattenable->getFactory(); |
michael@0 | 285 | SkASSERT(factory != NULL); |
michael@0 | 286 | |
michael@0 | 287 | /* |
michael@0 | 288 | * We can write 1 of 3 versions of the flattenable: |
michael@0 | 289 | * 1. function-ptr : this is the fastest for the reader, but assumes that |
michael@0 | 290 | * the writer and reader are in the same process. |
michael@0 | 291 | * 2. index into fFactorySet : This is assumes the writer will later |
michael@0 | 292 | * resolve the function-ptrs into strings for its reader. SkPicture |
michael@0 | 293 | * does exactly this, by writing a table of names (matching the indices) |
michael@0 | 294 | * up front in its serialized form. |
michael@0 | 295 | * 3. index into fNamedFactorySet. fNamedFactorySet will also store the |
michael@0 | 296 | * name. SkGPipe uses this technique so it can write the name to its |
michael@0 | 297 | * stream before writing the flattenable. |
michael@0 | 298 | */ |
michael@0 | 299 | if (this->isValidating()) { |
michael@0 | 300 | this->writeString(flattenable->getTypeName()); |
michael@0 | 301 | } else if (fFactorySet) { |
michael@0 | 302 | this->write32(fFactorySet->add(factory)); |
michael@0 | 303 | } else if (fNamedFactorySet) { |
michael@0 | 304 | int32_t index = fNamedFactorySet->find(factory); |
michael@0 | 305 | this->write32(index); |
michael@0 | 306 | if (0 == index) { |
michael@0 | 307 | return; |
michael@0 | 308 | } |
michael@0 | 309 | } else { |
michael@0 | 310 | this->writeFunctionPtr((void*)factory); |
michael@0 | 311 | } |
michael@0 | 312 | |
michael@0 | 313 | // make room for the size of the flattened object |
michael@0 | 314 | (void)fWriter.reserve(sizeof(uint32_t)); |
michael@0 | 315 | // record the current size, so we can subtract after the object writes. |
michael@0 | 316 | size_t offset = fWriter.bytesWritten(); |
michael@0 | 317 | // now flatten the object |
michael@0 | 318 | flattenable->flatten(*this); |
michael@0 | 319 | size_t objSize = fWriter.bytesWritten() - offset; |
michael@0 | 320 | // record the obj's size |
michael@0 | 321 | fWriter.overwriteTAt(offset - sizeof(uint32_t), SkToU32(objSize)); |
michael@0 | 322 | } |