001/*
002 * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.compiler.common.util;
024
025/**
026 * Provides low-level read access for signed and unsigned values of size 1, 2, 4, and 8 bytes.
027 */
028public interface TypeReader {
029
030    /** Returns the next byte index to be read. */
031    long getByteIndex();
032
033    /** Sets the next byte index to be read. */
034    void setByteIndex(long byteIndex);
035
036    /** Reads a signed 1 byte value. */
037    int getS1();
038
039    /** Reads an unsigned 1 byte value. */
040    int getU1();
041
042    /** Reads a signed 2 byte value. */
043    int getS2();
044
045    /** Reads an unsigned 2 byte value. */
046    int getU2();
047
048    /** Reads a signed 4 byte value. */
049    int getS4();
050
051    /** Reads an unsigned 4 byte value. */
052    long getU4();
053
054    /** Reads a signed 4 byte value. */
055    long getS8();
056
057    /**
058     * Reads a signed value that has been written using {@link TypeWriter#putSV variable byte size
059     * encoding}.
060     */
061    default long getSV() {
062        long result = 0;
063        int shift = 0;
064        long b;
065        do {
066            b = getU1();
067            result |= (b & 0x7f) << shift;
068            shift += 7;
069        } while ((b & 0x80) != 0);
070
071        if ((b & 0x40) != 0 && shift < 64) {
072            result |= -1L << shift;
073        }
074        return result;
075    }
076
077    /**
078     * Reads a signed variable byte size encoded value that is known to fit into the range of int.
079     */
080    default int getSVInt() {
081        return TypeConversion.asS4(getSV());
082    }
083
084    /**
085     * Reads an unsigned value that has been written using {@link TypeWriter#putSV variable byte
086     * size encoding}.
087     */
088    default long getUV() {
089        long result = 0;
090        int shift = 0;
091        long b;
092        do {
093            b = getU1();
094            result |= (b & 0x7f) << shift;
095            shift += 7;
096        } while ((b & 0x80) != 0);
097
098        return result;
099    }
100
101    /**
102     * Reads an unsigned variable byte size encoded value that is known to fit into the range of
103     * int.
104     */
105    default int getUVInt() {
106        return TypeConversion.asS4(getUV());
107    }
108}