
/***************************************************************************
**
**    $Header:   D:/EPSLDV1/SRC/LOG/SYMINDEX.CPP   1.8   20 Jun 1996 09:26:40   ZJRD  $
**
**    $Log:   D:/EPSLDV1/SRC/LOG/SYMINDEX.CPP  $
** 
**    Rev 1.8   20 Jun 1996 09:26:40   ZJRD
** EasyPack/SLD Version 1.20a
** 
**    Rev 1.6   10 Jun 1996 10:21:20   ZJRD
** EasyPack/SLD Version 1.20
** 
**    Rev 1.4   29 May 1996 09:31:30   ZJRD
** No change.
** 
**    Rev 1.3   16 May 1996 09:04:44   ZJRD
** No change.
** 
**    Rev 1.2   10 May 1996 09:13:36   ZJRD
** No change.
** 
**    Rev 1.1   02 May 1996 10:24:12   ZJRD
** EasyPack/SLD Version 1.92
** 
**    Rev 1.31   18 Apr 1996 12:53:24   Shirley
** No change.
** 
**    Rev 1.30   12 Apr 1996 10:40:12   Shirley
** EasyPack/SLD Version 1.90
** 
**    Rev 1.28   15 Feb 1996 08:53:52   Shirley
** No change.
** 
**    Rev 1.27   12 Feb 1996 14:09:10   Shirley
** No change.
** 
**    Rev 1.26   06 Feb 1996 15:35:34   Shirley
** No change.
** 
**    Rev 1.25   06 Feb 1996 13:49:50   Shirley
** No change.
** 
**    Rev 1.24   01 Feb 1996 10:14:20   Shirley
** No change.
** 
**    Rev 1.23   26 Jan 1996 09:20:14   Shirley
** No change.
** 
**    Rev 1.22   25 Jan 1996 13:20:08   Shirley
** No change.
** 
**    Rev 1.21   24 Jan 1996 10:38:58   Shirley
** No change.
** 
**    Rev 1.20   23 Jan 1996 11:27:48   Shirley
** No change.
** 
**    Rev 1.19   18 Jan 1996 10:09:44   Shirley
** No change.
** 
**    Rev 1.18   15 Jan 1996 16:16:00   Shirley
** No change.
** 
**    Rev 1.17   04 Jan 1996 11:11:32   Shirley
** No change.
** 
**    Rev 1.16   30 Nov 1995 09:08:12   Shirley
** No change.
** 
**    Rev 1.15   28 Nov 1995 15:34:44   Shirley
** No change.
** 
**    Rev 1.14   21 Nov 1995 11:22:26   Shirley
** No change.
** 
**    Rev 1.13   13 Nov 1995 09:27:48   Shirley
** No change.
** 
**    Rev 1.12   12 Nov 1995 11:31:18   Shirley
** No change.
** 
**    Rev 1.11   08 Nov 1995 16:27:54   Shirley
** No change.
** 
**    Rev 1.10   08 Nov 1995 12:41:06   Shirley
** No change.
** 
**    Rev 1.9   02 Nov 1995 10:06:48   Shirley
** No change.
** 
**    Rev 1.8   27 Oct 1995 16:51:14   Shirley
** No change.
** 
**    Rev 1.7   27 Oct 1995 13:44:58   Shirley
** No change.
** 
**    Rev 1.6   25 Oct 1995 14:31:22   Shirley
** No change.
** 
**    Rev 1.5   18 Oct 1995 14:47:14   Shirley
** No change.
** 
**    Rev 1.4   13 Oct 1995 13:19:16   Shirley
** No change.
** 
**    Rev 1.3   29 Sep 1995 09:51:44   Shirley
** No change.
** 
**    Rev 1.2   20 Sep 1995 10:58:04   Shirley
** No change.
** 
**    Rev 1.1   15 Sep 1995 09:46:34   Shirley
** No change.
** 
**    Rev 1.0   07 Sep 1995 09:55:24   Shirley
** Initial revision.
**
****************************************************************************/

/*-------------------------------------------------------------------------
** Name: SYMINDEX.CPP
**
** Title: Index Table
**
** Purpose:
**  Supports the creation of a Base Index Table and Type Index Table and
**  provides methods for adding an index and retrieving an offset for an index
**
**  Base class = table
**
** Status: PRELIMINARY
**
** $Log$
** 
** $Header:   D:/EPSLDV1/SRC/LOG/SYMINDEX.CPP   1.8   20 Jun 1996 09:26:40   ZJRD  $
**
** Copyright (C) 1995 Microtek International.  All rights reserved.
**
**------------------------------------------------------------------------*/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#include "stdafx.h"                      
#include "indextbl.h"
#include "mempool.h"

#ifdef DEBUG
#include "winio.h"
#endif
                       /****************************
                        *                          *
                        *        DEFINITIONS       *
                        *                          *
                        ****************************/


#define INDEXTABLE_INIT_SIZE      (4L * 256L)
#define INDEXTABLE_EXPANSION_SIZE (4L * 256L)
#define MAX_INDEX_SIZE           0xFFFFFFFFL // this is the max size of any
                                             // index table;  If desired to be
                                             // smaller, inherited class must
                                             // set smaller;
                                             // e.g. BaseIndexTable

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

//member functions for IndexTable

IndexTable::IndexTable():Table()      // constructor with no params
   {
   entryCount = 0L;  // initialize member vars
   initialSize = INDEXTABLE_INIT_SIZE;
   expandSize  = INDEXTABLE_EXPANSION_SIZE;
   maxIndex = MAX_INDEX_SIZE;
   }   // end of IndexTable constructor


