ReactOS 0.4.16-dev-334-g4d9f67c
dsa.c
Go to the documentation of this file.
1/*
2 * Dynamic structure array (DSA) implementation
3 *
4 * Copyright 1998 Eric Kohl
5 * 1998 Juergen Schmied <j.schmied@metronet.de>
6 * 2000 Eric Kohl for CodeWeavers
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 *
22 * NOTES
23 * These functions were involuntarily documented by Microsoft in 2002 as
24 * the outcome of an anti-trust suit brought by various U.S. governments.
25 * As a result the specifications on MSDN are inaccurate, incomplete
26 * and misleading. A much more complete (unofficial) documentation is
27 * available at:
28 *
29 * http://members.ozemail.com.au/~geoffch/samples/win32/shell/comctl32
30 */
31
32#include <stdarg.h>
33
34#include "windef.h"
35#include "winbase.h"
36#include "winuser.h"
37#include "commctrl.h"
38
39#include "comctl32.h"
40#include "wine/debug.h"
41
43
44struct _DSA
45{
51};
52
53/**************************************************************************
54 * DSA_Create [COMCTL32.320]
55 *
56 * Creates a dynamic storage array
57 *
58 * PARAMS
59 * nSize [I] size of the array elements
60 * nGrow [I] number of elements by which the array grows when it is filled
61 *
62 * RETURNS
63 * Success: pointer to an array control structure. Use this like a handle.
64 * Failure: NULL
65 *
66 * NOTES
67 * The DSA_ functions can be used to create and manipulate arrays of
68 * fixed-size memory blocks. These arrays can store any kind of data
69 * (e.g. strings and icons).
70 */
72{
73 HDSA hdsa;
74
75 TRACE("(size=%d grow=%d)\n", nSize, nGrow);
76
77 hdsa = Alloc (sizeof(*hdsa));
78 if (hdsa)
79 {
80 hdsa->nItemCount = 0;
81 hdsa->pData = NULL;
82 hdsa->nMaxCount = 0;
83 hdsa->nItemSize = nSize;
84 hdsa->nGrow = max(1, nGrow);
85 }
86
87 return hdsa;
88}
89
90
91/**************************************************************************
92 * DSA_Destroy [COMCTL32.321]
93 *
94 * Destroys a dynamic storage array
95 *
96 * PARAMS
97 * hdsa [I] pointer to the array control structure
98 *
99 * RETURNS
100 * Success: TRUE
101 * Failure: FALSE
102 */
104{
105 TRACE("(%p)\n", hdsa);
106
107 if (!hdsa)
108 return FALSE;
109
110 if (hdsa->pData && (!Free (hdsa->pData)))
111 return FALSE;
112
113 return Free (hdsa);
114}
115
116
117/**************************************************************************
118 * DSA_GetItem [COMCTL32.322]
119 *
120 * Copies the specified item into a caller-supplied buffer.
121 *
122 * PARAMS
123 * hdsa [I] pointer to the array control structure
124 * nIndex [I] number of the Item to get
125 * pDest [O] destination buffer. Has to be >= dwElementSize.
126 *
127 * RETURNS
128 * Success: TRUE
129 * Failure: FALSE
130 */
131BOOL WINAPI DSA_GetItem (HDSA hdsa, INT nIndex, LPVOID pDest)
132{
133 LPVOID pSrc;
134
135 TRACE("(%p %d %p)\n", hdsa, nIndex, pDest);
136
137 if (!hdsa)
138 return FALSE;
139 if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
140 return FALSE;
141
142 pSrc = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
143 memmove (pDest, pSrc, hdsa->nItemSize);
144
145 return TRUE;
146}
147
148
149/**************************************************************************
150 * DSA_GetItemPtr [COMCTL32.323]
151 *
152 * Retrieves a pointer to the specified item.
153 *
154 * PARAMS
155 * hdsa [I] pointer to the array control structure
156 * nIndex [I] index of the desired item
157 *
158 * RETURNS
159 * Success: pointer to an item
160 * Failure: NULL
161 */
163{
164 LPVOID pSrc;
165
166 TRACE("(%p %d)\n", hdsa, nIndex);
167
168 if (!hdsa)
169 return NULL;
170 if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
171 return NULL;
172
173 pSrc = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
174
175 TRACE("-- ret=%p\n", pSrc);
176
177 return pSrc;
178}
179
180
181/**************************************************************************
182 * DSA_SetItem [COMCTL32.325]
183 *
184 * Sets the contents of an item in the array.
185 *
186 * PARAMS
187 * hdsa [I] pointer to the array control structure
188 * nIndex [I] index for the item
189 * pSrc [I] pointer to the new item data
190 *
191 * RETURNS
192 * Success: TRUE
193 * Failure: FALSE
194 */
195BOOL WINAPI DSA_SetItem (HDSA hdsa, INT nIndex, LPVOID pSrc)
196{
197 INT nSize, nNewItems;
198 LPVOID pDest, lpTemp;
199
200 TRACE("(%p %d %p)\n", hdsa, nIndex, pSrc);
201
202 if ((!hdsa) || nIndex < 0)
203 return FALSE;
204
205 if (hdsa->nItemCount <= nIndex) {
206 /* within the old array */
207 if (hdsa->nMaxCount > nIndex) {
208 /* within the allocated space, set a new boundary */
209 hdsa->nItemCount = nIndex + 1;
210 }
211 else {
212 /* resize the block of memory */
213 nNewItems =
214 hdsa->nGrow * ((((nIndex + 1) - 1) / hdsa->nGrow) + 1);
215 nSize = hdsa->nItemSize * nNewItems;
216
217 lpTemp = ReAlloc (hdsa->pData, nSize);
218 if (!lpTemp)
219 return FALSE;
220
221 hdsa->nMaxCount = nNewItems;
222 hdsa->nItemCount = nIndex + 1;
223 hdsa->pData = lpTemp;
224 }
225 }
226
227 /* put the new entry in */
228 pDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
229 TRACE("-- move dest=%p src=%p size=%d\n",
230 pDest, pSrc, hdsa->nItemSize);
231 memmove (pDest, pSrc, hdsa->nItemSize);
232
233 return TRUE;
234}
235
236
237/**************************************************************************
238 * DSA_InsertItem [COMCTL32.324]
239 *
240 * Inserts an item into the array at the specified index.
241 *
242 * PARAMS
243 * hdsa [I] pointer to the array control structure
244 * nIndex [I] index for the new item
245 * pSrc [I] pointer to the element
246 *
247 * RETURNS
248 * Success: position of the new item
249 * Failure: -1
250 */
252{
253 INT nNewItems, nSize;
254 LPVOID lpTemp, lpDest;
255
256 TRACE("(%p %d %p)\n", hdsa, nIndex, pSrc);
257
258 if ((!hdsa) || nIndex < 0)
259 return -1;
260
261 /* when nIndex >= nItemCount then append */
262 if (nIndex >= hdsa->nItemCount)
263 nIndex = hdsa->nItemCount;
264
265 /* do we need to resize ? */
266 if (hdsa->nItemCount >= hdsa->nMaxCount) {
267 nNewItems = hdsa->nMaxCount + hdsa->nGrow;
268 nSize = hdsa->nItemSize * nNewItems;
269
270 if (nSize / hdsa->nItemSize != nNewItems)
271 return -1;
272
273 lpTemp = ReAlloc (hdsa->pData, nSize);
274 if (!lpTemp)
275 return -1;
276
277 hdsa->nMaxCount = nNewItems;
278 hdsa->pData = lpTemp;
279 }
280
281 /* do we need to move elements ? */
282 if (nIndex < hdsa->nItemCount) {
283 lpTemp = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
284 lpDest = (char *) lpTemp + hdsa->nItemSize;
285 nSize = (hdsa->nItemCount - nIndex) * hdsa->nItemSize;
286 TRACE("-- move dest=%p src=%p size=%d\n",
287 lpDest, lpTemp, nSize);
288 memmove (lpDest, lpTemp, nSize);
289 }
290
291 /* ok, we can put the new Item in */
292 hdsa->nItemCount++;
293 lpDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
294 TRACE("-- move dest=%p src=%p size=%d\n",
295 lpDest, pSrc, hdsa->nItemSize);
296 memmove (lpDest, pSrc, hdsa->nItemSize);
297
298 return nIndex;
299}
300
301
302/**************************************************************************
303 * DSA_DeleteItem [COMCTL32.326]
304 *
305 * Deletes the specified item from the array.
306 *
307 * PARAMS
308 * hdsa [I] pointer to the array control structure
309 * nIndex [I] index for the element to delete
310 *
311 * RETURNS
312 * Success: number of the deleted element
313 * Failure: -1
314 */
316{
317 LPVOID lpDest,lpSrc;
318 INT nSize;
319
320 TRACE("(%p %d)\n", hdsa, nIndex);
321
322 if (!hdsa)
323 return -1;
324 if (nIndex < 0 || nIndex >= hdsa->nItemCount)
325 return -1;
326
327 /* do we need to move ? */
328 if (nIndex < hdsa->nItemCount - 1) {
329 lpDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
330 lpSrc = (char *) lpDest + hdsa->nItemSize;
331 nSize = hdsa->nItemSize * (hdsa->nItemCount - nIndex - 1);
332 TRACE("-- move dest=%p src=%p size=%d\n",
333 lpDest, lpSrc, nSize);
334 memmove (lpDest, lpSrc, nSize);
335 }
336
337 hdsa->nItemCount--;
338
339 /* free memory ? */
340 if ((hdsa->nMaxCount - hdsa->nItemCount) >= hdsa->nGrow) {
341 nSize = hdsa->nItemSize * hdsa->nItemCount;
342
343 lpDest = ReAlloc (hdsa->pData, nSize);
344 if (!lpDest)
345 return -1;
346
347 hdsa->nMaxCount = hdsa->nItemCount;
348 hdsa->pData = lpDest;
349 }
350
351 return nIndex;
352}
353
354
355/**************************************************************************
356 * DSA_DeleteAllItems [COMCTL32.327]
357 *
358 * Removes all items and reinitializes the array.
359 *
360 * PARAMS
361 * hdsa [I] pointer to the array control structure
362 *
363 * RETURNS
364 * Success: TRUE
365 * Failure: FALSE
366 */
368{
369 TRACE("(%p)\n", hdsa);
370
371 if (!hdsa)
372 return FALSE;
373 if (hdsa->pData && (!Free (hdsa->pData)))
374 return FALSE;
375
376 hdsa->nItemCount = 0;
377 hdsa->pData = NULL;
378 hdsa->nMaxCount = 0;
379
380 return TRUE;
381}
382
383
384/**************************************************************************
385 * DSA_EnumCallback [COMCTL32.387]
386 *
387 * Enumerates all items in a dynamic storage array.
388 *
389 * PARAMS
390 * hdsa [I] handle to the dynamic storage array
391 * enumProc [I]
392 * lParam [I]
393 *
394 * RETURNS
395 * none
396 */
399{
400 INT i;
401
402 TRACE("(%p %p %p)\n", hdsa, enumProc, lParam);
403
404 if (!hdsa)
405 return;
406 if (hdsa->nItemCount <= 0)
407 return;
408
409 for (i = 0; i < hdsa->nItemCount; i++) {
410 LPVOID lpItem = DSA_GetItemPtr (hdsa, i);
411 if ((enumProc)(lpItem, lParam) == 0)
412 return;
413 }
414
415 return;
416}
417
418
419/**************************************************************************
420 * DSA_DestroyCallback [COMCTL32.388]
421 *
422 * Enumerates all items in a dynamic storage array and destroys it.
423 *
424 * PARAMS
425 * hdsa [I] handle to the dynamic storage array
426 * enumProc [I]
427 * lParam [I]
428 *
429 * RETURNS
430 * none
431 */
434{
435 TRACE("(%p %p %p)\n", hdsa, enumProc, lParam);
436
437 DSA_EnumCallback (hdsa, enumProc, lParam);
438 DSA_Destroy (hdsa);
439}
440
441/**************************************************************************
442 * DSA_Clone [COMCTL32.@]
443 *
444 * Creates a copy of a dsa
445 *
446 * PARAMS
447 * hdsa [I] handle to the dynamic storage array
448 *
449 * RETURNS
450 * Cloned dsa
451 */
453{
454 HDSA dest;
455 INT i;
456
457 TRACE("(%p)\n", hdsa);
458
459 if (!hdsa)
460 return NULL;
461
462 dest = DSA_Create (hdsa->nItemSize, hdsa->nGrow);
463 if (!dest)
464 return NULL;
465
466 for (i = 0; i < hdsa->nItemCount; i++) {
467 void *ptr = DSA_GetItemPtr (hdsa, i);
468 if (DSA_InsertItem (dest, DA_LAST, ptr) == -1) {
470 return NULL;
471 }
472 }
473
474 return dest;
475}
476
477/**************************************************************************
478 * DSA_GetSize [COMCTL32.@]
479 *
480 * Returns allocated memory size for this array
481 *
482 * PARAMS
483 * hdsa [I] handle to the dynamic storage array
484 *
485 * RETURNS
486 * Size
487 */
489{
490 TRACE("(%p)\n", hdsa);
491
492 if (!hdsa) return 0;
493
494 return sizeof(*hdsa) + (ULONGLONG)hdsa->nMaxCount*hdsa->nItemSize;
495}
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
PVOID ReAlloc(IN DWORD dwFlags, IN PVOID lpMem, IN SIZE_T dwBytes)
Definition: main.c:76
PVOID Alloc(IN DWORD dwFlags, IN SIZE_T dwBytes)
Definition: main.c:63
LPARAM lParam
Definition: combotst.c:139
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL WINAPI DSA_GetItem(HDSA hdsa, INT nIndex, LPVOID pDest)
Definition: dsa.c:131
LPVOID WINAPI DSA_GetItemPtr(HDSA hdsa, INT nIndex)
Definition: dsa.c:162
VOID WINAPI DSA_EnumCallback(HDSA hdsa, PFNDSAENUMCALLBACK enumProc, LPVOID lParam)
Definition: dsa.c:397
BOOL WINAPI DSA_DeleteAllItems(HDSA hdsa)
Definition: dsa.c:367
BOOL WINAPI DSA_Destroy(HDSA hdsa)
Definition: dsa.c:103
INT WINAPI DSA_DeleteItem(HDSA hdsa, INT nIndex)
Definition: dsa.c:315
void WINAPI DSA_DestroyCallback(HDSA hdsa, PFNDSAENUMCALLBACK enumProc, LPVOID lParam)
Definition: dsa.c:432
INT WINAPI DSA_InsertItem(HDSA hdsa, INT nIndex, LPVOID pSrc)
Definition: dsa.c:251
HDSA WINAPI DSA_Clone(HDSA hdsa)
Definition: dsa.c:452
HDSA WINAPI DSA_Create(INT nSize, INT nGrow)
Definition: dsa.c:71
BOOL WINAPI DSA_SetItem(HDSA hdsa, INT nIndex, LPVOID pSrc)
Definition: dsa.c:195
ULONGLONG WINAPI DSA_GetSize(HDSA hdsa)
Definition: dsa.c:488
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
static PVOID ptr
Definition: dispmode.c:27
static char * dest
Definition: rtl.c:135
int(CALLBACK * PFNDSAENUMCALLBACK)(void *p, void *pData)
Definition: commctrl.h:4798
#define DA_LAST
Definition: commctrl.h:4788
#define TRACE(s)
Definition: solgame.cpp:4
Definition: dsa.c:45
LPVOID pData
Definition: dsa.c:47
INT nItemSize
Definition: dsa.c:49
INT nGrow
Definition: dsa.c:50
INT nItemCount
Definition: dsa.c:46
INT nMaxCount
Definition: dsa.c:48
#define max(a, b)
Definition: svc.c:63
int32_t INT
Definition: typedefs.h:58
uint64_t ULONGLONG
Definition: typedefs.h:67
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2109
#define WINAPI
Definition: msvc.h:6
_In_opt_ PALLOCATE_FUNCTION _In_opt_ PFREE_FUNCTION Free
Definition: exfuncs.h:815