/*
 * Copyright 2004-2019 H2 Group. Multiple-Licensed under the MPL 2.0,
 * and the EPL 1.0 (http://h2database.com/html/license.html).
 * Initial Developer: H2 Group
 */
package org.h2.store;

import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import org.h2.util.IOUtils;

This class is backed by an input stream and supports reading values and variable size data.
/** * This class is backed by an input stream and supports reading values and * variable size data. */
public class DataReader extends Reader { private final InputStream in;
Create a new data reader.
Params:
  • in – the input stream
/** * Create a new data reader. * * @param in the input stream */
public DataReader(InputStream in) { this.in = in; }
Read a byte.
Returns:the byte
/** * Read a byte. * * @return the byte */
public byte readByte() throws IOException { int x = in.read(); if (x < 0) { throw new FastEOFException(); } return (byte) x; }
Read a variable size integer.
Returns:the value
/** * Read a variable size integer. * * @return the value */
public int readVarInt() throws IOException { int b = readByte(); if (b >= 0) { return b; } int x = b & 0x7f; b = readByte(); if (b >= 0) { return x | (b << 7); } x |= (b & 0x7f) << 7; b = readByte(); if (b >= 0) { return x | (b << 14); } x |= (b & 0x7f) << 14; b = readByte(); if (b >= 0) { return x | b << 21; } return x | ((b & 0x7f) << 21) | (readByte() << 28); }
Read a variable size long.
Returns:the value
/** * Read a variable size long. * * @return the value */
public long readVarLong() throws IOException { long x = readByte(); if (x >= 0) { return x; } x &= 0x7f; for (int s = 7;; s += 7) { long b = readByte(); x |= (b & 0x7f) << s; if (b >= 0) { return x; } } } /** * Read an integer. * * @return the value */ // public int readInt() throws IOException { // return (read() << 24) + ((read() & 0xff) << 16) + // ((read() & 0xff) << 8) + (read() & 0xff); //} /** * Read a long. * * @return the value */ // public long readLong() throws IOException { // return ((long) (readInt()) << 32) + (readInt() & 0xffffffffL); // }
Read a number of bytes.
Params:
  • buff – the target buffer
  • len – the number of bytes to read
/** * Read a number of bytes. * * @param buff the target buffer * @param len the number of bytes to read */
public void readFully(byte[] buff, int len) throws IOException { int got = IOUtils.readFully(in, buff, len); if (got < len) { throw new FastEOFException(); } }
Read a string from the stream.
Returns:the string
/** * Read a string from the stream. * * @return the string */
public String readString() throws IOException { int len = readVarInt(); return readString(len); } private String readString(int len) throws IOException { char[] chars = new char[len]; for (int i = 0; i < len; i++) { chars[i] = readChar(); } return new String(chars); }
Read one character from the input stream.
Returns:the character
/** * Read one character from the input stream. * * @return the character */
private char readChar() throws IOException { int x = readByte() & 0xff; if (x < 0x80) { return (char) x; } else if (x >= 0xe0) { return (char) (((x & 0xf) << 12) + ((readByte() & 0x3f) << 6) + (readByte() & 0x3f)); } else { return (char) (((x & 0x1f) << 6) + (readByte() & 0x3f)); } } @Override public void close() throws IOException { // ignore } @Override public int read(char[] buff, int off, int len) throws IOException { if (len == 0) { return 0; } int i = 0; try { for (; i < len; i++) { buff[off + i] = readChar(); } return len; } catch (EOFException e) { if (i == 0) { return -1; } return i; } }
Constructing such an EOF exception is fast, because the stack trace is not filled in. If used in a static context, this will also avoid classloader memory leaks.
/** * Constructing such an EOF exception is fast, because the stack trace is * not filled in. If used in a static context, this will also avoid * classloader memory leaks. */
static class FastEOFException extends EOFException { private static final long serialVersionUID = 1L; @Override public synchronized Throwable fillInStackTrace() { return null; } } }