//------------------------------------------------------------------------------
// Copyright (c) 1991,1992 Southeastern Universities Research Association,
//                         Continuous Electron Beam Accelerator Facility
//
// This software was developed under a United States Government license
// described in the NOTICE file included as part of this distribution.
//------------------------------------------------------------------------------
//
// description: rcsDataEntry.cc
//	This file contains the non-inlined functions associated with the
// 	rsvcDataEntry family of classes.
//
// Author: Walt Akers
//
// Revision History:
//   rsvcDataEntry.cc,v
// Revision 1.1  1998/01/22  17:08:05  akers
// Addition of new NameServer
//
//
//                               
//------------------------------------------------------------------------------
#include "rsvcDataEntry.h"


// *****************************************************************************
// * rsvcDataEntryeStorage::operator ==:
// *	This operator allows you to directly and rapidly compare two 
// *	rsvcDataEntryStorage objects...
// *****************************************************************************
int rsvcDataEntryStorage::operator == (rsvcDataEntryStorage & entry)
{
  int result = 0;
  int i      = 0;
	
  // *********************************************************************
  // * First compare all of the pertinent scalar values...
  // *********************************************************************
  if(strcmp (tag_,  entry.tag_) == 0  &&
     dataType_ == entry.dataType_ &&
     dim_      == entry.dim_      &&
     elems_    == entry.elems_)
    {
      // *************************************************************
      // * Next compare the contents of the data items...
      // *************************************************************
      if(dim_) 
	{
	  result = 0;
	  if(dataType_==RSVC_BYTE)
	    for(i=0; i<elems_ && !result; i++)
	      result=!(data_.cptr[i]==entry.data_.cptr[i]);
	  else if(dataType_==RSVC_INT16)
	    for(i=0; i<elems_ && !result; i++)
	      result=!(data_.sptr[i]==entry.data_.sptr[i]);
	  else if(dataType_==RSVC_UINT16)
	    for(i=0; i<elems_ && !result; i++)
	      result=!(data_.usptr[i]==entry.data_.usptr[i]);
	  else if(dataType_==RSVC_INT32)
	    for(i=0; i<elems_ && !result; i++)
	      result=!(data_.lptr[i]==entry.data_.lptr[i]);
	  else if(dataType_==RSVC_UINT32)
	    for(i=0; i<elems_ && !result; i++)
	      result=!(data_.ulptr[i]==entry.data_.ulptr[i]);
	  else if(dataType_==RSVC_FLOAT)
	    for(i=0; i<elems_ && !result; i++)
	      result=!(data_.fptr[i]==entry.data_.fptr[i]);
	  else if(dataType_==RSVC_DOUBLE)
	    for(i=0; i<elems_ && !result; i++)
	      result=!(data_.dptr[i]==entry.data_.dptr[i]);
	  else if(dataType_==RSVC_STRING)
	    for(i=0; i<elems_ && !result; i++)
	      result=strcmp(data_.strarr[i], entry.data_.strarr[i]);
	  else if(dataType_==RSVC_TIMESTAMP)
	    for(i=0; i<elems_ && !result; i++)
	      result=!((data_.tsptr[i].nsec==entry.data_.tsptr[i].nsec) && 
		       (data_.tsptr[i].secPastEpoch==entry.data_.tsptr[i].secPastEpoch));
	}
      else if(dataType_==RSVC_BYTE)      result=!(data_.cval==entry.data_.cval);
      else if(dataType_==RSVC_INT16)     result=!(data_.sval==entry.data_.sval);
      else if(dataType_==RSVC_UINT16)    result=!(data_.usval==entry.data_.usval);
      else if(dataType_==RSVC_INT32)     result=!(data_.lval==entry.data_.lval);
      else if(dataType_==RSVC_UINT32)    result=!(data_.ulval==entry.data_.ulval);
      else if(dataType_==RSVC_FLOAT)     result=!(data_.fval==entry.data_.fval);
      else if(dataType_==RSVC_DOUBLE)    result=!(data_.dval==entry.data_.dval);
      else if(dataType_==RSVC_STRING)    result=strcmp(data_.str, entry.data_.str);
      else if(dataType_==RSVC_TIMESTAMP) result=!((data_.ts.nsec==entry.data_.ts.nsec) && 
						  (data_.ts.secPastEpoch==entry.data_.ts.secPastEpoch));
      else result = memcmp(&data_, &entry.data_, sizeof(data_));
    } 
  else result = -1;
  return !result;
}

rsvcDataEntry::rsvcDataEntry (const rsvcDataEntry& entry)
{
  dataType_ = entry.dataType_;
  dim_ = entry.dim_;
  elems_ = entry.elems_;
  bytes_ = entry.bytes_;
  size_ = entry.size_;
  strcpy (tag_, entry.tag_);
  buffer_ = 0;
  next_ = 0;

  if (dim_ > 0) {
    // allocate memory
    allocate (entry.dim_, entry.elems_, entry.bytes_);
    // copy memory
    memcpy (buffer_, entry.buffer_, size_);
  }
  else 
    memcpy (&data_, &entry.data_, sizeof (data_));
}

rsvcDataEntry &
rsvcDataEntry::operator = (const rsvcDataEntry& entry)
{
  if (this != &entry) {
    clear ();

    dataType_ = entry.dataType_;
    dim_ = entry.dim_;
    elems_ = entry.elems_;
    bytes_ = entry.bytes_;
    size_ = entry.size_;
    strcpy (tag_, entry.tag_);
    buffer_ = 0;

    if (dim_ > 0 || (dim_ == 0 && dataType_ == RSVC_STRING)) {
      // allocate memory
      allocate (entry.dim_, entry.elems_, entry.bytes_);
      // copy memory
      memcpy (buffer_, entry.buffer_, size_);
    }
    else 
      memcpy (&data_, &entry.data_, sizeof (data_));
  }
  return *this;
}
    

// *****************************************************************************
// * Global initialization of the static freeList_ member of the 
// * rsvcDataEntry class.
// *****************************************************************************
rsvcDataEntry * rsvcDataEntry::freeList_ = NULL;

// *****************************************************************************
// * new:
// * Allocation function for the object.  It will get the next preallocated 
// * rsvcDataEntry object from the freeList_, or, if none are available, 
// * refill the freeList_ and then return a new rsvcDataEntry object.
// *****************************************************************************
void * rsvcDataEntry::operator new ( size_t )
{
  rsvcDataEntry * result = NULL;
	
  if(freeList_==NULL)
    {
      freeList_ = ::new rsvcDataEntry[ALLOCATION_COUNT];
      for(int i=0; i<ALLOCATION_COUNT; i++) {
	freeList_[i].next_ = (i<(ALLOCATION_COUNT-1))?&freeList_[i+1]:(rsvcDataEntry *)NULL;
      }
    }
  
  if(freeList_!=NULL) {
    result = freeList_;
    freeList_ = result->next_;
  }

  return result;
}
