home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xlmath10.zip / XLMUTIL.C < prev    next >
C/C++ Source or Header  |  1992-03-14  |  8KB  |  323 lines

  1. /*******************************************************************
  2.  
  3.   XLMUTIL.C
  4.   ==========
  5.  
  6.  Author:    Roy Kari
  7.              Dept. of Chemistry
  8.             Laurentian University
  9.             Sudbury, Ont.
  10.             Canada        P3E 2C6
  11.             (705) 675-1151
  12.             Internet: "ROY@NICKEL.LAURENTIAN.CA"
  13.  
  14.   This module contains all of the memory management routines for
  15.   the XLMATH module. The memory management is done with the aid
  16.   of the OPTIMEM memory manager (c) Applegate Software (206)868-8512.
  17.   The author strongly recommends the purchase of this memory manager
  18.   as a means of avoiding untold frustrations in both the comprehension
  19.   and use of Windows 3 memory management.
  20.   ***************************************************************** */
  21.  
  22. /* --------------------------< Include files >--------------------- */
  23.  
  24. #include <windows.h>
  25. #include <stdlib.h>
  26. #include "xlmopti.h"
  27. #include "xlmath.h"
  28. #include "xlmutil.h"
  29.  
  30. extern OMEM_POOL ReturnPool;
  31. extern OMEM_POOL ScratchPool;
  32.  
  33. extern HANDLE hLibInst;
  34. extern char *szLibName;
  35. extern TD TaskDescriptors[];
  36.  
  37. /*** Global Variables ***/
  38. static char szErrorBuf[MAX_ERROR_STRING];
  39.  
  40. // function prototypes
  41. static NPTD PASCAL FindTaskDescriptor(HANDLE hTask);
  42.  
  43. /********************************************************************
  44.  ExpungeTaskDescriptor()
  45.  =======================
  46.  This function deletes a task descriptor and any memory associated
  47.  with the descriptor block.
  48.  ********************************************************************/
  49. BOOL PASCAL ExpungeTaskDescriptor(HANDLE hTask)
  50. {
  51.     NPTD pTaskDesc = FindTaskDescriptor(hTask);
  52.     HANDLE hGlobal;
  53.     if (!pTaskDesc)
  54.         return FALSE;
  55.     if (pTaskDesc->lpReturnBuffer)
  56.         MemFreePtr(pTaskDesc->lpReturnBuffer);
  57.  
  58.     pTaskDesc->lpReturnBuffer = NULL;
  59.     pTaskDesc->hTask = NULL;
  60.  
  61.     return TRUE;
  62. }
  63. /********************************************************************
  64.  FindTaskDescriptor()
  65.  ====================
  66.  This function gets a pointer to the currently active tasks
  67.  descriptor block or returns NULL if none found. When called
  68.  with hTask = NULL, finds first available slot for new block.
  69.  ********************************************************************/
  70.  
  71. static NPTD PASCAL FindTaskDescriptor(HANDLE hTask)
  72. {
  73.     WORD wCount = MAX_TASK_DESC;
  74.     NPTD pTaskDesc = &TaskDescriptors[0];
  75.  
  76.     while (wCount--)
  77.         if (pTaskDesc->hTask == hTask)
  78.             return pTaskDesc;
  79.         else
  80.             ++pTaskDesc;
  81.  
  82.     return NULL;
  83. }
  84. /********************************************************************
  85.  GetTaskDescriptor()
  86.  ================
  87.  This function gets a pointer to the currently active task's
  88.  descriptor block. If not found then creates a new one
  89.  ********************************************************************/
  90. NPTD PASCAL GetTaskDescriptor(HANDLE hTask)
  91. {
  92.     NPTD pTaskDesc = FindTaskDescriptor(hTask);
  93.  
  94.     if (pTaskDesc)
  95.         return pTaskDesc;
  96.  
  97.  
  98.     // a new task
  99.     pTaskDesc = FindTaskDescriptor(0);    // look for empty one
  100.  
  101.     if (pTaskDesc)
  102.     {
  103.         pTaskDesc->hTask = hTask;
  104.         pTaskDesc->lpReturnBuffer = NULL;
  105.         return pTaskDesc;
  106.     }
  107.     else
  108.     {
  109.         ErrorHandler(XLM_NO_TASK);
  110.         return NULL;
  111.     }
  112. }
  113.  
  114.  
  115. /********************************************************************
  116.  InitRetBuff()
  117.  =============
  118.  This function allocates the XL transfer array in global memory &
  119.  inits the array. If hXLInt is NULL it will allocate, otherwise
  120.  reallocate.
  121.  ********************************************************************/
  122. LPFP PASCAL InitRetBuff(WORD wRows, WORD wCols)
  123. {
  124.     WORD wBlockSize = sizeof(WORD)*2 + sizeof(double)*wRows*wCols;
  125.     WORD i;
  126.     LPFP lpXLInt = NULL;
  127.     NPTD pTaskDesc;
  128.  
  129.  
  130.     pTaskDesc = GetTaskDescriptor(GetCurrentTask());
  131.  
  132.     if (pTaskDesc != NULL)
  133.     {
  134.         if ((lpXLInt = pTaskDesc->lpReturnBuffer) != NULL)
  135.  
  136.         {
  137.             // previously used memory is reallocated
  138.             lpXLInt = (LPFP)MemReAllocPtr((LPVOID) lpXLInt,
  139.                             wBlockSize, TRUE);
  140.         }
  141.         else
  142.         {
  143.             lpXLInt = (LPFP)MemAllocPtr(ReturnPool,
  144.                             wBlockSize, TRUE);
  145.         }
  146.         // init array
  147.         if (lpXLInt != NULL)
  148.         {
  149.             pTaskDesc->lpReturnBuffer = lpXLInt;
  150.             lpXLInt->wRows  = wRows;
  151.             lpXLInt->wCols = wCols;
  152.             for (i = 0; i < wRows*wCols; i++)
  153.                 lpXLInt->Data[i] = 0.0;
  154.         }
  155.     }
  156.     else
  157.         ErrorHandler(XLM_NULL_TASK);
  158.  
  159.     return (lpXLInt);
  160. }
  161. /********************************************************************
  162.  GetMem()
  163.  =============
  164.  This function allocates memory for temporary storage
  165.  ********************************************************************/
  166. LPVOID PASCAL GetMem(WORD wBytes)
  167. {
  168.     LPVOID lpPtr = (LPVOID)MemAllocPtr(ScratchPool, wBytes, FALSE);
  169.  
  170.     if (lpPtr == NULL)
  171.         ErrorHandler(XLM_NO_MEMORY);
  172.  
  173.     return (lpPtr);
  174.  
  175. }
  176. /********************************************************************
  177.  FreeMem()
  178.  =============
  179.  This function de-allocates memory previously allocated in GetMem()
  180.  ********************************************************************/
  181. void PASCAL FreeMem(LPVOID lpPtr)
  182. {
  183.     if ((MemFreePtr((LPVOID)lpPtr) == FALSE))
  184.         ErrorHandler(XLM_MEMORY_ERROR);
  185.  
  186.     lpPtr = NULL;
  187.  
  188. }
  189. /********************************************************************
  190.  InitPointers()
  191.  =============
  192.  This function allocates memory and calculates the pointers for a 2-D
  193.  array. Note: prior to setting pointers, the array data must be Locked
  194.  in memory so that the pointers remain valid
  195.  ********************************************************************/
  196. LPLPREAL PASCAL InitPointers(LPREAL lpData,
  197.             WORD wRows, WORD wCols)
  198. {
  199.     WORD id;
  200.     LPLPREAL lplpPtrs;
  201.     WORD wBytes = sizeof(LPREAL)*wRows;
  202.  
  203.     if ((lplpPtrs= (LPLPREAL)GetMem(wBytes))  == NULL)
  204.     {
  205.         ErrorHandler(XLM_NO_MEMORY);
  206.         return NULL;
  207.     }
  208.     // init row pointers
  209.     for(id = 0; id < wRows; id++)
  210.     {
  211.            lplpPtrs[id] = lpData;
  212.         lpData += wCols;
  213.     }
  214.     return(lplpPtrs);
  215. }
  216. /********************************************************************
  217.  CleanMemory()
  218.  =============
  219.  This function is called when a task terminates
  220.  ********************************************************************/
  221. void PASCAL CleanMemory(void)
  222. {
  223.     WORD wCount = MAX_TASK_DESC;
  224.     NPTD pTaskDesc = &TaskDescriptors[0];
  225.     WORD wActiveTasks = 0;
  226.     DWORD dwCountScratch = MemPoolCount(ScratchPool);
  227.     DWORD dwCountReturn = MemPoolCount(ReturnPool);
  228.  
  229.     // count no. active tasks
  230.     while (wCount--)
  231.     {
  232.         if (pTaskDesc->hTask)
  233.             ++wActiveTasks;
  234.         ++pTaskDesc;
  235.     }
  236.  
  237.     // never have ScratchPool blocks
  238.     if (dwCountScratch > 0)
  239.         ErrorHandler(XLM_SMEM_ERROR);
  240.  
  241.     // only one per active task
  242.     if (dwCountReturn > wActiveTasks)
  243.         ErrorHandler(XLM_RMEM_ERROR);
  244.  
  245. }
  246. /********************************************************************
  247.  ErrorHandler()
  248.  ================
  249.  This function is used to display an error message
  250.  ********************************************************************/
  251.  
  252. BOOL PASCAL ErrorHandler(XLM_ERROR nErrorCode)
  253. {
  254.     int nResult;
  255.  
  256.  
  257.     MessageBeep(0);
  258.     if (LoadString(hLibInst, nErrorCode, szErrorBuf, MAX_ERROR_STRING) > 0)
  259.     {
  260.         if ((nResult = MessageBox(0, szErrorBuf, szLibName,
  261.                 MB_OK | MB_ICONHAND | MB_TASKMODAL)) == 0)
  262.             nResult = MessageBox(0, szErrorBuf, szLibName,
  263.                 MB_OK | MB_ICONHAND | MB_SYSTEMMODAL);
  264.         return nResult == IDRETRY;
  265.     }
  266.     else
  267.         return FALSE;
  268. }
  269.  
  270. #ifdef SUB_OPTIMEM
  271.  
  272. OMEM_POOL PASCAL MemPoolInit(BOOL bShared)
  273. {
  274.     return (OMEM_POOL)NULL;
  275. }
  276. BOOL PASCAL MemPoolFree(OMEM_POOL pool)
  277. {
  278.     return TRUE;
  279. }
  280. DWORD PASCAL MemPoolCount(OMEM_POOL pool)
  281. {
  282.     return (DWORD)0;
  283. }
  284. LPVOID PASCAL MemAllocPtr(OMEM_POOL pool, WORD wSize,
  285.     BOOL bZeroInit)
  286. {
  287.     HANDLE hGlobal;
  288.     LPVOID lpPtr;
  289.     WORD wFlags = GMEM_MOVEABLE;
  290.  
  291.     if (bZeroInit)
  292.         wFlags = wFlags | GMEM_ZEROINIT;
  293.     if ((hGlobal = GlobalAlloc(wFlags, (DWORD)wSize)) == NULL)
  294.         return (LPVOID)NULL;
  295.     else
  296.         return (LPVOID)GlobalLock(hGlobal);
  297. }
  298. LPVOID PASCAL  MemReAllocPtr(LPVOID lpMem, WORD wSize,
  299.     BOOL bZeroInit)
  300. {
  301.     HANDLE hGlobal = LOWORD(GlobalHandle(HIWORD(lpMem)));
  302.     LPVOID lpPtr;
  303.     WORD wFlags = GMEM_MOVEABLE;
  304.  
  305.     if (bZeroInit)
  306.         wFlags = wFlags | GMEM_ZEROINIT;
  307.  
  308.     GlobalUnlock(hGlobal);
  309.     if ((hGlobal = GlobalReAlloc(hGlobal,(DWORD)wSize, wFlags))
  310.                      == NULL)
  311.         return (LPVOID)NULL;
  312.     else
  313.         return (LPVOID)GlobalLock(hGlobal);
  314. }
  315. BOOL PASCAL  MemFreePtr(LPVOID lpPtr)
  316. {
  317.     HANDLE hGlobal = LOWORD(GlobalHandle(HIWORD(lpPtr)));
  318.     GlobalUnlock(hGlobal);
  319.     GlobalFree(hGlobal);
  320.     return TRUE;
  321. }
  322. #endif
  323.