|
|
/*------------------------------------------------------------------------------ Copyright (c) 2000 Tyrell Corporation. All rights reserved. Tyrell DarkIce File : BufferedSink.h Version : $Revision: 1.7 $ Author : $Author: darkeye $ Location : $Source: /cvsroot/darkice/darkice/src/BufferedSink.h,v $ Copyright notice: This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ------------------------------------------------------------------------------*/ #ifndef BUFFERED_SINK_H #define BUFFERED_SINK_H #ifndef __cplusplus #error This is a C++ include file #endif /* ============================================================ include files */ #include "Ref.h" #include "Reporter.h" #include "Sink.h" /* ================================================================ constants */ /* =================================================================== macros */ /* =============================================================== data types */ /** * A Sink First-In First-Out buffer. * This buffer can always be written to, it overwrites any * data contained if needed. * The class is not thread-safe. * * @author $Author: darkeye $ * @version $Revision: 1.7 $ */ class BufferedSink : public Sink, public virtual Reporter { private: /** * The buffer. */ unsigned char * buffer; /** * The end of the buffer. */ unsigned char * bufferEnd; /** * The size of the buffer. */ unsigned int bufferSize; /** * The highest usage of the buffer. */ unsigned int peak; /** * All data written to this BufferedSink is handled by chuncks * of this size. */ unsigned int chunkSize; /** * Number of bytes the underlying stream is misaligned with * chunkSize. (It needs this many bytes more to be aligned.) */ unsigned int misalignment; /** * Start of free territory in buffer. */ unsigned char * inp; /** * Start of sensible data in buffer. */ unsigned char * outp; /** * The underlying Sink. */ Refsink; /** * Initialize the object. * * @param sink the Sink to attach this BufferedSink to. * @param size the size of the internal buffer to use. * @param chunkSize size of chunks to handle data in. * @exception Exception */ void init ( Sink * sink, unsigned int size, unsigned int chunkSize ) throw ( Exception ); /** * De-initialize the object. * * @exception Exception */ void strip ( void ) throw ( Exception ); /** * Slide a pointer in the internal buffer by offset. If the pointer * would reach beyond the end of the buffer, it goes wraps around. * * @param p the pointer to slide. * @param offset the amount to slide with. * @return pointer p + offset, wrapped around if needed. */ inline unsigned char * slidePointer ( unsigned char * p, unsigned int offset ) throw () { p += offset; while ( p >= bufferEnd ) { p -= bufferSize; } return p; } /** * Update the peak buffer usage indicator. * * @see #peak */ inline void updatePeak ( void ) throw () { unsigned int u; u = outp <= inp ? inp - outp : (bufferEnd - outp) + (inp - buffer); if ( peak < u ) { reportEvent( 4, "BufferedSink, new peak:", peak); reportEvent( 4, "BufferedSink, remaining:", bufferSize - peak); peak = u; } } /** * If the underlying Sink is misaligned on chunkSize, write as * many 0s as needed to get it aligned. * * @see #misalignment * @see #chunkSize */ inline bool align ( void ) throw ( Exception ) { char b[] = { 0 }; while ( misalignment ) { if ( sink->canWrite( 0, 0) ) { unsigned int ret; if ( !(ret = sink->write( b, 1)) ) { return false; } --misalignment; } else { return false; } } return true; } protected: /** * Default constructor. Always throws an Exception. * * @exception Exception */ inline BufferedSink ( void ) throw ( Exception ) { throw Exception( __FILE__, __LINE__); } /** * Get the size of the buffer. * * @return the size of the buffer. */ inline unsigned int getSize ( void ) const throw () { return bufferSize; } /** * Store data in the internal buffer. If there is not enough space, * discard all in the buffer and the beginning of the supplied * buffer if needed. * * @param buffer the data to store. * @param bufferSize the amount of data to store in bytes. * @return number of bytes really stored. */ unsigned int store ( const void * buffer, unsigned int bufferSize ) throw ( Exception ); public: /** * Constructor by an underlying Sink, buffer size and chunk size. * * @param sink the Sink to attach this BufferSink to. * @param size the size of the buffer to use for buffering. * @param chunkSize hanlde all data in write() as chunks of * chunkSize * @exception Exception */ inline BufferedSink ( Sink * sink, unsigned int size, unsigned int chunkSize = 1 ) throw ( Exception ) { init( sink, size, chunkSize); } /** * Copy constructor. * * @param buffer the object to copy. * @exception Exception */ BufferedSink ( const BufferedSink & buffer ) throw ( Exception ); /** * Destructor. * * @exception Exception */ inline virtual ~BufferedSink ( void ) throw ( Exception ) { strip(); } /** * Assignment operator. * * @param bs the object to assign to this one. * @return a reference to this object. * @exception Exception */ virtual BufferedSink & operator= ( const BufferedSink & bs ) throw ( Exception ); /** * Get the peak usage of the internal buffer. * * @return the peak usage of the internal buffer. */ inline unsigned int getPeak ( void ) const throw () { return peak; } /** * Open the BufferedSink. Opens the underlying Sink. * * @return true if opening was successful, false otherwise. * @exception Exception */ inline virtual bool open ( void ) throw ( Exception ) { return sink->open(); } /** * Check if a BufferedSink is open. * * @return true if the BufferedSink is open, false otherwise. */ inline virtual bool isOpen ( void ) const throw () { return sink->isOpen(); } /** * Check if the BufferedSink is ready to accept data. * Always returns true immediately. * * @param sec the maximum seconds to block. * @param usec micro seconds to block after the full seconds. * @return true * @exception Exception */ inline virtual bool canWrite ( unsigned int sec, unsigned int usec ) throw ( Exception ) { return true; } /** * Write data to the BufferedSink. * Always reads the maximum number of chunkSize chunks buf * holds. If the data can not be written to the underlying * stream, it is buffered. If the buffer overflows, the oldest * data is discarded. * * @param buf the data to write. * @param len number of bytes to write from buf. * @return the number of bytes written (may be less than len). * @exception Exception */ virtual unsigned int write ( const void * buf, unsigned int len ) throw ( Exception ); /** * Flush all data that was written to the BufferedSink to the * underlying Sink. * * @exception Exception */ inline virtual void flush ( void ) throw ( Exception ) { unsigned char b[1]; write( b, 0); } /** * Close the BufferedSink. Closes the underlying Sink. * * @exception Exception */ virtual void close ( void ) throw ( Exception ); }; /* ================================================= external data structures */ /* ====================================================== function prototypes */ #endif /* BUFFERED_SINK_H */ /*------------------------------------------------------------------------------ $Source: /cvsroot/darkice/darkice/src/BufferedSink.h,v $ $Log: BufferedSink.h,v $ Revision 1.7 2002/07/21 08:47:06 darkeye some exception cleanup (throw clauses in function declarations) Revision 1.6 2002/05/28 12:35:41 darkeye code cleanup: compiles under gcc-c++ 3.1, using -pedantic option Revision 1.5 2000/11/15 18:08:42 darkeye added multiple verbosity-level event reporting and verbosity command line option Revision 1.4 2000/11/11 12:33:13 darkeye added kdoc-style documentation Revision 1.3 2000/11/10 20:16:21 darkeye first real tests with multiple streaming Revision 1.2 2000/11/05 17:37:24 darkeye removed clone() functions Revision 1.1.1.1 2000/11/05 10:05:48 darkeye initial version ------------------------------------------------------------------------------*/
Generated by: darkeye on destroy on Sun Feb 15 23:41:12 2004, using kdoc 2.0a54. |