/*
    Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
    и других спецификаций для функционирования компактных приложений на языке
    Java (мидлетов) в среде программного обеспечения Малик Эмулятор.

    Copyright © 2016–2017, 2019–2022 Малик Разработчик

    Это свободная программа: вы можете перераспространять ее и/или изменять
    ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
    в каком она была опубликована Фондом свободного программного обеспечения;
    либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

    Эта программа распространяется в надежде, что она будет полезной,
    но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
    или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
    общественной лицензии GNU.

    Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
    вместе с этой программой. Если это не так, см.
    <https://www.gnu.org/licenses/>.
*/

package malik.emulator.fileformats;

import java.io.*;

public class ExtendedDataInputStream extends DataInputStream implements ExtendedDataInput
{
    public ExtendedDataInputStream(InputStream stream) {
        super(stream);
    }

    public final char readCharLE() throws IOException {
        int byte0;
        int byte1;
        InputStream stream = in;
        byte0 = stream.read();
        byte1 = stream.read();
        if((byte0 | byte1) < 0)
        {
            throw new EOFException("ExtendedDataInputStream.readCharLE: достигнут конец потока данных.");
        }
        return (char) (byte1 << 8 | byte0 & 0xff);
    }

    public final float readFloatLE() throws IOException {
        int byte0;
        int byte1;
        int byte2;
        int byte3;
        InputStream stream = in;
        byte0 = stream.read();
        byte1 = stream.read();
        byte2 = stream.read();
        byte3 = stream.read();
        if((byte0 | byte1 | byte2 | byte3) < 0)
        {
            throw new EOFException("ExtendedDataInputStream.readFloatLE: достигнут конец потока данных.");
        }
        return Float.intBitsToFloat((byte3 & 0xff) << 0x18 | (byte2 & 0xff) << 0x10 | (byte1 & 0xff) << 0x08 | (byte0 & 0xff));
    }

    public final double readDoubleLE() throws IOException {
        int byte0;
        int byte1;
        int byte2;
        int byte3;
        int byte4;
        int byte5;
        int byte6;
        int byte7;
        InputStream stream = in;
        byte0 = stream.read();
        byte1 = stream.read();
        byte2 = stream.read();
        byte3 = stream.read();
        byte4 = stream.read();
        byte5 = stream.read();
        byte6 = stream.read();
        byte7 = stream.read();
        if((byte0 | byte1 | byte2 | byte3 | byte4 | byte5 | byte6 | byte7) < 0)
        {
            throw new EOFException("ExtendedDataInputStream.readDoubleLE: достигнут конец потока данных.");
        }
        return Double.longBitsToDouble(
            (long) (byte7 & 0xff) << 0x38 | (long) (byte6 & 0xff) << 0x30 | (long) (byte5 & 0xff) << 0x28 | (long) (byte4 & 0xff) << 0x20 |
            (long) (byte3 & 0xff) << 0x18 | (long) (byte2 & 0xff) << 0x10 | (long) (byte1 & 0xff) << 0x08 | (long) (byte0 & 0xff)
        );
    }

    public final short readShortLE() throws IOException {
        int byte0;
        int byte1;
        InputStream stream = in;
        byte0 = stream.read();
        byte1 = stream.read();
        if((byte0 | byte1) < 0)
        {
            throw new EOFException("ExtendedDataInputStream.readShortLE: достигнут конец потока данных.");
        }
        return (short) (byte1 << 8 | byte0 & 0xff);
    }

    public final int readUnsignedShortLE() throws IOException {
        int byte0;
        int byte1;
        InputStream stream = in;
        byte0 = stream.read();
        byte1 = stream.read();
        if((byte0 | byte1) < 0)
        {
            throw new EOFException("ExtendedDataInputStream.readUnsignedShortLE: достигнут конец потока данных.");
        }
        return (byte1 & 0xff) << 8 | (byte0 & 0xff);
    }

    public final int readIntLE() throws IOException {
        int byte0;
        int byte1;
        int byte2;
        int byte3;
        InputStream stream = in;
        byte0 = stream.read();
        byte1 = stream.read();
        byte2 = stream.read();
        byte3 = stream.read();
        if((byte0 | byte1 | byte2 | byte3) < 0)
        {
            throw new EOFException("ExtendedDataInputStream.readIntLE: достигнут конец потока данных.");
        }
        return (byte3 & 0xff) << 0x18 | (byte2 & 0xff) << 0x10 | (byte1 & 0xff) << 0x08 | (byte0 & 0xff);
    }

    public final long readLongLE() throws IOException {
        int byte0;
        int byte1;
        int byte2;
        int byte3;
        int byte4;
        int byte5;
        int byte6;
        int byte7;
        InputStream stream = in;
        byte0 = stream.read();
        byte1 = stream.read();
        byte2 = stream.read();
        byte3 = stream.read();
        byte4 = stream.read();
        byte5 = stream.read();
        byte6 = stream.read();
        byte7 = stream.read();
        if((byte0 | byte1 | byte2 | byte3 | byte4 | byte5 | byte6 | byte7) < 0)
        {
            throw new EOFException("ExtendedDataInputStream.readLongLE: достигнут конец потока данных.");
        }
        return
            (long) (byte7 & 0xff) << 0x38 | (long) (byte6 & 0xff) << 0x30 | (long) (byte5 & 0xff) << 0x28 | (long) (byte4 & 0xff) << 0x20 |
            (long) (byte3 & 0xff) << 0x18 | (long) (byte2 & 0xff) << 0x10 | (long) (byte1 & 0xff) << 0x08 | (long) (byte0 & 0xff)
        ;
    }

    public final InputStream getSourceStream() {
        return in;
    }
}
