openMSX
CliConnection.hh
Go to the documentation of this file.
1 #ifndef CLICONNECTION_HH
2 #define CLICONNECTION_HH
3 
4 #include "CliListener.hh"
5 #include "Thread.hh"
6 #include "Semaphore.hh"
7 #include "EventListener.hh"
8 #include "Socket.hh"
9 #include "CliComm.hh"
10 #include <libxml/parser.h>
11 #include <string>
12 
13 namespace openmsx {
14 
15 class CommandController;
16 class EventDistributor;
17 
18 class CliConnection : public CliListener, private EventListener,
19  protected Runnable
20 {
21 public:
22  virtual ~CliConnection();
23 
24  void setUpdateEnable(CliComm::UpdateType type, bool value) {
25  updateEnabled[type] = value;
26  }
28  return updateEnabled[type];
29  }
30 
36  void start();
37 
38 protected:
39  CliConnection(CommandController& commandController,
40  EventDistributor& eventDistributor);
41 
42  virtual void output(string_ref message) = 0;
43 
48  void end();
49 
53  virtual void close() = 0;
54 
60  void startOutput();
61 
62  xmlParserCtxt* parser_context;
63  Thread thread; // TODO: Possible to make this private?
64 
65 private:
66  void execute(const std::string& command);
67 
68  // CliListener
69  virtual void log(CliComm::LogLevel level, string_ref message);
70  virtual void update(CliComm::UpdateType type, string_ref machine,
71  string_ref name, string_ref value);
72 
73  // EventListener
74  virtual int signalEvent(const std::shared_ptr<const Event>& event);
75 
76  enum State {
77  START, TAG_OPENMSX, TAG_COMMAND, END
78  };
79  struct ParseState {
80  State state;
81  unsigned unknownLevel;
82  std::string content;
83  CliConnection* object;
84  };
85 
86  static void cb_start_element(void* user_data, const xmlChar* localname,
87  const xmlChar* prefix, const xmlChar* uri,
88  int nb_namespaces, const xmlChar** namespaces,
89  int nb_attributes, int nb_defaulted,
90  const xmlChar** attrs);
91  static void cb_end_element(void* user_data, const xmlChar* localname,
92  const xmlChar* prefix, const xmlChar* uri);
93  static void cb_text(void* user_data, const xmlChar* chars, int len);
94 
95  xmlSAXHandler sax_handler;
96  ParseState user_data;
97 
98  CommandController& commandController;
99  EventDistributor& eventDistributor;
100 
101  bool updateEnabled[CliComm::NUM_UPDATES];
102 };
103 
105 {
106 public:
107  StdioConnection(CommandController& commandController,
108  EventDistributor& eventDistributor);
109  virtual ~StdioConnection();
110 
111  virtual void output(string_ref message);
112 
113 private:
114  virtual void close();
115  virtual void run();
116 
117  bool ok;
118 };
119 
120 #ifdef _WIN32
121 class PipeConnection : public CliConnection
122 {
123 public:
124  PipeConnection(CommandController& commandController,
125  EventDistributor& eventDistributor,
126  string_ref name);
127  virtual ~PipeConnection();
128 
129  virtual void output(string_ref message);
130 
131 private:
132  virtual void close();
133  virtual void run();
134 
135  HANDLE pipeHandle;
136  HANDLE shutdownEvent;
137 };
138 #endif
139 
141 {
142 public:
143  SocketConnection(CommandController& commandController,
144  EventDistributor& eventDistributor,
145  SOCKET sd);
146  virtual ~SocketConnection();
147 
148  virtual void output(string_ref message);
149 
150 private:
151  virtual void close();
152  virtual void run();
153 
154  Semaphore sem;
155  SOCKET sd;
156  bool established;
157 };
158 
159 } // namespace openmsx
160 
161 #endif
virtual void output(string_ref message)=0
xmlParserCtxt * parser_context
This class implements a subset of the proposal for std::string_ref (proposed for the next c++ standar...
Definition: string_ref.hh:18
void start()
Starts the helper thread.
int SOCKET
Definition: Socket.hh:22
StdioConnection(CommandController &commandController, EventDistributor &eventDistributor)
bool getUpdateEnable(CliComm::UpdateType type) const
virtual void output(string_ref message)
virtual void close()=0
Close the connection.
CliConnection(CommandController &commandController, EventDistributor &eventDistributor)
virtual void output(string_ref message)
void end()
End this connection by sending the closing tag and then closing the stream.
SocketConnection(CommandController &commandController, EventDistributor &eventDistributor, SOCKET sd)
void startOutput()
Send opening XML tag, should be called exactly once by a subclass shortly after opening a connection...
void setUpdateEnable(CliComm::UpdateType type, bool value)