//-----------------------------------------------------------------------------
// 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:
//      General cdev callback class
//
// Author:  Jie Chen
//
// Revision History:
//   cdevCallback.cc,v
// Revision 1.6  1997/03/03  17:35:33  chen
// add buffering to channel access connection
//
// Revision 1.5  1996/12/18  13:32:27  akers
// Added support for incomplete transactions and fireCallback method
//
// Revision 1.3  1995/10/16  17:43:19  chen
// fix a bug for SunOs gcc
//
// Revision 1.2  1995/09/05  17:18:32  chen
// add freelist and overload new/delete
//
// Revision 1.1.1.1  1995/06/16  17:14:09  epics
// initial import of cdev
//
//
#include <stdlib.h>
#include "cdevCallback.h"

// The static incomplete_ integer
int cdevCallback::incomplete_ = 0;

// the static free list header
cdevCallback *cdevCallback::newlist=0;

cdevCallback::cdevCallback(void)
  :function_(0), userarg_(0)
{
#ifdef _TRACE_OBJECTS
  printf("Create cdevCallback class object\n");
#endif
  // empty
}

cdevCallback::cdevCallback(cdevCallbackFunction func, void *userarg)
  :function_(func), userarg_(userarg)
{
#ifdef _TRACE_OBJECTS
  printf("Create cdevCallback class object\n");
#endif
  // empty
}

cdevCallback::cdevCallback(const cdevCallback &callback)
  :function_(callback.function_), userarg_(callback.userarg_)
{
#ifdef _TRACE_OBJECTS
  printf("Create cdevCallback class object\n");
#endif
  // empty
}

cdevCallback &cdevCallback::operator=(const cdevCallback &callback)
{
  if(this != &callback)
    {
      function_=callback.function_;
      userarg_=callback.userarg_;
    }
  return *this;
}

cdevCallback::~cdevCallback(void)
{
#ifdef _TRACE_OBJECTS
  printf("Delete cdevCallback class object\n");
#endif
  function_=0;
  // who release this memory
  userarg_=0;
}

cdevCallbackFunction
cdevCallback::callbackFunction(void) const
{
  return function_;
}

void *cdevCallback::userarg(void) const
{
  return userarg_;
}

int
cdevCallback::operator == (const cdevCallback &callback)
{
  if(function_ == callback.function_ && userarg_ == callback.userarg_)
    return 1;
  return 0;
}

int
cdevCallback::operator != (const cdevCallback &callback)
{
  return !operator == (callback);
}

void *cdevCallback::operator new(size_t size)
{
  if(size != sizeof(cdevCallback))
    {
      // This check is crutial for cases when class
      // derivation is used and the derived class
      // has no operator new. 
      // Operator delete will field this over-sized block
      // when it is reclaimed.
      return malloc(size);
    }
  else if((cdevCallback::newlist) == 0)
    {
      // allocate and link
#ifdef _CDEV_DEBUG
      printf("Allocate 100 cdevCallbacks \n");
#endif
      cdevCallback::newlist=(cdevCallback *) new char[100*sizeof(cdevCallback)];
      int i;
      // some compiler do not like to put decleration inside
      // for loop --jie chen Oct 16 1995
      for(i=0; i < 99; i++)
	{
	  cdevCallback::newlist[i].freePtr= &(cdevCallback::newlist[i+1]);
	}
      cdevCallback::newlist[i].freePtr=0;
    }
#ifdef _CDEV_DEBUG
  printf("Get a new cdevCallback from the newList\n");
#endif
  cdevCallback *savenew=cdevCallback::newlist;
  // move the pointer to the next available block
  cdevCallback::newlist=cdevCallback::newlist->freePtr;
  return savenew;
}

void
cdevCallback::operator delete(void *p, size_t size)
{
  if(size != sizeof(cdevCallback))
    {
      // See comments inside new operator
      free(p);
    }
  else
    {
#ifdef _CDEV_DEBUG
      printf("Put a cdevCallback onto the FreeList\n");
#endif
      cdevCallback *s=(cdevCallback *) p;
      // put this piece of memory back onto the head of the list
      s->freePtr=cdevCallback::newlist;
      cdevCallback::newlist=s;
    }
}


