// DWBS ------------------------------------------------------------------ DWBS
//
// PLATFORM		: ALL
// PRODUCT		: BIT_DEMON
// VISIBILITY	: PUBLIC
//
// DWBS ------------------------------------------------------------------ DWBS

// PURPOSE: A generic implementation of the bdStreamBuf class.

#ifndef BD_STDIO_STREAMBUF_H
#define BD_STDIO_STREAMBUF_H

#include <stdio.h>

#include <bdCore/bdMemory/bdMemory.h>
#include <bdCore/bdStreams/bdStreambuf.h>

/// Provides a generic implementation of the bdStreambuf abstract base.
/// This class uses the standard i/o routines of <stdio.h> to implement a
/// stream buffer.
/// Any input or output source to which you can get a stdio FILE* handle
/// can be used with this class. For an example see bdStdioFileStreambuf.
class bdStdioStreambuf : public bdStreambuf
{
	public:

		BD_DECLARE_NEW_AND_DELETE_OPERATORS

		/// Default constructor. \a m_handle is initialized to \a BD_NULL.
		bdStdioStreambuf();

		/// Constructs a \a bdStdioStreambuf with a given \a FILE handle.
		bdStdioStreambuf(FILE *const handle);

		/// Virtual destructor
		virtual ~bdStdioStreambuf();

	protected:

		/// Pure virtual function overridden from bdStreambuf.
		/// Attempts to read \a nbytes of raw data from the device pointed
		/// to by \a m_handle.
		/// \param dest[out] Put the requested data into this location.
		/// \param nbytes[in] The number of bytes to get from the device.
		/// \return The number bytes actually read.
		/// \note If the return value differs from \a nbytes,
		///  \a END_OF_FILE has been reached.
		virtual bdUInt bufGetFrom(bdNChar8 *const dest,
									const bdUInt nbytes);

		/// Pure virtual function overridden from bdStreambuf.
		/// Attempts to write \a nbytes of raw data from the device pointed
		/// to by \a m_handle.
		/// \param src[out] Get the required data from this location.
		/// \param nbytes[in] The number of bytes to try and write to the device.
		/// \return The number bytes actually written.
		/// \note If this differs from \a nbytes a \a WRITE_ERROR has occured.
		virtual bdUInt bufPutTo(bdNChar8 *const src,
								  const bdUInt nbytes);

		/// Virtual function overridden from bdStreambuf.
		/// Attempts to set the position indicator for the device pointed
		/// to by \a m_handle.
		/// \param offset[in] The offset to use when seeking.
		/// \param from[in] The place to start seeking.
		/// \return
		///  - True if successful.
		///  - False otherwise.
		virtual bdBool bufSeek(const bdInt offset,
							   const SeekFrom from);

		/// Virtual function overridden from bdStreambuf.
		/// Attempts to set \a offset to the current position indicator of the
		/// device pointed to by \a m_handle.
		/// \param offset[out] The offset to set.
		/// \return
		///  - True if successful.
		///  - False otherwise.
		virtual bdBool bufTell(bdUInt &offset) const;

		/// Virtual function overridden from bdStreambuf.
		/// Flushes the device pointed to by \a m_handle.
		virtual void bufFlush();

	protected:

		/// The handle to the file object manipulated by this stream buffer.
		FILE *m_handle;
};


#endif // BD_STDIO_STREAMBUF_H
