endpoint.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef CONEXUSIO_H
00020 #define CONEXUSIO_H
00021
00022 #include <set>
00023 #include <queue>
00024
00025 #include <sys/select.h>
00026
00027 #include <glibmm/dispatcher.h>
00028 #include <glibmm/thread.h>
00029
00030 #include <conexus/pointer.h>
00031 #include <conexus/enums.h>
00032 #include <conexus/except.h>
00033 #include <conexus/data.h>
00034 #include <conexus/object.h>
00035
00044 #define CONEXUS_ENDPOINT_GENERIC_CREATE() static Endpoint::pointer generic_create() { return create(); }
00045
00046 namespace Conexus
00047 {
00048
00053 struct Timeout
00054 {
00055 Timeout( long int us=0 ): sec(0), nsec(us*1000) { }
00056
00057 Timeout( long int s, long int ns ): sec(s), nsec(ns) { }
00058
00059 operator struct timeval()
00060 {
00061 struct timeval tv;
00062 tv.tv_sec = sec;
00063 tv.tv_usec = nsec / 1000 + ((nsec%1000>=500)?1:0);
00064 return tv;
00065 }
00066
00067 operator struct timespec()
00068 {
00069 struct timespec ts;
00070 ts.tv_sec = sec;
00071 ts.tv_nsec = nsec;
00072 return ts;
00073 }
00074
00075 operator bool() { return sec > 0 && nsec >= 0; }
00076
00077 operator double() { return sec + nsec/1000000000.0; }
00078
00079 Timeout& operator=(const struct timeval& tv) { sec = tv.tv_sec; nsec = tv.tv_usec * 1000; return *this; }
00080
00081 Timeout& operator=(const struct timespec& tv) { sec = tv.tv_sec; nsec = tv.tv_nsec; return *this; }
00082
00083 bool operator==( const Timeout& other ) const { return sec == other.sec && nsec == other.nsec; }
00084
00085 bool is_zero() const { return sec == 0 && nsec == 0; }
00086
00087 bool is_null() const { return sec < 0 || nsec < 0; }
00088
00089 long int sec;
00090 long int nsec;
00091 };
00092
00108 class Endpoint: public Object
00109 {
00110 protected:
00111
00119 Endpoint(bool close_on_destruct=true);
00120
00121 public:
00122
00124 typedef ConexusPointer<Endpoint> pointer;
00125
00130 virtual ~Endpoint();
00131
00143 virtual void start( );
00144
00149 virtual void start( bool use_dispatcher );
00150
00155 virtual void stop( );
00156
00158 virtual bool is_running();
00159
00161 virtual bool is_timestamping_received_data();
00162
00164 virtual void set_timestamp_received_data(bool t=true);
00165
00172 sigc::signal<void, const Data> signal_data();
00173
00181 sigc::signal<void, size_t> signal_data_received_size();
00182
00190 sigc::signal<void, size_t> signal_data_transmitted_size();
00191
00193 sigc::signal<void> signal_opened();
00194
00196 sigc::signal<void> signal_closed();
00197
00203 sigc::signal<void,StartStop> signal_start_stop();
00204
00208 sigc::signal<void> signal_eof();
00209
00213 sigc::signal<void> signal_disconnected();
00214
00216 const Timeout& default_read_timeout() const;
00217
00223 void set_default_read_timeout( Timeout t );
00224
00232 size_t fallback_read_size();
00233
00235 void set_fallback_read_size(size_t s);
00236
00238 const Timeout& default_write_timeout() const;
00239
00245 void set_default_write_timeout( Timeout t );
00246
00247 bool read_terminate_immediate();
00248
00249 void set_read_terminate_immediate( bool i=true );
00250
00254 virtual void open() throw (open_exception) = 0;
00255
00258 virtual void close(bool force=false) throw (close_exception) = 0;
00259
00271 ssize_t write(const void* data, size_t size) throw (write_exception);
00272
00281 ssize_t write(const void* data, size_t size, Timeout timeout ) throw (write_exception);
00282
00287 ssize_t write(Endpoint::pointer source, size_t block_size=65535, bool keep_open=true);
00288
00299 ssize_t write(const Data data) throw (write_exception);
00300
00308 ssize_t write(const Data data, Timeout timeout ) throw (write_exception);
00309
00324 Data read( size_t size=0 ) throw (read_exception);
00325
00340 Data read( size_t size, Timeout timeout ) throw (read_exception);
00341
00356 Data read( Timeout timeout ) throw (read_exception);
00357
00362 virtual size_t input_available() throw ();
00363
00378 virtual void change_state(long new_state) throw (state_exception);
00379
00384 long state();
00385
00387 void set_close_on_destruct(bool value);
00388
00390 bool close_on_destruct() const;
00391
00400 void close_and_reopen(long state = ENDPOINT_UNCHANGED);
00401
00403 bool is_open();
00404
00406 bool is_closed();
00407
00408 protected:
00409 bool m_use_blocking_reads;
00410 bool m_use_blocking_writes;
00411
00412 Glib::Thread *m_read_thread;
00413 Glib::Thread *m_read_delivery_thread;
00414 bool m_read_terminate;
00415 bool m_read_terminate_immediate;
00416
00417 Timeout m_default_read_timeout;
00418 size_t m_fallback_read_size;
00419 Timeout m_default_write_timeout;
00420 bool m_timestamp;
00421
00422 Glib::Mutex m_read_queue_lock;
00423
00424 Glib::Cond m_read_delivery_conditional;
00425
00426 Glib::Dispatcher* m_dispatcher;
00427 bool m_use_dispatcher;
00428
00429 sigc::signal<void, const Data> m_signal_data;
00430 sigc::signal<void, size_t> m_signal_data_received_size;
00431 sigc::signal<void, size_t> m_signal_data_transmitted_size;
00432 std::queue<Data> m_read_queue;
00433
00434 virtual void read_thread_main();
00435 void read_thread_main_proxy();
00436
00437 virtual void read_delivery_thread_main();
00438
00439 void queue_received_data( const Data d );
00440
00441 void emit_received_data( );
00442
00443
00444 bool m_close_on_destruct;
00445 long m_state;
00446 bool m_readable;
00447 bool m_writable;
00448
00449 virtual void set_state_opened();
00450 virtual void set_state_closed();
00451
00452 sigc::signal<void> m_signal_opened;
00453 sigc::signal<void> m_signal_closed;
00454 sigc::signal<void,StartStop> m_signal_start_stop;
00455 sigc::signal<void> m_signal_eof;
00456 sigc::signal<void> m_signal_disconnected;
00457
00458 virtual size_t write_data(const Data data, Timeout timeout) throw (write_exception) = 0;
00459
00486 virtual Data read_data( size_t size, Timeout timeout) throw (read_exception) = 0;
00487 };
00488
00489 }
00490
00491 Conexus::Endpoint& operator<<(Conexus::Endpoint& io, const Conexus::Data d);
00492 Conexus::Endpoint::pointer operator<<(Conexus::Endpoint::pointer io, const Conexus::Data d);
00493 Conexus::Endpoint& operator>>(Conexus::Endpoint& io, Conexus::Data d);
00494 Conexus::Endpoint::pointer operator>>(Conexus::Endpoint::pointer io, Conexus::Data d);
00495
01005 #endif