-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathPokeCmd.cpp
128 lines (98 loc) · 4.5 KB
/
PokeCmd.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
////////////////////////////////////////////////////////////////////////////////
//! \file PokeCmd.cpp
//! \brief The PokeCmd class definition.
//! \author Chris Oldwood
#include "Common.hpp"
#include "PokeCmd.hpp"
#include "CmdLineArgs.hpp"
#include <Core/CmdLineException.hpp>
#include <Core/AnsiWide.hpp>
#include <NCL/DDEClient.hpp>
#include <NCL/DDECltConvPtr.hpp>
#include <NCL/DDEData.hpp>
#include <NCL/DDELink.hpp>
#include <Core/InvalidArgException.hpp>
#include <Core/StringUtils.hpp>
////////////////////////////////////////////////////////////////////////////////
//! The table of command specific command line switches.
static Core::CmdLineSwitch s_switches[] =
{
{ USAGE, TXT("?"), nullptr, Core::CmdLineSwitch::ONCE, Core::CmdLineSwitch::NONE, nullptr, TXT("Display the command syntax") },
{ USAGE, nullptr, TXT("help"), Core::CmdLineSwitch::ONCE, Core::CmdLineSwitch::NONE, nullptr, TXT("Display the command syntax") },
{ SERVER, TXT("s"), TXT("server"), Core::CmdLineSwitch::ONCE, Core::CmdLineSwitch::SINGLE, TXT("server"), TXT("The DDE Server name") },
{ TOPIC, TXT("t"), TXT("topic"), Core::CmdLineSwitch::ONCE, Core::CmdLineSwitch::SINGLE, TXT("topic"), TXT("The DDE Server topic") },
{ ITEM, TXT("i"), TXT("item"), Core::CmdLineSwitch::ONCE, Core::CmdLineSwitch::SINGLE, TXT("item"), TXT("The item name(s)") },
{ VALUE, TXT("v"), TXT("value"), Core::CmdLineSwitch::ONCE, Core::CmdLineSwitch::SINGLE, TXT("value"), TXT("The value to poke") },
{ LINK, TXT("l"), TXT("link"), Core::CmdLineSwitch::ONCE, Core::CmdLineSwitch::SINGLE, TXT("link"), TXT("The DDE link") },
{ TIMEOUT, nullptr, TXT("timeout"), Core::CmdLineSwitch::ONCE, Core::CmdLineSwitch::SINGLE, TXT("timeout"), TXT("The timeout (ms) for the DDE reply") },
};
static size_t s_switchCount = ARRAY_SIZE(s_switches);
////////////////////////////////////////////////////////////////////////////////
//! Constructor.
PokeCmd::PokeCmd(int argc, tchar* argv[])
: WCL::ConsoleCmd(s_switches, s_switches+s_switchCount, argc, argv, USAGE)
{
}
////////////////////////////////////////////////////////////////////////////////
//! Destructor.
PokeCmd::~PokeCmd()
{
}
////////////////////////////////////////////////////////////////////////////////
//! Get the description of the command.
const tchar* PokeCmd::getDescription()
{
return TXT("Set the value for a single item");
}
////////////////////////////////////////////////////////////////////////////////
//! Get the expected command usage.
const tchar* PokeCmd::getUsage()
{
return TXT("USAGE: DDECmd poke [--server <server> --topic <topic> --item <item> ... | --link <link>] --value <value>");
}
////////////////////////////////////////////////////////////////////////////////
//! The implementation of the command.
int PokeCmd::doExecute(tostream& /*out*/, tostream& /*err*/)
{
ASSERT(m_parser.getUnnamedArgs().at(0) == TXT("poke"));
tstring server;
tstring topic;
tstring item;
// Validate and extract the command line arguments.
if (m_parser.isSwitchSet(LINK))
{
if (m_parser.isSwitchSet(SERVER) || m_parser.isSwitchSet(TOPIC) || m_parser.isSwitchSet(ITEM))
throw Core::CmdLineException(TXT("The --link switch cannot be mixed with --server, --topic & --item"));
tstring link = m_parser.getSwitchValue(LINK);
if (!CDDELink::ParseLink(link, server, topic, item))
throw Core::InvalidArgException(Core::fmt(TXT("Invalid DDE link format '%s'"), link.c_str()));
}
else
{
ASSERT(!m_parser.isSwitchSet(LINK));
if (!m_parser.isSwitchSet(SERVER))
throw Core::CmdLineException(TXT("No DDE server name specified [--server]"));
if (!m_parser.isSwitchSet(TOPIC))
throw Core::CmdLineException(TXT("No DDE server topic specified [--topic]"));
if (!m_parser.isSwitchSet(ITEM))
throw Core::CmdLineException(TXT("No item specified [--item]"));
server = m_parser.getSwitchValue(SERVER);
topic = m_parser.getSwitchValue(TOPIC);
item = m_parser.getSwitchValue(ITEM);
}
if (!m_parser.isSwitchSet(VALUE))
throw Core::CmdLineException(TXT("No value specified [--value]"));
tstring value = m_parser.getSwitchValue(VALUE);
DWORD timeout = 0;
if (m_parser.isSwitchSet(TIMEOUT))
timeout = Core::parse<DWORD>(m_parser.getSwitchValue(TIMEOUT));
// Open the conversation.
CDDEClient client;
DDE::CltConvPtr conv(client.CreateConversation(server.c_str(), topic.c_str()));
if (timeout != 0)
conv->SetTimeout(timeout);
// Set the value.
std::string ansiValue(T2A(value.c_str()));
conv->Poke(item.c_str(), CF_TEXT, ansiValue.data(), ansiValue.length());
return EXIT_SUCCESS;
}