jsocketbuffer.cpp 3.15 KB
/***************************************************************************
 *   Copyright (C) 2005 by Jeff Ferr                                       *
 *   root@sat                                                              *
 *                                                                         *
 *   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 "jsocketbuffer.h"
#include "jsocketexception.h"
#include "jsockettimeoutexception.h"

#include <errno.h>
#include <iostream>
#include <streambuf>
#include <stdio.h>

namespace jsocket {

SocketBuffer::SocketBuffer(uint16_t socket_, uint32_t size_)//:
//	std::streambuf()
{
	_socket = socket_;
	_size_buffer = size_;
	
	_buffer_in = new char[size_];
	_buffer_out = new char[size_];

	// TODO:: if (_buffer)in || _buffer_out) == NULL
	
	setg(_buffer_in, _buffer_in, _buffer_in);
	setp(_buffer_out, _buffer_out + _size_buffer);

	_sent_bytes = 0LL;
	_receive_bytes = 0LL;
}

SocketBuffer::~SocketBuffer()
{
	delete [] _buffer_in;
	delete [] _buffer_out;
}

int SocketBuffer::sync()
{
	std::streamsize n = pptr() - pbase();

	int sent;
	
	sent = send(_socket, pbase(), n, 0);

	if (sent < 0 && errno == EAGAIN) {
		throw SocketTimeoutException("Socket send timeout error !");
	}
	
	if (n && sent != n){
		return EOF;
	}

	_sent_bytes += sent;

	pbump(-n);

	return 0;
}

int SocketBuffer::overflow(int ch_)
{
	if (sync() == EOF) {
		return EOF;
	}

	if (ch_ != EOF) {
		pbase()[0] = ch_;
		pbump(1);
	}

	return 0;
}

/**
 *	return 0, peer shutdown
 */
int SocketBuffer::underflow()
{
	int n;

	n = recv(_socket, eback(), _size_buffer, 0);

	if (n < 0 && errno == EAGAIN) {
		throw SocketTimeoutException("Socket receive timeout exception !");
	} else if (n < 0) {
		throw SocketException("Read socket error !");
	}

	_receive_bytes += n;

	setg(eback(), eback(), eback()+n);

	return *eback();
}

uint64_t SocketBuffer::GetSentBytes()
{
	return _sent_bytes;
}

uint64_t SocketBuffer::GetReceiveBytes()
{
	return _receive_bytes;
}

};