//
// See the file LICENSE for redistribution information.
//
// Copyright (c) 2002-2003
//	Sleepycat Software.  All rights reserved.
//
// $Id: Buffer.hpp,v 1.14 2003/05/09 00:01:43 mjc Exp $
//

#ifndef __BUFFER_HPP
#define	__BUFFER_HPP

#include <string>

namespace DbXml
{

class DBXML_EXPORT Buffer
{
public:
	// Default constructor.  Use Set to construct the buffer.
	Buffer();
	// Construct from a buffer and size. Buffer copies this into its own memory.
	Buffer(const void *p, size_t size);
	// Construct from a Buffer, with some extra space. Buffer copies this into its own memory.
	Buffer(const Buffer& buffer, size_t extra = 0);
	// Construct from a buffer and size. Buffer points to this memory. Buffer can't expand. Buffer won't deallocate this.
	Buffer(const void *p, size_t size, bool wrapper);
	// Default destructor
	~Buffer();

	// Assignment operator
	Buffer& operator= (const Buffer& buffer);
	// Set the buffer contents from a buffer and size.  Used for delayed construction.
	void set(void *p, size_t nSize);

	// Get the size of the buffer in bytes.
	size_t getSize() const;
	// Get the current cursor position as a bytes offset.
	size_t getCursorPosition() const;
	// Set the buffer cursor to the start of the buffer.
	void resetCursorPosition();
	// Returns the amount of buffer used. The highest position reached by the cursor.
	size_t getOccupancy() const;
	// Set the buffer occupancy to zero.
	void resetOccupancy();
	// Return the buffer to its before use state. (Cursor==0 && Occupancy==0)
	void reset();
	// Get a pointer to the internal buffer
	void* getBuffer() const;
	// Get a pointer to the cursor position
	void* getCursor() const;
	// How much data is remaining between the cursor and the occupancy.
	size_t getRemaining() const;

	// Read n bytes into buffer p from the current position.
	size_t read(void *p, size_t n);
	// Write n bytes from buffer p to the current position.
	size_t write(const void *p, size_t n);

	// Comparison operator
	int operator==(const Buffer& buffer) const;
	int operator!=(const Buffer& buffer) const;

	// Debug method to get a text representation of the buffer
	std::string asString() const;

private:
	void deleteBuffer();
	void expandBuffer(size_t amount);

	size_t bufferSize_;
	void* pBuffer_;
	void* pCursor_;
	void* pOccupancy_;
	bool ownsMemory_;
};

inline size_t Buffer::getSize() const
{
	return bufferSize_;
}

inline void Buffer::resetCursorPosition()
{
	pCursor_ = pBuffer_;
}

inline void* Buffer::getBuffer() const
{
	return pBuffer_;
}

inline void* Buffer::getCursor() const
{
	return pCursor_;
}

inline int Buffer::operator!=(const Buffer& buffer) const
{
	return !operator==(buffer);
}

inline void Buffer::resetOccupancy()
{
	pOccupancy_ = pBuffer_;
}

inline void Buffer::reset()
{
	resetCursorPosition();
	resetOccupancy();
}

inline size_t Buffer::getRemaining() const
{
	return static_cast<char*>(pOccupancy_) - static_cast<char*>(pCursor_);
}

}

#endif

