gfx/skia/trunk/src/utils/win/SkDWriteFontFileStream.cpp

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 * Copyright 2012 Google Inc.
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license that can be
michael@0 5 * found in the LICENSE file.
michael@0 6 */
michael@0 7
michael@0 8 #include "SkTypes.h"
michael@0 9 #include "SkDWriteFontFileStream.h"
michael@0 10 #include "SkHRESULT.h"
michael@0 11 #include "SkTemplates.h"
michael@0 12 #include "SkTFitsIn.h"
michael@0 13 #include "SkTScopedComPtr.h"
michael@0 14
michael@0 15 #include <dwrite.h>
michael@0 16
michael@0 17 ///////////////////////////////////////////////////////////////////////////////
michael@0 18 // SkIDWriteFontFileStream
michael@0 19
michael@0 20 SkDWriteFontFileStream::SkDWriteFontFileStream(IDWriteFontFileStream* fontFileStream)
michael@0 21 : fFontFileStream(SkRefComPtr(fontFileStream))
michael@0 22 , fPos(0)
michael@0 23 , fLockedMemory(NULL)
michael@0 24 , fFragmentLock(NULL) {
michael@0 25 }
michael@0 26
michael@0 27 SkDWriteFontFileStream::~SkDWriteFontFileStream() {
michael@0 28 if (fFragmentLock) {
michael@0 29 fFontFileStream->ReleaseFileFragment(fFragmentLock);
michael@0 30 }
michael@0 31 }
michael@0 32
michael@0 33 size_t SkDWriteFontFileStream::read(void* buffer, size_t size) {
michael@0 34 HRESULT hr = S_OK;
michael@0 35
michael@0 36 if (NULL == buffer) {
michael@0 37 size_t fileSize = this->getLength();
michael@0 38
michael@0 39 if (fPos + size > fileSize) {
michael@0 40 size_t skipped = fileSize - fPos;
michael@0 41 fPos = fileSize;
michael@0 42 return skipped;
michael@0 43 } else {
michael@0 44 fPos += size;
michael@0 45 return size;
michael@0 46 }
michael@0 47 }
michael@0 48
michael@0 49 const void* start;
michael@0 50 void* fragmentLock;
michael@0 51 hr = fFontFileStream->ReadFileFragment(&start, fPos, size, &fragmentLock);
michael@0 52 if (SUCCEEDED(hr)) {
michael@0 53 memcpy(buffer, start, size);
michael@0 54 fFontFileStream->ReleaseFileFragment(fragmentLock);
michael@0 55 fPos += size;
michael@0 56 return size;
michael@0 57 }
michael@0 58
michael@0 59 //The read may have failed because we asked for too much data.
michael@0 60 size_t fileSize = this->getLength();
michael@0 61 if (fPos + size <= fileSize) {
michael@0 62 //This means we were within bounds, but failed for some other reason.
michael@0 63 return 0;
michael@0 64 }
michael@0 65
michael@0 66 size_t read = fileSize - fPos;
michael@0 67 hr = fFontFileStream->ReadFileFragment(&start, fPos, read, &fragmentLock);
michael@0 68 if (SUCCEEDED(hr)) {
michael@0 69 memcpy(buffer, start, read);
michael@0 70 fFontFileStream->ReleaseFileFragment(fragmentLock);
michael@0 71 fPos = fileSize;
michael@0 72 return read;
michael@0 73 }
michael@0 74
michael@0 75 return 0;
michael@0 76 }
michael@0 77
michael@0 78 bool SkDWriteFontFileStream::isAtEnd() const {
michael@0 79 return fPos == this->getLength();
michael@0 80 }
michael@0 81
michael@0 82 bool SkDWriteFontFileStream::rewind() {
michael@0 83 fPos = 0;
michael@0 84 return true;
michael@0 85 }
michael@0 86
michael@0 87 SkDWriteFontFileStream* SkDWriteFontFileStream::duplicate() const {
michael@0 88 return SkNEW_ARGS(SkDWriteFontFileStream, (fFontFileStream.get()));
michael@0 89 }
michael@0 90
michael@0 91 size_t SkDWriteFontFileStream::getPosition() const {
michael@0 92 return fPos;
michael@0 93 }
michael@0 94
michael@0 95 bool SkDWriteFontFileStream::seek(size_t position) {
michael@0 96 size_t length = this->getLength();
michael@0 97 fPos = (position > length) ? length : position;
michael@0 98 return true;
michael@0 99 }
michael@0 100
michael@0 101 bool SkDWriteFontFileStream::move(long offset) {
michael@0 102 return seek(fPos + offset);
michael@0 103 }
michael@0 104
michael@0 105 SkDWriteFontFileStream* SkDWriteFontFileStream::fork() const {
michael@0 106 SkAutoTUnref<SkDWriteFontFileStream> that(this->duplicate());
michael@0 107 that->seek(fPos);
michael@0 108 return that.detach();
michael@0 109 }
michael@0 110
michael@0 111 size_t SkDWriteFontFileStream::getLength() const {
michael@0 112 HRESULT hr = S_OK;
michael@0 113 UINT64 realFileSize = 0;
michael@0 114 hr = fFontFileStream->GetFileSize(&realFileSize);
michael@0 115 if (!SkTFitsIn<size_t>(realFileSize)) {
michael@0 116 return 0;
michael@0 117 }
michael@0 118 return static_cast<size_t>(realFileSize);
michael@0 119 }
michael@0 120
michael@0 121 const void* SkDWriteFontFileStream::getMemoryBase() {
michael@0 122 if (fLockedMemory) {
michael@0 123 return fLockedMemory;
michael@0 124 }
michael@0 125
michael@0 126 UINT64 fileSize;
michael@0 127 HRNM(fFontFileStream->GetFileSize(&fileSize), "Could not get file size");
michael@0 128 HRNM(fFontFileStream->ReadFileFragment(&fLockedMemory, 0, fileSize, &fFragmentLock),
michael@0 129 "Could not lock file fragment.");
michael@0 130 return fLockedMemory;
michael@0 131 }
michael@0 132
michael@0 133 ///////////////////////////////////////////////////////////////////////////////
michael@0 134 // SkIDWriteFontFileStreamWrapper
michael@0 135
michael@0 136 HRESULT SkDWriteFontFileStreamWrapper::Create(SkStream* stream, SkDWriteFontFileStreamWrapper** streamFontFileStream) {
michael@0 137 *streamFontFileStream = new SkDWriteFontFileStreamWrapper(stream);
michael@0 138 if (NULL == streamFontFileStream) {
michael@0 139 return E_OUTOFMEMORY;
michael@0 140 }
michael@0 141 return S_OK;
michael@0 142 }
michael@0 143
michael@0 144 SkDWriteFontFileStreamWrapper::SkDWriteFontFileStreamWrapper(SkStream* stream)
michael@0 145 : fRefCount(1), fStream(SkRef(stream)) {
michael@0 146 }
michael@0 147
michael@0 148 HRESULT STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::QueryInterface(REFIID iid, void** ppvObject) {
michael@0 149 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) {
michael@0 150 *ppvObject = this;
michael@0 151 AddRef();
michael@0 152 return S_OK;
michael@0 153 } else {
michael@0 154 *ppvObject = NULL;
michael@0 155 return E_NOINTERFACE;
michael@0 156 }
michael@0 157 }
michael@0 158
michael@0 159 ULONG STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::AddRef() {
michael@0 160 return InterlockedIncrement(&fRefCount);
michael@0 161 }
michael@0 162
michael@0 163 ULONG STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::Release() {
michael@0 164 ULONG newCount = InterlockedDecrement(&fRefCount);
michael@0 165 if (0 == newCount) {
michael@0 166 delete this;
michael@0 167 }
michael@0 168 return newCount;
michael@0 169 }
michael@0 170
michael@0 171 HRESULT STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::ReadFileFragment(
michael@0 172 void const** fragmentStart,
michael@0 173 UINT64 fileOffset,
michael@0 174 UINT64 fragmentSize,
michael@0 175 void** fragmentContext)
michael@0 176 {
michael@0 177 // The loader is responsible for doing a bounds check.
michael@0 178 UINT64 fileSize;
michael@0 179 this->GetFileSize(&fileSize);
michael@0 180 if (fileOffset > fileSize || fragmentSize > fileSize - fileOffset) {
michael@0 181 *fragmentStart = NULL;
michael@0 182 *fragmentContext = NULL;
michael@0 183 return E_FAIL;
michael@0 184 }
michael@0 185
michael@0 186 if (!SkTFitsIn<size_t>(fileOffset + fragmentSize)) {
michael@0 187 return E_FAIL;
michael@0 188 }
michael@0 189
michael@0 190 const void* data = fStream->getMemoryBase();
michael@0 191 if (NULL != data) {
michael@0 192 *fragmentStart = static_cast<BYTE const*>(data) + static_cast<size_t>(fileOffset);
michael@0 193 *fragmentContext = NULL;
michael@0 194
michael@0 195 } else {
michael@0 196 //May be called from multiple threads.
michael@0 197 SkAutoMutexAcquire ama(fStreamMutex);
michael@0 198
michael@0 199 *fragmentStart = NULL;
michael@0 200 *fragmentContext = NULL;
michael@0 201
michael@0 202 if (!fStream->rewind()) {
michael@0 203 return E_FAIL;
michael@0 204 }
michael@0 205 if (fStream->skip(static_cast<size_t>(fileOffset)) != fileOffset) {
michael@0 206 return E_FAIL;
michael@0 207 }
michael@0 208 SkAutoTMalloc<uint8_t> streamData(static_cast<size_t>(fragmentSize));
michael@0 209 if (fStream->read(streamData.get(), static_cast<size_t>(fragmentSize)) != fragmentSize) {
michael@0 210 return E_FAIL;
michael@0 211 }
michael@0 212
michael@0 213 *fragmentStart = streamData.get();
michael@0 214 *fragmentContext = streamData.detach();
michael@0 215 }
michael@0 216 return S_OK;
michael@0 217 }
michael@0 218
michael@0 219 void STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::ReleaseFileFragment(void* fragmentContext) {
michael@0 220 sk_free(fragmentContext);
michael@0 221 }
michael@0 222
michael@0 223 HRESULT STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::GetFileSize(UINT64* fileSize) {
michael@0 224 *fileSize = fStream->getLength();
michael@0 225 return S_OK;
michael@0 226 }
michael@0 227
michael@0 228 HRESULT STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::GetLastWriteTime(UINT64* lastWriteTime) {
michael@0 229 // The concept of last write time does not apply to this loader.
michael@0 230 *lastWriteTime = 0;
michael@0 231 return E_NOTIMPL;
michael@0 232 }

mercurial