ReactOS  0.4.14-dev-342-gdc047f9
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 
44 struct _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  */
131 BOOL 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  */
195 BOOL 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  */
251 INT WINAPI DSA_InsertItem (HDSA hdsa, INT nIndex, LPVOID pSrc)
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  */
398  LPVOID lParam)
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  */
433  LPVOID lParam)
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) {
469  DSA_Destroy (dest);
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 }
INT nItemSize
Definition: dsa.c:49
HDSA WINAPI DSA_Clone(HDSA hdsa)
Definition: dsa.c:452
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define max(a, b)
Definition: svc.c:63
#define TRUE
Definition: types.h:120
VOID WINAPI DSA_EnumCallback(HDSA hdsa, PFNDSAENUMCALLBACK enumProc, LPVOID lParam)
Definition: dsa.c:397
BOOL WINAPI DSA_Destroy(HDSA hdsa)
Definition: dsa.c:103
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2031
int32_t INT
Definition: typedefs.h:56
_In_opt_ PALLOCATE_FUNCTION _In_opt_ PFREE_FUNCTION Free
Definition: exfuncs.h:656
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
Definition: dsa.c:44
unsigned int BOOL
Definition: ntddk_ex.h:94
LPVOID pData
Definition: dsa.c:47
static PVOID ptr
Definition: dispmode.c:27
INT nMaxCount
Definition: dsa.c:48
smooth NULL
Definition: ftsmooth.c:416
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
INT WINAPI DSA_DeleteItem(HDSA hdsa, INT nIndex)
Definition: dsa.c:315
#define TRACE(s)
Definition: solgame.cpp:4
PVOID ReAlloc(IN DWORD dwFlags, IN PVOID lpMem, IN SIZE_T dwBytes)
Definition: main.c:76
BOOL WINAPI DSA_DeleteAllItems(HDSA hdsa)
Definition: dsa.c:367
BOOL WINAPI DSA_GetItem(HDSA hdsa, INT nIndex, LPVOID pDest)
Definition: dsa.c:131
uint64_t ULONGLONG
Definition: typedefs.h:65
#define WINAPI
Definition: msvc.h:8
INT nGrow
Definition: dsa.c:50
PVOID Alloc(IN DWORD dwFlags, IN SIZE_T dwBytes)
Definition: main.c:63
int(CALLBACK * PFNDSAENUMCALLBACK)(void *p, void *pData)
Definition: commctrl.h:4789
void WINAPI DSA_DestroyCallback(HDSA hdsa, PFNDSAENUMCALLBACK enumProc, LPVOID lParam)
Definition: dsa.c:432
LPVOID WINAPI DSA_GetItemPtr(HDSA hdsa, INT nIndex)
Definition: dsa.c:162
#define DA_LAST
Definition: commctrl.h:4779
INT nItemCount
Definition: dsa.c:46
static char * dest
Definition: rtl.c:135
INT WINAPI DSA_InsertItem(HDSA hdsa, INT nIndex, LPVOID pSrc)
Definition: dsa.c:251
LPARAM lParam
Definition: combotst.c:139
ULONGLONG WINAPI DSA_GetSize(HDSA hdsa)
Definition: dsa.c:488
WINE_DEFAULT_DEBUG_CHANNEL(dsa)