//-----------------------------------------------------------------------------
// 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:
//      rsvc data streamer class
//
// Author:  Jie Chen
//
//
//
#ifndef _RSVC_DATA_STREAMER
#define _RSVC_DATA_STREAMER

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#ifdef _WIN32
	#include <WinSock2.h>
#else
	#include <sys/socket.h>
	#include <netinet/in.h>
#endif

#include <rsvcDataTypes.h>

#define _RSVC_STREAM_BYTE_UNIT      (sizeof (long))

inline int _RSVC_RNDUP (size_t x)
{
  return ((x + _RSVC_STREAM_BYTE_UNIT - 1) / _RSVC_STREAM_BYTE_UNIT) 
    * _RSVC_STREAM_BYTE_UNIT;
}

inline size_t rsvcStreamSize (char c)
{
  return _RSVC_RNDUP (sizeof (c));
}

inline size_t rsvcStreamSize (unsigned char c)
{
  return _RSVC_RNDUP (sizeof (c));
}

inline size_t rsvcStreamSize (short c)
{
  return _RSVC_RNDUP (sizeof (c));
}

inline size_t rsvcStreamSize (unsigned short c)
{
  return _RSVC_RNDUP (sizeof (c));
}

inline size_t rsvcStreamSize (int c)
{
  return _RSVC_RNDUP (sizeof (c));
}

inline size_t rsvcStreamSize (unsigned int c)
{
  return _RSVC_RNDUP (sizeof (c));
}

inline size_t rsvcStreamSize (long c)
{
  return sizeof (c);
}

inline size_t rsvcStreamSize (unsigned long c)
{
  return sizeof (c);
}

inline size_t rsvcStreamSize (float c)
{
  return sizeof (c);
}

inline size_t rsvcStreamSize (double c)
{
  return sizeof (c);
}

inline size_t rsvcStreamSize (char* str)
{
  return sizeof (long) + _RSVC_RNDUP (strlen (str) + 1);
}

inline size_t rsvcStreamSize (void*, size_t size)
{
  return sizeof (long) + _RSVC_RNDUP (size);
}

inline size_t rsvcStreamSize (rsvc_TS_STAMP& ts)
{
  return sizeof (ts);
}

class rsvcDataStreamer
{
public:
  // destructor
  virtual ~rsvcDataStreamer (void);

  char*       buffer        (void) const;
  size_t      bufferLength  (void) const;

  int         streamStatus  (void) const;

protected:
  // constructor
  // attach to a stream buffer.
  // dealloc == 1 free buffer in the detrcutor.
  rsvcDataStreamer          (char* buffer, size_t buflen, int dealloc = 1);

  // binray stream buffer
  char*       buffer_;
  size_t      buflen_;

  // free memory stratege
  int         dealloc_;

  // index pointing to current position
  int         pos_;

  // streaming status
  int         err_;
};

class rsvcDataStreamWriter : public rsvcDataStreamer
{
public:
  // constructor and destrcutor
  rsvcDataStreamWriter  (char* buffer, size_t buflen, int dealloc = 1);
  ~rsvcDataStreamWriter (void);

  // operations
  int         write (char c);
  int         write (unsigned char c);
  int         write (short c);
  int         write (unsigned short c);
  int         write (int c);
  int         write (unsigned int c);
  int         write (long c);
  int         write (unsigned long c);  
  int         write (float c);
  int         write (double c);
  int         write (char* str);
  int         write (void* data, size_t size);
  int         write (rsvc_TS_STAMP& ts);
};

class rsvcDataStreamReader : public rsvcDataStreamer
{
public:
  // constructor and destrcutor
  rsvcDataStreamReader  (char* buffer, size_t buflen, int dealloc = 1);
  ~rsvcDataStreamReader (void);

  // operations
  int         read (char& c);
  int         read (unsigned char& c);
  int         read (short& c);
  int         read (unsigned short& c);
  int         read (int& c);
  int         read (unsigned int& c);
  int         read (long& c);
  int         read (unsigned long& c);  
  int         read (float& c);
  int         read (double& c);
  int         read (char* &str);
  int         read (void* data, size_t size);
  int         read (rsvc_TS_STAMP& ts);
};

#endif
