/*
 *
 *
 *    muxpipe.h
 *
 *    C++ header file for experimental buffered PIPE device
 *    class 'my::multiplexed::pipeend'
 *
 *    =========================================================================
 *
 *    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_PIPE_H
#define __MY_MUX_PIPE_H

	#include <my++/exception.h>
	#include <my++/watchable.h>
	#include <my++/pipe.h>
	#include <queue>

	namespace my {
		namespace multiplexed {
			class pipeend : public my::pipeend, public watchable {
				private: // internal object data
					std::queue<unsigned char> tx_buffer;
					std::queue<unsigned char> rx_buffer;
					size_t buffer_len;
					unsigned char *c_buffer;
					bool is_closed;
					bool tx_ok;
					static const size_t default_buffer_length = 1024;

				protected:
					void assign(int f, mode m);

				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 iodevice
					virtual size_t get (std::string &s);
					virtual size_t get (unsigned char *b, size_t len);
					virtual size_t get (char *b, size_t len);
					virtual size_t get (void *b, size_t len);

					virtual size_t put (const std::string &s);
					virtual size_t put (const unsigned char *b, size_t len);
					virtual size_t put (const char *b, size_t len);
					virtual size_t put (const void *b, size_t len);

					virtual void close (void) throw();

				public: // public interface
					// returns true if there are characters received and waiting
					size_t ready (void) { return rx_buffer.size(); };

					// returns true if the device has closed
					bool closed (void) { return is_closed; };

					// resizes the internal I/O buffer
					void buffer (size_t len = default_buffer_length);

				public: // ctors/dtors [ need to add more ctors ]
					pipeend (void);
					~pipeend (void) throw();

				private: // want to explicitly disallow these
					pipeend (const pipeend &s);
			};
		}
	}


#endif /* __MY_MUX_PIPE_H */
