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.

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

mercurial