Blob Blame Raw


#include <cstring>

#include "socket.h"
#include "connection.h"
#include "tcpqueue.h"



//#define DebugMsg HideDebugMSG
#define DebugMsg ShowDebugMSG



TcpQueue::TcpQueue(Connection &connection):
	connection(connection), buffer(), begin(), end() { }


TcpQueue::~TcpQueue()
	{ }


bool TcpQueue::push(const void *data, int size) {
	if (!data || size <= 0 || freeSize() < size)
		return false;
	
	int part1 = ALLOCATED_SIZE - end;
	if (size > part1) {
		memcpy(buffer + end, data, part1);
		memcpy(buffer, (const unsigned char*)data + part1, size - part1);
	} else {
		memcpy(buffer + end, data, size);
	}
	end = (end + size)%ALLOCATED_SIZE;
	
	return true;
}


bool TcpQueue::pop(void *data, int size) {
	if (!data || size <= 0 || busySize() < size)
		return false;
	
	int part1 = ALLOCATED_SIZE - begin;
	if (size > part1) {
		memcpy(data, buffer + begin, part1);
		memcpy((unsigned char*)data + part1, buffer, size - part1);
	} else {
		memcpy(data, buffer + begin, size);
	}
	begin = (begin + size)%ALLOCATED_SIZE;
	
	return true;
}


int TcpQueue::readFromTcp() {
	if (connection.tcpSockId < 0)
		return 0;
	int size = freeSize();
	if (size <= 0)
		return 0;
	
	int doneSize = 0;
	int parts[2] = { size, 0 };
	int p0 = ALLOCATED_SIZE - end;
	if (size > p0)
		{ parts[0] = p0; parts[1] = size - p0; }
	
	for(int i = 0; i < 2; ++i) {
		while(parts[i]) {
			int res = Socket::tcpRecvAsync(connection.tcpSockId, buffer + end, parts[i]);
			if (res <= 0) {
				DebugMsg("%u, %d", connection.id.id, doneSize);
				return doneSize;
			}
			doneSize += res;
			end += res;
			parts[i] -= res;
		}
		if (end >= ALLOCATED_SIZE) end = 0;
	}
	
	DebugMsg("%u, %d", connection.id.id, doneSize);
	return doneSize;
}


int TcpQueue::writeToTcp() {
	if (connection.tcpSockId < 0)
		return 0;
	int size = busySize();
	if (size <= 0)
		return 0;
	
	int doneSize = 0;
	int parts[2] = { size, 0 };
	int p0 = ALLOCATED_SIZE - begin;
	if (size > p0)
		{ parts[0] = p0; parts[1] = size - p0; }
	
	for(int i = 0; i < 2; ++i) {
		while(parts[i]) {
			int res = Socket::tcpSendAsync(connection.tcpSockId, buffer + begin, parts[i]);
			if (res <= 0) {
				DebugMsg("%u, %d", connection.id.id, doneSize);
				return doneSize;
			}
			doneSize += res;
			begin += res;
			parts[i] -= res;
		}
		if (begin >= ALLOCATED_SIZE) begin = 0;
	}
	
	DebugMsg("%u, %d", connection.id.id, doneSize);
	return doneSize;
}