1 | /*! \mainpage Very Simple Cross-Platform Library Documentation
|
---|
2 | *
|
---|
3 | * \section intro Introduction
|
---|
4 | *
|
---|
5 | * VSCPL is a simple library containing some useful classes related to
|
---|
6 | * thread handling and I/O for POSIX and Windows systems. It is
|
---|
7 | * intended to be extended eventually, but has been written chiefly
|
---|
8 | * for the X-Plane Remote Access plugin and its client libraries,
|
---|
9 | * which is reflected by the rather minimal functionality.
|
---|
10 | *
|
---|
11 | * To avoid namespace clashes, the classes of the library are put in
|
---|
12 | * the \c hu::varadiistvan::scpl namespace or children of it.
|
---|
13 | *
|
---|
14 | * \subsection threading Threading
|
---|
15 | *
|
---|
16 | * The usual \ref hu::varadiistvan::scpl::Thread "thread" class and
|
---|
17 | * some threading primitives are provided:
|
---|
18 | * \ref hu::varadiistvan::scpl::Mutex "mutexes" and
|
---|
19 | * \ref hu::varadiistvan::scpl::CondVar "conditional variables".
|
---|
20 | *
|
---|
21 | * \subsection io Input/Output
|
---|
22 | *
|
---|
23 | * The I/O parts are somewhat generic, but currently support
|
---|
24 | * communication via so-called "local" sockets, which are Unix sockets
|
---|
25 | * on POSIX and named pipes on Windows. Of course, a common interface
|
---|
26 | * is provided, so the actual details are hidden.
|
---|
27 | *
|
---|
28 | * Input/output handling is based on the notion of a thread waiting
|
---|
29 | * for one or more I/O events and then handling them. For this purpose
|
---|
30 | * an instance of the \ref hu::varadiistvan::scpl::io::Waiter class
|
---|
31 | * should be created and then this instance should be passed to the
|
---|
32 | * instances of other classes. Waiting can be accomplished by calling
|
---|
33 | * its \ref hu::varadiistvan::scpl::io::Waiter::wait "wait" function
|
---|
34 | * and optionally passing a timeout.
|
---|
35 | *
|
---|
36 | * A local server socket can be created by instantiation the
|
---|
37 | * \ref hu::varadiistvan::scpl::io::LocalServerSocket class. Besides
|
---|
38 | * the waiter, it is given a name. It is ensured that if several users
|
---|
39 | * of the computer run programs using the same name, each will see
|
---|
40 | * their own socket.
|
---|
41 | *
|
---|
42 | * A server socket needs to accept incoming connections. For this
|
---|
43 | * purpose and \ref hu::varadiistvan::scpl::io::LocalAcceptor
|
---|
44 | * "acceptor" instance is used, which can be acquired by calling the
|
---|
45 | * \ref hu::varadiistvan::scpl::io::LocalServerSocket::getAcceptor
|
---|
46 | * "getAcceptor" function. To check, if there is an incoming
|
---|
47 | * connection, call the acceptor's
|
---|
48 | * \ref hu::varadiistvan::scpl::io::LocalAcceptor::accept "accept"
|
---|
49 | * function. It returns immediately with a boolean telling whether
|
---|
50 | * there is a connection. If so, you should call the
|
---|
51 | * \ref hu::varadiistvan::scpl::io::LocalAcceptor::getSocket
|
---|
52 | * "getSocket" function to get the socket representing the connection.
|
---|
53 | * If there is no incoming connection, you can wait for one using the
|
---|
54 | * waiter. Note, that
|
---|
55 | * \ref hu::varadiistvan::scpl::io::LocalAcceptor::accept "accept"
|
---|
56 | * should be called once unsuccessfully before trying to wait,
|
---|
57 | * otherwise it is not guaranteed that waiting will finish if a new
|
---|
58 | * connection comes in.
|
---|
59 | *
|
---|
60 | * \c LocalAcceptor is a subclass of
|
---|
61 | * \ref hu::varadiistvan::scpl::io::Failable "Failable", which can be
|
---|
62 | * used to check if some error occured. If \c accept returns \c false,
|
---|
63 | * it should be check if the failure of accepting is due to an error,
|
---|
64 | * or is caused simply by no client wanting to connect.
|
---|
65 | *
|
---|
66 | * A local client socket is created by instantiation
|
---|
67 | * \ref hu::varadiistvan::scpl::io::LocalClientSocket. It receives the
|
---|
68 | * same name as the server socket to which we want to
|
---|
69 | * connect. Similarly to accepting a connection on a server socket,
|
---|
70 | * the client socket's
|
---|
71 | * \ref hu::varadiistvan::scpl::io::LocalClientSocket::getConnector
|
---|
72 | * "getConnector" should be called to retrieve a
|
---|
73 | * \ref hu::varadiistvan::scpl::io::LocalConnector "LocalConnector"
|
---|
74 | * instance. Its
|
---|
75 | * \ref hu::varadiistvan::scpl::io::LocalConnector::connect "connect"
|
---|
76 | * member function should be called to initiate the connection. If it
|
---|
77 | * returns \c true, the connection has succeeded. Otherwise one can
|
---|
78 | * wait using the socket's waiter for the connection to succeed. If
|
---|
79 | * waiting finishes, \c connect can be called again to check, if the
|
---|
80 | * connection has been established. In case of a \c false return
|
---|
81 | * value, the error condition should be checked here as well.
|
---|
82 | *
|
---|
83 | * Once the connection has been established, the actual communication
|
---|
84 | * can begin. Both \c LocalSocket and \c LocalClientSocket are
|
---|
85 | * subclasses of
|
---|
86 | * \ref hu::varadiistvan::scpl::io::BufferedStream "BufferedStream".
|
---|
87 | * It can be used to acquire an instance of
|
---|
88 | * \ref hu::varadiistvan::scpl::io::ReadingBuffer "ReadingBuffer" for
|
---|
89 | * reading, and an instance of
|
---|
90 | * \ref hu::varadiistvan::scpl::io::WritingBuffer "WritingBuffer" for
|
---|
91 | * writing.
|
---|
92 | *
|
---|
93 | * To read, call the
|
---|
94 | * \ref hu::varadiistvan::scpl::io::ReadingBuffer::read "read"
|
---|
95 | * function. It returns \c true, if reading has succeeded, \c false
|
---|
96 | * otherwise which may indicate an error condition or simply the fact
|
---|
97 | * that nothing has been received yet, in which case the program can
|
---|
98 | * wait using the \c Waiter. If data has been read, it can be accessed
|
---|
99 | * by the buffer's methods inherited from
|
---|
100 | * \ref hu::varadiistvan::scpl::io::Buffer "Buffer". Before reading
|
---|
101 | * again, the buffer's
|
---|
102 | * \ref hu::varadiistvan::scpl::io::Buffer::reset "reset" function
|
---|
103 | * should be called, otherwise \c read just returns \c true and
|
---|
104 | * nothing happens.
|
---|
105 | *
|
---|
106 | * To write, put data into the writing buffer and call its
|
---|
107 | * \ref hu::varadiistvan::scpl::io::WritingBuffer::write "write"
|
---|
108 | * function. If all data in the buffer could be written, it returns
|
---|
109 | * \c true, otherwise \c false, which, again, might indicate error,
|
---|
110 | * but also the fact that not all data could be written. In this case,
|
---|
111 | * the program can wait, and then retry writing again, and do this
|
---|
112 | * until finally \c write returns \c true. If writing succeeds, the
|
---|
113 | * buffer is reset automatically, and one can put new data into it.
|
---|
114 | *
|
---|
115 | * The facilities described above provide for asynchronous,
|
---|
116 | * event-based stream handling, which is perfect for programs or
|
---|
117 | * threads that should work with several streams, timeouts and
|
---|
118 | * possibly other events simultaneously. This is, however, not always
|
---|
119 | * the case. It might very well be that one thread is dedicated to
|
---|
120 | * just deal with one stream only or at least with one stream at a
|
---|
121 | * time. In such a case this hocus-pocus with always (re)trying
|
---|
122 | * operations and waiting can be very cumbersome. It would be much
|
---|
123 | * better to just call a function to read or write, which would return
|
---|
124 | * only, if the requested operation has completed.
|
---|
125 | *
|
---|
126 | * This is provided by the
|
---|
127 | * \ref hu::varadiistvan::scpl::io::BlockingStream class. Its
|
---|
128 | * constructor receives and instance of \c BufferedStream, and it
|
---|
129 | * provides blocking read, write and flushing operations. It also has
|
---|
130 | * a \ref hu::varadiistvan::scpl::io::BlockingStream::interrupt "interrupt"
|
---|
131 | * function, which can be called from another thread. If the stream is
|
---|
132 | * blocking on an operation, that operation will then return with \c
|
---|
133 | * false, and the interrupted condition can the be
|
---|
134 | * \ref hu::varadiistvan::scpl::io::BlockingStream::isInterrupted
|
---|
135 | * "checked".
|
---|
136 | *
|
---|
137 | * \c BlockingStream has a subclass called
|
---|
138 | * \ref hu::varadiistvan::scpl::io::DataStream "DataStream", which can
|
---|
139 | * be used to read and write values of the primitive data types. The
|
---|
140 | * endianness is that of the processor, i.e. no conversion is made to
|
---|
141 | * a common one.
|
---|
142 | */
|
---|