ReactOS  0.4.13-dev-651-g5dbc677
enumx.c
Go to the documentation of this file.
1 /*
2  * IEnum* implementation
3  *
4  * Copyright 2006 Mike McCormack
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #define COBJMACROS
22 
23 #include <stdarg.h>
24 
25 #include "windef.h"
26 #include "winbase.h"
27 #include "objbase.h"
28 
29 #include "enumx.h"
30 
31 #include "wine/list.h"
32 #include "wine/debug.h"
33 
35 
37 {
38  const void *vtbl;
40  struct list elements;
41  struct list *current;
46 };
47 
48 /************************************************************************
49  * enumx_QueryInterface
50  */
53  REFIID riid,
54  void** ppvObject)
55 {
56  if ( ppvObject==0 )
57  return E_INVALIDARG;
58 
59  *ppvObject = 0;
60 
61  if (IsEqualGUID(&IID_IUnknown, riid) ||
62  IsEqualGUID(&This->riid, riid))
63  {
64  IUnknown_AddRef(((IUnknown*)This));
65  *ppvObject = This;
66  return S_OK;
67  }
68 
69  return E_NOINTERFACE;
70 }
71 
72 /************************************************************************
73  * enumx_AddRef
74  */
76 {
77  return InterlockedIncrement(&This->ref);
78 }
79 
80 /************************************************************************
81  * enumx_Release
82  */
84 {
85  ULONG ref;
86 
87  ref = InterlockedDecrement(&This->ref);
88  if (ref == 0)
89  {
90  while (!list_empty(&This->elements))
91  {
92  struct list *x = list_head(&This->elements);
93  list_remove(x);
94  HeapFree(GetProcessHeap(), 0, x);
95  }
96  IUnknown_Release(This->parent);
98  }
99  return ref;
100 }
101 
102 /************************************************************************
103  * enumx_Next
104  */
106  void *rgelt, ULONG *pceltFetched)
107 {
108  unsigned char *p;
109  ULONG count = 0;
110 
111  TRACE("%p %u %p\n", This, celt, pceltFetched);
112 
113  if (This->current == NULL)
114  This->current = list_head(&This->elements);
115  p = rgelt;
116  while (count < celt && This->current && This->current != &This->elements)
117  {
118  if (This->copy_cb)
119  This->copy_cb(This->parent, &This->current[1], p);
120  else
121  memcpy(p, &This->current[1], This->elem_size);
122  p += This->elem_size;
123  This->current = This->current->next;
124  count++;
125  }
126  if (pceltFetched)
127  *pceltFetched = count;
128  if (count < celt)
129  return S_FALSE;
130  return S_OK;
131 }
132 
133 /************************************************************************
134  * enumx_Skip
135  */
137 {
138  ULONG count = 0;
139 
140  TRACE("%p %u\n", This, celt);
141 
142  if (This->current == NULL)
143  This->current = list_head(&This->elements);
144 
145  while (count < celt && This->current && This->current != &This->elements)
146  count++;
147 
148  return S_OK;
149 }
150 
151 /************************************************************************
152  * enumx_Reset
153  */
155 {
156  TRACE("\n");
157 
158  This->current = NULL;
159  return S_OK;
160 }
161 
162 /************************************************************************
163  * enumx_fnClone
164  */
166  enumx_impl *iface,
167  enumx_impl **ppenum)
168 {
169  FIXME("\n");
170  return E_NOTIMPL;
171 }
172 
173 /************************************************************************
174  * enumx_allocate
175  *
176  * Allocate a generic enumerator
177  */
178 enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size,
179  IUnknown *parent, enumx_copy_cb copy_cb)
180 {
181  enumx_impl *enumx;
182 
183  enumx = HeapAlloc(GetProcessHeap(), 0, sizeof *enumx);
184  if (enumx)
185  {
186  enumx->vtbl = vtbl;
187  enumx->ref = 1;
188  enumx->current = NULL;
189  enumx->elem_size = elem_size;
190  enumx->riid = *riid;
191  enumx->parent = parent;
192  enumx->copy_cb = copy_cb;
193 
194  IUnknown_AddRef(parent);
195 
196  list_init(&enumx->elements);
197  }
198 
199  return enumx;
200 }
201 
202 /************************************************************************
203  * enumx_add_element
204  *
205  * Add an element to the enumeration.
206  */
207 void *enumx_add_element(enumx_impl *enumx, const void *data)
208 {
209  struct list *element;
210 
211  element = HeapAlloc(GetProcessHeap(), 0, sizeof *element + enumx->elem_size);
212  if (!element)
213  return NULL;
214  memcpy(&element[1], data, enumx->elem_size);
215  list_add_tail(&enumx->elements, element);
216  return &element[1];
217 }
HRESULT WINAPI enumx_Reset(enumx_impl *This)
Definition: enumx.c:154
#define REFIID
Definition: guiddef.h:113
#define E_NOINTERFACE
Definition: winerror.h:2364
void * enumx_add_element(enumx_impl *enumx, const void *data)
Definition: enumx.c:207
enumx_copy_cb copy_cb
Definition: enumx.c:45
REFIID riid
Definition: precomp.h:44
HRESULT WINAPI enumx_Skip(enumx_impl *This, ULONG celt)
Definition: enumx.c:136
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
struct list elements
Definition: enumx.c:40
Definition: send.c:47
__WINE_SERVER_LIST_INLINE struct list * list_head(const struct list *list)
Definition: list.h:131
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
HRESULT WINAPI enumx_Next(enumx_impl *This, ULONG celt, void *rgelt, ULONG *pceltFetched)
Definition: enumx.c:105
long LONG
Definition: pedump.c:60
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:110
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
smooth NULL
Definition: ftsmooth.c:416
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
r parent
Definition: btrfs.c:2708
LONG HRESULT
Definition: typedefs.h:77
enumx_impl * enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size, IUnknown *parent, enumx_copy_cb copy_cb)
Definition: enumx.c:178
const GUID IID_IUnknown
#define WINAPI
Definition: msvc.h:8
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define InterlockedDecrement
Definition: armddk.h:52
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
Definition: _list.h:228
REFIID LPVOID * ppvObject
Definition: precomp.h:44
struct list * current
Definition: enumx.c:41
ULONG WINAPI enumx_Release(enumx_impl *This)
Definition: enumx.c:83
__WINE_SERVER_LIST_INLINE int list_empty(const struct list *list)
Definition: list.h:143
#define S_OK
Definition: intsafe.h:59
#define InterlockedIncrement
Definition: armddk.h:53
#define E_NOTIMPL
Definition: ddrawi.h:99
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
HRESULT WINAPI enumx_QueryInterface(enumx_impl *This, REFIID riid, void **ppvObject)
Definition: enumx.c:51
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
const void * vtbl
Definition: enumx.c:38
unsigned int ULONG
Definition: retypes.h:1
void(* enumx_copy_cb)(IUnknown *parent, void *orig, void *dest)
Definition: enumx.h:24
HRESULT WINAPI enumx_Clone(enumx_impl *iface, enumx_impl **ppenum)
Definition: enumx.c:165
GLfloat GLfloat p
Definition: glext.h:8902
#define HeapFree(x, y, z)
Definition: compat.h:394
WINE_DEFAULT_DEBUG_CHANNEL(ole)
struct task_struct * current
Definition: linux.c:32
ULONG WINAPI enumx_AddRef(enumx_impl *This)
Definition: enumx.c:75