/*! \file piiobytearray.h
 * \ingroup IO
 * \~\brief
 * \~english PIIODevice wrapper around PIByteArray.
 * \~russian Обертка PIIODevice вокруг PIByteArray.
 */
/*
    PIP - Platform Independent Primitives
    PIIODevice wrapper around PIByteArray
    Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru

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

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

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef PIIOBYTEARRAY_H
#define PIIOBYTEARRAY_H

#include "piiodevice.h"


//! \~\ingroup IO
//! \~\brief
//! \~english PIIODevice wrapper around PIByteArray.
//! \~russian Обёртка PIIODevice вокруг PIByteArray.
class PIP_EXPORT PIIOByteArray: public PIIODevice {
	PIIODEVICE(PIIOByteArray, "");

public:
	//! \~english Constructs %PIIOByteArray with "buffer" content and "mode" open mode.
	//! \~russian Создает %PIIOByteArray с содержимым "buffer" и режимом открытия "mode".
	explicit PIIOByteArray(PIByteArray * buffer = 0, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);

	//! \~english Constructs %PIIOByteArray with "buffer" content only for read.
	//! \~russian Создает %PIIOByteArray с содержимым "buffer" только для чтения.
	explicit PIIOByteArray(const PIByteArray & buffer);

	//! \~english Returns content.
	//! \~russian Возвращает содержимое.
	PIByteArray * byteArray() const { return data_; }

	//! \~english Clears content buffer.
	//! \~russian Очищает содержимое буфера.
	void clear() {
		if (data_) data_->clear();
		pos = 0;
	}

	//! \~english Opens "buffer" content with "mode" open mode.
	//! \~russian Открывает содержимое "buffer" с режимом открытия "mode".
	bool open(PIByteArray * buffer, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);

	//! \~english Opens "buffer" content only for read.
	//! \~russian Открывает содержимое "buffer" только для чтения.
	bool open(const PIByteArray & buffer);

	//! \~english Returns true if position is at the end of content.
	//! \~russian Возвращает true, если позиция в конце содержимого.
	bool isEnd() const {
		if (!data_) return true;
		return pos >= data_->size_s();
	}


	//! \~english Moves read/write position to "position".
	//! \~russian Перемещает позицию чтения/записи на "position".
	void seek(llong position) { pos = position; }

	//! \~english Moves read/write position to the beginning of the buffer.
	//! \~russian Перемещает позицию чтения/записи на начало буфера.
	void seekToBegin() {
		if (data_) pos = 0;
	}

	//! \~english Moves read/write position to the end of the buffer.
	//! \~russian Перемещает позицию чтения/записи на конец буфера.
	void seekToEnd() {
		if (data_) pos = data_->size_s();
	}


	//! \~english Inserts data "ba" into content at current position.
	//! \~russian Вставляет данные "ba" в содержимое буфера в текущую позицию.
	int writeByteArray(const PIByteArray & ba);

	//! \~english Returns number of bytes available for reading.
	//! \~russian Возвращает количество доступных для чтения байт.
	ssize_t bytesAvailable() const override {
		if (data_)
			return data_->size();
		else
			return 0;
	}

protected:
	//! \~english Opens the device.
	//! \~russian Открывает устройство.
	bool openDevice() override;

	//! \~english Reads data from the device.
	//! \~russian Читает данные из устройства.
	ssize_t readDevice(void * read_to, ssize_t size) override;

	//! \~english Writes data to the device.
	//! \~russian Записывает данные в устройство.
	ssize_t writeDevice(const void * data_, ssize_t size) override;

	//! \~english Returns device info flags.
	//! \~russian Возвращает флаги информации об устройстве.
	DeviceInfoFlags deviceInfoFlags() const override { return PIIODevice::Sequential | PIIODevice::Reliable; }

	//! \~english Current read/write position.
	//! \~russian Текущая позиция чтения/записи.
	ssize_t pos;

	//! \~english Pointer to data buffer.
	//! \~russian Указатель на буфер данных.
	PIByteArray * data_;
};

#endif // PIIOBYTEARRAY_H
