Added some missing functions.
[wine] / dlls / quartz / enumpins.c
1 /*
2  * Implementation of IEnumPins Interface
3  *
4  * Copyright 2003 Robert Shearman
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "quartz_private.h"
22
23 #include "wine/debug.h"
24
25 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
26
27 typedef struct IEnumPinsImpl
28 {
29     const IEnumPinsVtbl * lpVtbl;
30     ULONG refCount;
31     ENUMPINDETAILS enumPinDetails;
32     ULONG uIndex;
33 } IEnumPinsImpl;
34
35 static const struct IEnumPinsVtbl IEnumPinsImpl_Vtbl;
36
37 HRESULT IEnumPinsImpl_Construct(const ENUMPINDETAILS * pDetails, IEnumPins ** ppEnum)
38 {
39     IEnumPinsImpl * pEnumPins = CoTaskMemAlloc(sizeof(IEnumPinsImpl));
40     if (!pEnumPins)
41     {
42         *ppEnum = NULL;
43         return E_OUTOFMEMORY;
44     }
45     pEnumPins->lpVtbl = &IEnumPinsImpl_Vtbl;
46     pEnumPins->refCount = 1;
47     pEnumPins->uIndex = 0;
48     CopyMemory(&pEnumPins->enumPinDetails, pDetails, sizeof(ENUMPINDETAILS));
49     *ppEnum = (IEnumPins *)(&pEnumPins->lpVtbl);
50     return S_OK;
51 }
52
53 static HRESULT WINAPI IEnumPinsImpl_QueryInterface(IEnumPins * iface, REFIID riid, LPVOID * ppv)
54 {
55     TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv);
56
57     *ppv = NULL;
58
59     if (IsEqualIID(riid, &IID_IUnknown))
60         *ppv = (LPVOID)iface;
61     else if (IsEqualIID(riid, &IID_IEnumPins))
62         *ppv = (LPVOID)iface;
63
64     if (*ppv)
65     {
66         IUnknown_AddRef((IUnknown *)(*ppv));
67         return S_OK;
68     }
69
70     FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
71
72     return E_NOINTERFACE;
73 }
74
75 static ULONG WINAPI IEnumPinsImpl_AddRef(IEnumPins * iface)
76 {
77     ICOM_THIS(IEnumPinsImpl, iface);
78
79     TRACE("()\n");
80
81     return ++This->refCount;
82 }
83
84 static ULONG WINAPI IEnumPinsImpl_Release(IEnumPins * iface)
85 {
86     ICOM_THIS(IEnumPinsImpl, iface);
87
88     TRACE("()\n");
89     
90     if (!--This->refCount)
91     {
92         CoTaskMemFree(This);
93         return 0;
94     }
95     else
96         return This->refCount;
97 }
98
99 static HRESULT WINAPI IEnumPinsImpl_Next(IEnumPins * iface, ULONG cPins, IPin ** ppPins, ULONG * pcFetched)
100 {
101     ULONG cFetched; 
102     ICOM_THIS(IEnumPinsImpl, iface);
103
104     cFetched = min(This->enumPinDetails.cPins, This->uIndex + cPins) - This->uIndex;
105
106     TRACE("(%lu, %p, %p)\n", cPins, ppPins, pcFetched);
107
108     if (cFetched > 0)
109     {
110         ULONG i;
111
112         *ppPins = This->enumPinDetails.ppPins[This->uIndex];
113         for (i = This->uIndex; i < This->uIndex + cFetched; i++)
114             IPin_AddRef(This->enumPinDetails.ppPins[i]);
115     }
116
117     if ((cPins != 1) || pcFetched)
118         *pcFetched = cFetched;
119
120     This->uIndex += cFetched;
121
122     if (cFetched != cPins)
123         return S_FALSE;
124     return S_OK;
125 }
126
127 static HRESULT WINAPI IEnumPinsImpl_Skip(IEnumPins * iface, ULONG cPins)
128 {
129     ICOM_THIS(IEnumPinsImpl, iface);
130
131     TRACE("(%lu)\n", cPins);
132
133     if (This->uIndex + cPins < This->enumPinDetails.cPins)
134     {
135         This->uIndex += cPins;
136         return S_OK;
137     }
138     return S_FALSE;
139 }
140
141 static HRESULT WINAPI IEnumPinsImpl_Reset(IEnumPins * iface)
142 {
143     ICOM_THIS(IEnumPinsImpl, iface);
144
145     TRACE("IEnumPinsImpl::Reset()\n");
146
147     This->uIndex = 0;
148     return S_OK;
149 }
150
151 static HRESULT WINAPI IEnumPinsImpl_Clone(IEnumPins * iface, IEnumPins ** ppEnum)
152 {
153     HRESULT hr;
154     ICOM_THIS(IEnumPinsImpl, iface);
155
156     TRACE("(%p)\n", ppEnum);
157
158     hr = IEnumPinsImpl_Construct(&This->enumPinDetails, ppEnum);
159     if (FAILED(hr))
160         return hr;
161     return IEnumPins_Skip(*ppEnum, This->uIndex);
162 }
163
164 static const IEnumPinsVtbl IEnumPinsImpl_Vtbl =
165 {
166     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
167     IEnumPinsImpl_QueryInterface,
168     IEnumPinsImpl_AddRef,
169     IEnumPinsImpl_Release,
170     IEnumPinsImpl_Next,
171     IEnumPinsImpl_Skip,
172     IEnumPinsImpl_Reset,
173     IEnumPinsImpl_Clone
174 };