#include "AsyncEventServer.h"
-#include "ProtocolStrategy.h"
-
#include <algorithm>
#include <array>
#include <string>
#include <set>
-#include <vector>
+#include <memory>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/lexical_cast.hpp>
-#include <boost/locale.hpp>
-#include <boost/algorithm/string/split.hpp>
using boost::asio::ip::tcp;
typedef std::set<spl::shared_ptr<connection>> connection_set;
-class connection : public spl::enable_shared_from_this<connection>, public ClientInfo
+class connection : public spl::enable_shared_from_this<connection>, public client_connection<char>
{
const spl::shared_ptr<tcp::socket> socket_;
const spl::shared_ptr<connection_set> connection_set_;
const std::wstring name_;
- const spl::shared_ptr<IProtocolStrategy> protocol_;
+ protocol_strategy_factory<char>::ptr protocol_factory_;
+ std::shared_ptr<protocol_strategy<char>> protocol_;
std::array<char, 32768> data_;
- std::string input_;
public:
- static spl::shared_ptr<connection> create(spl::shared_ptr<tcp::socket> socket, const ProtocolStrategyPtr& protocol, spl::shared_ptr<connection_set> connection_set)
+ static spl::shared_ptr<connection> create(spl::shared_ptr<tcp::socket> socket, const protocol_strategy_factory<char>::ptr& protocol, spl::shared_ptr<connection_set> connection_set)
{
spl::shared_ptr<connection> con(new connection(std::move(socket), std::move(protocol), std::move(connection_set)));
con->read_some();
/* ClientInfo */
- virtual void Send(const std::wstring& data)
+ virtual void send(std::string&& data)
{
- write_some(data);
+ write_some(std::move(data));
}
- virtual void Disconnect()
+ virtual void disconnect()
{
stop();
}
}
private:
- connection(const spl::shared_ptr<tcp::socket>& socket, const ProtocolStrategyPtr& protocol, const spl::shared_ptr<connection_set>& connection_set)
+ connection(const spl::shared_ptr<tcp::socket>& socket, const protocol_strategy_factory<char>::ptr& protocol, const spl::shared_ptr<connection_set>& connection_set)
: socket_(socket)
, name_((socket_->is_open() ? u16(socket_->local_endpoint().address().to_string() + ":" + boost::lexical_cast<std::string>(socket_->local_endpoint().port())) : L"no-address"))
, connection_set_(connection_set)
- , protocol_(protocol)
+ , protocol_factory_(protocol)
{
CASPAR_LOG(info) << print() << L" Connected.";
}
+
+ protocol_strategy<char>& protocol()
+ {
+ if (!protocol_)
+ protocol_ = protocol_factory_->create(shared_from_this());
+
+ return *protocol_;
+ }
void handle_read(const boost::system::error_code& error, size_t bytes_transferred)
{
{
try
{
- CASPAR_LOG(trace) << print() << L" Received: " << u16(std::string(data_.begin(), data_.begin() + bytes_transferred));
-
- input_.append(data_.begin(), data_.begin() + bytes_transferred);
-
- std::vector<std::string> split;
- boost::iter_split(split, input_, boost::algorithm::first_finder("\r\n"));
-
- input_ = std::move(split.back());
- split.pop_back();
-
- BOOST_FOREACH(auto cmd, split)
- {
- auto u16cmd = boost::locale::conv::to_utf<wchar_t>(cmd, protocol_->GetCodepage()) + L"\r\n";
- protocol_->Parse(u16cmd.data(), static_cast<int>(u16cmd.size()), shared_from_this());
- }
+ std::string data(data_.begin(), data_.begin() + bytes_transferred);
+
+ CASPAR_LOG(trace) << print() << L" Received: " << u16(data);
+
+ protocol().parse(data);
}
catch(...)
{
socket_->async_read_some(boost::asio::buffer(data_.data(), data_.size()), std::bind(&connection::handle_read, shared_from_this(), std::placeholders::_1, std::placeholders::_2));
}
- void write_some(const std::wstring& data)
+ void write_some(std::string&& data)
{
- auto str = spl::make_shared<std::string>(boost::locale::conv::from_utf<wchar_t>(data, protocol_->GetCodepage()));
+ auto str = spl::make_shared<std::string>(std::move(data));
socket_->async_write_some(boost::asio::buffer(str->data(), str->size()), std::bind(&connection::handle_write, shared_from_this(), str, std::placeholders::_1, std::placeholders::_2));
}
};
{
boost::asio::io_service service_;
tcp::acceptor acceptor_;
- spl::shared_ptr<IProtocolStrategy> protocol_;
+ protocol_strategy_factory<char>::ptr protocol_;
spl::shared_ptr<connection_set> connection_set_;
boost::thread thread_;
- implementation(const spl::shared_ptr<IProtocolStrategy>& protocol, unsigned short port)
+ implementation(const protocol_strategy_factory<char>::ptr& protocol, unsigned short port)
: acceptor_(service_, tcp::endpoint(tcp::v4(), port))
, protocol_(protocol)
, thread_(std::bind(&boost::asio::io_service::run, &service_))
}
};
-AsyncEventServer::AsyncEventServer(const spl::shared_ptr<IProtocolStrategy>& protocol, unsigned short port) : impl_(new implementation(protocol, port)){}
-AsyncEventServer::~AsyncEventServer(){}
+AsyncEventServer::AsyncEventServer(
+ const protocol_strategy_factory<char>::ptr& protocol, unsigned short port)
+ : impl_(new implementation(protocol, port))
+{
+}
+
+AsyncEventServer::~AsyncEventServer()
+{
+}
+
}}
\ No newline at end of file