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

org.apache.flink.runtime.state.gemini.engine.page.bmap.ByteBufferDataInputView Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.flink.runtime.state.gemini.engine.page.bmap;

import org.apache.flink.annotation.Internal;
import org.apache.flink.core.memory.DataInputView;
import org.apache.flink.util.Preconditions;

import java.io.EOFException;
import java.io.IOException;
import java.io.UTFDataFormatException;
import java.nio.ByteBuffer;

/**
 * Un-synchronized stream similar to Java's ByteArrayInputStream that also exposes the current position.
 * In this class, will not change position of ByteBuffer.
 */
@Internal
public class ByteBufferDataInputView implements DataInputView {

	protected ByteBuffer buffer;
	protected int position;
	protected int count;
	protected int mark = 0;
	private char[] lineBuffer;

	public ByteBufferDataInputView(ByteBuffer buffer, int offset, int length) {
		this.position = offset;
		this.buffer = buffer;
		this.mark = offset;
		this.count = offset + length;
	}

	public int read() {
		return (position < count) ? 0xFF & (buffer.get(position++)) : -1;
	}

	@Override
	public void skipBytesToRead(int numBytes) throws IOException {
		if (skipBytes(numBytes) != numBytes) {
			throw new EOFException("Could not skip " + numBytes + " bytes.");
		}
	}

	@Override
	public int read(byte[] b, int off, int len) {
		Preconditions.checkNotNull(b);

		if (off < 0 || len < 0 || len > b.length - off) {
			throw new IndexOutOfBoundsException();
		}

		if (position >= count) {
			return -1; // signal EOF
		}

		int available = count - position;

		if (len > available) {
			len = available;
		}

		if (len <= 0) {
			return 0;
		}

		ByteBufferUtils.copyFromBufferToArray(buffer, b, position, off, len);
		position += len;
		return len;
	}

	@Override
	public int read(byte[] b) throws IOException {
		return read(b, 0, b.length);
	}

	public long skip(long toSkip) {
		long remain = count - position;

		if (toSkip < remain) {
			remain = toSkip < 0 ? 0 : toSkip;
		}

		position += remain;
		return remain;
	}

	public boolean markSupported() {
		return true;
	}

	public void mark(int readAheadLimit) {
		mark = position;
	}

	public void reset() {
		position = mark;
	}

	public int available() {
		return count - position;
	}

	public void close() throws IOException {
	}

	public long getPos() {
		return position;
	}

	public void seek(long pos) {
		Preconditions.checkArgument(pos >= 0 && pos <= count, "Position out of bounds.");
		this.position = (int) pos;
	}

	@Override
	public void readFully(byte[] b) throws IOException {
		readFully(b, 0, b.length);
	}

	@Override
	public void readFully(byte[] b, int off, int len) throws IOException {
		if (len < 0) {
			throw new IndexOutOfBoundsException();
		}
		int n = 0;
		while (n < len) {
			int count = read(b, off + n, len - n);
			if (count < 0) {
				throw new EOFException();
			}
			n += count;
		}
	}

	@Override
	public int skipBytes(int n) throws IOException {
		int total = 0;
		int cur = 0;

		while ((total < n) && ((cur = (int) skip(n - total)) > 0)) {
			total += cur;
		}

		return total;
	}

	@Override
	public boolean readBoolean() throws IOException {
		int ch = read();
		if (ch < 0) {
			throw new EOFException();
		}
		return (ch != 0);
	}

	@Override
	public byte readByte() throws IOException {
		int ch = read();
		if (ch < 0) {
			throw new EOFException();
		}
		return (byte) (ch);
	}

	@Override
	public int readUnsignedByte() throws IOException {
		int ch = read();
		if (ch < 0) {
			throw new EOFException();
		}
		return ch;
	}

	@Override
	public short readShort() throws IOException {
		int ch1 = read();
		int ch2 = read();
		if ((ch1 | ch2) < 0) {
			throw new EOFException();
		}
		return (short) ((ch1 << 8) + (ch2 << 0));
	}

