ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

dsa.c
Go to the documentation of this file.
00001 /*
00002  * Dynamic structure array (DSA) implementation
00003  *
00004  * Copyright 1998 Eric Kohl
00005  *           1998 Juergen Schmied <j.schmied@metronet.de>
00006  *           2000 Eric Kohl for CodeWeavers
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00021  *
00022  * NOTES
00023  *     These functions were involuntarily documented by Microsoft in 2002 as
00024  *     the outcome of an anti-trust suit brought by various U.S. governments.
00025  *     As a result the specifications on MSDN are inaccurate, incomplete 
00026  *     and misleading. A much more complete (unofficial) documentation is
00027  *     available at:
00028  *
00029  *     http://members.ozemail.com.au/~geoffch/samples/win32/shell/comctl32  
00030  */
00031 
00032 #include <stdarg.h>
00033 
00034 #include "windef.h"
00035 #include "winbase.h"
00036 #include "winuser.h"
00037 #include "commctrl.h"
00038 
00039 #include "comctl32.h"
00040 #include "wine/debug.h"
00041 
00042 WINE_DEFAULT_DEBUG_CHANNEL(dsa);
00043 
00044 struct _DSA
00045 {
00046     INT  nItemCount;
00047     LPVOID pData;
00048     INT  nMaxCount;
00049     INT  nItemSize;
00050     INT  nGrow;
00051 };
00052 
00053 /**************************************************************************
00054  * DSA_Create [COMCTL32.320]
00055  *
00056  * Creates a dynamic storage array
00057  *
00058  * PARAMS
00059  *     nSize [I] size of the array elements
00060  *     nGrow [I] number of elements by which the array grows when it is filled
00061  *
00062  * RETURNS
00063  *     Success: pointer to an array control structure. Use this like a handle.
00064  *     Failure: NULL
00065  *
00066  * NOTES
00067  *     The DSA_ functions can be used to create and manipulate arrays of
00068  *     fixed-size memory blocks. These arrays can store any kind of data
00069  *     (e.g. strings and icons).
00070  */
00071 HDSA WINAPI DSA_Create (INT nSize, INT nGrow)
00072 {
00073     HDSA hdsa;
00074 
00075     TRACE("(size=%d grow=%d)\n", nSize, nGrow);
00076 
00077     hdsa = Alloc (sizeof(*hdsa));
00078     if (hdsa)
00079     {
00080         hdsa->nItemCount = 0;
00081         hdsa->pData = NULL;
00082         hdsa->nMaxCount = 0;
00083         hdsa->nItemSize = nSize;
00084         hdsa->nGrow = max(1, nGrow);
00085     }
00086 
00087     return hdsa;
00088 }
00089 
00090 
00091 /**************************************************************************
00092  * DSA_Destroy [COMCTL32.321]
00093  * 
00094  * Destroys a dynamic storage array
00095  *
00096  * PARAMS
00097  *     hdsa [I] pointer to the array control structure
00098  *
00099  * RETURNS
00100  *     Success: TRUE
00101  *     Failure: FALSE
00102  */
00103 BOOL WINAPI DSA_Destroy (const HDSA hdsa)
00104 {
00105     TRACE("(%p)\n", hdsa);
00106 
00107     if (!hdsa)
00108         return FALSE;
00109 
00110     if (hdsa->pData && (!Free (hdsa->pData)))
00111         return FALSE;
00112 
00113     return Free (hdsa);
00114 }
00115 
00116 
00117 /**************************************************************************
00118  * DSA_GetItem [COMCTL32.322]
00119  *
00120  * Copies the specified item into a caller-supplied buffer.
00121  *
00122  * PARAMS
00123  *     hdsa   [I] pointer to the array control structure
00124  *     nIndex [I] number of the Item to get
00125  *     pDest  [O] destination buffer. Has to be >= dwElementSize.
00126  *
00127  * RETURNS
00128  *     Success: TRUE
00129  *     Failure: FALSE
00130  */
00131 BOOL WINAPI DSA_GetItem (const HDSA hdsa, INT nIndex, LPVOID pDest)
00132 {
00133     LPVOID pSrc;
00134 
00135     TRACE("(%p %d %p)\n", hdsa, nIndex, pDest);
00136 
00137     if (!hdsa)
00138         return FALSE;
00139     if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
00140         return FALSE;
00141 
00142     pSrc = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
00143     memmove (pDest, pSrc, hdsa->nItemSize);
00144 
00145     return TRUE;
00146 }
00147 
00148 
00149 /**************************************************************************
00150  * DSA_GetItemPtr [COMCTL32.323]
00151  *
00152  * Retrieves a pointer to the specified item.
00153  *
00154  * PARAMS
00155  *     hdsa   [I] pointer to the array control structure
00156  *     nIndex [I] index of the desired item
00157  *
00158  * RETURNS
00159  *     Success: pointer to an item
00160  *     Failure: NULL
00161  */
00162 LPVOID WINAPI DSA_GetItemPtr (const HDSA hdsa, INT nIndex)
00163 {
00164     LPVOID pSrc;
00165 
00166     TRACE("(%p %d)\n", hdsa, nIndex);
00167 
00168     if (!hdsa)
00169         return NULL;
00170     if ((nIndex < 0) || (nIndex >= hdsa->nItemCount))
00171         return NULL;
00172 
00173     pSrc = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
00174 
00175     TRACE("-- ret=%p\n", pSrc);
00176 
00177     return pSrc;
00178 }
00179 
00180 
00181 /**************************************************************************
00182  * DSA_SetItem [COMCTL32.325]
00183  *
00184  * Sets the contents of an item in the array.
00185  *
00186  * PARAMS
00187  *     hdsa   [I] pointer to the array control structure
00188  *     nIndex [I] index for the item
00189  *     pSrc   [I] pointer to the new item data
00190  *
00191  * RETURNS
00192  *     Success: TRUE
00193  *     Failure: FALSE
00194  */
00195 BOOL WINAPI DSA_SetItem (const HDSA hdsa, INT nIndex, LPVOID pSrc)
00196 {
00197     INT  nSize, nNewItems;
00198     LPVOID pDest, lpTemp;
00199 
00200     TRACE("(%p %d %p)\n", hdsa, nIndex, pSrc);
00201 
00202     if ((!hdsa) || nIndex < 0)
00203         return FALSE;
00204 
00205     if (hdsa->nItemCount <= nIndex) {
00206         /* within the old array */
00207         if (hdsa->nMaxCount > nIndex) {
00208             /* within the allocated space, set a new boundary */
00209             hdsa->nItemCount = nIndex + 1;
00210         }
00211         else {
00212             /* resize the block of memory */
00213             nNewItems =
00214                 hdsa->nGrow * ((((nIndex + 1) - 1) / hdsa->nGrow) + 1);
00215             nSize = hdsa->nItemSize * nNewItems;
00216 
00217             lpTemp = ReAlloc (hdsa->pData, nSize);
00218             if (!lpTemp)
00219                 return FALSE;
00220 
00221             hdsa->nMaxCount = nNewItems;
00222             hdsa->nItemCount = nIndex + 1;
00223             hdsa->pData = lpTemp;
00224         }
00225     }
00226 
00227     /* put the new entry in */
00228     pDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
00229     TRACE("-- move dest=%p src=%p size=%d\n",
00230            pDest, pSrc, hdsa->nItemSize);
00231     memmove (pDest, pSrc, hdsa->nItemSize);
00232 
00233     return TRUE;
00234 }
00235 
00236 
00237 /**************************************************************************
00238  * DSA_InsertItem [COMCTL32.324]
00239  *
00240  * Inserts an item into the array at the specified index.
00241  *
00242  * PARAMS
00243  *     hdsa   [I] pointer to the array control structure
00244  *     nIndex [I] index for the new item
00245  *     pSrc   [I] pointer to the element
00246  *
00247  * RETURNS
00248  *     Success: position of the new item
00249  *     Failure: -1
00250  */
00251 INT WINAPI DSA_InsertItem (const HDSA hdsa, INT nIndex, LPVOID pSrc)
00252 {
00253     INT   nNewItems, nSize;
00254     LPVOID  lpTemp, lpDest;
00255 
00256     TRACE("(%p %d %p)\n", hdsa, nIndex, pSrc);
00257 
00258     if ((!hdsa) || nIndex < 0)
00259         return -1;
00260 
00261     /* when nIndex >= nItemCount then append */
00262     if (nIndex >= hdsa->nItemCount)
00263          nIndex = hdsa->nItemCount;
00264 
00265     /* do we need to resize ? */
00266     if (hdsa->nItemCount >= hdsa->nMaxCount) {
00267         nNewItems = hdsa->nMaxCount + hdsa->nGrow;
00268         nSize = hdsa->nItemSize * nNewItems;
00269 
00270         lpTemp = ReAlloc (hdsa->pData, nSize);
00271         if (!lpTemp)
00272             return -1;
00273 
00274         hdsa->nMaxCount = nNewItems;
00275         hdsa->pData = lpTemp;
00276     }
00277 
00278     /* do we need to move elements ? */
00279     if (nIndex < hdsa->nItemCount) {
00280         lpTemp = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
00281         lpDest = (char *) lpTemp + hdsa->nItemSize;
00282         nSize = (hdsa->nItemCount - nIndex) * hdsa->nItemSize;
00283         TRACE("-- move dest=%p src=%p size=%d\n",
00284                lpDest, lpTemp, nSize);
00285         memmove (lpDest, lpTemp, nSize);
00286     }
00287 
00288     /* ok, we can put the new Item in */
00289     hdsa->nItemCount++;
00290     lpDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
00291     TRACE("-- move dest=%p src=%p size=%d\n",
00292            lpDest, pSrc, hdsa->nItemSize);
00293     memmove (lpDest, pSrc, hdsa->nItemSize);
00294 
00295     return nIndex;
00296 }
00297 
00298 
00299 /**************************************************************************
00300  * DSA_DeleteItem [COMCTL32.326]
00301  *
00302  * Deletes the specified item from the array.
00303  *
00304  * PARAMS
00305  *     hdsa   [I] pointer to the array control structure
00306  *     nIndex [I] index for the element to delete
00307  *
00308  * RETURNS
00309  *     Success: number of the deleted element
00310  *     Failure: -1
00311  */
00312 INT WINAPI DSA_DeleteItem (const HDSA hdsa, INT nIndex)
00313 {
00314     LPVOID lpDest,lpSrc;
00315     INT  nSize;
00316 
00317     TRACE("(%p %d)\n", hdsa, nIndex);
00318 
00319     if (!hdsa)
00320         return -1;
00321     if (nIndex < 0 || nIndex >= hdsa->nItemCount)
00322         return -1;
00323 
00324     /* do we need to move ? */
00325     if (nIndex < hdsa->nItemCount - 1) {
00326         lpDest = (char *) hdsa->pData + (hdsa->nItemSize * nIndex);
00327         lpSrc = (char *) lpDest + hdsa->nItemSize;
00328         nSize = hdsa->nItemSize * (hdsa->nItemCount - nIndex - 1);
00329         TRACE("-- move dest=%p src=%p size=%d\n",
00330                lpDest, lpSrc, nSize);
00331         memmove (lpDest, lpSrc, nSize);
00332     }
00333 
00334     hdsa->nItemCount--;
00335 
00336     /* free memory ? */
00337     if ((hdsa->nMaxCount - hdsa->nItemCount) >= hdsa->nGrow) {
00338         nSize = hdsa->nItemSize * hdsa->nItemCount;
00339 
00340         lpDest = ReAlloc (hdsa->pData, nSize);
00341         if (!lpDest)
00342             return -1;
00343 
00344         hdsa->nMaxCount = hdsa->nItemCount;
00345         hdsa->pData = lpDest;
00346     }
00347 
00348     return nIndex;
00349 }
00350 
00351 
00352 /**************************************************************************
00353  * DSA_DeleteAllItems [COMCTL32.327]
00354  *
00355  * Removes all items and reinitializes the array.
00356  *
00357  * PARAMS
00358  *     hdsa [I] pointer to the array control structure
00359  *
00360  * RETURNS
00361  *     Success: TRUE
00362  *     Failure: FALSE
00363  */
00364 BOOL WINAPI DSA_DeleteAllItems (const HDSA hdsa)
00365 {
00366     TRACE("(%p)\n", hdsa);
00367 
00368     if (!hdsa)
00369         return FALSE;
00370     if (hdsa->pData && (!Free (hdsa->pData)))
00371         return FALSE;
00372 
00373     hdsa->nItemCount = 0;
00374     hdsa->pData = NULL;
00375     hdsa->nMaxCount = 0;
00376 
00377     return TRUE;
00378 }
00379 
00380 
00381 /**************************************************************************
00382  * DSA_EnumCallback [COMCTL32.387]
00383  *
00384  * Enumerates all items in a dynamic storage array.
00385  *
00386  * PARAMS
00387  *     hdsa     [I] handle to the dynamic storage array
00388  *     enumProc [I]
00389  *     lParam   [I]
00390  *
00391  * RETURNS
00392  *     none
00393  */
00394 VOID WINAPI DSA_EnumCallback (HDSA hdsa, PFNDSAENUMCALLBACK enumProc,
00395                               LPVOID lParam)
00396 {
00397     INT i;
00398 
00399     TRACE("(%p %p %p)\n", hdsa, enumProc, lParam);
00400 
00401     if (!hdsa)
00402         return;
00403     if (hdsa->nItemCount <= 0)
00404         return;
00405 
00406     for (i = 0; i < hdsa->nItemCount; i++) {
00407         LPVOID lpItem = DSA_GetItemPtr (hdsa, i);
00408         if ((enumProc)(lpItem, lParam) == 0)
00409             return;
00410     }
00411 
00412     return;
00413 }
00414 
00415 
00416 /**************************************************************************
00417  * DSA_DestroyCallback [COMCTL32.388]
00418  *
00419  * Enumerates all items in a dynamic storage array and destroys it.
00420  *
00421  * PARAMS
00422  *     hdsa     [I] handle to the dynamic storage array
00423  *     enumProc [I]
00424  *     lParam   [I]
00425  *
00426  * RETURNS
00427  *     none
00428  */
00429 void WINAPI DSA_DestroyCallback (HDSA hdsa, PFNDSAENUMCALLBACK enumProc,
00430                                  LPVOID lParam)
00431 {
00432     TRACE("(%p %p %p)\n", hdsa, enumProc, lParam);
00433 
00434     DSA_EnumCallback (hdsa, enumProc, lParam);
00435     DSA_Destroy (hdsa);
00436 }

Generated on Fri May 25 2012 04:20:57 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.