185 lines
6.2 KiB
C++
185 lines
6.2 KiB
C++
/*************************************************************************\
|
|
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
|
* National Laboratory.
|
|
* Copyright (c) 2002 The Regents of the University of California, as
|
|
* Operator of Los Alamos National Laboratory.
|
|
* EPICS BASE Versions 3.13.7
|
|
* and higher are distributed subject to a Software License Agreement found
|
|
* in file LICENSE that is included with this distribution.
|
|
\*************************************************************************/
|
|
|
|
/*
|
|
* $Id$
|
|
*
|
|
*
|
|
* L O S A L A M O S
|
|
* Los Alamos National Laboratory
|
|
* Los Alamos, New Mexico 87545
|
|
*
|
|
* Copyright, 1986, The Regents of the University of California.
|
|
*
|
|
*
|
|
* Author Jeffrey O. Hill
|
|
* johill@lanl.gov
|
|
* 505 665 1831
|
|
*/
|
|
|
|
#ifndef comQueRecvh
|
|
#define comQueRecvh
|
|
|
|
#include "comBuf.h"
|
|
|
|
class comQueRecv {
|
|
public:
|
|
comQueRecv ( comBufMemoryManager & ) epics_throws (());
|
|
~comQueRecv () epics_throws (());
|
|
unsigned occupiedBytes () const epics_throws (());
|
|
unsigned copyOutBytes ( epicsInt8 *pBuf, unsigned nBytes ) epics_throws (());
|
|
unsigned removeBytes ( unsigned nBytes ) epics_throws (());
|
|
void pushLastComBufReceived ( comBuf & ) epics_throws (());
|
|
void clear () epics_throws (());
|
|
epicsInt8 popInt8 () epics_throws (( comBuf::insufficentBytesAvailable ));
|
|
epicsUInt8 popUInt8 () epics_throws (( comBuf::insufficentBytesAvailable ));
|
|
epicsInt16 popInt16 () epics_throws (( comBuf::insufficentBytesAvailable ));
|
|
epicsUInt16 popUInt16 () epics_throws (( comBuf::insufficentBytesAvailable ));
|
|
epicsInt32 popInt32 () epics_throws (( comBuf::insufficentBytesAvailable ));
|
|
epicsUInt32 popUInt32 () epics_throws (( comBuf::insufficentBytesAvailable ));
|
|
epicsFloat32 popFloat32 () epics_throws (( comBuf::insufficentBytesAvailable ));
|
|
epicsFloat64 popFloat64 () epics_throws (( comBuf::insufficentBytesAvailable ));
|
|
void popString ( epicsOldString * ) epics_throws (( comBuf::insufficentBytesAvailable ));
|
|
private:
|
|
tsDLList < comBuf > bufs;
|
|
comBufMemoryManager & comBufMemMgr;
|
|
unsigned nBytesPending;
|
|
epicsUInt16 multiBufferPopUInt16 () epics_throws (( comBuf::insufficentBytesAvailable ));
|
|
epicsUInt32 multiBufferPopUInt32 () epics_throws (( comBuf::insufficentBytesAvailable ));
|
|
void removeAndDestroyBuf ( comBuf & ) epics_throws (());
|
|
comQueRecv ( const comQueRecv & ) epics_throws (());
|
|
comQueRecv & operator = ( const comQueRecv & ) epics_throws (());
|
|
};
|
|
|
|
inline unsigned comQueRecv::occupiedBytes () const
|
|
epics_throws (())
|
|
{
|
|
return this->nBytesPending;
|
|
}
|
|
|
|
inline epicsInt8 comQueRecv::popInt8 ()
|
|
epics_throws (( comBuf::insufficentBytesAvailable ))
|
|
{
|
|
return static_cast < epicsInt8 > ( this->popUInt8() );
|
|
}
|
|
|
|
inline epicsInt16 comQueRecv::popInt16 ()
|
|
epics_throws (( comBuf::insufficentBytesAvailable ))
|
|
{
|
|
return static_cast < epicsInt16 > ( this->popInt8() << 8u
|
|
| this->popInt8() << 0u );
|
|
}
|
|
|
|
inline epicsInt32 comQueRecv::popInt32 ()
|
|
epics_throws (( comBuf::insufficentBytesAvailable ))
|
|
{
|
|
epicsInt32 tmp ;
|
|
tmp = this->popInt8() << 24u;
|
|
tmp |= this->popInt8() << 16u;
|
|
tmp |= this->popInt8() << 8u;
|
|
tmp |= this->popInt8() << 0u;
|
|
return tmp;
|
|
}
|
|
|
|
inline epicsFloat32 comQueRecv::popFloat32 ()
|
|
epics_throws (( comBuf::insufficentBytesAvailable ))
|
|
{
|
|
epicsFloat32 tmp;
|
|
epicsUInt8 wire[ sizeof ( tmp ) ];
|
|
// optimizer will unroll this loop
|
|
for ( unsigned i = 0u; i < sizeof ( tmp ); i++ ) {
|
|
wire[i] = this->popUInt8 ();
|
|
}
|
|
osiConvertFromWireFormat ( tmp, wire );
|
|
return tmp;
|
|
}
|
|
|
|
inline epicsFloat64 comQueRecv::popFloat64 ()
|
|
epics_throws (( comBuf::insufficentBytesAvailable ))
|
|
{
|
|
epicsFloat64 tmp;
|
|
epicsUInt8 wire[ sizeof ( tmp ) ];
|
|
// optimizer will unroll this loop
|
|
for ( unsigned i = 0u; i < sizeof ( tmp ); i++ ) {
|
|
wire[i] = this->popUInt8 ();
|
|
}
|
|
osiConvertFromWireFormat ( tmp, wire );
|
|
return tmp;
|
|
}
|
|
|
|
inline epicsUInt8 comQueRecv::popUInt8 ()
|
|
epics_throws (( comBuf::insufficentBytesAvailable ))
|
|
{
|
|
comBuf * pComBuf = this->bufs.first ();
|
|
if ( ! pComBuf ) {
|
|
comBuf::throwInsufficentBytesException ();
|
|
}
|
|
epicsUInt8 tmp = pComBuf->popUInt8 ();
|
|
if ( pComBuf->occupiedBytes() == 0u ) {
|
|
this->removeAndDestroyBuf ( *pComBuf );
|
|
}
|
|
this->nBytesPending--;
|
|
return tmp;
|
|
}
|
|
|
|
// optimization here complicates this function somewhat
|
|
inline epicsUInt16 comQueRecv::popUInt16 ()
|
|
epics_throws (( comBuf::insufficentBytesAvailable ))
|
|
{
|
|
comBuf *pComBuf = this->bufs.first ();
|
|
if ( ! pComBuf ) {
|
|
comBuf::throwInsufficentBytesException ();
|
|
}
|
|
// try first for all in one buffer efficent version
|
|
// (double check here avoids slow C++ exception)
|
|
// (hopefully optimizer removes inside check)
|
|
epicsUInt16 tmp;
|
|
unsigned bytesAvailable = pComBuf->occupiedBytes();
|
|
if ( bytesAvailable >= sizeof (tmp) ) {
|
|
tmp = pComBuf->popUInt16 ();
|
|
if ( bytesAvailable == sizeof (tmp) ) {
|
|
this->removeAndDestroyBuf ( *pComBuf );
|
|
}
|
|
this->nBytesPending -= sizeof( tmp );
|
|
}
|
|
else {
|
|
tmp = this->multiBufferPopUInt16 ();
|
|
}
|
|
return tmp;
|
|
}
|
|
|
|
// optimization here complicates this function somewhat
|
|
inline epicsUInt32 comQueRecv::popUInt32 ()
|
|
epics_throws (( comBuf::insufficentBytesAvailable ))
|
|
{
|
|
comBuf *pComBuf = this->bufs.first ();
|
|
if ( ! pComBuf ) {
|
|
comBuf::throwInsufficentBytesException ();
|
|
}
|
|
epicsUInt32 tmp;
|
|
// try first for all in one buffer efficent version
|
|
// (double check here avoids slow C++ exception)
|
|
// (hopefully optimizer removes inside check)
|
|
unsigned bytesAvailable = pComBuf->occupiedBytes();
|
|
if ( pComBuf->occupiedBytes() >= sizeof (tmp) ) {
|
|
tmp = pComBuf->popUInt32 ();
|
|
if ( bytesAvailable == sizeof (tmp) ) {
|
|
this->removeAndDestroyBuf ( *pComBuf );
|
|
}
|
|
this->nBytesPending -= sizeof ( tmp );
|
|
}
|
|
else {
|
|
tmp = this->multiBufferPopUInt32 ();
|
|
}
|
|
return tmp;
|
|
}
|
|
|
|
#endif // ifndef comQueRecvh
|