/*
 *
 *
 *    muxudpsocket.h
 *
 *    C++ header file for experimental buffered TCP socket
 *    class 'my::multiplexed::udpsocket'
 *
 *    =========================================================================
 *
 *    Copyright (C) 2001-2003 by Matt Roberts, KK5JY.
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation; either
 *    version 2.1 of the License, or (at your option) any later version.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *    =========================================================================
 *
 *
 */


#ifndef __MY_MUX_UDPSOCKET_H
#define __MY_MUX_UDPSOCKET_H

	#include <my++/exception.h>
	#include <my++/udpsocket.h>
	#include <my++/watchable.h>
	#include <my++/dgqueue.h>
	#include <deque>

	namespace my {
		namespace multiplexed {
			class udpsocket : public my::udpsocket, public watchable {
				public:

					/*
					 *
					 *    address
					 *
					 */

					typedef my::udpsocket::address address;


				private: // internal object data
					typedef unsigned char byte_t;
					dgqueue<byte_t> rx_buffer, tx_buffer;
					std::deque<address> rx_address, tx_address;
					size_t buffer_len;
					unsigned char *c_buffer;
					bool tx_ok;

				protected: // from watchable: used for multiplexing
					virtual bool read_action(void);
					virtual bool write_action(void);

					virtual bool should_watch_read(void);
					virtual bool should_watch_write(void);

					virtual int read_desc (void) { return getfd(); };
					virtual int write_desc (void) { return getfd(); };
					virtual int except_desc (void) { return getfd(); };

				public: // from datagram_socket
					virtual size_t get_from (socket::address &a, unsigned char *b, size_t len);
					virtual size_t get_from (socket::address &a, char *b, size_t len);
					virtual size_t get_from (socket::address &a, void *b, size_t len);

					virtual size_t put_to (const socket::address &a, const unsigned char *b, size_t len);
					virtual size_t put_to (const socket::address &a, const char *b, size_t len);
					virtual size_t put_to (const socket::address &a, const void *b, size_t len);

				public: // public 1nt3rf8c3
					size_t ready (void) { return rx_buffer.size(); };
					size_t tx_queue (void) const { return tx_buffer.size(); };
					size_t rx_queue (void) const { return rx_buffer.size(); };
					void buffer (size_t len);

				public: // ctors/dtors
					udpsocket (void);
					udpsocket (const inet_address &a, int p);
					udpsocket (const address &a);
					udpsocket (const std::string &a, int p);
					~udpsocket (void) throw() { if (c_buffer != 0) delete [] c_buffer; };

				private:
					udpsocket (const my::multiplexed::udpsocket &s);
			};
		}
	}


#endif /* __MY_MUX_UDPSOCKET */
