class RandomAccessReadDataStream extends TTFDataStream
{
    private final long length;
    private final byte[] data;
    private int currentPosition = 0;

    /**
     * Constructor.
     *
     * @param randomAccessRead source to be read from
     *
     * @throws IOException If there is a problem reading the source data.
     */
    RandomAccessReadDataStream(RandomAccessRead randomAccessRead) throws IOException
    {
        length = randomAccessRead.length();
        data = new byte[(int) length];
        int remainingBytes = data.length;
        int amountRead;
        while ((amountRead = randomAccessRead.read(data, data.length - remainingBytes,
                remainingBytes)) > 0)
        {
            remainingBytes -= amountRead;
        }
    }

    /**
     * Constructor.
     *
     * @param inputStream source to be read from
     *
     * @throws IOException If there is a problem reading the source data.
     */
    RandomAccessReadDataStream(InputStream inputStream) throws IOException
    {
        data = inputStream.readAllBytes();
        length = data.length;
    }

    /**
     * Get the current position in the stream.
     * @return The current position in the stream.
     * @throws IOException If an error occurs while reading the stream.
     */
    @Override
    public long getCurrentPosition() throws IOException
    {
        return currentPosition;
    }

    /**
     * Close the underlying resources.
     *
     * @throws IOException If there is an error closing the resources.
     */
    @Override
    public void close() throws IOException
    {
        // nothing to do
    }

    /**
     * Read an unsigned byte.
     * @return An unsigned byte, or -1, signalling 'no more data'
     * @throws IOException If there is an error reading the data.
     */
    @Override
    public int read() throws IOException
    {
        if (currentPosition >= length)
        {
            return -1;
        }
        return data[currentPosition++] & 0xff;
    }

    /**
     * Read a signed 64-bit integer.
     *
     * @return eight bytes interpreted as a long.
     * @throws IOException If there is an error reading the data.
     */
    @Override
    public final long readLong() throws IOException
    {
        return ((long) readInt() << 32) + (readInt() & 0xFFFFFFFFL);
    }

    /**
     * Read a signed 32-bit integer.
     *
     * @return 4 bytes interpreted as an int.
     * @throws IOException If there is an error reading the data.
     */
    private int readInt() throws IOException
    {
        int b1 = read();
        int b2 = read();
        int b3 = read();
        int b4 = read();
        return (b1 << 24) + (b2 << 16) + (b3 << 8) + b4;
    }
    /**
     * Seek into the datasource.
     * When the requested <code>pos</code> is &lt; 0, an IOException() is fired.
     * When the requested <code>pos</code> is &ge; {@link #length}, the {@link #currentPosition}
     * is set to the first byte <i>after</i> the {@link #data}!
     *
     * @param pos The position to seek to.
     * @throws IOException If there is an error seeking to that position.
     */
    @Override
    public void seek(long pos) throws IOException
    {<FILL_FUNCTION_BODY>}

    /**
     * @see java.io.InputStream#read( byte[], int, int )
     *
     * @param b The buffer to write to.
     * @param off The offset into the buffer.
     * @param len The length into the buffer.
     *
     * @return The number of bytes read or -1, signalling 'no more data'
     *
     * @throws IOException If there is an error reading from the stream.
     */
    @Override
    public int read(byte[] b, int off, int len) throws IOException
    {
        if (currentPosition >= length)
        {
            return -1;
        }
        int remainingBytes = (int) (length - currentPosition);
        int bytesToRead = Math.min(remainingBytes, len);
        System.arraycopy(data, currentPosition, b, off, bytesToRead);
        currentPosition += bytesToRead;
        return bytesToRead;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public InputStream getOriginalData() throws IOException
    {
        return new ByteArrayInputStream(data);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public long getOriginalDataSize()
    {
        return length;
    }
}

        if (pos < 0)
        {
            throw new IOException("Invalid position " + pos);
        }
        currentPosition = pos < length ? (int) pos : (int) length;
    
<methods>public abstract long getCurrentPosition() throws java.io.IOException,public abstract java.io.InputStream getOriginalData() throws java.io.IOException,public abstract long getOriginalDataSize() ,public abstract int read() throws java.io.IOException,public byte[] read(int) throws java.io.IOException,public abstract int read(byte[], int, int) throws java.io.IOException,public float read32Fixed() throws java.io.IOException,public java.util.Calendar readInternationalDate() throws java.io.IOException,public abstract long readLong() throws java.io.IOException,public int readSignedByte() throws java.io.IOException,public short readSignedShort() throws java.io.IOException,public java.lang.String readString(int) throws java.io.IOException,public java.lang.String readString(int, java.nio.charset.Charset) throws java.io.IOException,public java.lang.String readTag() throws java.io.IOException,public int readUnsignedByte() throws java.io.IOException,public int[] readUnsignedByteArray(int) throws java.io.IOException,public long readUnsignedInt() throws java.io.IOException,public int readUnsignedShort() throws java.io.IOException,public int[] readUnsignedShortArray(int) throws java.io.IOException,public abstract void seek(long) throws java.io.IOException<variables>private static final java.util.TimeZone TIMEZONE_UTC