Recovered from microbel
This commit is contained in:
189
common/lib/srvcli/stream.C
Normal file
189
common/lib/srvcli/stream.C
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* PVVMUD a 3D MUD
|
||||
* Copyright (C) 1998-1999 Programvareverkstedet (pvv@pvv.org)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
#include "pvvmud.H"
|
||||
#include <unistd.h>
|
||||
#include <iostream.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "stream.H"
|
||||
|
||||
#define INC_START if (++start >= STREAMSIZE) start = 0; size--
|
||||
#define INC_STOP if (++stop >= STREAMSIZE) stop = 0; size++
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Stream exceptions
|
||||
CEmptyStreamException::CEmptyStreamException()
|
||||
:CException("Empty stream exception"){
|
||||
|
||||
}
|
||||
|
||||
CEOFException::CEOFException():CException("EOF exception"){
|
||||
}
|
||||
|
||||
CIOException::CIOException():CException("IO exception"){
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor and destructor
|
||||
|
||||
CStream::CStream(int fd){
|
||||
start = stop = size = 0;
|
||||
this->fd = fd;
|
||||
}
|
||||
|
||||
CStream::~CStream(){
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Private functions
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int CStream::writeInBuf(char * msg, int length){
|
||||
int nn = 0;
|
||||
if ((STREAMSIZE - size) < length) return FALSE;
|
||||
while (nn < length){
|
||||
buf[stop] = msg[nn++];
|
||||
INC_STOP;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
unsigned long totalread = 0;
|
||||
unsigned long totalwrite = 0;
|
||||
|
||||
int CStream::fillBuf(){
|
||||
long length,max;
|
||||
char rbuf[STREAMSIZE];
|
||||
|
||||
max = MIN(STREAMSIZE-size,READBUFSIZE);
|
||||
|
||||
#ifndef CRYPTO
|
||||
length=::read(fd,&rbuf,max);
|
||||
if (length > 0) {
|
||||
totalread+=length;
|
||||
writeInBuf(rbuf,length);
|
||||
};
|
||||
#else
|
||||
length=CCrypto::read(fd,&m_rbuf,(STREAMSIZE-size));
|
||||
if (length > 0) {
|
||||
totalread+=length;
|
||||
writeInBuf(m_rbuf,length);
|
||||
};
|
||||
#endif
|
||||
// Check for errors
|
||||
if ((max != 0) && (length == 0)){
|
||||
throw new CEOFException();
|
||||
} else if (length == -1){
|
||||
switch(errno){
|
||||
case EAGAIN: // Non-blocking I/O
|
||||
break;
|
||||
default:
|
||||
cdebug << "Error reading socket: " << strerror(errno) << "\n";
|
||||
throw new CIOException();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Public functions
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// peepByte
|
||||
//
|
||||
// Description: Returning first byte in input stream without removing it from
|
||||
// input buf.
|
||||
//
|
||||
// Return : First byte in input stream
|
||||
//
|
||||
// Exceptions : CEmptyStreamException, CEOFException, CIOException
|
||||
//
|
||||
|
||||
BYTE CStream::peepByte(){
|
||||
fillBuf();
|
||||
if (size < 1) throw new CEmptyStreamException();
|
||||
return buf[start];
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// readBuf
|
||||
//
|
||||
// Description: Read length bytes from stream
|
||||
//
|
||||
// Return : Number of bytes read or -1 if read would have blocked
|
||||
//
|
||||
// Exceptions : CEOFException , CIOException
|
||||
//
|
||||
|
||||
int CStream::readBuf(BYTE * msg, int length){
|
||||
if (fillBuf() == 0) return -1;
|
||||
int nn = 0;
|
||||
while ((size >= 1) && (nn < length)){
|
||||
msg[nn++] = buf[start];
|
||||
INC_START;
|
||||
if (size == 0) fillBuf();
|
||||
}
|
||||
return nn;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// writeBuf
|
||||
//
|
||||
// Description: Write length bytes to stream
|
||||
//
|
||||
// Return : Number of bytes writen or -1 if write would have blocked
|
||||
//
|
||||
// Exceptions : CEOFException , CIOException
|
||||
//
|
||||
|
||||
int CStream::writeBuf(BYTE * buf,int length){
|
||||
#ifdef CRYPTO
|
||||
int num = CCrypto::write(fd,buf,length);
|
||||
#else
|
||||
int num = ::write(fd,buf,length);
|
||||
#endif
|
||||
if (num >= 0){
|
||||
totalwrite += num;
|
||||
} else {
|
||||
if (num == -2) return -1; // Error handling in crypto-routines
|
||||
switch (errno){
|
||||
case EPIPE:
|
||||
throw new CEOFException();
|
||||
break;
|
||||
case EAGAIN: // Non-Blocking I/O
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
throw new CIOException();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user