/*****************************************************************************/
// Copyright 2006-2019 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE:  Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/

/** \file
 * Stream abstraction to/from in-memory data.
 */

/*****************************************************************************/

#ifndef __dng_memory_stream__
#define __dng_memory_stream__

/*****************************************************************************/

#include "dng_stream.h"

/*****************************************************************************/

/// \brief A dng_stream which can be read from or written to memory.
///
/// Stream is populated via writing and either read or accessed by asking for contents as a pointer.

class dng_memory_stream: public dng_stream
	{
	
	protected:
	
		dng_memory_allocator &fAllocator;
		
		uint32 fPageSize;
		
		uint32 fPageCount;
		uint32 fPagesAllocated;
		
		dng_memory_block **fPageList;
		
		uint64 fMemoryStreamLength;
        
        uint64 fLengthLimit;
		
	public:

		/// Construct a new memory-based stream.
		/// \param allocator Allocator to use to allocate memory in stream as needed.
		/// \param sniffer If non-NULL used to check for user cancellation.
		/// \param pageSize Unit of allocation for data stored in stream.

		dng_memory_stream (dng_memory_allocator &allocator,
						   dng_abort_sniffer *sniffer = NULL,
						   uint32 pageSize = 64 * 1024);
						   
		virtual ~dng_memory_stream ();
        
        /// Sets a maximum length limit.
        
        void SetLengthLimit (uint64 limit)
            {
            fLengthLimit = limit;
            }

		/// Copy a specified number of bytes to a target stream.
		/// \param dstStream The target stream.
		/// \param count The number of bytes to copy.
		
		virtual void CopyToStream (dng_stream &dstStream,
								   uint64 count);
		
	protected:
		
		virtual uint64 DoGetLength ();
	
		virtual void DoRead (void *data,
							 uint32 count,
							 uint64 offset);
							 
		virtual void DoSetLength (uint64 length);
							 
		virtual void DoWrite (const void *data,
							  uint32 count,
							  uint64 offset);
		
	};

/*****************************************************************************/

#endif
	
/*****************************************************************************/
