2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
4 * This file is part of CasparCG (www.casparcg.com).
6 * CasparCG is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * CasparCG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
19 * Author: Nicklas P Andersson
23 #include "../StdAfx.h"
25 #include "CLKProtocolStrategy.h"
26 #include "clk_commands.h"
34 namespace caspar { namespace protocol { namespace CLK {
36 class CLKProtocolStrategy : public IO::protocol_strategy<wchar_t>
38 enum class ParserState
45 ParserState currentState_ = ParserState::ExpectingNewCommand;
46 std::wstringstream currentCommandString_;
47 std::wstring command_name_;
48 std::vector<std::wstring> parameters_;
49 clk_command_processor& command_processor_;
50 IO::client_connection<wchar_t>::ptr client_connection_;
53 const IO::client_connection<wchar_t>::ptr& client_connection,
54 clk_command_processor& command_processor)
55 : command_processor_(command_processor)
56 , client_connection_(client_connection)
60 void parse(const std::basic_string<wchar_t>& data)
62 for (int index = 0; index < data.length(); ++index)
64 wchar_t currentByte = data[index];
67 currentCommandString_ << L"<" << static_cast<int>(currentByte) << L">";
69 currentCommandString_ << currentByte;
73 switch (currentState_)
75 case ParserState::ExpectingNewCommand:
77 currentState_ = ParserState::ExpectingCommand;
78 //just throw anything else away
80 case ParserState::ExpectingCommand:
82 currentState_ = ParserState::ExpectingParameter;
84 command_name_ += currentByte;
86 case ParserState::ExpectingParameter:
87 //allocate new parameter
88 if (parameters_.size() == 0 || currentByte == 2)
89 parameters_.push_back(std::wstring());
91 //add the character to end end of the last parameter
94 //add the character to end end of the last parameter
95 if (currentByte == L'<')
96 parameters_.back() += L"<";
97 else if (currentByte == L'>')
98 parameters_.back() += L">";
99 else if (currentByte == L'\"')
100 parameters_.back() += L""";
102 parameters_.back() += currentByte;
111 command_name_.begin(), command_name_.end(),
112 command_name_.begin(),
117 if (!command_processor_.handle(command_name_, parameters_))
118 CASPAR_LOG(error) << "CLK: Unknown command: " << command_name_;
120 CASPAR_LOG(debug) << L"CLK: Executed valid command: "
121 << currentCommandString_.str();
125 CASPAR_LOG_CURRENT_EXCEPTION();
126 CASPAR_LOG(error) << "CLK: Failed to interpret command: "
127 << currentCommandString_.str();
137 currentState_ = ParserState::ExpectingNewCommand;
138 currentCommandString_.str(L"");
139 command_name_.clear();
144 clk_protocol_strategy_factory::clk_protocol_strategy_factory(
145 const std::vector<spl::shared_ptr<core::video_channel>>& channels,
146 const spl::shared_ptr<core::cg_producer_registry>& cg_registry)
148 add_command_handlers(command_processor_, channels, channels.at(0), cg_registry);
151 IO::protocol_strategy<wchar_t>::ptr clk_protocol_strategy_factory::create(
152 const IO::client_connection<wchar_t>::ptr& client_connection)
154 return spl::make_shared<CLKProtocolStrategy>(client_connection, command_processor_);