/******************************************************************************/
/* MEMORY STREAMS *************************************************************/
/******************************************************************************/

#pragma once
#include <lw/lib/Streams.hh>
namespace lw {


class T_MemoryInputStream final : public A_InputStream
{
   private:
	uint8_t const* buffer_;

   public:
	T_MemoryInputStream( ) = delete;
	T_MemoryInputStream( void const* buffer , size_t size );

	T_MemoryInputStream( T_MemoryInputStream const& other ) noexcept;
	friend void swap( T_MemoryInputStream& lhs , T_MemoryInputStream& rhs ) noexcept;

	T_MemoryInputStream& operator= ( T_MemoryInputStream const& other ) noexcept;

	template< int S , typename T >
	explicit T_MemoryInputStream( T_FixedBuffer< S , T > const& buffer );

	template< typename T >
	explicit T_MemoryInputStream( T_Buffer< T > const& buffer );

	size_t read( void* data , size_t size ) override;
};
M_CLASS_POINTERS( MemoryInputStream );


/*----------------------------------------------------------------------------*/

class T_MemoryOutputStream final : public A_OutputStream
{
	typedef std::function< uint8_t*( uint8_t* , size_t ) > F_Resizer;

   private:
	uint8_t* buffer_;
	F_Resizer resizer_;

   public:
	T_MemoryOutputStream( ) = delete;

	T_MemoryOutputStream( void* buffer , size_t size , F_Resizer resizer = nullptr );

	template< int S , typename T >
	explicit T_MemoryOutputStream( T_FixedBuffer< S , T >& buffer );

	template< typename T >
	explicit T_MemoryOutputStream( T_Buffer< T >& buffer );

	size_t write( void const* data , size_t size ) override;
};
M_CLASS_POINTERS( MemoryOutputStream );


} // namespace
#include <lw/lib/inline/MemoryStreams.hh>