blob: e19128b68bfc7d921970373d22edc62ce91234fd [file] [log] [blame]
bungeman@google.com9df621d2011-06-23 21:43:52 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2011 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.
bungeman@google.com9df621d2011-06-23 21:43:52 +00006 */
7
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/core/SkTypes.h"
Mike Klein8f11d4d2018-01-24 12:42:55 -05009#if defined(SK_BUILD_FOR_WIN)
epoger@google.comec3ed6a2011-07-28 14:26:00 +000010
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkStream.h"
12#include "src/utils/win/SkIStream.h"
bungeman@google.com9df621d2011-06-23 21:43:52 +000013
14/**
15 * SkBaseIStream
16 */
17SkBaseIStream::SkBaseIStream() : _refcount(1) { }
18SkBaseIStream::~SkBaseIStream() { }
19
Ben Wagner6cb6a072019-08-12 18:30:27 -040020SK_STDMETHODIMP SkBaseIStream::QueryInterface(REFIID iid, void ** ppvObject) {
halcanary96fcdcc2015-08-27 07:41:13 -070021 if (nullptr == ppvObject) {
bungeman@google.com9df621d2011-06-23 21:43:52 +000022 return E_INVALIDARG;
23 }
24 if (iid == __uuidof(IUnknown)
25 || iid == __uuidof(IStream)
26 || iid == __uuidof(ISequentialStream))
27 {
28 *ppvObject = static_cast<IStream*>(this);
29 AddRef();
30 return S_OK;
31 } else {
halcanary96fcdcc2015-08-27 07:41:13 -070032 *ppvObject = nullptr;
rmistry@google.comd6176b02012-08-23 18:14:13 +000033 return E_NOINTERFACE;
bungeman@google.com9df621d2011-06-23 21:43:52 +000034 }
35}
36
Ben Wagner6cb6a072019-08-12 18:30:27 -040037SK_STDMETHODIMP_(ULONG) SkBaseIStream::AddRef() {
bungeman@google.com9df621d2011-06-23 21:43:52 +000038 return (ULONG)InterlockedIncrement(&_refcount);
39}
40
Ben Wagner6cb6a072019-08-12 18:30:27 -040041SK_STDMETHODIMP_(ULONG) SkBaseIStream::Release() {
bungeman@google.com9df621d2011-06-23 21:43:52 +000042 ULONG res = (ULONG) InterlockedDecrement(&_refcount);
43 if (0 == res) {
44 delete this;
45 }
46 return res;
47}
48
49// ISequentialStream Interface
Ben Wagner6cb6a072019-08-12 18:30:27 -040050SK_STDMETHODIMP SkBaseIStream::Read(void* pv, ULONG cb, ULONG* pcbRead)
bungeman@google.com9df621d2011-06-23 21:43:52 +000051{ return E_NOTIMPL; }
52
Ben Wagner6cb6a072019-08-12 18:30:27 -040053SK_STDMETHODIMP SkBaseIStream::Write(void const* pv, ULONG cb, ULONG* pcbWritten)
bungeman@google.com9df621d2011-06-23 21:43:52 +000054{ return E_NOTIMPL; }
55
56// IStream Interface
Ben Wagner6cb6a072019-08-12 18:30:27 -040057SK_STDMETHODIMP SkBaseIStream::SetSize(ULARGE_INTEGER)
bungeman@google.com9df621d2011-06-23 21:43:52 +000058{ return E_NOTIMPL; }
59
Ben Wagner6cb6a072019-08-12 18:30:27 -040060SK_STDMETHODIMP SkBaseIStream::CopyTo(IStream*, ULARGE_INTEGER, ULARGE_INTEGER*, ULARGE_INTEGER*)
bungeman@google.com9df621d2011-06-23 21:43:52 +000061{ return E_NOTIMPL; }
62
Ben Wagner6cb6a072019-08-12 18:30:27 -040063SK_STDMETHODIMP SkBaseIStream::Commit(DWORD)
bungeman@google.com9df621d2011-06-23 21:43:52 +000064{ return E_NOTIMPL; }
65
Ben Wagner6cb6a072019-08-12 18:30:27 -040066SK_STDMETHODIMP SkBaseIStream::Revert()
bungeman@google.com9df621d2011-06-23 21:43:52 +000067{ return E_NOTIMPL; }
68
Ben Wagner6cb6a072019-08-12 18:30:27 -040069SK_STDMETHODIMP SkBaseIStream::LockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD)
bungeman@google.com9df621d2011-06-23 21:43:52 +000070{ return E_NOTIMPL; }
71
Ben Wagner6cb6a072019-08-12 18:30:27 -040072SK_STDMETHODIMP SkBaseIStream::UnlockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD)
bungeman@google.com9df621d2011-06-23 21:43:52 +000073{ return E_NOTIMPL; }
74
Ben Wagner6cb6a072019-08-12 18:30:27 -040075SK_STDMETHODIMP SkBaseIStream::Clone(IStream**)
bungeman@google.com9df621d2011-06-23 21:43:52 +000076{ return E_NOTIMPL; }
77
Ben Wagner6cb6a072019-08-12 18:30:27 -040078SK_STDMETHODIMP SkBaseIStream::Seek(LARGE_INTEGER liDistanceToMove,
79 DWORD dwOrigin,
80 ULARGE_INTEGER* lpNewFilePointer)
bungeman@google.com9df621d2011-06-23 21:43:52 +000081{ return E_NOTIMPL; }
82
Ben Wagner6cb6a072019-08-12 18:30:27 -040083SK_STDMETHODIMP SkBaseIStream::Stat(STATSTG* pStatstg, DWORD grfStatFlag)
bungeman@google.com9df621d2011-06-23 21:43:52 +000084{ return E_NOTIMPL; }
85
86
87/**
88 * SkIStream
89 */
bungeman2dca8172015-01-22 06:08:31 -080090SkIStream::SkIStream(SkStream* stream, bool deleteOnRelease)
bungeman@google.com9df621d2011-06-23 21:43:52 +000091 : SkBaseIStream()
92 , fSkStream(stream)
bungeman2dca8172015-01-22 06:08:31 -080093 , fDeleteOnRelease(deleteOnRelease)
bungeman@google.com60157922011-08-13 00:06:17 +000094 , fLocation()
95{
96 this->fSkStream->rewind();
97}
bungeman@google.com9df621d2011-06-23 21:43:52 +000098
99SkIStream::~SkIStream() {
bungeman44af7ba2015-01-22 07:33:51 -0800100 if (fDeleteOnRelease) {
bungeman2dca8172015-01-22 06:08:31 -0800101 delete this->fSkStream;
bungeman@google.com9df621d2011-06-23 21:43:52 +0000102 }
103}
104
Ben Wagner6cb6a072019-08-12 18:30:27 -0400105HRESULT SkIStream::CreateFromSkStream(SkStream* stream, bool deleteOnRelease, IStream ** ppStream) {
halcanary96fcdcc2015-08-27 07:41:13 -0700106 if (nullptr == stream) {
bungeman@google.com635091f2013-10-01 15:03:18 +0000107 return E_INVALIDARG;
108 }
bungeman2dca8172015-01-22 06:08:31 -0800109 *ppStream = new SkIStream(stream, deleteOnRelease);
bungeman@google.com9df621d2011-06-23 21:43:52 +0000110 return S_OK;
111}
112
113// ISequentialStream Interface
Ben Wagner6cb6a072019-08-12 18:30:27 -0400114SK_STDMETHODIMP SkIStream::Read(void* pv, ULONG cb, ULONG* pcbRead) {
bungeman@google.com4b18f572013-07-22 15:21:23 +0000115 *pcbRead = static_cast<ULONG>(this->fSkStream->read(pv, cb));
bungeman@google.com60157922011-08-13 00:06:17 +0000116 this->fLocation.QuadPart += *pcbRead;
bungeman@google.com9df621d2011-06-23 21:43:52 +0000117 return (*pcbRead == cb) ? S_OK : S_FALSE;
118}
119
Ben Wagner6cb6a072019-08-12 18:30:27 -0400120SK_STDMETHODIMP SkIStream::Write(void const* pv, ULONG cb, ULONG* pcbWritten) {
bungeman@google.com9df621d2011-06-23 21:43:52 +0000121 return STG_E_CANTSAVE;
122}
123
124// IStream Interface
Ben Wagner6cb6a072019-08-12 18:30:27 -0400125SK_STDMETHODIMP SkIStream::Seek(LARGE_INTEGER liDistanceToMove,
126 DWORD dwOrigin,
127 ULARGE_INTEGER* lpNewFilePointer)
bungeman@google.com9df621d2011-06-23 21:43:52 +0000128{
bungeman@google.com9df621d2011-06-23 21:43:52 +0000129 HRESULT hr = S_OK;
bungeman@google.com60157922011-08-13 00:06:17 +0000130
bungeman@google.com9df621d2011-06-23 21:43:52 +0000131 switch(dwOrigin) {
132 case STREAM_SEEK_SET: {
133 if (!this->fSkStream->rewind()) {
134 hr = E_FAIL;
135 } else {
Chris Dalton1ef80942017-12-04 12:01:30 -0700136 size_t skip = static_cast<size_t>(liDistanceToMove.QuadPart);
137 size_t skipped = this->fSkStream->skip(skip);
bungeman@google.com60157922011-08-13 00:06:17 +0000138 this->fLocation.QuadPart = skipped;
Chris Dalton1ef80942017-12-04 12:01:30 -0700139 if (skipped != skip) {
bungeman@google.com9df621d2011-06-23 21:43:52 +0000140 hr = E_FAIL;
141 }
142 }
143 break;
144 }
145 case STREAM_SEEK_CUR: {
Chris Dalton1ef80942017-12-04 12:01:30 -0700146 size_t skip = static_cast<size_t>(liDistanceToMove.QuadPart);
147 size_t skipped = this->fSkStream->skip(skip);
bungeman@google.com60157922011-08-13 00:06:17 +0000148 this->fLocation.QuadPart += skipped;
Chris Dalton1ef80942017-12-04 12:01:30 -0700149 if (skipped != skip) {
bungeman@google.com9df621d2011-06-23 21:43:52 +0000150 hr = E_FAIL;
151 }
152 break;
153 }
154 case STREAM_SEEK_END: {
155 if (!this->fSkStream->rewind()) {
156 hr = E_FAIL;
157 } else {
scroggo@google.comb5571b32013-09-25 21:34:24 +0000158 // FIXME: Should not depend on getLength.
159 // See https://code.google.com/p/skia/issues/detail?id=1570
Chris Dalton1ef80942017-12-04 12:01:30 -0700160 size_t skip = static_cast<size_t>(this->fSkStream->getLength() +
161 liDistanceToMove.QuadPart);
162 size_t skipped = this->fSkStream->skip(skip);
bungeman@google.com60157922011-08-13 00:06:17 +0000163 this->fLocation.QuadPart = skipped;
164 if (skipped != skip) {
bungeman@google.com9df621d2011-06-23 21:43:52 +0000165 hr = E_FAIL;
166 }
167 }
168 break;
169 }
170 default:
171 hr = STG_E_INVALIDFUNCTION;
172 break;
173 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000174
bsalomon49f085d2014-09-05 13:34:00 -0700175 if (lpNewFilePointer) {
bungeman@google.come25c6842011-08-17 14:53:54 +0000176 lpNewFilePointer->QuadPart = this->fLocation.QuadPart;
bungeman@google.com60157922011-08-13 00:06:17 +0000177 }
bungeman@google.com9df621d2011-06-23 21:43:52 +0000178 return hr;
179}
180
Ben Wagner6cb6a072019-08-12 18:30:27 -0400181SK_STDMETHODIMP SkIStream::Stat(STATSTG* pStatstg, DWORD grfStatFlag) {
bsalomon@google.com9d12f5c2011-09-29 18:08:18 +0000182 if (0 == (grfStatFlag & STATFLAG_NONAME)) {
bungeman@google.com9df621d2011-06-23 21:43:52 +0000183 return STG_E_INVALIDFLAG;
184 }
halcanary96fcdcc2015-08-27 07:41:13 -0700185 pStatstg->pwcsName = nullptr;
scroggo@google.comb5571b32013-09-25 21:34:24 +0000186 // FIXME: Should not depend on getLength
187 // See https://code.google.com/p/skia/issues/detail?id=1570
bungeman@google.com9df621d2011-06-23 21:43:52 +0000188 pStatstg->cbSize.QuadPart = this->fSkStream->getLength();
189 pStatstg->clsid = CLSID_NULL;
190 pStatstg->type = STGTY_STREAM;
191 pStatstg->grfMode = STGM_READ;
192 return S_OK;
193}
194
195
196/**
197 * SkIWStream
198 */
199SkWIStream::SkWIStream(SkWStream* stream)
200 : SkBaseIStream()
201 , fSkWStream(stream)
202{ }
203
204SkWIStream::~SkWIStream() {
bsalomon49f085d2014-09-05 13:34:00 -0700205 if (this->fSkWStream) {
bungeman@google.com9df621d2011-06-23 21:43:52 +0000206 this->fSkWStream->flush();
207 }
208}
209
Ben Wagner6cb6a072019-08-12 18:30:27 -0400210HRESULT SkWIStream::CreateFromSkWStream(SkWStream* stream, IStream ** ppStream) {
bungeman@google.com9df621d2011-06-23 21:43:52 +0000211 *ppStream = new SkWIStream(stream);
212 return S_OK;
213}
214
215// ISequentialStream Interface
Ben Wagner6cb6a072019-08-12 18:30:27 -0400216SK_STDMETHODIMP SkWIStream::Write(void const* pv, ULONG cb, ULONG* pcbWritten) {
bungeman@google.com9df621d2011-06-23 21:43:52 +0000217 HRESULT hr = S_OK;
218 bool wrote = this->fSkWStream->write(pv, cb);
219 if (wrote) {
220 *pcbWritten = cb;
221 } else {
222 *pcbWritten = 0;
223 hr = S_FALSE;
224 }
225 return hr;
226}
227
228// IStream Interface
Ben Wagner6cb6a072019-08-12 18:30:27 -0400229SK_STDMETHODIMP SkWIStream::Commit(DWORD) {
bungeman@google.com14fc3212011-08-01 20:41:53 +0000230 this->fSkWStream->flush();
231 return S_OK;
232}
233
Ben Wagner6cb6a072019-08-12 18:30:27 -0400234SK_STDMETHODIMP SkWIStream::Stat(STATSTG* pStatstg, DWORD grfStatFlag) {
bsalomon@google.com9d12f5c2011-09-29 18:08:18 +0000235 if (0 == (grfStatFlag & STATFLAG_NONAME)) {
bungeman@google.com9df621d2011-06-23 21:43:52 +0000236 return STG_E_INVALIDFLAG;
237 }
halcanary96fcdcc2015-08-27 07:41:13 -0700238 pStatstg->pwcsName = nullptr;
bungeman@google.com9df621d2011-06-23 21:43:52 +0000239 pStatstg->cbSize.QuadPart = 0;
240 pStatstg->clsid = CLSID_NULL;
241 pStatstg->type = STGTY_STREAM;
242 pStatstg->grfMode = STGM_WRITE;
243 return S_OK;
244}
Mike Klein8f11d4d2018-01-24 12:42:55 -0500245#endif//defined(SK_BUILD_FOR_WIN)