2 * IEnum* implementation
4 * Copyright 2006 Mike McCormack
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.
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.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "wine/list.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
33 typedef struct tagEnumSTATPROPSETSTG_impl
43 /************************************************************************
44 * enumx_QueryInterface
46 HRESULT WINAPI
enumx_QueryInterface(
51 if ( (This
==0) || (ppvObject
==0) )
56 if (IsEqualGUID(&IID_IUnknown
, riid
) ||
57 IsEqualGUID(&This
->riid
, riid
))
59 IUnknown_AddRef(((IUnknown
*)This
));
67 /************************************************************************
70 ULONG WINAPI
enumx_AddRef(enumx_impl
*This
)
72 return InterlockedIncrement(&This
->ref
);
75 /************************************************************************
78 ULONG WINAPI
enumx_Release(enumx_impl
*This
)
82 ref
= InterlockedDecrement(&This
->ref
);
85 while (!list_empty(&This
->elements
))
87 struct list
*x
= list_head(&This
->elements
);
89 HeapFree(GetProcessHeap(), 0, x
);
91 HeapFree(GetProcessHeap(), 0, This
);
96 /************************************************************************
99 HRESULT WINAPI
enumx_Next(enumx_impl
*This
, ULONG celt
,
100 void *rgelt
, ULONG
*pceltFetched
)
105 TRACE("%p %u %p\n", This
, celt
, pceltFetched
);
107 if (This
->current
== NULL
)
108 This
->current
= list_head(&This
->elements
);
110 while (count
< celt
&& This
->current
&& This
->current
!= &This
->elements
)
112 memcpy(p
, &This
->current
[1], This
->elem_size
);
113 p
+= This
->elem_size
;
114 This
->current
= This
->current
->next
;
118 *pceltFetched
= count
;
124 /************************************************************************
127 HRESULT WINAPI
enumx_Skip(enumx_impl
*This
, ULONG celt
)
131 TRACE("%p %u\n", This
, celt
);
133 if (This
->current
== NULL
)
134 This
->current
= list_head(&This
->elements
);
136 while (count
< celt
&& This
->current
&& This
->current
!= &This
->elements
)
142 /************************************************************************
145 HRESULT WINAPI
enumx_Reset(enumx_impl
*This
)
149 This
->current
= NULL
;
153 /************************************************************************
156 HRESULT WINAPI
enumx_Clone(
164 /************************************************************************
167 * Allocate a generic enumerator
169 enumx_impl
*enumx_allocate(REFIID riid
, const void *vtbl
, ULONG elem_size
)
173 enumx
= HeapAlloc(GetProcessHeap(), 0, sizeof *enumx
);
178 enumx
->current
= NULL
;
179 enumx
->elem_size
= elem_size
;
180 memcpy(&enumx
->riid
, riid
, sizeof *riid
);
181 list_init(&enumx
->elements
);
187 /************************************************************************
190 * Add an element to the enumeration.
192 void *enumx_add_element(enumx_impl
*enumx
, void *data
)
194 struct list
*element
;
196 element
= HeapAlloc(GetProcessHeap(), 0, sizeof *element
+ enumx
->elem_size
);
199 memcpy(&element
[1], data
, enumx
->elem_size
);
200 list_add_tail(&enumx
->elements
, element
);