#include <cstring>
#include "socket.h"
#include "connection.h"
#include "tcpqueue.h"
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];
parts[0] = ALLOCATED_SIZE - end;
parts[1] = parts[0] - size;
if (parts[1] < 0)
{ parts[0] = size; parts[1] = 0; }
for(int i = 0; i < 2; ++i) {
while(parts[i]) {
int res = Socket::tcpRecvAsync(connection.tcpSockId, buffer + end, parts[i]);
if (res <= 0)
return doneSize;
doneSize += res;
end += res;
parts[i] -= res;
}
if (end >= ALLOCATED_SIZE) end = 0;
}
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];
parts[0] = ALLOCATED_SIZE - begin;
parts[1] = parts[0] - size;
if (parts[1] < 0)
{ parts[0] = size; parts[1] = 0; }
for(int i = 0; i < 2; ++i) {
while(parts[i]) {
int res = Socket::tcpSendAsync(connection.tcpSockId, buffer + begin, parts[i]);
if (res <= 0)
return doneSize;
doneSize += res;
begin += res;
parts[i] -= res;
}
if (begin >= ALLOCATED_SIZE) begin = 0;
}
return doneSize;
}