/* * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.max.vm.ext.maxri; import java.io.*; /** * Variation on {@link ByteArrayInputStream} and {@link DataInputStream} that supports * direct access to the underlying buffer and read position. */ final class DecodingStream { byte[] buf; int pos; public DecodingStream(byte[] buf) { this.buf = buf; } public int read() { if (pos < buf.length) { return buf[pos++] & 0xff; } throw new InternalError("ran off end of decoding stream"); } /** * Decodes an unsigned integer from a given stream. * * @return the decoded value * @see EncodingStream#encodeUInt(int) */ int decodeUInt() { int lo = read() & 0xFF; if (lo < 128) { /* 0xxxxxxx */ return lo; } lo &= 0x7f; int mid = read() & 0xFF; if (mid < 128) { /* 1xxxxxxx 0xxxxxxx */ return (mid << 7) + lo; } mid &= 0x7f; int hi = read() & 0xFF; if (hi < 128) { /* 1xxxxxxx 1xxxxxxx 0xxxxxxx */ return (hi << 14) + (mid << 7) + lo; } hi &= 0x7f; int last = read() & 0xFF; if (last < 128) { /* 1xxxxxxx 1xxxxxxx 1xxxxxxx 0xxxxxxx */ return (last << 21) + (hi << 14) + (mid << 7) + lo; } throw new InternalError(); } public byte readByte() { return (byte) read(); } public boolean readBoolean() { return read() != 0; } public char readChar() { int ch1 = read(); int ch2 = read(); return (char) ((ch1 << 8) + (ch2 << 0)); } public short readShort() { int ch1 = read(); int ch2 = read(); return (short) ((ch1 << 8) + (ch2 << 0)); } public int readInt() { int ch1 = read(); int ch2 = read(); int ch3 = read(); int ch4 = read(); return (ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0); } public float readFloat() { return Float.intBitsToFloat(readInt()); } public long readLong() { return ((long) read() << 56) + ((long) (read() & 255) << 48) + ((long) (read() & 255) << 40) + ((long) (read() & 255) << 32) + ((long) (read() & 255) << 24) + ((read() & 255) << 16) + ((read() & 255) << 8) + ((read() & 255) << 0); } public double readDouble() { return Double.longBitsToDouble(readLong()); } }