	@Override
	public int readUnsignedShort() throws IOException {
		int ch1 = read();
		int ch2 = read();
		if ((ch1 | ch2) < 0) {
			throw new EOFException();
		}
		return (ch1 << 8) + (ch2 << 0);
	}

	@Override
	public char readChar() throws IOException {
		int ch1 = read();
		int ch2 = read();
		if ((ch1 | ch2) < 0) {
			throw new EOFException();
		}
		return (char) ((ch1 << 8) + (ch2 << 0));
	}

	@Override
	public int readInt() throws IOException {
		int result = ByteBufferUtils.toInt(buffer, position);
		position += 4;
		return result;
	}

	@Override
	public long readLong() throws IOException {
		long result = ByteBufferUtils.toLong(buffer, position);
		position += 8;
		return result;
	}

	@Override
	public float readFloat() throws IOException {
		return Float.intBitsToFloat(readInt());
	}

	@Override
	public double readDouble() throws IOException {
		return Double.longBitsToDouble(readLong());
	}

	@Override
	public String readLine() throws IOException {
		char[] buf = lineBuffer;

		if (buf == null) {
			buf = lineBuffer = new char[128];
		}

		int room = buf.length;
		int offset = 0;
		int c;

		loop:
		while (true) {
			switch (c = read()) {
				case -1:
				case '\n':
					break loop;

				case '\r':
					int c2 = read();
					if ((c2 != '\n') && (c2 != -1)) {
						position--;
					}
					break loop;

				default:
					if (--room < 0) {
						buf = new char[offset + 128];
						room = buf.length - offset - 1;
						System.arraycopy(lineBuffer, 0, buf, 0, offset);
						lineBuffer = buf;
					}
					buf[offset++] = (char) c;
					break;
			}
		}
		if ((c == -1) && (offset == 0)) {
			return null;
		}
		return String.copyValueOf(buf, 0, offset);
	}

	@Override
	public String readUTF() throws IOException {
		int utflen = readUnsignedShort();
		byte[] bytearr = new byte[utflen];
		char[] chararr = new char[utflen];

		int c, char2, char3;
		int count = 0;
		int chararrCount = 0;

		readFully(bytearr, 0, utflen);

		while (count < utflen) {
			c = (int) bytearr[count] & 0xff;
			if (c > 127) {
				break;
			}
			count++;
			chararr[chararrCount++] = (char) c;
		}

		while (count < utflen) {
			c = (int) bytearr[count] & 0xff;
			switch (c >> 4) {
				case 0:
				case 1:
				case 2:
				case 3:
				case 4:
				case 5:
				case 6:
				case 7:
					/* 0xxxxxxx*/
					count++;
					chararr[chararrCount++] = (char) c;
					break;
				case 12:
				case 13:
					/* 110x xxxx   10xx xxxx*/
					count += 2;
					if (count > utflen) {
						throw new UTFDataFormatException("malformed input: partial character at end");
					}
					char2 = (int) bytearr[count - 1];
					if ((char2 & 0xC0) != 0x80) {
						throw new UTFDataFormatException("malformed input around byte " + count);
					}
					chararr[chararrCount++] = (char) (((c & 0x1F) << 6) | (char2 & 0x3F));
					break;
				case 14:
					/* 1110 xxxx  10xx xxxx  10xx xxxx */
					count += 3;
					if (count > utflen) {
						throw new UTFDataFormatException("malformed input: partial character at end");
					}
					char2 = (int) bytearr[count - 2];
					char3 = (int) bytearr[count - 1];
					if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) {
						throw new UTFDataFormatException("malformed input around byte " + (count - 1));
					}
					chararr[chararrCount++] = (char) (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
					break;
				default:
					/* 10xx xxxx,  1111 xxxx */
					throw new UTFDataFormatException("malformed input around byte " + count);
			}
		}
		// The number of chars produced may be less than utflen
		return new String(chararr, 0, chararrCount);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy