3 * Copyright 2011 Google Inc.
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
10 #define WIN32_LEAN_AND_MEAN
13 #include "SkIStream.h"
19 SkBaseIStream::SkBaseIStream() : _refcount(1) { }
20 SkBaseIStream::~SkBaseIStream() { }
22 HRESULT STDMETHODCALLTYPE SkBaseIStream::QueryInterface(REFIID iid
25 if (NULL == ppvObject) {
28 if (iid == __uuidof(IUnknown)
29 || iid == __uuidof(IStream)
30 || iid == __uuidof(ISequentialStream))
32 *ppvObject = static_cast<IStream*>(this);
41 ULONG STDMETHODCALLTYPE SkBaseIStream::AddRef(void) {
42 return (ULONG)InterlockedIncrement(&_refcount);
45 ULONG STDMETHODCALLTYPE SkBaseIStream::Release(void) {
46 ULONG res = (ULONG) InterlockedDecrement(&_refcount);
53 // ISequentialStream Interface
54 HRESULT STDMETHODCALLTYPE SkBaseIStream::Read(void* pv
59 HRESULT STDMETHODCALLTYPE SkBaseIStream::Write(void const* pv
65 HRESULT STDMETHODCALLTYPE SkBaseIStream::SetSize(ULARGE_INTEGER)
68 HRESULT STDMETHODCALLTYPE SkBaseIStream::CopyTo(IStream*
74 HRESULT STDMETHODCALLTYPE SkBaseIStream::Commit(DWORD)
77 HRESULT STDMETHODCALLTYPE SkBaseIStream::Revert(void)
80 HRESULT STDMETHODCALLTYPE SkBaseIStream::LockRegion(ULARGE_INTEGER
85 HRESULT STDMETHODCALLTYPE SkBaseIStream::UnlockRegion(ULARGE_INTEGER
90 HRESULT STDMETHODCALLTYPE SkBaseIStream::Clone(IStream **)
93 HRESULT STDMETHODCALLTYPE SkBaseIStream::Seek(LARGE_INTEGER liDistanceToMove
95 , ULARGE_INTEGER* lpNewFilePointer)
98 HRESULT STDMETHODCALLTYPE SkBaseIStream::Stat(STATSTG* pStatstg
100 { return E_NOTIMPL; }
106 SkIStream::SkIStream(SkStream* stream, bool unrefOnRelease)
109 , fUnrefOnRelease(unrefOnRelease)
112 this->fSkStream->rewind();
115 SkIStream::~SkIStream() {
116 if (this->fSkStream && fUnrefOnRelease) {
117 this->fSkStream->unref();
121 HRESULT SkIStream::CreateFromSkStream(SkStream* stream
122 , bool unrefOnRelease
123 , IStream ** ppStream)
125 if (NULL == stream) {
128 *ppStream = new SkIStream(stream, unrefOnRelease);
132 // ISequentialStream Interface
133 HRESULT STDMETHODCALLTYPE SkIStream::Read(void* pv, ULONG cb, ULONG* pcbRead) {
134 *pcbRead = static_cast<ULONG>(this->fSkStream->read(pv, cb));
135 this->fLocation.QuadPart += *pcbRead;
136 return (*pcbRead == cb) ? S_OK : S_FALSE;
139 HRESULT STDMETHODCALLTYPE SkIStream::Write(void const* pv
143 return STG_E_CANTSAVE;
147 HRESULT STDMETHODCALLTYPE SkIStream::Seek(LARGE_INTEGER liDistanceToMove
149 , ULARGE_INTEGER* lpNewFilePointer)
154 case STREAM_SEEK_SET: {
155 if (!this->fSkStream->rewind()) {
158 size_t skipped = this->fSkStream->skip(
159 static_cast<size_t>(liDistanceToMove.QuadPart)
161 this->fLocation.QuadPart = skipped;
162 if (skipped != liDistanceToMove.QuadPart) {
168 case STREAM_SEEK_CUR: {
169 size_t skipped = this->fSkStream->skip(
170 static_cast<size_t>(liDistanceToMove.QuadPart)
172 this->fLocation.QuadPart += skipped;
173 if (skipped != liDistanceToMove.QuadPart) {
178 case STREAM_SEEK_END: {
179 if (!this->fSkStream->rewind()) {
182 // FIXME: Should not depend on getLength.
183 // See https://code.google.com/p/skia/issues/detail?id=1570
184 LONGLONG skip = this->fSkStream->getLength()
185 + liDistanceToMove.QuadPart;
186 size_t skipped = this->fSkStream->skip(static_cast<size_t>(skip));
187 this->fLocation.QuadPart = skipped;
188 if (skipped != skip) {
195 hr = STG_E_INVALIDFUNCTION;
199 if (lpNewFilePointer) {
200 lpNewFilePointer->QuadPart = this->fLocation.QuadPart;
205 HRESULT STDMETHODCALLTYPE SkIStream::Stat(STATSTG* pStatstg
208 if (0 == (grfStatFlag & STATFLAG_NONAME)) {
209 return STG_E_INVALIDFLAG;
211 pStatstg->pwcsName = NULL;
212 // FIXME: Should not depend on getLength
213 // See https://code.google.com/p/skia/issues/detail?id=1570
214 pStatstg->cbSize.QuadPart = this->fSkStream->getLength();
215 pStatstg->clsid = CLSID_NULL;
216 pStatstg->type = STGTY_STREAM;
217 pStatstg->grfMode = STGM_READ;
225 SkWIStream::SkWIStream(SkWStream* stream)
230 SkWIStream::~SkWIStream() {
231 if (this->fSkWStream) {
232 this->fSkWStream->flush();
236 HRESULT SkWIStream::CreateFromSkWStream(SkWStream* stream
237 , IStream ** ppStream)
239 *ppStream = new SkWIStream(stream);
243 // ISequentialStream Interface
244 HRESULT STDMETHODCALLTYPE SkWIStream::Write(void const* pv
249 bool wrote = this->fSkWStream->write(pv, cb);
260 HRESULT STDMETHODCALLTYPE SkWIStream::Commit(DWORD) {
261 this->fSkWStream->flush();
265 HRESULT STDMETHODCALLTYPE SkWIStream::Stat(STATSTG* pStatstg
268 if (0 == (grfStatFlag & STATFLAG_NONAME)) {
269 return STG_E_INVALIDFLAG;
271 pStatstg->pwcsName = NULL;
272 pStatstg->cbSize.QuadPart = 0;
273 pStatstg->clsid = CLSID_NULL;
274 pStatstg->type = STGTY_STREAM;
275 pStatstg->grfMode = STGM_WRITE;