All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.datakernel.datastream.processor.BufferReader Maven / Gradle / Ivy

/*
 * Copyright (C) 2015 SoftIndex LLC.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.datakernel.datastream.processor;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.io.Reader;
import java.nio.charset.StandardCharsets;

/**
 * Reads characters from a character-input stream, buffers characters
 */
public final class BufferReader extends Reader {
	private byte[] buf;
	private int pos;
	private int limit;

	// region creators
	private BufferReader(byte[] array, int position, int length) {
		set(array, position, length);
	}

	/**
	 * Creates a new instance of this object
	 *
	 * @param array    array for buffering read characters
	 * @param position the index of the next element to be written
	 * @param length   number of bytes which can be written to this array
	 */
	public static BufferReader create(byte[] array, int position, int length) {return new BufferReader(array, position, length);}
	// endregion

	@Override
	public void close() {
	}

	public void set(byte[] array, int position, int len) {
		assert position >= 0 && len >= 0;
		this.buf = array;
		this.pos = position;
		this.limit = position + len;
	}

	/**
	 * Returns a buffer for this object
	 */
	public byte[] array() {
		return buf;
	}

	/**
	 * Returns a position for its buffer
	 */
	public int position() {
		return pos;
	}

	/**
	 * Sets a position for its buffer
	 *
	 * @param position position to set
	 */
	public void position(int position) {
		assert pos >= 0;
		pos = position;
	}

	/**
	 * Returns elements between the current position and the size of buffer.
	 */
	public int remaining() {
		return buf.length - pos;
	}

	/**
	 * Reads a single character
	 *
	 * @return the character read, as an integer
	 * @throws IOException if an I/O error occurs
	 */
	@Override
	public int read() throws IOException {
		if (pos >= limit)
			return -1;

		try {
			int c = buf[pos] & 0xff;
			if (c < 0x80) {
				pos++;
			} else if (c < 0xE0) {
				c = (char) ((c & 0x1F) << 6 | buf[pos + 1] & 0x3F);
				pos += 2;
			} else {
				c = (char) ((c & 0x0F) << 12 | (buf[pos + 1] & 0x3F) << 6 | (buf[pos + 2] & 0x3F));
				pos += 3;
			}
			if (pos > limit)
				throw new IOException("Read more bytes than the limit");
			return c;
		} catch (ArrayIndexOutOfBoundsException e) {
			throw new IOException(e);
		}
	}

	/**
	 * Reads characters into a portion of an array
	 *
	 * @param cbuf destination buffer
	 * @param off  offset at which to start storing characters
	 * @param len  maximum number of characters to read
	 * @return the number of characters read, or -1 if the end of the stream has been reached
	 * @throws IOException if an I/O error occurs
	 */
	@Override
	public int read(@NotNull char[] cbuf, int off, int len) throws IOException {
		if (pos > limit)
			return -1;

		try {
			int i;
			int to = off + len;
			for (i = off; i < to && pos < limit; i++) {
				int c = buf[pos] & 0xff;
				if (c < 0x80) {
					cbuf[i] = (char) c;
					pos++;
				} else if (c < 0xE0) {
					cbuf[i] = (char) ((c & 0x1F) << 6 | buf[pos + 1] & 0x3F);
					pos += 2;
				} else {
					cbuf[i] = (char) ((c & 0x0F) << 12 | (buf[pos + 1] & 0x3F) << 6 | (buf[pos + 2] & 0x3F));
					pos += 3;
				}
			}
			if (pos > limit) {
				throw new IOException("Read more bytes than the limit");
			}
			if (pos == limit) {
				pos = Integer.MAX_VALUE;
			}
			return i - off;
		} catch (ArrayIndexOutOfBoundsException e) {
			throw new IOException(e);
		}
	}

	@Override
	public String toString() {
		return new String(buf, pos, limit - pos, StandardCharsets.UTF_8);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy