]> git.sesse.net Git - casparcg/blobdiff - protocol/util/AsyncEventServer.cpp
Merged CLK changes from trunk, and separated delimiter message splitting and codepage...
[casparcg] / protocol / util / AsyncEventServer.cpp
index 97c5fcfd4ecac5baa63aba85491bb5c789eba54c..2552d78696da343f0e78889c04b69a3e613fad0c 100644 (file)
 
 #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;
 
@@ -45,18 +41,18 @@ class connection;
 
 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();
@@ -70,12 +66,12 @@ public:
        
        /* 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();
        }
@@ -97,14 +93,22 @@ public:
        }
 
 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) 
        {               
@@ -112,21 +116,11 @@ private:
                {
                        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(...)
                        {
@@ -152,9 +146,9 @@ private:
                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));
        }
 };
@@ -163,11 +157,11 @@ struct AsyncEventServer::implementation
 {
        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_))
@@ -214,6 +208,14 @@ struct AsyncEventServer::implementation
     }
 };
 
-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