//------------------------------------------------------------------------
// IndexTable::AddIndex
//
// Purpose:
//    Add an index into the index table with its offset to the item.
//
// Input parameters:
//    index: TABLE_OFFSET index into index table.
//    itemOffset: offset into the symbol table to be stored at table[index]
//
// Output parameters: None
//
// Error:
//    Reports ER_INDEX_ALREADY_EXISTS if the index already has a legitimate
//    value in the index location in the table.
//    Reports ER_INDEX_OUT_OF_BOUNDS if the requested index is larger than
//       the maximum table size
//
// Pseudo-code for allocation
//    if table not alloc'ed yet, set up to alloc on 256 byte boundary that
//       includes requested index
//    if table alloc'ed, set up to realloc on 256 byte boundary, also to
//       include requested index
//    if table alloc'ed, must set expandSize = additional amount to extend
//       table by
//------------------------------------------------------------------------
RETCODE IndexTable::AddIndex(TABLE_INDEX index, TABLE_OFFSET itemOffset) {

   HP_TABLE_OFFSET hpTable;
   U32 tmpTableSize;
   RETCODE retCode;
   TABLE_INDEX indexPlus1;

   indexPlus1 = index + 1;
   if (indexPlus1 > maxIndex) return ER_INDEX_OUT_OF_BOUNDS;
   // index starts at 0; must incr to calculate the number of bytes needed
   // at that point in the array before testing for greater than tableSize
   if (((indexPlus1) * (sizeof(TABLE_OFFSET))) > tableSize) {
      // must expand table to accommodate new index

      // calculate needed table size and round up (will add extra 256 if it
      // is initially on an even 256 boundary)
      tmpTableSize = (indexPlus1 * (sizeof(TABLE_OFFSET)) + 256)
                     & 0xFFFFFF00L;

      if (!tableSize)  {     // table has not been allocated yet
         initialSize = max(initialSize, tmpTableSize);
         }
      else {
        // must convert absolute request to relative size increase;
        // subtract the present table size from the requested size
        // to come up with the amount to expand the table by
         tmpTableSize = tmpTableSize - tableSize;
         expandSize = max(expandSize, tmpTableSize);
         }
      // allocate the memory for new table
      if ((retCode =
         InitOrExtendTable(GMEM_ZEROINIT)) == ER_SYM_OUT_OF_MEMORY) {
         return retCode;
         }
      }
   // memory available; store itemOffset if one is not already there
   hpTable = (HP_TABLE_OFFSET)GetHugeDataPtr(index * (sizeof(TABLE_OFFSET)));
   if (!*hpTable)  {
      *hpTable = itemOffset;  // save offset to item in symbol table
      entryCount++;
      return SUCCESS;
      }
   else
      return ER_INDEX_ALREADY_EXISTS;
   }   // end of AddIndex


//------------------------------------------------------------------------
// IndexTable::GetOffset
//
// Purpose:
//    Retrieve offset to item in symbol table given the index to the index
//    table.
//
// Input parameters:
//    index:
//       TABLE_OFFSET index into index table; the index is to the size
//       of a TABLE_OFFSET
//
// Output parameters:
//    itemOffset:
//       offset into symbol table of item
//
// Error:
//    Reports ER_INDEX_NOT_IN_TABLE if the index field is NULL
//    Reports ER_INDEX_OUT_OF_BOUNDS if the requested index is larger than
//       the maximum index parameter allowed (it is not depended on table
//       size because the table can be alloc'ed bigger).
//------------------------------------------------------------------------
 RETCODE IndexTable::GetOffset(TABLE_INDEX index,
                               TABLE_OFFSET& itemOffset) {

   if ((index + 1) > maxIndex)
      return ER_INDEX_OUT_OF_BOUNDS;
   else if ((index + 1) > (tableSize / (sizeof(TABLE_OFFSET)))) {
      return ER_TABLE_SMALLER_THAN_INDEX; }
   else {
      itemOffset =
         *(HP_TABLE_OFFSET)GetHugeDataPtr(index * (sizeof(TABLE_OFFSET)));
      if (!itemOffset)  // if NULL then item not in table
         return ER_INDEX_NOT_IN_TABLE;
      else
         return SUCCESS;
      }
   }   // end of GetOffset


//------------------------------------------------------------------------
// IndexTable::ObliterateTable
//------------------------------------------------------------------------
VOID IndexTable::ObliterateTable(VOID) {

   Table::ObliterateTable();
   entryCount = 0L;  // initialize member vars
   initialSize = INDEXTABLE_INIT_SIZE;
   expandSize  = INDEXTABLE_EXPANSION_SIZE;
   maxIndex = MAX_INDEX_SIZE;

}  // end of IndexTable::ObliterateTable


//------------------------------------------------------------------------
// IndexTable::UpdateOffset
//------------------------------------------------------------------------
RETCODE IndexTable::UpdateOffset(TABLE_INDEX index, TABLE_OFFSET newOffset) {

   HPU8 offsetPtr;
   
   if ((index + 1) > maxIndex)
      return ER_INDEX_OUT_OF_BOUNDS;
   else if ((index + 1) > (tableSize / (sizeof(TABLE_OFFSET)))) {
      return ER_TABLE_SMALLER_THAN_INDEX;
   } else {
      offsetPtr = GetHugeDataPtr(index * (sizeof(TABLE_OFFSET)));
      if (! (U32 *) offsetPtr)  // if NULL then item not in table
         return ER_INDEX_NOT_IN_TABLE;
      else
         *(U32 *)offsetPtr = newOffset;
         return SUCCESS;
   }
}  // end of IndexTable::UpdateOffset

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