/****************************************************************************
**
**  Name:  DARRAY.CPP
**
**  Description:
**     Contains the template DArray class definitions.
**
**  $Log:   S:/tbird/mt2_186/omf86/darray.cpv  $
** 
**    Rev 1.0   26 Feb 1997 11:40:34   Judy
** Initial revision.
** 
**    Rev 1.0   14 Jun 1996 16:36:48   Judy
** Initial revision.
** 
**    Rev 1.1   13 Apr 1995 08:55:28   nghia
** Revised DArray() constructor to clear memory buffer to NULL.
** 
**    Rev 1.0   07 Apr 1995 09:17:48   nghia
** Initial revision.
**
**  $Header:   S:/tbird/mt2_186/omf86/darray.cpv   1.0   26 Feb 1997 11:40:34   Judy  $
**
**  Copyright (C) 1994 Microtek International.  All rights reserved.
**
*****************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#ifndef __DARRAY_H
#include "darray.h"
#endif

                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *     LOCAL PROTOTYPES     *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *      EXECUTABLE CODE     *
                        *                          *
                        ****************************/
//-----------------------------------------------------------------------------
// Ctor DArray
//
// Purpose: default constructor - initializes the instances of DArray
// using default size.
//
//-----------------------------------------------------------------------------
template<class T>
DArray<T>::DArray() {
   // initialize data members
   memset(this, NULL, sizeof(*this));
   arrayPtr = new T[arraySize = DEFAULT_ARRAY_SIZE];
   memset(arrayPtr, NULL, (sizeof(T)*arraySize));
   LastError = (arrayPtr != NULL) ? GOOD : ER_NO_MEMORY;        
}

//-----------------------------------------------------------------------------
// Ctor DArray
//
// Purpose: initializes the instances of DArray.  Prepare DArray for
// storing <maxIndex> of elements
//
//-----------------------------------------------------------------------------
template<class T>
DArray<T>::DArray(U16 size = DEFAULT_ARRAY_SIZE) {
   
   // initialize data members
   memset(this, NULL, sizeof(*this));
   // make sure we can hold at least 1 element
   arraySize = (size) ? size : 1;  
   // allocate arrayPtr and clear it
   arrayPtr = new T[arraySize];
   memset(arrayPtr, NULL, (sizeof(T)*arraySize));
   LastError = (arrayPtr != NULL) ? GOOD : ER_NO_MEMORY;
}

//-----------------------------------------------------------------------------
// Ctor DArray
//
// Purpose: copy the instances of DArray.
//
//-----------------------------------------------------------------------------
template<class T>
DArray<T>::DArray(DArray<T>& srcArray) {
   LastError = Copy(srcArray);
}

//-----------------------------------------------------------------------------
// Dtor ~DArray
//
// Purpose: destructor - destroy the instances of DArray.
//
//-----------------------------------------------------------------------------
template<class T>
DArray<T>::~DArray() {
   // deallocate the <arrayPtr>
   if (arrayPtr != NULL)
      delete [] arrayPtr;
   memset(this, NULL, sizeof(*this));
}

//-----------------------------------------------------------------------------
// Grow
//
// Purpose: grow the current arraySize of this object to the specified size. 
// Parameter:
//    newSize - new array size for this object.
//
//-----------------------------------------------------------------------------
template<class T>
RETCODE DArray<T>::Grow(U16 newSize) {
   T* tmpPtr;

   if (newSize < arraySize)
      return GOOD;  // do not reduce the size
   // Cannot allocate more than MAX_ARRAY_SIZE
   if (newSize >= MAX_ARRAY_SIZE)
      return ER_NO_MEMORY;
   // Allocate the space for the new array
   if ((tmpPtr = new T[newSize]) == NULL)
      return ER_NO_MEMORY;
   // Clear memory
   memset(tmpPtr, NULL, (sizeof(T)*newSize));
   
   // copy data if current array has data
   if (arrayPtr != NULL) {
      // copy arrayPtr in members
      for (U16 i = 0; i < arraySize; i++)
        *(tmpPtr + i) = *(arrayPtr + i);
      // destroy the old array
      delete [] arrayPtr;
    }
    // assign pointer tmpPtr to pointer arrayPtr
    arrayPtr = tmpPtr;
    // update the arraySize to the newSize
    arraySize = newSize;
    return GOOD;
}

//-----------------------------------------------------------------------------
// Insert
//
// Purpose: store the input <T> object into self. 
// Parameter:
//    obj - <T> object.
//
//-----------------------------------------------------------------------------
template<class T>
RETCODE DArray<T>::Insert(T& obj) {
   // check for available space in self to insert
   if (availIndex+1 == arraySize)
      return ER_NO_MEMORY;
   // insert <T> object into arrayPtr[]
   arrayPtr[availIndex++] = obj;
   return GOOD;
}

//-----------------------------------------------------------------------------
// operator []
//
// Purpose: return the <T> object at self[index]. 
// Parameter:
//    index - index of <T> object.
//
//-----------------------------------------------------------------------------
template<class T>
T& DArray<T>::operator[](const U16 index) {
  
   if (index < arraySize) 
      return *(arrayPtr + index);
   // index out of bounds
   LastError = ER_INDEX_OUT_OF_BOUNDS;
   return BadIndex;
}

//-----------------------------------------------------------------------------
// operator =
//
// Purpose: assign a DArray<T> object to this object. 
// Parameter:
//    array - the DArray<T> object to be assigned.
//
//-----------------------------------------------------------------------------
template<class T>
DArray<T>& DArray<T>::operator=(DArray<T>& array) {
   LastError = Copy(array);
   return *this;
}

//-----------------------------------------------------------------------------
// Copy
//
// Purpose: copy a DArray object to self.  Caller must make sure that all
//  elements <T> stored in this object is OK to be overwritten.
//     
// Parameter:
//    srcArray - source DArray<T> object.
//
//-----------------------------------------------------------------------------
template<class T>
RETCODE DArray<T>::Copy(DArray<T>& srcArray) {
  T *p, *q;
  
  // destroy this arrayPtr
  delete [] arrayPtr;
  arraySize = srcArray.arraySize;
  availIndex = srcArray.availIndex;
  // Allocate new arrayPtr for this object
  if ((arrayPtr = new T[arraySize]) == NULL)
     return ER_NO_MEMORY;
  // clear memory
  memset(arrayPtr, NULL, (sizeof(T)*arraySize));
  // copy all T objects over
  p = arrayPtr;
  q = srcArray.arrayPtr;
  for (U16 i = 0; i < arraySize; i++, p++, q++)
    *p = *q;
  return GOOD;
}

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