]> git.sesse.net Git - casparcg/blob - protocol/util/strategy_adapters.cpp
Changed default log level to info and moved logging statements that we always want...
[casparcg] / protocol / util / strategy_adapters.cpp
1 /*\r
2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>\r
3 *\r
4 * This file is part of CasparCG (www.casparcg.com).\r
5 *\r
6 * CasparCG is free software: you can redistribute it and/or modify\r
7 * it under the terms of the GNU General Public License as published by\r
8 * the Free Software Foundation, either version 3 of the License, or\r
9 * (at your option) any later version.\r
10 *\r
11 * CasparCG is distributed in the hope that it will be useful,\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14 * GNU General Public License for more details.\r
15 *\r
16 * You should have received a copy of the GNU General Public License\r
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.\r
18 *\r
19 * Author: Helge Norberg, helge.norberg@svt.se\r
20 */\r
21 \r
22 #include "../StdAfx.h"\r
23 \r
24 #include "strategy_adapters.h"\r
25 \r
26 #include <boost/locale.hpp>\r
27 #include <boost/algorithm/string/replace.hpp>\r
28 \r
29 namespace caspar { namespace IO {\r
30 \r
31 class to_unicode_adapter : public protocol_strategy<char>\r
32 {\r
33         std::string codepage_;\r
34         protocol_strategy<wchar_t>::ptr unicode_strategy_;\r
35 public:\r
36         to_unicode_adapter(\r
37                         const std::string& codepage, \r
38                         const protocol_strategy<wchar_t>::ptr& unicode_strategy)\r
39                 : codepage_(codepage)\r
40                 , unicode_strategy_(unicode_strategy)\r
41         {\r
42         }\r
43 \r
44         void parse(const std::basic_string<char>& data) override\r
45         {\r
46                 auto utf_data = boost::locale::conv::to_utf<wchar_t>(data, codepage_);\r
47 \r
48                 unicode_strategy_->parse(utf_data);\r
49         }\r
50 };\r
51 \r
52 class from_unicode_client_connection : public client_connection<wchar_t>\r
53 {\r
54         client_connection<char>::ptr client_;\r
55         std::string codepage_;\r
56 public:\r
57         from_unicode_client_connection(\r
58                         const client_connection<char>::ptr& client, const std::string& codepage)\r
59                 : client_(client)\r
60                 , codepage_(codepage)\r
61         {\r
62                 CASPAR_LOG(trace) << "from_unicode_client_connection created.";\r
63         }\r
64         ~from_unicode_client_connection()\r
65         {\r
66                 CASPAR_LOG(trace) << "from_unicode_client_connection destroyed.";\r
67         }\r
68 \r
69         void send(std::basic_string<wchar_t>&& data) override\r
70         {\r
71                 auto str = boost::locale::conv::from_utf<wchar_t>(data, codepage_);\r
72 \r
73                 client_->send(std::move(str));\r
74 \r
75                 if (data.length() < 512)\r
76                 {\r
77                         boost::replace_all(data, L"\n", L"\\n");\r
78                         boost::replace_all(data, L"\r", L"\\r");\r
79                         CASPAR_LOG(info) << L"Sent message to " << client_->address() << L":" << data;\r
80                 }\r
81                 else\r
82                         CASPAR_LOG(info) << L"Sent more than 512 bytes to " << client_->address();\r
83         }\r
84 \r
85         void disconnect() override\r
86         {\r
87                 client_->disconnect();\r
88         }\r
89 \r
90         std::wstring address() const override\r
91         {\r
92                 return client_->address();\r
93         }\r
94 \r
95         void add_lifecycle_bound_object(const std::wstring& key, const std::shared_ptr<void>& lifecycle_bound) override\r
96         {\r
97                 client_->add_lifecycle_bound_object(key, lifecycle_bound);\r
98         }\r
99         std::shared_ptr<void> remove_lifecycle_bound_object(const std::wstring& key) override\r
100         {\r
101                 return client_->remove_lifecycle_bound_object(key);\r
102         }\r
103 };\r
104 \r
105 to_unicode_adapter_factory::to_unicode_adapter_factory(\r
106                 const std::string& codepage, \r
107                 const protocol_strategy_factory<wchar_t>::ptr& unicode_strategy_factory)\r
108         : codepage_(codepage)\r
109         , unicode_strategy_factory_(unicode_strategy_factory)\r
110 {\r
111 }\r
112 \r
113 protocol_strategy<char>::ptr to_unicode_adapter_factory::create(\r
114         const client_connection<char>::ptr& client_connection)\r
115 {\r
116         auto client = spl::make_shared<from_unicode_client_connection>(client_connection, codepage_);\r
117 \r
118         return spl::make_shared<to_unicode_adapter>(codepage_, unicode_strategy_factory_->create(client));\r
119 }\r
120 \r
121 class legacy_strategy_adapter : public protocol_strategy<wchar_t>\r
122 {\r
123         ProtocolStrategyPtr strategy_;\r
124         ClientInfoPtr client_info_;\r
125 public:\r
126         legacy_strategy_adapter(\r
127                         const ProtocolStrategyPtr& strategy, \r
128                         const client_connection<wchar_t>::ptr& client_connection)\r
129                 : strategy_(strategy)\r
130                 , client_info_(client_connection)\r
131         {\r
132                 CASPAR_LOG(trace) << "legacy_strategy_adapter created.";\r
133         }\r
134         ~legacy_strategy_adapter()\r
135         {\r
136                 CASPAR_LOG(trace) << "legacy_strategy_adapter destroyed.";\r
137         }\r
138 \r
139         void parse(const std::basic_string<wchar_t>& data) override\r
140         {\r
141                 strategy_->Parse(data, client_info_);\r
142         }\r
143 };\r
144 \r
145 legacy_strategy_adapter_factory::legacy_strategy_adapter_factory(\r
146                 const ProtocolStrategyPtr& strategy)\r
147         : strategy_(strategy)\r
148 {\r
149 }\r
150 \r
151 protocol_strategy<wchar_t>::ptr legacy_strategy_adapter_factory::create(\r
152                 const client_connection<wchar_t>::ptr& client_connection)\r
153 {\r
154         return spl::make_shared<legacy_strategy_adapter>(strategy_, client_connection);\r
155 }\r
156 \r
157 protocol_strategy_factory<char>::ptr wrap_legacy_protocol(\r
158                 const std::string& delimiter, \r
159                 const ProtocolStrategyPtr& strategy)\r
160 {\r
161         return spl::make_shared<delimiter_based_chunking_strategy_factory<char>>(\r
162                         delimiter,\r
163                         spl::make_shared<to_unicode_adapter_factory>(\r
164                                         strategy->GetCodepage(),\r
165                                         spl::make_shared<legacy_strategy_adapter_factory>(strategy)));\r
166 }\r
167 \r
168 }}\r