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
00367 #define CONEXUS_ENDPOINT_GENERIC_CREATE() static Endpoint::pointer generic_create() { return create(); }
00368
00369 namespace Conexus
00370 {
00371
00376 struct Timeout
00377 {
00378 Timeout( long int us=0 ): sec(0), nsec(us*1000) { }
00379
00380 Timeout( long int s, long int ns ): sec(s), nsec(ns) { }
00381
00382 operator struct timeval()
00383 {
00384 struct timeval tv;
00385 tv.tv_sec = sec;
00386 tv.tv_usec = nsec / 1000 + ((nsec%1000>=500)?1:0);
00387 return tv;
00388 }
00389
00390 operator struct timespec()
00391 {
00392 struct timespec ts;
00393 ts.tv_sec = sec;
00394 ts.tv_nsec = nsec;
00395 return ts;
00396 }
00397
00398 operator bool() { return sec > 0 && nsec >= 0; }
00399
00400 operator double() { return sec + nsec/1000000000.0; }
00401
00402 Timeout& operator=(const struct timeval& tv) { sec = tv.tv_sec; nsec = tv.tv_usec * 1000; return *this; }
00403
00404 Timeout& operator=(const struct timespec& tv) { sec = tv.tv_sec; nsec = tv.tv_nsec; return *this; }
00405
00406 bool operator==( const Timeout& other ) const { return sec == other.sec && nsec == other.nsec; }
00407
00408 bool is_zero() const { return sec == 0 && nsec == 0; }
00409
00410 bool is_null() const { return sec < 0 || nsec < 0; }
00411
00412 long int sec;
00413 long int nsec;
00414 };
00415
00431 class Endpoint: public Object
00432 {
00433 protected:
00434
00442 Endpoint(bool close_on_destruct=true);
00443
00444 public:
00445
00447 typedef ConexusPointer<Endpoint> pointer;
00448
00453 virtual ~Endpoint();
00454
00466 virtual void start( );
00467
00472 virtual void start( bool use_dispatcher );
00473
00478 virtual void stop( );
00479
00481 virtual bool is_running();
00482
00484 virtual bool is_timestamping_received_data();
00485
00487 virtual void set_timestamp_received_data(bool t=true);
00488
00495 sigc::signal<void, const Data> signal_data();
00496
00504 sigc::signal<void, size_t> signal_data_received_size();
00505
00513 sigc::signal<void, size_t> signal_data_transmitted_size();
00514
00516 sigc::signal<void> signal_opened();
00517
00519 sigc::signal<void> signal_closed();
00520
00526 sigc::signal<void,StartStop> signal_start_stop();
00527
00531 sigc::signal<void> signal_eof();
00532
00536 sigc::signal<void> signal_disconnected();
00537
00539 const Timeout& default_read_timeout() const;
00540
00546 void set_default_read_timeout( Timeout t );
00547
00555 size_t fallback_read_size();
00556
00558 void set_fallback_read_size(size_t s);
00559
00561 const Timeout& default_write_timeout() const;
00562
00568 void set_default_write_timeout( Timeout t );
00569
00570 bool read_terminate_immediate();
00571
00572 void set_read_terminate_immediate( bool i=true );
00573
00577 virtual void open() throw (open_exception) = 0;
00578
00581 virtual void close(bool force=false) throw (close_exception) = 0;
00582
00594 ssize_t write(const void* data, size_t size) throw (write_exception);
00595
00604 ssize_t write(const void* data, size_t size, Timeout timeout ) throw (write_exception);
00605
00610 ssize_t write(Endpoint::pointer source, size_t block_size=65535, bool keep_open=true);
00611
00622 ssize_t write(const Data data) throw (write_exception);
00623
00631 ssize_t write(const Data data, Timeout timeout ) throw (write_exception);
00632
00647 Data read( size_t size=0 ) throw (read_exception);
00648
00663 Data read( size_t size, Timeout timeout ) throw (read_exception);
00664
00679 Data read( Timeout timeout ) throw (read_exception);
00680
00685 virtual size_t input_available() throw ();
00686
00701 virtual void change_state(long new_state) throw (state_exception);
00702
00707 long state();
00708
00710 void set_close_on_destruct(bool value);
00711
00713 bool close_on_destruct() const;
00714
00723 void close_and_reopen(long state = ENDPOINT_UNCHANGED);
00724
00726 bool is_open();
00727
00729 bool is_closed();
00730
00731 protected:
00732 bool m_use_blocking_reads;
00733 bool m_use_blocking_writes;
00734
00735 Glib::Thread *m_read_thread;
00736 Glib::Thread *m_read_delivery_thread;
00737 bool m_read_terminate;
00738 bool m_read_terminate_immediate;
00739
00740 Timeout m_default_read_timeout;
00741 size_t m_fallback_read_size;
00742 Timeout m_default_write_timeout;
00743 bool m_timestamp;
00744
00745 Glib::Mutex m_read_queue_lock;
00746
00747 Glib::Cond m_read_delivery_conditional;
00748
00749 Glib::Dispatcher* m_dispatcher;
00750 bool m_use_dispatcher;
00751
00752 sigc::signal<void, const Data> m_signal_data;
00753 sigc::signal<void, size_t> m_signal_data_received_size;
00754 sigc::signal<void, size_t> m_signal_data_transmitted_size;
00755 std::queue<Data> m_read_queue;
00756
00757 virtual void read_thread_main();
00758 void read_thread_main_proxy();
00759
00760 virtual void read_delivery_thread_main();
00761
00762 void queue_received_data( const Data d );
00763
00764 void emit_received_data( );
00765
00766
00767 bool m_close_on_destruct;
00768 long m_state;
00769 bool m_readable;
00770 bool m_writable;
00771
00772 virtual void set_state_opened();
00773 virtual void set_state_closed();
00774
00775 sigc::signal<void> m_signal_opened;
00776 sigc::signal<void> m_signal_closed;
00777 sigc::signal<void,StartStop> m_signal_start_stop;
00778 sigc::signal<void> m_signal_eof;
00779 sigc::signal<void> m_signal_disconnected;
00780
00781 virtual size_t write_data(const Data data, Timeout timeout) throw (write_exception) = 0;
00782
00809 virtual Data read_data( size_t size, Timeout timeout) throw (read_exception) = 0;
00810 };
00811
00812 }
00813
00814 Conexus::Endpoint& operator<<(Conexus::Endpoint& io, const Conexus::Data d);
00815 Conexus::Endpoint::pointer operator<<(Conexus::Endpoint::pointer io, const Conexus::Data d);
00816 Conexus::Endpoint& operator>>(Conexus::Endpoint& io, Conexus::Data d);
00817 Conexus::Endpoint::pointer operator>>(Conexus::Endpoint::pointer io, Conexus::Data d);
00818
00819 #endif