/*

Copyright (c) 2002-2005, Yauheni Akhotnikau
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

- Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

- The name of the author may not be used to endorse or promote products derived
from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.

*/

/*!
	\file oess_1/io/h/bstring_buf.hpp
	\brief Классы %oess_1::io::ibstring_t, %oess_1::io::obstring_t.
*/

#if !defined( _OESS_1__IO__BSTRING_BUF_HPP_ )
#define _OESS_1__IO__BSTRING_BUF_HPP_

#include <oess_1/io/h/declspec.hpp>

#include <auto_ptr_3/h/vect_ptr.hpp>

#include <oess_1/io/h/binbuffer.hpp>

namespace oess_1 {

namespace io {

//
// ibstring_t
//

//! Двоичный входной поток из объекта std::string.
/*!
	Класс, предоставляющий средства ввода
	из объекта std::string, содержащего двоичные
	данные.

	Объект этого класса использует существующий
	объект std::string, ссылку на который получает в
	конструкторе.

	Объект ibstring_t не уничтожает std::string
	в своем деструкторе.

	Чтение идет от начала строки до конца.

	\attention Начиная с версии 1.4.0 к строке, которой
	инициализируется поток ibstring_t предъявляется дополнительное
	требование: строка не должна изменяться во жизни объекта 
	ibstring_t.

	\note v.1.1.1
	Сделан производным от oess_1::io::ibinbuffer_t.
*/
class	OESS_1__IO__TYPE	ibstring_t :
	public ibinbuffer_t
{
	public :
		ibstring_t(
			//! Ссылка на объект, из которого будет
			//! осуществляться чтение данных.
			/*!
				Данный объект должен существовать все
				время, в течении которого существует
				объект ibstring_t.
			*/
			const std::string & from );
		virtual ~ibstring_t();

		//! Длина исходной строки.
		/*!
			\deprecated Необходимо использовать метод
				oess_1::io::ibstring_t::size(). */
		size_t
		capacity() const;

		//! Длина исходной строки.
		/*!
			\since v.1.1.1 */
		virtual size_t
		size() const;

		//! Текущая позиция, с которой будет осуществляться
		//! очередная операция чтения.
		virtual size_t
		pos() const;

		//! Установить позицию, с которой будет осуществляться
		//! очередная операци чтения.
		/*!
			Операция выполняется только, если pos меньше,
			чем size().
		*/
		void
		set_pos( size_t pos );

		//! Достигли ли конца строки?
		/*!
			\return true, если текущая позиция достигла
			конца строки.
		*/
		virtual bool
		eof() const;

	protected :
		//! Реализация метода из базового класса.
		/*!
			Если нет достаточного объема данных для чтения
			хотя бы одного элемента, то порождается
			исключение.
		*/
		virtual const oess_1::char_t *
		in_reserve(
			//! Количество элементов, которые нужно
			//! прочитать.
			size_t item_count,
			//! Размер одного элемента в байтах.
			size_t item_size,
			//! Количество элементов, доступных по
			//! возвращенному указателю.
			size_t & item_available );

		//! Реализация метода из базового класса.
		virtual void
		in_shift(
			//! Количество успешно прочитанных элементов.
			size_t item_count,
			//! Размер одного элемента в байтах.
			size_t item_size );

	private :
		//! Строка из которой происходит чтение.
		const std::string &	m_from;
		//! Текущая позиция.
		size_t	m_pos;

	private :
		//! Защита от копирования.
		ibstring_t(
			const ibstring_t & );
		//! Защита от копирования.
		ibstring_t &
		operator=(
			const ibstring_t & );
};

//
// obstring_t
//

//! Двоичный выходной поток в объекта std::string.
/*!
	Класс, предоставляющий средства вывода
	в объект std::string.

	Объект этого класса использует существующий
	объект std::string, ссылку на который получает в
	конструкторе.

	Объект obstring_t не уничтожает std::string
	в своем деструкторе.

	Данные только дописываются в конец строки. Если
	строка уже содержала какие-то данные, то новые
	данные конкатенируются со старыми.

	Можно определить только текущую длину строки.
	Понятия текущей позиции не существует, т.к. данные
	всегда дописываются в конец строки.

	\note v.1.1.1
	Сделан производным от oess_1::io::obinbuffer_t.
*/
class	OESS_1__IO__TYPE	obstring_t :
	public obinbuffer_t
{
	public :
		obstring_t(
			//! Ссылка на объект, в который будет
			//! осуществляться запись данных.
			/*!
				Данный объект должен существовать все
				время, в течении которого существует
				объект оbstring_t.
			*/
			std::string & to );
		virtual ~obstring_t();

		//! Текущая длина строки.
		/*!
			\deprecated Необходимо использовать метод
				oess_1::io::obstring_t::size(). */
		size_t
		len() const;

		//! Общий объем буфера.
		/*!
			\size v.1.1.1
			\return Значение метода capacity контролируемой строки. */
		virtual size_t
		capacity() const;

		//! Объем помещенных в буфер данных.
		/*!
			\size v.1.1.1
			\return Значение метода size контролируемой строки. */
		virtual size_t
		size() const;

		//! Текущая позиция в буфере.
		/*!
			\size v.1.1.1
			\return Значение метода size контролируемой строки,
				т.к. запись всегда осуществляется в конец
				контролируемой строки. */
		virtual size_t
		pos() const;

	protected :
		//! Реализация метода из базового класса.
		virtual oess_1::char_t *
		out_reserve(
			//! Количество элементов, которые нужно
			//! записать.
			size_t item_count,
			//! Размер одного элемента в байтах.
			size_t item_size,
			//! Количество элементов, доступных для записи по
			//! возвращенному указателю.
			size_t & item_available );

		//! Реализация метода из базового класса.
		virtual void
		out_shift(
			//! Количество успешно записанных элементов.
			size_t item_count,
			//! Размер одного элемента в байтах.
			size_t item_size );

	private :
		//! Строка, в которую происходит запись.
		std::string &	m_to;

		//! Содержит корректные значения только между вызовами
		//! out_reserve и out_shift.
		auto_ptr_3::vect_ptr_t< oess_1::char_t >	m_buf;

	private :
		//! Защита от копирования.
		obstring_t(
			const obstring_t & );
		//! Защита от копирования.
		obstring_t &
		operator=(
			const obstring_t & );
};

} /* namespace io */

} /* namespace oess_1 */

#endif
