/***************************************************************************
                          SIMPLY POWERFUL TOOLKIT (SPTK)
                          CBuffer.h  -  description
                             -------------------
    begin                : Mon Apr 17 2000
    copyright            : (C) 2000-2005 by Alexey S.Parshin
    email                : alexeyp@gmail.com
 ***************************************************************************/

/***************************************************************************
   This library is free software; you can redistribute it and/or modify it 
   under the terms of the GNU Library General Public License as published by
   the Free Software Foundation; either version 2 of the License, or (at 
   your option) any later version.

   This library 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 Library
   General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; if not, write to the Free Software Foundation, 
   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.

   Please report all bugs and problems to "alexeyp@gmail.com"
 ***************************************************************************/

#ifndef __CBUFFER_H__
#define __CBUFFER_H__

#include <sptk3/sptk.h>

#include <string>

/// @addtogroup utility Utility Classes
/// @{

/// @brief Memory data buffer
///
/// Generic buffer with a special memory-allocation strategy for effective append() operation 
class SP_EXPORT CBuffer {
protected:
   unsigned m_size;     ///< Allocated size of the buffer
   unsigned m_bytes;    ///< Actual size of the data in buffer
   char *   m_buffer;   ///< The buffer itself
public:

   /// Default constructor creates an empty buffer.
   /// The return of the bytes() method will be 0.
   /// @param sz buffer size to be pre-allocated
   CBuffer(unsigned sz=16);

   /// Constructor creates a buffer from string.
   /// The string is copied inside the buffer.
   /// The return of the bytes() method will be the input string length.
   /// @param str const char *, input string
   CBuffer(const char *str);

   /// Constructor creates a buffer from string.
   /// The string is copied inside the buffer.
   /// The return of the bytes() method will be the input string length.
   /// @param str const std::string&, input string
   CBuffer(const std::string& str);

   /// Constructor creates a buffer from void *data.
   /// The data is copied inside the buffer.
   /// The return of the bytes() method will be the input data size.
   /// @param data void * data buffer
   /// @param sz data buffer size
   CBuffer(const void *data,unsigned sz);

   /// Copy constructor creates a buffer from another buffer.
   /// The data is copied inside the buffer.
   /// The return of the bytes() method will be the input data size.
   /// @param buffer CBuffer, data buffer
   CBuffer(const CBuffer& buffer);

   /// Destructor releases the allocated memory
   ~CBuffer();

   /// Method data()
   /// @returns pointer on the data buffer.
   char *data() const { return m_buffer; }

   /// Method checkSize() checks if the current buffer size is enogh
   /// to fit in the sz (required memory size) bytes. Allocates memory
   /// if needed.
   /// @param sz required memory size
   /// @returns success (true) or failure (false)
   bool checkSize(unsigned sz);

   /// Method set() copies the external data of size sz into the current buffer.
   /// Allocates memory if needed.
   /// @param data external data buffer
   /// @param sz required memory size
   /// @returns success (true) or failure (false)
   void set(const char *data,unsigned sz);

   /// Method append() appends a single to the current buffer.
   /// Allocates memory if needed.
   /// @param ch single character
   /// @returns success (true) or failure (false)
   bool append(char ch);

   /// Method append() appends the external data of size sz to the current buffer.
   /// Allocates memory if needed.
   /// @param data external data buffer
   /// @param sz required memory size
   /// @returns success (true) or failure (false)
   bool append(const char *data,unsigned sz);

   /// Method append() appends the string to the current buffer.
   /// Allocates memory if needed.
   /// @param str std::string
   /// @returns success (true) or failure (false)
   bool append(const std::string& str) { return append(str.c_str(),str.length()); }

   /// Method reset() truncates the current buffer to the size sz.
   /// Deallocates unused memory if needed.
   /// @param sz the required data size in bytes
   void reset(unsigned sz=0);

   /// Method fill() fills the bytes() charcters in buffer with character ch.
   /// @param ch the charater to fill the buffer
   void fill(char ch);

   /// Returns thes size of memory allocated for the data buffer
   /// @returns buffer size 
   unsigned size()  const { return m_size;   }

   /// Returns the size of data in the data buffer
   /// @returns data size
   unsigned bytes() const { return m_bytes;  }

   /// Sets the size of the data buffer to b. This method
   /// simply sets the internal buffer size. It doesn't check anything
   /// so use it this caution.
   /// @param b the new size of the buffer
   void bytes(unsigned b) { m_bytes = b;     }

   /// Loads the buffer from file fileName.
   /// @param fileName the name of the input file
   void loadFromFile(const char *fileName);

   /// Saves the buffer to the file fileName.
   /// @param fileName the name of the output file
   void saveToFile(const char *fileName) const;

   /// Assigns from CBuffer
   /// @param b const CBuffer&, the buffer to assign from
   /// @returns this object
   CBuffer& operator = (const CBuffer& b);

   /// Assigns from CString
   /// @param str const std::string&, the string to assign from
   /// @returns this object
   CBuffer& operator = (const std::string& str);

   /// Assigns from char *
   /// @param str const char *, the string to assign from
   /// @returns this object
   CBuffer& operator = (const char *str);
};

/// @}

#endif
