#include <msp/core/except.h>
-#include <msp/core/refptr.h>
#include <msp/net/resolve.h>
#include <msp/time/timedelta.h>
#include "client.h"
Client::~Client()
{
- delete sock;
- delete request;
- delete response;
}
void Client::use_event_dispatcher(IO::EventDispatcher *ed)
void Client::use_resolver(Net::Resolver *r)
{
if(resolver)
- {
- delete resolve_listener;
- resolve_listener = nullptr;
- }
+ resolve_listener.reset();
resolver = r;
if(resolver)
- resolve_listener = new ResolveListener(*this);
+ resolve_listener = make_unique<ResolveListener>(*this);
}
void Client::start_request(const Request &r)
if(request)
throw invalid_state("already processing a request");
- delete sock;
- sock = nullptr;
+ sock.reset();
- request = new Request(r);
+ request = make_unique<Request>(r);
if(!user_agent.empty())
request->set_header("User-Agent", user_agent);
- delete response;
- response = nullptr;
+ response.reset();
in_buf.clear();
string host = r.get_header("Host");
resolve_tag = resolver->resolve(host);
else
{
- RefPtr<Net::SockAddr> addr = Net::resolve(host);
+ unique_ptr<Net::SockAddr> addr(Net::resolve(host));
address_resolved(resolve_tag, *addr);
}
}
{
start_request(Request::from_url(url));
wait_response();
- return response;
+ return response.get();
}
void Client::tick()
{
signal_response_complete.emit(*response);
- delete sock;
- sock = nullptr;
- delete request;
- request = nullptr;
+ sock.reset();
+ request.reset();
}
}
void Client::abort()
{
- delete sock;
- sock = nullptr;
- delete request;
- request = nullptr;
+ sock.reset();
+ request.reset();
}
void Client::address_resolved(unsigned tag, const Net::SockAddr &addr)
return;
resolve_tag = 0;
- sock = new Net::StreamSocket(addr.get_family());
+ sock = make_unique<Net::StreamSocket>(addr.get_family());
sock->set_block(false);
sock->signal_data_available.connect(sigc::mem_fun(this, &Client::data_available));
return;
resolve_tag = 0;
- delete request;
- request = nullptr;
+ request.reset();
if(signal_socket_error.empty())
throw err;
{
if(err)
{
- delete request;
- request = nullptr;
+ request.reset();
if(signal_socket_error.empty())
throw *err;
{
if(in_buf.find("\r\n\r\n")!=string::npos || in_buf.find("\n\n")!=string::npos)
{
- response = new Response(Response::parse(in_buf));
+ response = make_unique<Response>(Response::parse(in_buf));
response->set_user_data(request->get_user_data());
in_buf = string();
}
{
signal_response_complete.emit(*response);
- delete request;
- request = nullptr;
+ request.reset();
}
}
#ifndef MSP_HTTP_CLIENT_H_
#define MSP_HTTP_CLIENT_H_
+#include <memory>
#include <string>
#include <sigc++/signal.h>
#include <msp/io/eventdispatcher.h>
void resolve_failed(unsigned, const std::exception &);
};
- Net::StreamSocket *sock = nullptr;
+ std::unique_ptr<Net::StreamSocket> sock;
IO::EventDispatcher *event_disp = nullptr;
Net::Resolver *resolver = nullptr;
- ResolveListener *resolve_listener = nullptr;
+ std::unique_ptr<ResolveListener> resolve_listener;
unsigned resolve_tag = 0;
std::string user_agent = "libmspnet/1.0";
- Request *request = nullptr;
- Response *response = nullptr;
+ std::unique_ptr<Request> request;
+ std::unique_ptr<Response> response;
std::string in_buf;
Client(const Client &);
void tick();
void wait_response();
void abort();
- const Request *get_request() const { return request; }
- const Response *get_response() const { return response; }
+ const Request *get_request() const { return request.get(); }
+ const Response *get_response() const { return response.get(); }
private:
void address_resolved(unsigned, const Net::SockAddr &);
void resolve_failed(unsigned, const std::exception &);
#include <exception>
#include <typeinfo>
#include <msp/core/maputils.h>
-#include <msp/core/refptr.h>
#include <msp/debug/demangle.h>
#include <msp/net/inet.h>
#include <msp/net/resolve.h>
void Server::listen(unsigned port)
{
- RefPtr<Net::SockAddr> addr = Net::resolve("*", format("%d", port), Net::INET6);
+ unique_ptr<Net::SockAddr> addr(Net::resolve("*", format("%d", port), Net::INET6));
sock.listen(*addr, 8);
sock.signal_data_available.connect(sigc::mem_fun(this, &Server::data_available));
}
void Server::data_available()
{
- Net::StreamSocket *csock = sock.accept();
- clients.push_back(Client(csock));
- csock->signal_data_available.connect(sigc::bind(sigc::mem_fun(this, &Server::client_data_available), sigc::ref(clients.back())));
- csock->signal_end_of_file.connect(sigc::bind(sigc::mem_fun(this, &Server::client_end_of_file), sigc::ref(clients.back())));
+ unique_ptr<Net::StreamSocket> csock(sock.accept());
+ clients.emplace_back(move(csock));
+ Client &cl = clients.back();
+ cl.sock->signal_data_available.connect(sigc::bind(sigc::mem_fun(this, &Server::client_data_available), sigc::ref(clients.back())));
+ cl.sock->signal_end_of_file.connect(sigc::bind(sigc::mem_fun(this, &Server::client_end_of_file), sigc::ref(clients.back())));
if(event_disp)
- event_disp->add(*csock);
+ event_disp->add(*cl.sock);
}
void Server::client_data_available(Client &cl)
return;
}
- RefPtr<Response> response;
+ unique_ptr<Response> response;
if(!cl.request)
{
if(cl.in_buf.find("\r\n\r\n")!=string::npos || cl.in_buf.find("\n\n")!=string::npos)
{
try
{
- cl.request = new Request(Request::parse(cl.in_buf));
+ cl.request = make_unique<Request>(Request::parse(cl.in_buf));
string addr_str = cl.sock->get_peer_address().str();
string::size_type colon = addr_str.find(':');
if(cl.request->get_method()!="GET" && cl.request->get_method()!="POST")
{
- response = new Response(NOT_IMPLEMENTED);
+ response = make_unique<Response>(NOT_IMPLEMENTED);
response->add_content("Method not implemented\n");
}
else if(cl.request->get_path()[0]!='/')
{
- response = new Response(BAD_REQUEST);
+ response = make_unique<Response>(BAD_REQUEST);
response->add_content("Path must be absolute\n");
}
}
catch(const exception &e)
{
- response = new Response(BAD_REQUEST);
+ response = make_unique<Response>(BAD_REQUEST);
response->add_content(format("An error occurred while parsing request headers:\ntype: %s\nwhat: %s",
Debug::demangle(typeid(e).name()), e.what()));
}
if(cl.request->has_header("Connection"))
cl.keepalive = !strcasecmp(cl.request->get_header("Connection"), "keep-alive");
- response = new Response(NONE);
+ response = make_unique<Response>(NONE);
try
{
- cl.response = response.get();
- responses[cl.response] = &cl;
- signal_request.emit(*cl.request, *response);
- if(cl.async)
- response.release();
- else
+ cl.response = move(response);
+ responses[cl.response.get()] = &cl;
+ signal_request.emit(*cl.request, *cl.response);
+ if(!cl.async)
{
- responses.erase(cl.response);
- cl.response = nullptr;
+ responses.erase(cl.response.get());
+ response = move(cl.response);
if(response->get_status()==NONE)
{
- response = new Response(NOT_FOUND);
+ response = make_unique<Response>(NOT_FOUND);
response->add_content("The requested resource was not found\n");
}
}
}
catch(const exception &e)
{
- responses.erase(cl.response);
- cl.response = nullptr;
- response = new Response(INTERNAL_ERROR);
+ responses.erase(cl.response.get());
+ cl.response.reset();
+ response = make_unique<Response>(INTERNAL_ERROR);
response->add_content(format("An error occurred while processing the request:\ntype: %s\nwhat: %s",
Debug::demangle(typeid(e).name()), e.what()));
}
cl.async = false;
if(cl.keepalive)
{
- delete cl.request;
- cl.request = nullptr;
- delete cl.response;
- cl.response = nullptr;
+ cl.request.reset();
+ cl.response.reset();
}
else
{
}
-Server::Client::Client(RefPtr<Net::StreamSocket> s):
- sock(s)
+Server::Client::Client(unique_ptr<Net::StreamSocket> s):
+ sock(move(s))
{ }
-Server::Client::~Client()
-{
- delete request;
- delete response;
-}
-
} // namespace Http
} // namespace Msp
#ifndef MSP_HTTP_SERVER_H_
#define MSP_HTTP_SERVER_H_
-#include <msp/core/refptr.h>
#include <msp/io/eventdispatcher.h>
#include <msp/net/streamserversocket.h>
#include <msp/time/timedelta.h>
private:
struct Client
{
- RefPtr<Net::StreamSocket> sock;
+ std::unique_ptr<Net::StreamSocket> sock;
std::string in_buf;
- Request *request = nullptr;
- Response *response = nullptr;
+ std::unique_ptr<Request> request;
+ std::unique_ptr<Response> response;
bool keepalive = false;
bool async = false;
bool stale = false;
- Client(RefPtr<Net::StreamSocket>);
- ~Client();
+ Client(std::unique_ptr<Net::StreamSocket>);
};
Net::StreamServerSocket sock;
ClientSocket::~ClientSocket()
{
signal_flush_required.emit();
-
- delete peer_addr;
}
void ClientSocket::shutdown(IO::Mode m)
protected:
bool connecting = false;
bool connected = false;
- SockAddr *peer_addr = nullptr;
+ std::unique_ptr<SockAddr> peer_addr;
ClientSocket(const Private &, const SockAddr &);
ClientSocket(Family, int, int);
SockAddr::SysAddr sa = addr.to_sys();
check_sys_connect_error(::connect(priv->handle, reinterpret_cast<const sockaddr *>(&sa.addr), sa.size));
- delete peer_addr;
- peer_addr = addr.copy();
+ peer_addr.reset(addr.copy());
- delete local_addr;
SockAddr::SysAddr lsa;
getsockname(priv->handle, reinterpret_cast<sockaddr *>(&lsa.addr), &lsa.size);
- local_addr = SockAddr::new_from_sys(lsa);
+ local_addr.reset(SockAddr::new_from_sys(lsa));
connected = true;
.fields(&PacketHeader::type, &PacketHeader::length);
}
-Protocol::~Protocol()
-{
- for(auto &kvp: packet_class_defs)
- delete kvp.second;
-}
-
unsigned Protocol::get_next_packet_class_id()
{
static unsigned next_id = 1;
return next_id++;
}
-void Protocol::add_packet(PacketDefBase *pdef)
+void Protocol::add_packet(unique_ptr<PacketDefBase> pdef)
{
- PacketDefBase *&ptr = packet_class_defs[pdef->get_class_id()];
+ unique_ptr<PacketDefBase> &ptr = packet_class_defs[pdef->get_class_id()];
if(ptr)
- {
packet_id_defs.erase(ptr->get_id());
- delete ptr;
- }
- ptr = pdef;
- if(unsigned id = pdef->get_id())
- packet_id_defs[id] = pdef;
+ ptr = move(pdef);
+ if(unsigned id = ptr->get_id())
+ packet_id_defs[id] = ptr.get();
}
const Protocol::PacketDefBase &Protocol::get_packet_by_class_id(unsigned id) const
#include <cstdint>
#include <map>
+#include <memory>
#include <stdexcept>
#include <vector>
#include <msp/core/hash.h>
class PacketTypeDef: public PacketDefBase
{
private:
- Serializer<P> *serializer;
+ std::unique_ptr<Serializer<P>> serializer;
public:
PacketTypeDef(unsigned);
- ~PacketTypeDef();
unsigned get_class_id() const override { return get_packet_class_id<P>(); }
PacketHeader(std::uint16_t, std::uint16_t);
};
- typedef std::map<unsigned, PacketDefBase *> PacketMap;
-
PacketTypeDef<PacketHeader> header_def;
unsigned next_packet_id;
- PacketMap packet_class_defs;
- PacketMap packet_id_defs;
+ std::map<unsigned, std::unique_ptr<PacketDefBase>> packet_class_defs;
+ std::map<unsigned, PacketDefBase *> packet_id_defs;
protected:
Protocol(unsigned = 1);
-public:
- ~Protocol();
private:
static unsigned get_next_packet_class_id();
template<typename P>
static unsigned get_packet_class_id();
- void add_packet(PacketDefBase *);
+ void add_packet(std::unique_ptr<PacketDefBase>);
protected:
template<typename P>
template<typename P>
Protocol::PacketDefBuilder<P, Protocol::Serializer<P>> Protocol::add(unsigned id)
{
- PacketTypeDef<P> *pdef = new PacketTypeDef<P>(id);
- add_packet(pdef);
- return PacketDefBuilder<P, Serializer<P>>(*this, *pdef, Serializer<P>());
+ std::unique_ptr<PacketTypeDef<P>> pdef = std::make_unique<PacketTypeDef<P>>(id);
+ PacketDefBuilder<P, Serializer<P>> next(*this, *pdef, Serializer<P>());
+ add_packet(move(pdef));
+ return next;
}
template<typename P>
template<typename P>
Protocol::PacketTypeDef<P>::PacketTypeDef(unsigned i):
PacketDefBase(i),
- serializer(new Serializer<P>)
+ serializer(std::make_unique<Serializer<P>>())
{ }
-template<typename P>
-Protocol::PacketTypeDef<P>::~PacketTypeDef()
-{
- delete serializer;
-}
-
template<typename P>
template<typename S>
void Protocol::PacketTypeDef<P>::set_serializer(const S &ser)
{
- delete serializer;
- serializer = new S(ser);
+ serializer = std::make_unique<S>(ser);
}
template<typename P>
task.host = host;
task.serv = serv;
task.family = family;
- thread.add_task(task);
+ thread.add_task(move(task));
return task.tag;
}
{
if(signal_resolve_failed.empty())
{
- RefPtr<runtime_error> err = task->error;
- task->error = nullptr;
+ unique_ptr<runtime_error> err = move(task->error);
thread.pop_complete_task();
throw *err;
}
join();
}
-void Resolver::WorkerThread::add_task(const Task &t)
+void Resolver::WorkerThread::add_task(Task &&t)
{
MutexLock lock(queue_mutex);
bool was_starved = (queue.empty() || queue.back().is_complete());
- queue.push_back(t);
+ queue.push_back(move(t));
if(was_starved)
sem.signal();
}
{
MutexLock lock(queue_mutex);
if(!queue.empty() && queue.front().is_complete())
- {
- delete queue.front().addr;
- delete queue.front().error;
queue.pop_front();
- }
}
void Resolver::WorkerThread::main()
{
try
{
- SockAddr *addr = Net::resolve(task->host, task->serv, task->family);
+ unique_ptr<SockAddr> addr(Net::resolve(task->host, task->serv, task->family));
{
MutexLock lock(queue_mutex);
- task->addr = addr;
+ task->addr = move(addr);
}
}
catch(const runtime_error &e)
{
MutexLock lock(queue_mutex);
- task->error = new runtime_error(e);
+ task->error = make_unique<runtime_error>(e);
}
notify_pipe.put(1);
}
#define MSP_NET_RESOLVE_H_
#include <deque>
+#include <memory>
#include <string>
#include <msp/core/mutex.h>
#include <msp/core/semaphore.h>
std::string host;
std::string serv;
Family family = UNSPEC;
- SockAddr *addr = nullptr;
- std::runtime_error *error = nullptr;
+ std::unique_ptr<SockAddr> addr;
+ std::unique_ptr<std::runtime_error> error;
bool is_complete() const { return addr || error; }
};
WorkerThread();
~WorkerThread();
- void add_task(const Task &);
+ void add_task(Task &&);
Task *get_complete_task();
void pop_complete_task();
namespace Net {
Socket::Socket(const Private &p):
- priv(new Private)
+ priv(make_unique<Private>())
{
mode = IO::M_RDWR;
SockAddr::SysAddr sa;
getsockname(priv->handle, reinterpret_cast<sockaddr *>(&sa.addr), &sa.size);
- local_addr = SockAddr::new_from_sys(sa);
+ local_addr.reset(SockAddr::new_from_sys(sa));
platform_init();
}
Socket::Socket(Family af, int type, int proto):
- priv(new Private)
+ priv(make_unique<Private>())
{
mode = IO::M_RDWR;
Socket::~Socket()
{
platform_cleanup();
-
- delete local_addr;
- delete priv;
}
void Socket::set_block(bool b)
if(err==-1)
throw system_error("bind");
- delete local_addr;
- local_addr = addr.copy();
+ local_addr.reset(addr.copy());
}
const SockAddr &Socket::get_local_address() const
#ifndef MSP_NET_SOCKET_H_
#define MSP_NET_SOCKET_H_
+#include <memory>
#include <msp/core/except.h>
#include <msp/io/eventobject.h>
#include <msp/io/handle.h>
struct Private;
- Private *priv = nullptr;
- SockAddr *local_addr = nullptr;
+ std::unique_ptr<Private> priv;
+ std::unique_ptr<SockAddr> local_addr;
Socket(const Private &);
Socket(Family, int, int);
users of the address. */
void bind(const SockAddr &);
- bool is_bound() const { return local_addr; }
+ bool is_bound() const { return static_cast<bool>(local_addr); }
const SockAddr &get_local_address() const;
void set_timeout(const Time::TimeDelta &);
set_socket_events(S_CONNECT);
}
- delete peer_addr;
- peer_addr = addr.copy();
+ peer_addr.reset(addr.copy());
- delete local_addr;
SockAddr::SysAddr lsa;
getsockname(priv->handle, reinterpret_cast<sockaddr *>(&lsa.addr), &lsa.size);
- local_addr = SockAddr::new_from_sys(lsa);
+ local_addr.reset(SockAddr::new_from_sys(lsa));
if(finished)
{
signal_connect_finished.emit(0);
if(err!=0)
- {
- delete peer_addr;
- peer_addr = nullptr;
- }
+ peer_addr.reset();
set_socket_events((err==0) ? S_INPUT : S_NONE);
}