/****************************************************************************/
/* Copyright (c) 2000 MBARI                                                 */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
/* Summary  :                                                               */
/* Filename : ExternalMessage.cc                                            */
/* Author   :                                                               */
/* Project  :                                                               */
/* Version  : 1.0                                                           */
/* Created  : 02/07/2000                                                    */
/* Modified :                                                               */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include "ExternalMessage.h"
#include "Syslog.h"

const char *ExternalMessage::_delimiter = "$";
const char *ExternalMessage::_messageCodeFormat = "%05d";


ExternalMessage::ExternalMessage(size_t maxBytes)
{
  _bufferSize = maxBytes;

  if ((_buffer = (char *)malloc(_bufferSize)) == 0) {
    Syslog::write("ExternalMessage::ExternalMessage() - "
		  "malloc() of _buffer failed\n");

    exit(1);
  }


  if ((_buffer2 = (char *)malloc(_bufferSize)) == 0) {
    Syslog::write("ExternalMessage::ExternalMessage() - "
		  "malloc() of _buffer2 failed\n");

    exit(1);
  }

  setMessageCode(UnknownCode);
}


ExternalMessage::~ExternalMessage()
{
  free((void *)_buffer);
  free((void *)_buffer2);
}


ExternalMessage::MessageCode ExternalMessage::messageCode()
{
  return _messageCode;
}


int ExternalMessage::read(int socket)
{
  memset(_buffer, 0, _bufferSize);
  int status = ::read(socket, _buffer, _bufferSize);

  if (status <= 0)
    return status;

  // Parse buffer for message code
  _messageCode = (MessageCode )atoi(_buffer);

  return status;
}


int ExternalMessage::write(int socket, int nBytes)
{
  return ::write(socket, _buffer, nBytes);
}


void ExternalMessage::setMessageCode(MessageCode code)
{
  sprintf(_buffer, _messageCodeFormat, code);
  strcat(_buffer, _delimiter);
}


const char *ExternalMessage::token(unsigned tokenNo)
{
  strncpy(_buffer2, _buffer, sizeof(_bufferSize));

  // Parse task index
  char *ptr = _buffer2;
  char *token;
  int nTokens = 0;

  while ((token = strtok(ptr, _delimiter)) != 0) {
    ptr = 0;

    if (nTokens == tokenNo)
      return token;

    nTokens++;
  }

  // Couldn't find token
  throw TokenNotFound(tokenNo);
}


void ExternalMessage::addToken(const char *token)
{
  strcat(_buffer, token);
  strcat(_buffer, _delimiter);
}



ExternalMethodMessage::ExternalMethodMessage(size_t maxBytes)
  : ExternalMessage(maxBytes)
{
  setMessageCode(InvokeTaskMethod);
}


ExternalMethodMessage::~ExternalMethodMessage()
{
}


int ExternalMethodMessage::taskIndex()
{
  return atoi(token(TaskIndexToken));
}


int ExternalMethodMessage::requestCode()
{
  return atoi(token(RequestCodeToken));
}


size_t ExternalMethodMessage::size()
{
  return 0;
}


SubscriptionMessage::SubscriptionMessage(size_t maxBytes)
  : ExternalMethodMessage(maxBytes)
{
}


SubscriptionMessage::~SubscriptionMessage()
{
}


int SubscriptionMessage::eventCode()
{
  return atoi(token(EventCodeToken));
}








