Various cosmetic changes.
[wine] / dlls / quartz / enumunk.c
1 /*
2  * Implementation of IEnumUnknown (for internal use).
3  *
4  * hidenori@a2.ctktv.ne.jp
5  */
6
7 #include "config.h"
8
9 #include "windef.h"
10 #include "winbase.h"
11 #include "winerror.h"
12 #include "wine/obj_base.h"
13 #include "wine/obj_misc.h"
14
15 #include "debugtools.h"
16 DEFAULT_DEBUG_CHANNEL(quartz);
17
18 #include "quartz_private.h"
19 #include "enumunk.h"
20 #include "iunk.h"
21
22
23
24 typedef struct IEnumUnknownImpl
25 {
26         ICOM_VFIELD(IEnumUnknown);
27 } IEnumUnknownImpl;
28
29 typedef struct
30 {
31         QUARTZ_IUnkImpl unk;
32         IEnumUnknownImpl        enumunk;
33         struct QUARTZ_IFEntry   IFEntries[1];
34         QUARTZ_CompList*        pCompList;
35         QUARTZ_CompListItem*    pItemCur;
36 } CEnumUnknown;
37
38 #define CEnumUnknown_THIS(iface,member)         CEnumUnknown*   This = ((CEnumUnknown*)(((char*)iface)-offsetof(CEnumUnknown,member)))
39
40
41
42
43 static HRESULT WINAPI
44 IEnumUnknown_fnQueryInterface(IEnumUnknown* iface,REFIID riid,void** ppobj)
45 {
46         CEnumUnknown_THIS(iface,enumunk);
47
48         TRACE("(%p)->()\n",This);
49
50         return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
51 }
52
53 static ULONG WINAPI
54 IEnumUnknown_fnAddRef(IEnumUnknown* iface)
55 {
56         CEnumUnknown_THIS(iface,enumunk);
57
58         TRACE("(%p)->()\n",This);
59
60         return IUnknown_AddRef(This->unk.punkControl);
61 }
62
63 static ULONG WINAPI
64 IEnumUnknown_fnRelease(IEnumUnknown* iface)
65 {
66         CEnumUnknown_THIS(iface,enumunk);
67
68         TRACE("(%p)->()\n",This);
69
70         return IUnknown_Release(This->unk.punkControl);
71 }
72
73 static HRESULT WINAPI
74 IEnumUnknown_fnNext(IEnumUnknown* iface,ULONG cReq,IUnknown** ppunk,ULONG* pcFetched)
75 {
76         CEnumUnknown_THIS(iface,enumunk);
77         HRESULT hr;
78         ULONG   cFetched;
79
80         TRACE("(%p)->(%lu,%p,%p)\n",This,cReq,ppunk,pcFetched);
81
82         if ( pcFetched == NULL && cReq > 1 )
83                 return E_INVALIDARG;
84         if ( ppunk == NULL )
85                 return E_POINTER;
86
87         QUARTZ_CompList_Lock( This->pCompList );
88
89         hr = NOERROR;
90         cFetched = 0;
91         while ( cReq > 0 )
92         {
93                 if ( This->pItemCur == NULL )
94                 {
95                         hr = S_FALSE;
96                         break;
97                 }
98                 ppunk[ cFetched ++ ] = QUARTZ_CompList_GetItemPtr( This->pItemCur );
99                 IUnknown_AddRef( *ppunk );
100
101                 This->pItemCur =
102                         QUARTZ_CompList_GetNext( This->pCompList, This->pItemCur );
103                 cReq --;
104         }
105
106         QUARTZ_CompList_Unlock( This->pCompList );
107
108         if ( pcFetched != NULL )
109                 *pcFetched = cFetched;
110
111         return hr;
112 }
113
114 static HRESULT WINAPI
115 IEnumUnknown_fnSkip(IEnumUnknown* iface,ULONG cSkip)
116 {
117         CEnumUnknown_THIS(iface,enumunk);
118         HRESULT hr;
119
120         TRACE("(%p)->()\n",This);
121
122         QUARTZ_CompList_Lock( This->pCompList );
123
124         hr = NOERROR;
125         while ( cSkip > 0 )
126         {
127                 if ( This->pItemCur == NULL )
128                 {
129                         hr = S_FALSE;
130                         break;
131                 }
132                 This->pItemCur =
133                         QUARTZ_CompList_GetNext( This->pCompList, This->pItemCur );
134                 cSkip --;
135         }
136
137         QUARTZ_CompList_Unlock( This->pCompList );
138
139         return hr;
140 }
141
142 static HRESULT WINAPI
143 IEnumUnknown_fnReset(IEnumUnknown* iface)
144 {
145         CEnumUnknown_THIS(iface,enumunk);
146
147         TRACE("(%p)->()\n",This);
148
149         QUARTZ_CompList_Lock( This->pCompList );
150
151         This->pItemCur = QUARTZ_CompList_GetFirst( This->pCompList );
152
153         QUARTZ_CompList_Unlock( This->pCompList );
154
155         return NOERROR;
156 }
157
158 static HRESULT WINAPI
159 IEnumUnknown_fnClone(IEnumUnknown* iface,IEnumUnknown** ppunk)
160 {
161         CEnumUnknown_THIS(iface,enumunk);
162         HRESULT hr;
163
164         TRACE("(%p)->()\n",This);
165
166         if ( ppunk == NULL )
167                 return E_POINTER;
168
169         QUARTZ_CompList_Lock( This->pCompList );
170
171         hr = QUARTZ_CreateEnumUnknown(
172                 This->IFEntries[0].piid,
173                 (void**)ppunk,
174                 This->pCompList );
175         FIXME( "current pointer must be seeked correctly\n" );
176
177         QUARTZ_CompList_Unlock( This->pCompList );
178
179         return hr;
180 }
181
182
183 static ICOM_VTABLE(IEnumUnknown) ienumunk =
184 {
185         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
186         /* IUnknown fields */
187         IEnumUnknown_fnQueryInterface,
188         IEnumUnknown_fnAddRef,
189         IEnumUnknown_fnRelease,
190         /* IEnumUnknown fields */
191         IEnumUnknown_fnNext,
192         IEnumUnknown_fnSkip,
193         IEnumUnknown_fnReset,
194         IEnumUnknown_fnClone,
195 };
196
197 void QUARTZ_DestroyEnumUnknown(IUnknown* punk)
198 {
199         CEnumUnknown_THIS(punk,unk);
200
201         if ( This->pCompList != NULL )
202                 QUARTZ_CompList_Free( This->pCompList );
203 }
204
205 HRESULT QUARTZ_CreateEnumUnknown(
206         REFIID riidEnum, void** ppobj, const QUARTZ_CompList* pCompList )
207 {
208         CEnumUnknown*   penum;
209         QUARTZ_CompList*        pCompListDup;
210
211         TRACE("(%s,%p,%p)\n",debugstr_guid(riidEnum),ppobj,pCompList);
212
213         pCompListDup = QUARTZ_CompList_Dup( pCompList, FALSE );
214         if ( pCompListDup == NULL )
215                 return E_OUTOFMEMORY;
216
217         penum = (CEnumUnknown*)QUARTZ_AllocObj( sizeof(CEnumUnknown) );
218         if ( penum == NULL )
219         {
220                 QUARTZ_CompList_Free( pCompListDup );
221                 return E_OUTOFMEMORY;
222         }
223
224         QUARTZ_IUnkInit( &penum->unk, NULL );
225         ICOM_VTBL(&penum->enumunk) = &ienumunk;
226
227         penum->IFEntries[0].piid = riidEnum;
228         penum->IFEntries[0].ofsVTPtr =
229                 offsetof(CEnumUnknown,enumunk)-offsetof(CEnumUnknown,unk);
230         penum->pCompList = pCompListDup;
231         penum->pItemCur = QUARTZ_CompList_GetFirst( pCompListDup );
232
233         penum->unk.pEntries = penum->IFEntries;
234         penum->unk.dwEntries = 1;
235         penum->unk.pOnFinalRelease = QUARTZ_DestroyEnumUnknown;
236
237         *ppobj = (void*)(&penum->enumunk);
238
239         return S_OK;
240 }
241