Bug fixes. Better syntax.
SocketReactor actually calls callbacks. receive_all no longer tries to access out of bound array indexes. fr::Packet constructor can now take as many arguments as you like and they'll be added to it automatically. Added bool fr::Packet<< operator overload.
This commit is contained in:
parent
70779fbe9c
commit
f74f1f1a94
@ -14,6 +14,28 @@ namespace fr
|
||||
class Packet
|
||||
{
|
||||
public:
|
||||
Packet() noexcept = default;
|
||||
|
||||
//Nasty constructor to allow things like Packet{1, 2, 3, "bob"}.
|
||||
template <typename T, typename ...Args>
|
||||
Packet(T const &part, Args &&...args)
|
||||
{
|
||||
add(part, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename T, typename ...Args>
|
||||
void add(T const& part, Args &&...args)
|
||||
{
|
||||
*this << part;
|
||||
add(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void add(T const part)
|
||||
{
|
||||
*this << part;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Gets the data added to the packet
|
||||
*
|
||||
@ -24,6 +46,26 @@ namespace fr
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds a boolean variable to the packet
|
||||
*/
|
||||
inline Packet &operator<<(bool var)
|
||||
{
|
||||
buffer.resize(buffer.size() + sizeof(var));
|
||||
memcpy(&buffer[buffer.size() - sizeof(var)], &var, sizeof(var));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extracts a boolean variable from the packet
|
||||
*/
|
||||
inline Packet &operator>>(bool &var)
|
||||
{
|
||||
memcpy(&var, &buffer[0], sizeof(var));
|
||||
buffer.erase(0, sizeof(var));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds a 16bit variable to the packet
|
||||
*/
|
||||
|
||||
@ -113,10 +113,10 @@ namespace fr
|
||||
* an error.
|
||||
*
|
||||
* @param dest Where to read the data into
|
||||
* @param size The number of bytes to read
|
||||
* @param buffer_size The number of bytes to read
|
||||
* @return Operation status.
|
||||
*/
|
||||
Status receive_all(void *dest, size_t size);
|
||||
Status receive_all(void *dest, size_t buffer_size);
|
||||
|
||||
/*!
|
||||
* Checks to see if we're connected to a socket or not
|
||||
|
||||
@ -16,6 +16,7 @@ namespace fr
|
||||
class SocketReactor
|
||||
{
|
||||
public:
|
||||
SocketReactor() noexcept = default;
|
||||
SocketReactor(const SocketReactor&)=delete;
|
||||
SocketReactor(SocketReactor&&) noexcept = default;
|
||||
|
||||
@ -45,7 +46,7 @@ namespace fr
|
||||
bool wait(std::chrono::milliseconds timeout = std::chrono::milliseconds(0));
|
||||
|
||||
private:
|
||||
std::vector<std::pair<fr::Socket&, std::function<void()>>> callbacks;
|
||||
std::vector<std::pair<const fr::Socket*, std::function<void()>>> callbacks;
|
||||
fr::SocketSelector socket_selector;
|
||||
|
||||
};
|
||||
|
||||
@ -61,11 +61,11 @@ public:
|
||||
* read in 'received'.
|
||||
*
|
||||
* @param data Where to store the received data.
|
||||
* @param data_size The number of bytes to try and receive. Be sure that it's not larger than data.
|
||||
* @param buffer_size The number of bytes to try and receive. Be sure that it's not larger than data.
|
||||
* @param received Will be filled with the number of bytes actually received, might be less than you requested.
|
||||
* @return The status of the operation, if the socket has disconnected etc.
|
||||
*/
|
||||
virtual Status receive_raw(void *data, size_t data_size, size_t &received) override;
|
||||
virtual Status receive_raw(void *data, size_t buffer_size, size_t &received) override;
|
||||
|
||||
/*!
|
||||
* Sets the connections remote address.
|
||||
|
||||
@ -72,21 +72,23 @@ namespace fr
|
||||
return Socket::Status::Success;
|
||||
}
|
||||
|
||||
Socket::Status Socket::receive_all(void *dest, size_t size)
|
||||
Socket::Status Socket::receive_all(void *dest, size_t buffer_size)
|
||||
{
|
||||
if(!is_connected)
|
||||
return Socket::Disconnected;
|
||||
|
||||
ssize_t bytes_remaining = buffer_size;
|
||||
size_t bytes_read = 0;
|
||||
while(bytes_read < size)
|
||||
while(bytes_remaining > 0)
|
||||
{
|
||||
size_t read = 0;
|
||||
Socket::Status status = receive_raw((uintptr_t*)dest + bytes_read, size, read);
|
||||
if(status == Socket::Status::Success)
|
||||
bytes_read += read;
|
||||
else
|
||||
size_t received = 0;
|
||||
Status status = receive_raw((uintptr_t*)dest + bytes_read, (size_t)bytes_remaining, received);
|
||||
if(status != fr::Socket::Success)
|
||||
return status;
|
||||
bytes_remaining -= received;
|
||||
bytes_read += received;
|
||||
}
|
||||
|
||||
return Socket::Status::Success;
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
// Created by fred on 20/12/16.
|
||||
//
|
||||
|
||||
#include <algorithm>
|
||||
#include "frnetlib/SocketReactor.h"
|
||||
|
||||
namespace fr
|
||||
@ -10,27 +11,33 @@ namespace fr
|
||||
void SocketReactor::add(const Socket &socket, std::function<void()> callback)
|
||||
{
|
||||
socket_selector.add(socket);
|
||||
callbacks.emplace_back(std::make_pair(&socket, callback));
|
||||
}
|
||||
|
||||
void SocketReactor::remove(const Socket &socket)
|
||||
{
|
||||
socket_selector.remove(socket);
|
||||
callbacks.erase(std::find_if(callbacks.begin(), callbacks.end(), [&](const std::pair<const fr::Socket*, std::function<void()>> &check) {
|
||||
return check.first->get_socket_descriptor() == socket.get_socket_descriptor();
|
||||
}));
|
||||
}
|
||||
|
||||
bool SocketReactor::wait(std::chrono::milliseconds timeout)
|
||||
{
|
||||
bool found = false;
|
||||
if(socket_selector.wait(timeout))
|
||||
{
|
||||
//Find which socket sent the activity
|
||||
for(auto &callback : callbacks)
|
||||
{
|
||||
if(socket_selector.is_ready(callback.first))
|
||||
if(socket_selector.is_ready(*callback.first))
|
||||
{
|
||||
//Call the socket's callback
|
||||
callback.second();
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return found;
|
||||
}
|
||||
}
|
||||
@ -52,10 +52,10 @@ namespace fr
|
||||
}
|
||||
}
|
||||
|
||||
Socket::Status TcpSocket::receive_raw(void *data, size_t data_size, size_t &received)
|
||||
Socket::Status TcpSocket::receive_raw(void *data, size_t buffer_size, size_t &received)
|
||||
{
|
||||
received = 0;
|
||||
if(unprocessed_buffer.size() < data_size)
|
||||
if(unprocessed_buffer.size() < buffer_size)
|
||||
{
|
||||
//Read RECV_CHUNK_SIZE bytes into the recv buffer
|
||||
ssize_t status = ::recv(socket_descriptor, recv_buffer.get(), RECV_CHUNK_SIZE, 0);
|
||||
@ -80,12 +80,12 @@ namespace fr
|
||||
return Socket::Status::Disconnected;
|
||||
}
|
||||
|
||||
if(received > data_size)
|
||||
received = data_size;
|
||||
if(received > buffer_size)
|
||||
received = buffer_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
received = data_size;
|
||||
received = buffer_size;
|
||||
}
|
||||
|
||||
//Copy data to where it needs to go
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user