/*
	Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
	и других спецификаций для функционирования компактных приложений на языке
	Java (мидлетов) в среде программного обеспечения Малик Эмулятор.

	Copyright © 2016, 2019 Малик Разработчик

	Это свободная программа: вы можете перераспространять ее и/или изменять
	ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
	в каком она была опубликована Фондом свободного программного обеспечения;
	либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

	Эта программа распространяется в надежде, что она будет полезной,
	но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
	или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
	общественной лицензии GNU.

	Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
	вместе с этой программой. Если это не так, см.
	<https://www.gnu.org/licenses/>.
*/


package java.io;

public abstract class Writer extends Object
{
	private static final int WRITE_BUFFER_SIZE = 0x0400;


	protected Object lock;
	private char[] writeBuffer;

	protected Writer()
	{
		this.lock = this;
	}

	protected Writer(Object lock)
	{
		if(lock == null)
		{
			throw new NullPointerException("Writer: " +
					"параметр lock равен нулевой ссылке.");
		}
		this.lock = lock;
	}

	public abstract void close()
			throws IOException;

	public abstract void flush()
			throws IOException;

	public abstract void write(char[] src, int offset, int length)
			throws IOException;

	public void write(int src)
			throws IOException
	{
		char[] c;
		synchronized(lock)
		{
			if((c = writeBuffer) == null)
			{
				writeBuffer = c = new char[WRITE_BUFFER_SIZE];
			}
			c[0] = (char) src;
			write(c, 0, 1);
		}
	}

	public void write(char[] src)
			throws IOException
	{
		if(src == null)
		{
			throw new NullPointerException("Writer.write: " +
					"параметр src равен нулевой ссылке.");
		}
		write(src, 0, src.length);
	}

	public void write(String src)
			throws IOException
	{
		int length;
		char[] c;
		char[] cbuf;
		if(src == null)
		{
			throw new NullPointerException("Writer.write: " +
					"параметр src равен нулевой ссылке.");
		}
		synchronized(lock)
		{
			src.getChars(0, length = src.length(), cbuf =
					(length <= WRITE_BUFFER_SIZE) ?
					(
						((c = writeBuffer) == null) ?
						(
							writeBuffer = new char[WRITE_BUFFER_SIZE]
						) :
						(
							c
						)
					) :
					(
						new char[length]
					), 0);
			write(cbuf, 0, length);
		}
	}

	public void write(String src, int offset, int length)
			throws IOException
	{
		int lim;
		int len;
		char[] c;
		char[] cbuf;
		if(src == null)
		{
			throw new NullPointerException("Writer.write: " +
					"параметр src равен нулевой ссылке.");
		}
		if((lim = offset + length) > (len = src.length()) ||
				lim < offset || offset > len || offset < 0)
		{
			throw new StringIndexOutOfBoundsException("Writer.write: " +
					"индекс выходит из диапазона.");
		}
		synchronized(lock)
		{
			src.getChars(offset, lim, cbuf =
					(length <= WRITE_BUFFER_SIZE) ?
					(
						((c = writeBuffer) == null) ?
						(
							writeBuffer = new char[WRITE_BUFFER_SIZE]
						) :
						(
							c
						)
					) :
					(
						new char[length]
					), 0);
			write(cbuf, 0, length);
		}
	}
}
