631 lines
12 KiB
C++
Executable File
631 lines
12 KiB
C++
Executable File
//-----------------------------------------------------------------------------
|
|
// 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
|
|
//
|
|
// Revision History:
|
|
// rsvcDataStreamer.cc,v
|
|
// Revision 1.1 1998/01/22 17:08:08 akers
|
|
// Addition of new NameServer
|
|
//
|
|
//
|
|
//
|
|
#include "rsvcErr.h"
|
|
#include "rsvcDataStreamer.h"
|
|
|
|
// ******************************************************************
|
|
// float and double conversion routines
|
|
// not portable yet especially for VAX machines
|
|
// ******************************************************************
|
|
static float htonf (float f)
|
|
{
|
|
float fret;
|
|
long *p = (long *)&f;
|
|
long nl = htonl (*p);
|
|
fret = *(float *)&nl;
|
|
return fret;
|
|
}
|
|
|
|
static float ntohf (float f)
|
|
{
|
|
float fret;
|
|
|
|
long *p = (long *)&f;
|
|
long nl = ntohl (*p);
|
|
fret = *(float *)&nl;
|
|
return fret;
|
|
}
|
|
|
|
static double htond (double d)
|
|
{
|
|
long *lp, *lq;
|
|
long *dp, *dq;
|
|
double ret;
|
|
|
|
// move high byte first
|
|
lp = lq = (long *)&d;
|
|
lp++;
|
|
|
|
dp = dq = (long *)&ret;
|
|
*dp = htonl (*lp);
|
|
|
|
lp--; dp++;
|
|
*dp = htonl (*lp);
|
|
|
|
ret = *(double *)dq;
|
|
return ret;
|
|
}
|
|
|
|
static double ntohd (double d)
|
|
{
|
|
long *lp, *lq;
|
|
long *dp, *dq;
|
|
double ret;
|
|
|
|
// low byte of incoming data should be high byte of host native data
|
|
lp = lq = (long *)&d;
|
|
dp = dq = (long *)&ret;
|
|
dp++;
|
|
|
|
*dp = ntohl (*lp);
|
|
|
|
lp++; dp--;
|
|
*dp = ntohl (*lp);
|
|
|
|
ret = *(double *)dq;
|
|
return ret;
|
|
}
|
|
|
|
static rsvc_TS_STAMP htonts (rsvc_TS_STAMP& ts)
|
|
{
|
|
rsvc_TS_STAMP rts;
|
|
|
|
rts.secPastEpoch = htonl (ts.secPastEpoch);
|
|
rts.nsec = htonl (ts.nsec);
|
|
return rts;
|
|
}
|
|
|
|
static rsvc_TS_STAMP ntohts (rsvc_TS_STAMP& ts)
|
|
{
|
|
rsvc_TS_STAMP rts;
|
|
|
|
rts.secPastEpoch = ntohl (ts.secPastEpoch);
|
|
rts.nsec = ntohl (ts.nsec);
|
|
return rts;
|
|
}
|
|
|
|
|
|
rsvcDataStreamer::rsvcDataStreamer (char* buffer, size_t buflen,
|
|
int dealloc)
|
|
:buffer_ (buffer), buflen_ (buflen), dealloc_ (dealloc), pos_ (0),
|
|
err_ (RSVC_SUCCESS)
|
|
{
|
|
#ifdef _TRACE_OBJECTS
|
|
printf ("Create rsvcDataStreamer Class Object\n");
|
|
#endif
|
|
}
|
|
|
|
rsvcDataStreamer::~rsvcDataStreamer (void)
|
|
{
|
|
#ifdef _TRACE_OBJECTS
|
|
printf ("Delete rsvcDataStreamer Class Object\n");
|
|
#endif
|
|
if (dealloc_)
|
|
if (buffer_) {
|
|
delete []buffer_;
|
|
buffer_ = 0;
|
|
}
|
|
}
|
|
|
|
char*
|
|
rsvcDataStreamer::buffer (void) const
|
|
{
|
|
return buffer_;
|
|
}
|
|
|
|
size_t
|
|
rsvcDataStreamer::bufferLength (void) const
|
|
{
|
|
return buflen_;
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamer::streamStatus (void) const
|
|
{
|
|
return err_;
|
|
}
|
|
|
|
|
|
//===============================================================
|
|
// Implementation of rsvcDataStreamWriter
|
|
//===============================================================
|
|
rsvcDataStreamWriter::rsvcDataStreamWriter (char* buffer, size_t size,
|
|
int dealloc)
|
|
:rsvcDataStreamer (buffer, size, dealloc)
|
|
{
|
|
#ifdef _TRACE_OBJECTS
|
|
printf (" Create rsvcDataStreamWriter Class Object\n");
|
|
#endif
|
|
}
|
|
|
|
rsvcDataStreamWriter::~rsvcDataStreamWriter (void)
|
|
{
|
|
#ifdef _TRACE_OBJECTS
|
|
printf (" Delete rsvcDataStreamWriter Class Object\n");
|
|
#endif
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamWriter::write (char c)
|
|
{
|
|
long tmp = (long)c;
|
|
return write (tmp);
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamWriter::write (unsigned char c)
|
|
{
|
|
long tmp = (long)c;
|
|
return write (tmp);
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamWriter::write (short c)
|
|
{
|
|
long tmp = (long)c;
|
|
return write (tmp);
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamWriter::write (unsigned short c)
|
|
{
|
|
long tmp = (long)c;
|
|
return write (tmp);
|
|
}
|
|
|
|
|
|
int
|
|
rsvcDataStreamWriter::write (int c)
|
|
{
|
|
long tmp = (long)c;
|
|
return write (tmp);
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamWriter::write (unsigned int c)
|
|
{
|
|
long tmp = (long)c;
|
|
return write (tmp);
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamWriter::write (long c)
|
|
{
|
|
long tmp = htonl (c);
|
|
if (pos_ + rsvcStreamSize (c) > buflen_) {
|
|
#ifdef _RSVC_DEBUG
|
|
fprintf (stderr, "Fatal Error: write overflow buffer at %d with bufsize %d\n",
|
|
pos_, buflen_);
|
|
#endif
|
|
err_ = RSVC_ERROR;
|
|
return err_;
|
|
}
|
|
memcpy (&(buffer_[pos_]), &tmp, rsvcStreamSize (c));
|
|
pos_ += rsvcStreamSize (c);
|
|
|
|
return RSVC_SUCCESS;
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamWriter::write (unsigned long c)
|
|
{
|
|
long tmp = (long)c;
|
|
return write (tmp);
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamWriter::write (float c)
|
|
{
|
|
float ftmp = htonf (c);
|
|
|
|
if (pos_ + rsvcStreamSize (c) > buflen_) {
|
|
#ifdef _RSVC_DEBUG
|
|
fprintf (stderr, "Fatal Error: write float overflow buffer at %d with bufsize %d\n",
|
|
pos_, buflen_);
|
|
#endif
|
|
err_ = RSVC_ERROR;
|
|
return err_;
|
|
}
|
|
memcpy (&(buffer_[pos_]), &ftmp, rsvcStreamSize (c));
|
|
pos_ += rsvcStreamSize (c);
|
|
|
|
return RSVC_SUCCESS;
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamWriter::write (double c)
|
|
{
|
|
double dtmp = htond (c);
|
|
|
|
if (pos_ + rsvcStreamSize (c) > buflen_) {
|
|
#ifdef _RSVC_DEBUG
|
|
fprintf (stderr, "Fatal Error: write double overflow buffer at %d with bufsize %d\n",
|
|
pos_, buflen_);
|
|
#endif
|
|
err_ = RSVC_ERROR;
|
|
return err_;
|
|
}
|
|
memcpy (&(buffer_[pos_]), &dtmp, rsvcStreamSize (c));
|
|
|
|
pos_ += rsvcStreamSize (c);
|
|
#ifdef _RSVC_DEBUG
|
|
printf ("Write cursor is %d\n", pos_);
|
|
#endif
|
|
return RSVC_SUCCESS;
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamWriter::write (char* str)
|
|
{
|
|
size_t slen = strlen (str) + 1;
|
|
size_t rlen = _RSVC_RNDUP (slen);
|
|
size_t len = sizeof (long) + _RSVC_RNDUP (slen);
|
|
|
|
if (pos_ + len > buflen_) {
|
|
#ifdef _RSVC_DEBUG
|
|
fprintf (stderr, "Fatal Error: write string %s overflow buffer at %d with bufsize %d\n",
|
|
str, pos_, buflen_);
|
|
#endif
|
|
err_ = RSVC_ERROR;
|
|
return err_;
|
|
}
|
|
|
|
// write size of string first
|
|
write ((long)rlen);
|
|
|
|
memcpy (&(buffer_[pos_]), str, slen);
|
|
pos_ += slen;
|
|
|
|
if (rlen > slen)
|
|
memset (&(buffer_[pos_]), 0, rlen - slen);
|
|
pos_ += (rlen - slen);
|
|
|
|
return RSVC_SUCCESS;
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamWriter::write (void* data, size_t len)
|
|
{
|
|
size_t rlen = _RSVC_RNDUP (len);
|
|
size_t wlen = sizeof (long) + rlen;
|
|
|
|
if (pos_ + wlen > buflen_) {
|
|
#ifdef _RSVC_DEBUG
|
|
fprintf (stderr, "Fatal Error: write void * overflow buffer at %d with bufsize %d\n",
|
|
pos_, buflen_);
|
|
#endif
|
|
err_ = RSVC_ERROR;
|
|
return err_;
|
|
}
|
|
|
|
// write out size of data first
|
|
write ((long)rlen);
|
|
|
|
memcpy (&(buffer_[pos_]), data, len);
|
|
pos_ += len;
|
|
|
|
if (rlen > len)
|
|
memset (&(buffer_[pos_]), 0, rlen - len);
|
|
|
|
pos_ += (rlen - len);
|
|
|
|
return RSVC_SUCCESS;
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamWriter::write (rsvc_TS_STAMP& ts)
|
|
{
|
|
rsvc_TS_STAMP tts = htonts (ts);
|
|
|
|
if (pos_ + rsvcStreamSize (ts) > buflen_) {
|
|
#ifdef _RSVC_DEBUG
|
|
fprintf (stderr, "Fatal Error: write TS overflow buffer at %d with bufsize %d\n",
|
|
pos_, buflen_);
|
|
#endif
|
|
err_ = RSVC_ERROR;
|
|
return err_;
|
|
}
|
|
memcpy (&(buffer_[pos_]), &tts, rsvcStreamSize (ts));
|
|
pos_ += rsvcStreamSize (ts);
|
|
|
|
return RSVC_SUCCESS;
|
|
}
|
|
|
|
//===============================================================
|
|
// Implementation of rsvcDataStreamReader
|
|
//===============================================================
|
|
rsvcDataStreamReader::rsvcDataStreamReader (char* buffer, size_t buflen,
|
|
int dealloc)
|
|
:rsvcDataStreamer (buffer, buflen, dealloc)
|
|
{
|
|
#ifdef _TRACE_OBJECTS
|
|
printf (" Create rsvcDataStreamReader Class Object\n");
|
|
#endif
|
|
}
|
|
|
|
rsvcDataStreamReader::~rsvcDataStreamReader (void)
|
|
{
|
|
#ifdef _TRACE_OBJECTS
|
|
printf (" Delete rsvcDataStreamReader Class Object\n");
|
|
#endif
|
|
}
|
|
|
|
|
|
int
|
|
rsvcDataStreamReader::read (char& c)
|
|
{
|
|
long tmp;
|
|
int st;
|
|
|
|
if ((st = read (tmp)) == RSVC_SUCCESS)
|
|
c = (char)tmp;
|
|
else
|
|
c = 0;
|
|
|
|
return st;
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamReader::read (unsigned char& c)
|
|
{
|
|
long tmp;
|
|
int st;
|
|
|
|
if ((st = read (tmp)) == RSVC_SUCCESS)
|
|
c = (unsigned char)tmp;
|
|
else
|
|
c = 0;
|
|
|
|
return st;
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamReader::read (short & c)
|
|
{
|
|
long tmp;
|
|
int st;
|
|
|
|
if ((st = read (tmp)) == RSVC_SUCCESS)
|
|
c = (short)tmp;
|
|
else
|
|
c = 0;
|
|
|
|
return st;
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamReader::read (unsigned short& c)
|
|
{
|
|
long tmp;
|
|
int st;
|
|
|
|
if ((st = read (tmp)) == RSVC_SUCCESS)
|
|
c = (unsigned short)tmp;
|
|
else
|
|
c = 0;
|
|
|
|
return st;
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamReader::read (int& c)
|
|
{
|
|
long tmp;
|
|
int st;
|
|
|
|
if ((st = read (tmp)) == RSVC_SUCCESS)
|
|
c = (int)tmp;
|
|
else
|
|
c = 0;
|
|
|
|
return st;
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamReader::read (unsigned int& c)
|
|
{
|
|
long tmp;
|
|
int st;
|
|
|
|
if ((st = read (tmp)) == RSVC_SUCCESS)
|
|
c = (unsigned int)tmp;
|
|
else
|
|
c = 0;
|
|
|
|
return st;
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamReader::read (long& c)
|
|
{
|
|
long tmp;
|
|
|
|
if (pos_ + sizeof (c) > buflen_) {
|
|
#ifdef _RSVC_DEBUG
|
|
fprintf (stderr, "Fatal Error: read long overflow buffer at %d with bufsize %d\n",
|
|
pos_, buflen_);
|
|
#endif
|
|
err_ = RSVC_ERROR;
|
|
return err_;
|
|
}
|
|
|
|
memcpy (&tmp, &(buffer_[pos_]), sizeof (long));
|
|
pos_ += sizeof (long);
|
|
|
|
c = ntohl (tmp);
|
|
return RSVC_SUCCESS;
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamReader::read (unsigned long& c)
|
|
{
|
|
long tmp;
|
|
int st;
|
|
|
|
if ((st = read (tmp)) == RSVC_SUCCESS)
|
|
c = (unsigned long)tmp;
|
|
else
|
|
c = 0;
|
|
|
|
return st;
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamReader::read (float& c)
|
|
{
|
|
float ftmp;
|
|
|
|
if (pos_ + rsvcStreamSize (c) > buflen_) {
|
|
#ifdef _RSVC_DEBUG
|
|
fprintf (stderr, "Fatal Error: read float overflow buffer at %d with bufsize %d\n",
|
|
pos_, buflen_);
|
|
#endif
|
|
err_ = RSVC_ERROR;
|
|
return err_;
|
|
}
|
|
memcpy (&ftmp, &(buffer_[pos_]), rsvcStreamSize (c));
|
|
pos_ += rsvcStreamSize (c);
|
|
|
|
c = ntohf (ftmp);
|
|
|
|
return RSVC_SUCCESS;
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamReader::read (double& c)
|
|
{
|
|
double dtmp;
|
|
|
|
if (pos_ + rsvcStreamSize (c) > buflen_) {
|
|
#ifdef _RSVC_DEBUG
|
|
fprintf (stderr, "Fatal Error: read double overflow buffer at %d with bufsize %d\n",
|
|
pos_, buflen_);
|
|
#endif
|
|
err_ = RSVC_ERROR;
|
|
return err_;
|
|
}
|
|
memcpy (&dtmp, &(buffer_[pos_]), rsvcStreamSize (c));
|
|
pos_ += rsvcStreamSize (c);
|
|
|
|
c = ntohd (dtmp);
|
|
|
|
return RSVC_SUCCESS;
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamReader::read (rsvc_TS_STAMP & ts)
|
|
{
|
|
rsvc_TS_STAMP tts;
|
|
|
|
if (pos_ + rsvcStreamSize (ts) > buflen_) {
|
|
#ifdef _RSVC_DEBUG
|
|
fprintf (stderr, "Fatal Error: read TS overflow buffer at %d with bufsize %d\n",
|
|
pos_, buflen_);
|
|
#endif
|
|
err_ = RSVC_ERROR;
|
|
return err_;
|
|
}
|
|
memcpy (&tts, &(buffer_[pos_]), rsvcStreamSize (ts));
|
|
pos_ += rsvcStreamSize (ts);
|
|
|
|
ts = ntohts (tts);
|
|
return RSVC_SUCCESS;
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamReader::read (char* & str)
|
|
{
|
|
long str_size = 0;
|
|
int st = RSVC_SUCCESS;
|
|
|
|
if (pos_ + sizeof (long) > buflen_) {
|
|
#ifdef _RSVC_DEBUG
|
|
fprintf (stderr, "Fatal Error: read string header overflow buffer at %d with bufsize %d\n",
|
|
pos_, buflen_);
|
|
#endif
|
|
st = err_ = RSVC_ERROR;
|
|
return err_;
|
|
}
|
|
|
|
if ((st = read (str_size)) == RSVC_SUCCESS) {
|
|
if (pos_ + str_size > buflen_) {
|
|
#ifdef _RSVC_DEBUG
|
|
fprintf (stderr, "Fatal Error: read string overflow buffer at %d with bufsize %d\n",
|
|
pos_, buflen_);
|
|
#endif
|
|
err_ = RSVC_ERROR;
|
|
return err_;
|
|
}
|
|
|
|
if (str_size > 0) {
|
|
str = new char[str_size];
|
|
memcpy (str, &(buffer_[pos_]), (unsigned int)str_size);
|
|
pos_ += (int)str_size;
|
|
}
|
|
else {
|
|
str = 0;
|
|
err_ = st = RSVC_ERROR;
|
|
}
|
|
}
|
|
else {
|
|
str = 0;
|
|
st = err_ = RSVC_ERROR;
|
|
}
|
|
return st;
|
|
}
|
|
|
|
int
|
|
rsvcDataStreamReader::read (void* data, size_t size)
|
|
{
|
|
long data_size = 0;
|
|
int st = RSVC_SUCCESS;
|
|
|
|
if (pos_ + sizeof (long) > buflen_) {
|
|
#ifdef _RSVC_DEBUG
|
|
fprintf (stderr, "Fatal Error: read void * header overflow buffer at %d with bufsize %d\n",
|
|
pos_, buflen_);
|
|
#endif
|
|
st = err_ = RSVC_ERROR;
|
|
return err_;
|
|
}
|
|
|
|
if ((st = read (data_size)) == RSVC_SUCCESS) {
|
|
if (pos_ + data_size > buflen_) {
|
|
#ifdef _RSVC_DEBUG
|
|
fprintf (stderr, "Fatal Error: read void * overflow buffer at %d with bufsize %d\n",
|
|
pos_, buflen_);
|
|
#endif
|
|
st = err_ = RSVC_ERROR;
|
|
return err_;
|
|
}
|
|
if (data_size > 0) {
|
|
memcpy (data, &(buffer_[pos_]), size);
|
|
pos_ += (int)data_size;
|
|
}
|
|
else
|
|
st = err_ = RSVC_ERROR;
|
|
}
|
|
return st;
|
|
}
|
|
|
|
|