#include "Sockets.h"

#ifndef WIN32
	#include <sys/types.h>
	#include <sys/socket.h>
	#include <netinet/in.h>
	#include <arpa/inet.h>
	#include <unistd.h>
#else
	#include <winsock2.h>
#endif

const unsigned RecvBufSize = 64;

ClientSocket::ClientSocket()
{
	this->socket = ::socket(AF_INET, SOCK_STREAM, 0);
	if (this->socket == -1) throw CreateError();
}

void ClientSocket::Connect(const String host, const unsigned port) const
{
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
#ifndef WIN32
	if (!inet_aton(host.CStr(), &(addr.sin_addr))) throw InvalidHost();
#else
	addr.sin_addr.s_addr = inet_addr(host.CStr());
#endif
	if (connect(socket, (sockaddr*)&addr, sizeof(addr)) != 0) throw ConnectError();
}

String ClientSocket::Receive() const
{
	char buffer[RecvBufSize];
	unsigned received = recv(socket, buffer, RecvBufSize - 1, 0);
	buffer[received] = '\0';
	return buffer;
}

void ClientSocket::Send(const String data) const
{
	const char *buffer = data.CStr();
	unsigned left = data.GetLength();
	while (left > 0)
	{
		unsigned count = send(socket, buffer, left, 0);
		left -= count;
		buffer += count;
	}
}
