/*----------------------------------------------------------------------------
** Name: ordtbl.cpp
**
** Title: Ord Table
**
** Purpose:
**  Create and manage the table that holds offsets to symbols in the order
**    they were loaded.  Provides:
**       PutU32 (inherited from MemPool)
**       GetOffset
**       GetOrdinalFromPercent
**
**  Base class = MemPool
**
** Status: PRELIMINARY | CODED
**
** $Log:   S:/tbird/mt2_68k/symbol/ordtbl.cpv  $
** 
**    Rev 1.0   13 Feb 1997 09:06:16   gene
** Initial revision.
** 
**    Rev 1.0   07 Sep 1995 11:16:42   gene
** Initial revision.
** 
**    Rev 1.5   09 Feb 1993 17:03:34   brucea
** Cosmetic changes
** 
**    Rev 1.4   06 Dec 1991 17:05:38   john
** Added member function to free the allocated memory for the 
** ordinal table.
** 
**    Rev 1.3   06 Nov 1991 14:42:02   brucea
** Added AddSymOffsetToOT
** 
**    Rev 1.2   13 Sep 1991 14:39:42   brucea
** Added GetOffset method
** 
**    Rev 1.1   12 Sep 1991 10:53:40   john
** fixed up module so it would compile
** 
**    Rev 1.0   11 Sep 1991 09:09:18   brucea
** Initial revision.
**
** $Header:   S:/tbird/mt2_68k/symbol/ordtbl.cpv   1.0   13 Feb 1997 09:06:16   gene  $
**
** Copyright (C) 1991 Microtek International.  All rights reserved.
**
**--------------------------------------------------------------------------*/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#ifndef _MEMPOOL_
#include "mempool.h"
#endif
#ifndef _ORDTBL_
#include "ordtbl.h"
#endif

                       /****************************
                        *                          *
                        *        DEFINITIONS       *
                        *                          *
                        ****************************/

#define ORDTABLE_INIT_SIZE      (4L * 1024L)
#define ORDTABLE_EXPANSION_SIZE (4L * 1024L)

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

//member functions for OrdinalTable

//------------------------------------------------------------------------
// OrdinalTable::OrdinalTable()     constructor
//------------------------------------------------------------------------
OrdinalTable::OrdinalTable():MemPool()  {

   initialSize = ORDTABLE_INIT_SIZE;
   expandSize  = ORDTABLE_EXPANSION_SIZE;
};  // end of OrdinalTable constructor


//------------------------------------------------------------------------
// OrdinalTable::AddSymOffsetToOT
//------------------------------------------------------------------------
RETCODE
OrdinalTable::AddSymOffsetToOT(TABLE_OFFSET symOffset,
                               ORDINAL_INDEX& ordIndex) {

   RETCODE retCode;
   TABLE_OFFSET offset;
   
   if ((retCode = AllocBytes(sizeof(symOffset), offset)) == SUCCESS) {
      *(TABLE_OFFSET *)GetHugeDataPtr(offset) = symOffset;
      ordIndex = GetOrdinalCount();
   }
   return retCode;
}  // end of AddSymOffsetToOT


//------------------------------------------------------------------------
// OrdinalTable::GetOffset
//
// Purpose:
//    Retrieve offset to symbol table item given the index to the ordinal
//    table.
//
// Input parameters:
//    ordIndex:
//       ORDINAL_INDEX index into ordinal table; the index is an even 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 or
//    Reports ER_INDEX_OUT_OF_BOUNDS if the requested index is larger than
//       last item in the table or larger than the table size
//------------------------------------------------------------------------
RETCODE OrdinalTable::GetOffset(ORDINAL_INDEX ordIndex,
                                TABLE_OFFSET& itemOffset)  {

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


//------------------------------------------------------------------------
// OrdinalTable::GetOrdinalFromPercent
//------------------------------------------------------------------------
U32 OrdinalTable::GetOrdinalFromPercent(U8 percent)  {

   return ((GetOrdinalCount() * (U32)(min(percent, 100))) / 100L);
}  // end of OrdinalTable::GetOrdinalFromPercent

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

   MemPool::ObliterateTable();
   initialSize = ORDTABLE_INIT_SIZE;
   expandSize  = ORDTABLE_EXPANSION_SIZE;
}

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