
/***************************************************************************
**
**    $Header$
**
**    $Log$
** 
****************************************************************************/

/*----------------------------------------------------------------------------
** Name: SYMMPOOL.CPP
**
** Title: Memory Pool
**
** Purpose:
**  Create and manage a pool of allocated memory.  Provides:
**    AllocBytes
**    GetString
**    PutBytes
**    PutString
**    PutU32
**  Base class = Table
**
** Status: PRELIMINARY
**
** $Log$
** 
** $Header:   D:/EPSLDV1/SRC/LOG/SYMMPOOL.CPP   1.7.1.0.1.0   11 Nov 1996 13:00:04   ZJRD  $
**
** Copyright (C) 1995 Microtek International.  All rights reserved.
**
**--------------------------------------------------------------------------*/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/

#include "stdafx.h"                      
#include "sympool.h"

#ifdef DEBUG
#include <stdio.h>
#endif
                       /****************************
                        *                          *
                        *        DEFINITIONS       *
                        *                          *
                        ****************************/


#define MEMTABLE_EXPANSION_SIZE 4096L * 4L
#define MEMTABLE_INIT_SIZE      4096L * 4L

MemPool st;

                       /****************************
                        *                          *
                        *     EXECUTABLE CODE      *
                        *                          *
                        ****************************/

//member functions for MemPool

MemPool::MemPool():Table()        // constructor
   {
   availMemOffset = 0L;
   bytesThrownAway = 0;  // initialize member vars

   initialSize = MEMTABLE_INIT_SIZE;
   expandSize  = MEMTABLE_EXPANSION_SIZE;
   };  // end of MemPool constructor


RETCODE MemPool::AllocBytes(U8 size, TABLE_OFFSET& tableDataOffset)
   {
   RETCODE retCode;
   U32  memoryLeft;

   tableDataOffset = 0;    // set to null in case of a memory failure
   if ((memoryLeft = (tableSize-availMemOffset)) < (U32)size)
      {  // not enough space or empty table; must get more
      if ((retCode = InitOrExtendTable(0)) != SUCCESS) return retCode;
      // a non-zero retcode means no memory was found; otherwise fall thru

      else
         { // found more memory;
         // jump over any unused bytes to preserve 64K boundary
         // move pointer past boundary of old partition

         availMemOffset+= memoryLeft;
         bytesThrownAway += (U16)memoryLeft;
         }
      } // end of if that checked for enough memory or retrieved more memory

   // set the return pointer to the head of the data
   tableDataOffset = availMemOffset;

   // bump pointer to available memory by size of data
   availMemOffset += size;

   return SUCCESS;
   }  // end of MemPool::AllocBytes


VOID MemPool::GetString(TABLE_OFFSET tableDataOffset,
                        U8 FAR       *outputString)
   {
   HPU8  symPtr;
   U8    length;

   symPtr = GetHugeDataPtr(tableDataOffset);
   length = *symPtr++;                 // first byte is length
   for (; length > 0; length--)  {
      *outputString++ = *symPtr++;     // copy name one byte at a time
      };
   *outputString = '\0';                 // terminate string
   };  // end of MemPool::MemGetString


VOID MemPool::ObliterateTable(VOID) {
   Table::ObliterateTable();
   availMemOffset = 0L;
   bytesThrownAway = 0;  // initialize member vars

   initialSize = MEMTABLE_INIT_SIZE;
   expandSize  = MEMTABLE_EXPANSION_SIZE;
}

RETCODE MemPool::PutBytes(U8 *inputDataPtr, U8 size,
                          TABLE_OFFSET& tableDataOffset)
   {
   RETCODE retCode;
   HPU8 tempHugePtr;

   retCode = AllocBytes(size, tableDataOffset);
   if (retCode != SUCCESS) return retCode;  // return if some error

   // tableDataOffset points to head of allocated memory
   // calculate pointer to this data
   tempHugePtr = hpTableObject + tableDataOffset;

   // store the data
   for (; size > 0; size--)  {
      *tempHugePtr++ = *inputDataPtr++;
      }
   return SUCCESS;
   }  // end of MemPool::PutBytes


RETCODE MemPool::PutString(LPSTR lpString, TABLE_OFFSET& tableDataOffset)
   {
   RETCODE retCode;
   U32  memoryLeft;
   HPU8 tempHugePtr;
   U16 length;       // length of input string
   U8 i;

   tableDataOffset = 0;    // set to null in case of a memory failure
   length = (U16)lstrlen(lpString);

// removing check for 0 length string; instead, it places size of 0 into
// memory.  GetString will correctly create a NULL return string
//   if (length == 0)  {
//      return ER_STRING_LENGTH_ZERO;
//      }
   length = min(length, 255);    // truncate long strings

   // check for enough memory where requirement is string length plus one
   // byte for the header length byte.

   if ((memoryLeft = (tableSize-availMemOffset)) < (U32)(length + 1))  {
      // not enough space or empty table; must get more
#ifdef DEBUG
      printf("extending st\n");
#endif
      if ((retCode = InitOrExtendTable(0)) != SUCCESS)  return retCode;
      // a non-zero retcode means no memory was found; otherwise fall thru
      else  {
         // found more memory;
         // jump over any unused bytes to preserve 64K boundary
         // move pointer past boundary of old partition

         availMemOffset += memoryLeft;
         bytesThrownAway += (U16)memoryLeft;
         }
      } // end of if that checked for enough memory or retrieved more memory

   // put string into table
   // set the return pointer to the head of the data
   tableDataOffset = availMemOffset;

   // set huge pointer to available memory
   tempHugePtr = hpTableObject + availMemOffset;

   // increment offset pointer, by size of data, to next available memory loc
   availMemOffset += length + 1;

   // store length, then string
   *tempHugePtr++ = (U8)(length);   // put length into first byte
   for (i = 1; i <= length;)  {     // copy rest of string
      *tempHugePtr++ = *lpString++;
      i++;
      }
   return SUCCESS;
   };  // end of MemPool::PutString


RETCODE MemPool::PutU32(U32 data)
   {
   RETCODE retCode;
   U32  memoryLeft;
   HPU8 tempHugePtr;

   if ((memoryLeft = (tableSize-availMemOffset)) < 4)  {
      // not enough space or empty table; must get more
      if ((retCode = InitOrExtendTable(0)) != SUCCESS) return retCode;
      // a non-zero retcode means no memory was found; otherwise fall thru

      else  {
         // found more memory;
         // jump over any unused bytes to preserve 64K boundary
         // move pointer past boundary of old partition

         availMemOffset+= memoryLeft;
         bytesThrownAway += (U16)memoryLeft;
         }
      } // end of "if" that checked for enough memory or retrieved more memory

   // put the bytes into table

   // set huge pointer to available memory
   tempHugePtr = hpTableObject + availMemOffset;

   // bump pointer to available memory by size of data
   availMemOffset += 4;    // increment by size of U32

   // store the data
   *(U32 *)tempHugePtr = data;

   return SUCCESS;
   }  // end of MemPool::PutU32

/******************************** E O F *************************************/
