180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc.
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define WIN32_LEAN_AND_MEAN
11910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger#include <windows.h>
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include <ole2.h>
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkIStream.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkStream.h"
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/**
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * SkBaseIStream
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkBaseIStream::SkBaseIStream() : _refcount(1) { }
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkBaseIStream::~SkBaseIStream() { }
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkBaseIStream::QueryInterface(REFIID iid
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                      , void ** ppvObject)
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (NULL == ppvObject) {
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return E_INVALIDARG;
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (iid == __uuidof(IUnknown)
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        || iid == __uuidof(IStream)
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        || iid == __uuidof(ISequentialStream))
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        *ppvObject = static_cast<IStream*>(this);
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        AddRef();
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return S_OK;
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        *ppvObject = NULL;
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return E_NOINTERFACE;
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruULONG STDMETHODCALLTYPE SkBaseIStream::AddRef(void) {
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (ULONG)InterlockedIncrement(&_refcount);
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruULONG STDMETHODCALLTYPE SkBaseIStream::Release(void) {
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    ULONG res = (ULONG) InterlockedDecrement(&_refcount);
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (0 == res) {
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        delete this;
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return res;
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// ISequentialStream Interface
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkBaseIStream::Read(void* pv
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                            , ULONG cb
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                            , ULONG* pcbRead)
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ return E_NOTIMPL; }
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkBaseIStream::Write(void const* pv
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                             , ULONG cb
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                             , ULONG* pcbWritten)
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ return E_NOTIMPL; }
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// IStream Interface
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkBaseIStream::SetSize(ULARGE_INTEGER)
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ return E_NOTIMPL; }
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkBaseIStream::CopyTo(IStream*
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                              , ULARGE_INTEGER
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                              , ULARGE_INTEGER*
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                              , ULARGE_INTEGER*)
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ return E_NOTIMPL; }
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkBaseIStream::Commit(DWORD)
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ return E_NOTIMPL; }
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkBaseIStream::Revert(void)
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ return E_NOTIMPL; }
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkBaseIStream::LockRegion(ULARGE_INTEGER
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                  , ULARGE_INTEGER
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                  , DWORD)
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ return E_NOTIMPL; }
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkBaseIStream::UnlockRegion(ULARGE_INTEGER
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                    , ULARGE_INTEGER
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                    , DWORD)
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ return E_NOTIMPL; }
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkBaseIStream::Clone(IStream **)
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ return E_NOTIMPL; }
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkBaseIStream::Seek(LARGE_INTEGER liDistanceToMove
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                            , DWORD dwOrigin
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                            , ULARGE_INTEGER* lpNewFilePointer)
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ return E_NOTIMPL; }
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkBaseIStream::Stat(STATSTG* pStatstg
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                            , DWORD grfStatFlag)
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ return E_NOTIMPL; }
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/**
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * SkIStream
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkIStream::SkIStream(SkStream* stream, bool unrefOnRelease)
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    : SkBaseIStream()
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    , fSkStream(stream)
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    , fUnrefOnRelease(unrefOnRelease)
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    , fLocation()
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->fSkStream->rewind();
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkIStream::~SkIStream() {
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (NULL != this->fSkStream && fUnrefOnRelease) {
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->fSkStream->unref();
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT SkIStream::CreateFromSkStream(SkStream* stream
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                    , bool unrefOnRelease
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                    , IStream ** ppStream)
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
1250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (NULL == stream) {
1260a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return E_INVALIDARG;
1270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    *ppStream = new SkIStream(stream, unrefOnRelease);
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return S_OK;
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// ISequentialStream Interface
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkIStream::Read(void* pv, ULONG cb, ULONG* pcbRead) {
13458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    *pcbRead = static_cast<ULONG>(this->fSkStream->read(pv, cb));
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->fLocation.QuadPart += *pcbRead;
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (*pcbRead == cb) ? S_OK : S_FALSE;
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkIStream::Write(void const* pv
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                         , ULONG cb
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                         , ULONG* pcbWritten)
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return STG_E_CANTSAVE;
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// IStream Interface
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkIStream::Seek(LARGE_INTEGER liDistanceToMove
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                        , DWORD dwOrigin
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                        , ULARGE_INTEGER* lpNewFilePointer)
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    HRESULT hr = S_OK;
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    switch(dwOrigin) {
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    case STREAM_SEEK_SET: {
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (!this->fSkStream->rewind()) {
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            hr = E_FAIL;
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else {
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            size_t skipped = this->fSkStream->skip(
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                static_cast<size_t>(liDistanceToMove.QuadPart)
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            );
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            this->fLocation.QuadPart = skipped;
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (skipped != liDistanceToMove.QuadPart) {
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                hr = E_FAIL;
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        break;
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    case STREAM_SEEK_CUR: {
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        size_t skipped = this->fSkStream->skip(
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            static_cast<size_t>(liDistanceToMove.QuadPart)
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        );
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->fLocation.QuadPart += skipped;
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (skipped != liDistanceToMove.QuadPart) {
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            hr = E_FAIL;
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        break;
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    case STREAM_SEEK_END: {
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (!this->fSkStream->rewind()) {
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            hr = E_FAIL;
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else {
1820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            // FIXME: Should not depend on getLength.
1830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            // See https://code.google.com/p/skia/issues/detail?id=1570
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            LONGLONG skip = this->fSkStream->getLength()
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                          + liDistanceToMove.QuadPart;
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            size_t skipped = this->fSkStream->skip(static_cast<size_t>(skip));
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            this->fLocation.QuadPart = skipped;
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (skipped != skip) {
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                hr = E_FAIL;
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        break;
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    default:
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        hr = STG_E_INVALIDFUNCTION;
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        break;
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (NULL != lpNewFilePointer) {
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        lpNewFilePointer->QuadPart = this->fLocation.QuadPart;
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return hr;
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkIStream::Stat(STATSTG* pStatstg
20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                        , DWORD grfStatFlag)
20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (0 == (grfStatFlag & STATFLAG_NONAME)) {
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return STG_E_INVALIDFLAG;
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pStatstg->pwcsName = NULL;
2120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    // FIXME: Should not depend on getLength
2130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    // See https://code.google.com/p/skia/issues/detail?id=1570
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pStatstg->cbSize.QuadPart = this->fSkStream->getLength();
21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pStatstg->clsid = CLSID_NULL;
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pStatstg->type = STGTY_STREAM;
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pStatstg->grfMode = STGM_READ;
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return S_OK;
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/**
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * SkIWStream
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkWIStream::SkWIStream(SkWStream* stream)
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    : SkBaseIStream()
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    , fSkWStream(stream)
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ }
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkWIStream::~SkWIStream() {
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (NULL != this->fSkWStream) {
23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->fSkWStream->flush();
23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT SkWIStream::CreateFromSkWStream(SkWStream* stream
23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                      , IStream ** ppStream)
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    *ppStream = new SkWIStream(stream);
24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return S_OK;
24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// ISequentialStream Interface
24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkWIStream::Write(void const* pv
24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                          , ULONG cb
24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                          , ULONG* pcbWritten)
24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    HRESULT hr = S_OK;
24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool wrote = this->fSkWStream->write(pv, cb);
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (wrote) {
25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        *pcbWritten = cb;
25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        *pcbWritten = 0;
25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        hr = S_FALSE;
25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return hr;
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// IStream Interface
26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkWIStream::Commit(DWORD) {
26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->fSkWStream->flush();
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return S_OK;
26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkWIStream::Stat(STATSTG* pStatstg
26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                         , DWORD grfStatFlag)
26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (0 == (grfStatFlag & STATFLAG_NONAME)) {
26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return STG_E_INVALIDFLAG;
27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pStatstg->pwcsName = NULL;
27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pStatstg->cbSize.QuadPart = 0;
27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pStatstg->clsid = CLSID_NULL;
27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pStatstg->type = STGTY_STREAM;
27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pStatstg->grfMode = STGM_WRITE;
27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return S_OK;
27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
278