home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************
- * *
- * HUGEARR.DLL *
- * *
- * Huge array support for Microsoft Visual Basic *
- * *
- * By Mike Warning *
- * *
- ************************************************************************/
-
- #include <memory.h>
- #include <windows.h>
- #include "hugearr.h"
-
- HANDLE hLocalMem; // handle to local memory
- int NumArrays; // total number of arrays
-
- /************************************************************************
- * LibMain - *
- * Standard DLL constructor. Allocates all of local heap to store *
- * array descriptors and then set the total number of arrays possible. *
- ************************************************************************/
- int FAR pascal
- LibMain(HANDLE hModule, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine)
- {
- if (cbHeapSize > 0)
- UnlockData(0);
- // Allocate memory for array descrips.
- hLocalMem = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,
- LocalCompact((WORD) 65500));
- if (hLocalMem == NULL)
- return 0; // Something happened, bomb out
- // calc total number of arrays
- NumArrays = (int) (LocalSize(hLocalMem) / sizeof(struct ArrayDesc));
- return (1);
- }
-
- /************************************************************************
- * WEP - *
- * Standard DLL destructor. Free up local memory and quit. *
- ************************************************************************/
- int FAR pascal WEP(int bSystemExit)
- {
- LocalFree(hLocalMem);
- return (1);
- }
-
- /************************************************************************
- * HugeDim - *
- * Dimensions a new array. The size of the array is *
- * (recsize * ubound+1). Recsize is the size in bytes of each element in *
- * the array and ubound is the upper bound of the array. All arrays have *
- * a lower bound of 0. *
- * *
- * Note: If total size of the array is greater than 64k, recsize should *
- * be an integer power of two (1,2,4,8,16,etc.) Otherwise, the *
- * huge pointers will not be added correctly. *
- ************************************************************************/
- int FAR pascal HugeDim(int recsize, long ubound)
- {
- int hArray; // handle to array to dimension
- pDescrip pArray; // pointer to array descriptor
- int ret; // return value from HugeAlloc
-
- pArray = (pDescrip) LocalLock(hLocalMem); // find a free array
- if ((hArray = GetFreeArray(pArray)) == HA_TOMANYARRAYS) {
- LocalUnlock(hLocalMem); // couldn't find one,
- return (HA_TOMANYARRAYS); // return error.
- }
- // allocate new array
- ret = HugeAlloc(pArray + hArray, recsize, ubound, FALSE);
- LocalUnlock(hLocalMem);
-
- if (ret < 0) // if an error occured during alloc
- return (ret); // return the error, else
- else
- return (hArray); // return the handle to the array
-
- }
-
- /************************************************************************
- * HugeRedim - *
- * Redimenions the given array to have the new 'ubound'. The old *
- * recsize is kept. All data in the array is preserved and any new data *
- * (created by expanding the array) is initialized to 0. *
- * *
- * Note: The recsize must be an integer power of two if the total array *
- * size is greater than 64k. *
- ************************************************************************/
- int FAR pascal HugeRedim(int hArray, long ubound)
- {
- pDescrip pArray; // pointer to array desciptor
- register ret; // return code of HugeAlloc
-
- if (hArray < 0 | hArray >= NumArrays)
- return (HA_BADARRAY); // illegal array handle
-
- pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
-
- if (pArray -> handle != NULL) // reallocate array
- ret = HugeAlloc(pArray, pArray -> recsize, ubound, TRUE);
- else
- ret = HA_BADARRAY; // array has never been allocated
-
- LocalUnlock(hLocalMem);
- return (ret);
- }
-
-
- /********************************************************************
- * GetFreeArray - *
- * Searches the array descriptor table looking for a free entry. *
- * It returns the index into the table if an entry is free or *
- * HA_TOMANYARRAYS otherwise. pArray is the pointer to the start of *
- * the table. *
- ********************************************************************/
- int GetFreeArray(pDescrip pArray)
- {
- int i = 0;
- // loop until found or out of entries
- while ((i < NumArrays) && (pArray -> handle != NULL)) {
- ++pArray;
- ++i;
- }
-
- if (i == NumArrays) // didn't find a spot
- return (HA_TOMANYARRAYS);
-
- return (i); // found one, return index to it
- }
-
- /********************************************************************
- * GetHugeEl - *
- * Retrieves an element of the array storing it into the buffer *
- * pointed to by 'buffer'. hArray is the index into the descriptor *
- * table of the array, element is the element to get. *
- * *
- * NOTE: there is absolutely no type checking done on the buffer. *
- * It is up to the programmer to make sure it points to the *
- * correct data type. *
- ********************************************************************/
- int FAR pascal GetHugeEl(int hArray, long element, BYTE FAR *buffer)
- {
- BYTE _huge *ptr; // pointer to array element
- pDescrip pArray; // pointer to array descriptor
-
- if (hArray < 0 || hArray >= NumArrays)
- return (HA_BADARRAY); // illegal array handle
-
- // point to proper descriptor
- pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
-
- if (pArray -> handle == NULL) {
- LocalUnlock(hLocalMem);
- return (HA_BADARRAY); // array hasn't been allocated
- }
- if ((pArray -> ubound < element) || (element < 0)) {
- LocalUnlock(hLocalMem);
- return (HA_SUBSCRIPT); // subscript out of range
- }
- // calculate pointer to element
- ptr = (BYTE _huge *) GlobalLock(pArray -> handle);
- ptr = ptr + element * pArray->recsize;
- _fmemcpy(buffer, ptr, pArray -> recsize); // copy data
-
- GlobalUnlock(pArray -> handle);
- LocalUnlock(hLocalMem);
- return (HA_OK);
- }
-
- /********************************************************************
- * SetHugeEl - *
- * Sets the value of an array element. This routine is exactly *
- * the same as 'GetHugeEl' except that the memory copy is resversed. *
- ********************************************************************/
- int FAR pascal SetHugeEl(int hArray, long element, BYTE FAR *buffer)
- {
- BYTE _huge *ptr; // pointer to array element
- pDescrip pArray; // pointer to array descriptor
-
- if (hArray < 0 || hArray >= NumArrays)
- return (HA_BADARRAY); // illegal array handle
-
- // point to proper descriptor
- pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
-
- if (pArray -> handle == NULL) {
- LocalUnlock(hLocalMem);
- return (HA_BADARRAY); // array hasn't been allocated
- }
- if ((pArray -> ubound < element) || (element < 0)) {
- LocalUnlock(hLocalMem);
- return (HA_SUBSCRIPT); // subscript out of range
- }
- // calculate pointer to element
- ptr = (BYTE _huge *) GlobalLock(pArray -> handle);
- ptr = ptr + element * pArray->recsize;
- _fmemcpy(ptr, buffer, pArray -> recsize); // copy data
-
- GlobalUnlock(pArray -> handle);
- LocalUnlock(hLocalMem);
- return (HA_OK);
- }
-
- /********************************************************************
- * HugeErase - *
- * Deletes an array and marks it as free in the descriptor table. *
- * 'hArray' is the array to erase. *
- ********************************************************************/
- int FAR pascal HugeErase(int hArray)
- {
- pDescrip pArray; // pointer to array descriptor
-
- if (hArray < 0 || hArray >= NumArrays)
- return (HA_BADARRAY); // illegal array handle
-
- pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
- if (pArray -> handle == NULL) {
- LocalUnlock(hLocalMem);
- return (HA_BADARRAY); // array hasn't been allocated yet
- }
-
- GlobalFree(pArray -> handle); // free the memory
- pArray -> handle = NULL;
-
- LocalUnlock(hLocalMem);
- return (HA_OK);
- }
-
- /********************************************************************
- * NumHugeArrays - *
- * Returns the number of free entries in the array descriptor table*
- ********************************************************************/
- int FAR pascal NumHugeArrays(void)
- {
- pDescrip pArray; // pointer to current descriptor
- int num, i; // number free so far
-
- pArray = (pDescrip) LocalLock(hLocalMem);
- for (i = 0, num = 0; i < NumArrays; i++, pArray++)
- if (pArray -> handle == NULL)
- ++num;
-
- LocalUnlock(hLocalMem);
- return (num);
- }
-
-
- /********************************************************************
- * HugeUbound - *
- * Returns the upper bound of a given array *
- ********************************************************************/
- long FAR pascal HugeUbound(int hArray)
- {
- pDescrip pArray; // pointer to array descriptor
- long ubound; // upper bound of array
-
- if (hArray < 0 || hArray >= NumArrays)
- return (HA_BADARRAY); // illegal array handle
-
- pArray = (pDescrip) LocalLock(hLocalMem) + hArray;
- if (pArray -> handle == NULL) {
- LocalUnlock(hLocalMem);
- return (HA_BADARRAY); // array hasn't been allocated yet
- }
-
- ubound = pArray -> ubound;
- LocalUnlock(hLocalMem);
-
- return (ubound);
- }
-
-
- /********************************************************************
- * HugeInt - *
- * Same as GetHugeEl except that it explicitly returns an integer. *
- * Use this function when you are in an expression such as: *
- * i% = 5 * HugeInt(4, 5) *
- * *
- * NOTE: Because the user could store anything in the array element, *
- * they will not know if the value returned is a real value or *
- * if an error occured. Use GetHugeEl if the error code must *
- * be checked. *
- ********************************************************************/
- int FAR pascal HugeInt(int hArray, long element)
- {
- int retval;
-
- GetHugeEl(hArray, element, (BYTE FAR *) &retval);
- return (retval);
- }
-
-
- /********************************************************************
- * HugeLong - *
- * Returns an element of a long integer array. (re. HugeInt) *
- ********************************************************************/
- long FAR pascal HugeLong(int hArray, long element)
- {
- long retval;
-
- GetHugeEl(hArray, element, (BYTE FAR *) &retval);
- return (retval);
- }
-
-
-
- /********************************************************************
- * HugeSingle - *
- * Returns an element of a single precesion array. (re. HugeInt) *
- ********************************************************************/
- float FAR pascal HugeSingle(int hArray, long element)
- {
- float retval;
-
- GetHugeEl(hArray, element, (BYTE FAR *) &retval);
- return (retval);
- }
-
-
- /********************************************************************
- * HugeDouble - *
- * Returns an element of a double precesion array. (re. HugeInt) *
- ********************************************************************/
- double FAR pascal HugeDouble(int hArray, long element)
- {
- double retval;
-
- GetHugeEl(hArray, element, (BYTE FAR *) &retval);
- return (retval);
- }
-
-
- /********************************************************************
- * HugeCurrency - *
- * Returns an element of a currency array. (re. HugeInt) *
- ********************************************************************/
- currency FAR pascal HugeCurrency(int hArray, long element)
- {
- return((currency) HugeDouble(hArray, element));
- }
-
- /********************************************************************
- * HugeAlloc - *
- * Allocates (or reallocates) global memory for an array. The size *
- * of the array is recsize * (ubound + 1) bytes. The information *
- * for the array is stored in the array descriptor pointed to by *
- * 'pArray'. *
- * *
- * Note: See HugeDim for a discussion on array size limitations. *
- ********************************************************************/
- int HugeAlloc(pDescrip pArray,int recsize,long ubound, BOOL realloc)
- {
- HANDLE handle; // temp handle for alloc
-
- ++ubound; // ubound = #elements - 1
- if (recsize * ubound > 0xffff) // is size integer power two?
- if ((recsize <= 0) || (((recsize - 1) & recsize) != 0))
- return (HA_BADELEMENTSIZE);
-
- if (realloc) // allocate array
- handle = GlobalReAlloc(pArray -> handle, recsize * ubound,
- GMEM_MOVEABLE || GMEM_ZEROINIT);
- else
- handle = GlobalAlloc(GMEM_MOVEABLE || GMEM_ZEROINIT, recsize * ubound);
-
- if (handle == NULL)
- return (HA_OUTOFMEMORY); // out of memory
-
- pArray -> handle = handle; // save new handle
- pArray -> recsize = recsize; // record element size
- pArray -> ubound = ubound - 1;
-
- return (HA_OK);
- }
-