]> git.saurik.com Git - wxWidgets.git/blame - samples/ipc/baseserver.cpp
skip apple options
[wxWidgets.git] / samples / ipc / baseserver.cpp
CommitLineData
ebe887ed
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: samples/ipc/baseserver.cpp
3// Purpose: IPC sample: console server
4// Author: Anders Larsen
5// Most of the code was stolen from: samples/ipc/server.cpp
6// (c) Julian Smart, Jurgen Doornik
7// Created: 2007-11-08
ebe887ed 8// Copyright: (c) 2007 Anders Larsen
526954c5 9// Licence: wxWindows licence
ebe887ed
VZ
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#ifndef WX_PRECOMP
28 #include "wx/wx.h"
29#endif
30
31// Settings common to both executables: determines whether
32// we're using TCP/IP or real DDE.
33#include "ipcsetup.h"
34
521d3436
VZ
35#include "connection.h"
36
ebe887ed
VZ
37#include "wx/timer.h"
38#include "wx/datetime.h"
39
40// ----------------------------------------------------------------------------
65669e31 41// local classes
ebe887ed
VZ
42// ----------------------------------------------------------------------------
43
65669e31 44// a simple connection class testing and logging various operations
521d3436 45class MyConnection : public MyConnectionBase, public wxTimer
ebe887ed
VZ
46{
47public:
ebe887ed 48 virtual bool Disconnect() { return wxConnection::Disconnect(); }
65669e31
VZ
49 virtual bool OnExecute(const wxString& topic,
50 const void *data,
51 size_t size,
52 wxIPCFormat format);
53 virtual const void *OnRequest(const wxString& topic,
54 const wxString& item,
55 size_t *size,
56 wxIPCFormat format);
57 virtual bool OnPoke(const wxString& topic,
58 const wxString& item,
59 const void *data,
60 size_t size,
61 wxIPCFormat format);
ebe887ed
VZ
62 virtual bool OnStartAdvise(const wxString& topic, const wxString& item);
63 virtual bool OnStopAdvise(const wxString& topic, const wxString& item);
65669e31
VZ
64 virtual bool DoAdvise(const wxString& item,
65 const void *data,
66 size_t size,
67 wxIPCFormat format);
ebe887ed
VZ
68 virtual bool OnDisconnect();
69 virtual void Notify();
70
ea84f255 71private:
ebe887ed
VZ
72 wxString m_sAdvise;
73
ebe887ed
VZ
74 wxString m_sRequestDate;
75 char m_achRequestBytes[3];
76};
77
65669e31
VZ
78// a connection used for benchmarking some IPC operations by
79// tests/benchmarks/ipcclient.cpp
80class BenchConnection : public wxConnection
81{
82public:
83 BenchConnection() { m_advise = false; }
84
85 virtual bool OnPoke(const wxString& topic,
86 const wxString& item,
87 const void *data,
88 size_t size,
89 wxIPCFormat format);
90 virtual bool OnStartAdvise(const wxString& topic, const wxString& item);
91 virtual bool OnStopAdvise(const wxString& topic, const wxString& item);
92
93private:
94 // return true if this is the supported topic+item combination, log an
95 // error message otherwise
96 bool IsSupportedTopicAndItem(const wxString& operation,
97 const wxString& topic,
98 const wxString& item) const;
99
100 // the item which can be manipulated by the client via Poke() calls
101 wxString m_item;
102
103 // should we notify the client about changes to m_item?
104 bool m_advise;
105
c0c133e1 106 wxDECLARE_NO_COPY_CLASS(BenchConnection);
65669e31
VZ
107};
108
109// a simple server accepting connections to IPC_TOPIC and IPC_BENCHMARK_TOPIC
ea84f255 110class MyServer : public wxServer
ebe887ed
VZ
111{
112public:
113 MyServer();
114 virtual ~MyServer();
115 void Disconnect();
116 bool IsConnected() { return m_connection != NULL; };
ea84f255
VZ
117
118 virtual wxConnectionBase *OnAcceptConnection(const wxString& topic);
119
120private:
121 wxConnection *m_connection;
122};
123
124// Define a new application
125class MyApp : public wxApp
126{
127public:
128 virtual bool OnInit();
ebe887ed
VZ
129
130protected:
ea84f255 131 MyServer m_server;
ebe887ed
VZ
132};
133
ea84f255
VZ
134DECLARE_APP(MyApp)
135
ebe887ed
VZ
136// ============================================================================
137// implementation
138// ============================================================================
139
2e334012 140IMPLEMENT_APP_CONSOLE(MyApp)
ebe887ed
VZ
141
142// ----------------------------------------------------------------------------
143// MyApp
144// ----------------------------------------------------------------------------
145
146bool MyApp::OnInit()
147{
148 if ( !wxApp::OnInit() )
149 return false;
150
151 delete wxLog::SetActiveTarget(new wxLogStderr);
152
ea84f255 153 const char * const kind =
ebe887ed 154#if wxUSE_DDE_FOR_IPC
ea84f255
VZ
155 "DDE"
156#else
157 "TCP"
158#endif
159 ;
160
161 // Create a new server
162 if ( !m_server.Create(IPC_SERVICE) )
ebe887ed 163 {
ea84f255 164 wxLogMessage("%s server failed to start on %s", kind, IPC_SERVICE);
ebe887ed
VZ
165 return false;
166 }
ebe887ed 167
ea84f255
VZ
168 wxLogMessage("%s server started on %s", kind, IPC_SERVICE);
169 return true;
ebe887ed
VZ
170}
171
172// ----------------------------------------------------------------------------
173// MyServer
174// ----------------------------------------------------------------------------
175
176MyServer::MyServer()
177{
178 m_connection = NULL;
179}
180
181MyServer::~MyServer()
182{
183 Disconnect();
184}
185
186wxConnectionBase *MyServer::OnAcceptConnection(const wxString& topic)
187{
65669e31 188 wxLogMessage("OnAcceptConnection(\"%s\")", topic);
ebe887ed
VZ
189
190 if ( topic == IPC_TOPIC )
191 {
192 m_connection = new MyConnection;
65669e31
VZ
193 }
194 else if ( topic == IPC_BENCHMARK_TOPIC )
195 {
196 m_connection = new BenchConnection;
197 }
198 else // unknown topic
199 {
200 wxLogMessage("Unknown topic");
201 return NULL;
ebe887ed 202 }
ea84f255 203
65669e31
VZ
204 wxLogMessage("Connection accepted");
205 return m_connection;
ebe887ed
VZ
206}
207
208void MyServer::Disconnect()
209{
65669e31 210 if ( m_connection )
ebe887ed
VZ
211 {
212 m_connection->Disconnect();
5276b0a5 213 wxDELETE(m_connection);
ea84f255 214 wxLogMessage("Disconnected client");
ebe887ed
VZ
215 }
216}
217
218// ----------------------------------------------------------------------------
219// MyConnection
220// ----------------------------------------------------------------------------
221
ea84f255
VZ
222bool
223MyConnection::OnExecute(const wxString& topic,
224 const void *data,
225 size_t size,
226 wxIPCFormat format)
ebe887ed 227{
ea84f255 228 Log("OnExecute", topic, "", data, size, format);
ebe887ed
VZ
229 return true;
230}
231
ea84f255
VZ
232bool
233MyConnection::OnPoke(const wxString& topic,
234 const wxString& item,
235 const void *data,
236 size_t size,
237 wxIPCFormat format)
ebe887ed 238{
ea84f255 239 Log("OnPoke", topic, item, data, size, format);
ebe887ed
VZ
240 return wxConnection::OnPoke(topic, item, data, size, format);
241}
242
ea84f255
VZ
243const void *
244MyConnection::OnRequest(const wxString& topic,
245 const wxString& item,
246 size_t *size,
247 wxIPCFormat format)
ebe887ed
VZ
248{
249 const void *data;
ea84f255 250 if (item == "Date")
ebe887ed
VZ
251 {
252 m_sRequestDate = wxDateTime::Now().Format();
253 data = m_sRequestDate.c_str();
254 *size = wxNO_LEN;
255 }
ea84f255 256 else if (item == "Date+len")
ebe887ed 257 {
65669e31
VZ
258 m_sRequestDate = wxDateTime::Now().FormatTime() +
259 " " + wxDateTime::Now().FormatDate();
ebe887ed
VZ
260 data = m_sRequestDate.c_str();
261 *size = m_sRequestDate.Length() + 1;
262 }
ea84f255 263 else if (item == "bytes[3]")
ebe887ed
VZ
264 {
265 data = m_achRequestBytes;
65669e31
VZ
266 m_achRequestBytes[0] = '1';
267 m_achRequestBytes[1] = '2';
268 m_achRequestBytes[2] = '3';
ebe887ed
VZ
269 *size = 3;
270 }
271 else
272 {
273 data = NULL;
274 *size = 0;
275 }
ea84f255 276 Log("OnRequest", topic, item, data, *size, format);
ebe887ed
VZ
277 return data;
278}
279
ea84f255 280bool MyConnection::OnStartAdvise(const wxString& topic, const wxString& item)
ebe887ed 281{
65669e31 282 wxLogMessage("OnStartAdvise(\"%s\",\"%s\")", topic, item);
ea84f255 283 wxLogMessage("Returning true");
ebe887ed 284 m_sAdvise = item;
ea84f255 285 Start(3000); // schedule our Notify() to be called in 3 seconds
ebe887ed
VZ
286 return true;
287}
288
ea84f255 289bool MyConnection::OnStopAdvise(const wxString& topic, const wxString& item)
ebe887ed 290{
65669e31 291 wxLogMessage("OnStopAdvise(\"%s\",\"%s\")", topic, item);
ea84f255
VZ
292 wxLogMessage("Returning true");
293 m_sAdvise.clear();
ebe887ed
VZ
294 Stop();
295 return true;
296}
297
298void MyConnection::Notify()
299{
ea84f255 300 if (!m_sAdvise.empty())
ebe887ed
VZ
301 {
302 wxString s = wxDateTime::Now().Format();
303 Advise(m_sAdvise, s);
65669e31
VZ
304 s = wxDateTime::Now().FormatTime() + " "
305 + wxDateTime::Now().FormatDate();
ea84f255 306 Advise(m_sAdvise, s.mb_str(), s.length() + 1);
ebe887ed
VZ
307
308#if wxUSE_DDE_FOR_IPC
ea84f255
VZ
309 wxLogMessage("DDE Advise type argument cannot be wxIPC_PRIVATE. "
310 "The client will receive it as wxIPC_TEXT, "
311 "and receive the correct no of bytes, "
312 "but not print a correct log entry.");
313#endif // DDE
314
ebe887ed
VZ
315 char bytes[3];
316 bytes[0] = '1'; bytes[1] = '2'; bytes[2] = '3';
317 Advise(m_sAdvise, bytes, 3, wxIPC_PRIVATE);
318 // this works, but the log treats it as a string now
319// m_connection->Advise(m_connection->m_sAdvise, bytes, 3, wxIPC_TEXT );
320 }
321}
322
65669e31
VZ
323bool MyConnection::DoAdvise(const wxString& item,
324 const void *data,
325 size_t size,
326 wxIPCFormat format)
ebe887ed 327{
ea84f255 328 Log("Advise", "", item, data, size, format);
ebe887ed
VZ
329 return wxConnection::DoAdvise(item, data, size, format);
330}
331
332bool MyConnection::OnDisconnect()
333{
ea84f255 334 wxLogMessage("OnDisconnect()");
ebe887ed
VZ
335 return true;
336}
65669e31
VZ
337
338// ----------------------------------------------------------------------------
339// BenchConnection
340// ----------------------------------------------------------------------------
341
342bool BenchConnection::IsSupportedTopicAndItem(const wxString& operation,
343 const wxString& topic,
344 const wxString& item) const
345{
346 if ( topic != IPC_BENCHMARK_TOPIC ||
347 item != IPC_BENCHMARK_ITEM )
348 {
349 wxLogMessage("Unexpected %s(\"%s\", \"%s\") call.",
350 operation, topic, item);
351 return false;
352 }
353
354 return true;
355}
356
357bool BenchConnection::OnPoke(const wxString& topic,
358 const wxString& item,
359 const void *data,
360 size_t size,
361 wxIPCFormat format)
362{
363 if ( !IsSupportedTopicAndItem("OnPoke", topic, item) )
364 return false;
365
366 if ( !IsTextFormat(format) )
367 {
368 wxLogMessage("Unexpected format %d in OnPoke().", format);
369 return false;
370 }
371
372 m_item = GetTextFromData(data, size, format);
373
374 if ( m_advise )
375 {
376 if ( !Advise(item, m_item) )
43b2d5e7 377 {
65669e31 378 wxLogMessage("Failed to advise client about the change.");
43b2d5e7 379 }
65669e31
VZ
380 }
381
382 return true;
383}
384
385bool BenchConnection::OnStartAdvise(const wxString& topic, const wxString& item)
386{
387 if ( !IsSupportedTopicAndItem("OnStartAdvise", topic, item) )
388 return false;
389
390 m_advise = true;
391
392 return true;
393}
394
395bool BenchConnection::OnStopAdvise(const wxString& topic, const wxString& item)
396{
397 if ( !IsSupportedTopicAndItem("OnStopAdvise", topic, item) )
398 return false;
399
400 m_advise = false;
401
402 return true;
403}
404