//-----------------------------------------------------------------------------
// Copyright (c) 1994,1995 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:
//      CDEV Skeleton request object
//
// Author:  Jie Chen
//
// Revision History:
//   skRequestObject.cc,v
// Revision 1.3  1996/01/05  18:41:28  chen
// Fix a potential bug for GCC
//
// Revision 1.2  1995/07/22  22:58:59  watson
// var1,var2 version
//
// Revision 1.1  1995/07/22  20:20:08  watson
// add skeleton service
//
//
#include <cdevTranObj.h>
#include <cdevGroup.h>
#include <cdevDirectory.h>
#include "skService.h"
#include "skRequestObject.h"

skRequestObject::skRequestObject (char *device, char *msg, cdevSystem& system)
:cdevRequestObject (device, msg, system)
{
#ifdef _TRACE_OBJECTS
  printf ("    Create skRequestObject class\n");
#endif
  int status = findSvcData(device, msg, system, index_);
  status = skRequestObject::findAction (msg, action_);
}

skRequestObject::~skRequestObject (void)
{
#ifdef _TRACE_OBJECTS
  printf ("    Destroy skRequestObject class\n");
#endif
}

int
skRequestObject::findSvcData (char *device,
			      char *msg,
			      cdevSystem& system,
			      int& index)
{
  char message[256], fullname[128];

  if (system.prefix())
    ::sprintf (fullname, "%s%s",system.prefix(),device);
  else
    ::strcpy (fullname, device);

  ::sprintf (message,"resolveServiceData %s %s", fullname, msg);

  cdevData result;
  int status = (system.nameServer()).send (message, 0, result);
  if (status == CDEV_SUCCESS){
    status = result.get (skService::SK_TAG_XYZ, &index);
#ifdef _CDEV_DEBUG
    printf("Service data is %i\n",index);
#endif
    return status;
  }
  else
    return CDEV_ERROR;
}


int
skRequestObject::findAction (char *msg, int& action)
{
  char token0[32];

#ifdef __GNUC__
  // some version of gcc demand memory location for char string
  char buffer[256];
  ::strncpy (buffer, msg, sizeof (buffer));
  int status = ::sscanf (buffer, "%s", token0);
#else
  int status = ::sscanf (msg, "%s", token0);
#endif
  if (status == 1){
    if (::strcmp (token0, "get") == 0)
      action = skRequestObject::GET;
    else if (::strcmp (token0, "set") == 0)
      action = skRequestObject::SET;
    else
      action = skRequestObject::UNKNOWN;
  }
  else
    action = skRequestObject::UNKNOWN;    
  return 0;
}

int
skRequestObject::send (cdevData& out, cdevData& result)
{
  return send (&out, &result);
}

int
skRequestObject::send (cdevData& out, cdevData* result)
{
  return send (&out, result);
}

int
skRequestObject::send (cdevData* out, cdevData& result)
{
  return send (out, &result);
}

int
skRequestObject::send (cdevData* out, cdevData* result)
{
  switch (action_){
  case GET:
    if (!result)
      return CDEV_ERROR;
    if (index_ == 1)
      result->insert (skService::SK_TAG_VALUE, 
		    ((skService *)service_)->var1);
    else if (index_ == 2)
      result->insert (skService::SK_TAG_VALUE, 
		    ((skService *)service_)->var2);
    else
      result->insert (skService::SK_TAG_VALUE, 
		      0 );
    break;
  case SET:
    if (!out)
      return CDEV_ERROR;
    {
      int tmp;
      if (out->get (skService::SK_TAG_VALUE, &tmp) != CDEV_SUCCESS)
	return CDEV_ERROR;
      if (index_ == 1) 
	((skService *)service_)->var1 = tmp;
      else if (index_ == 2) 
	((skService *)service_)->var2 = tmp;
    }
    break;
  default:
    return CDEV_ERROR;
  }
  return CDEV_SUCCESS;
}

int
skRequestObject::sendNoBlock (cdevData& data, cdevData& result)
{
  return sendNoBlock (&data, &result);
}

int
skRequestObject::sendNoBlock (cdevData& data, cdevData* result)
{
  return sendNoBlock (&data, result);
}

int
skRequestObject::sendNoBlock (cdevData* data, cdevData& result)
{
  return sendNoBlock (data, &result);
}

int
skRequestObject::sendNoBlock (cdevData* data, cdevData* result)
{
  int status = send (data, result);
  return status;
}

int
skRequestObject::sendCallback (cdevData& data, cdevCallback& callback)
{
  return sendCallback (&data, callback);
}

int
skRequestObject::sendCallback (cdevData* data, cdevCallback& callback)
{
  cdevData result;
  int status = send (data, result);
  (*callback.callbackFunction ())(status, callback.userarg (),
				  *this, result);
  return status;
}




