package com.jscape.util.io.primitive;

import com.jscape.util.EndianBits;
import com.jscape.util.IOTools;
import com.jscape.util.io.DataCodec;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * @author Alex Usun
 */
public class IntCodec
        implements DataCodec<Integer> {

    private final EndianBits bits;

    public static void writeValue(int value, EndianBits bits, OutputStream out)
            throws IOException {
        byte[] data = bits.putInt(value, new byte[4], 0);
        out.write(data);
    }

    public static void writeBigEndianValue(int value, OutputStream out)
            throws IOException {
        out.write(value >>> 24);
        out.write(value >>> 16);
        out.write(value >>> 8);
        out.write(value);
    }

    public static void writeLittleEndianValue(int value, OutputStream out)
            throws IOException {
        out.write(value);
        out.write(value >>> 8);
        out.write(value >>> 16);
        out.write(value >>> 24);
    }

    public static int readValue(EndianBits bits, InputStream in)
            throws IOException {
        byte[] data = IOTools.read(new byte[4], in);
        return bits.getInt(data, 0);
    }

    public static int readBigEndianValue(InputStream in)
            throws IOException {
        int value = IOTools.read(in) << 24;
        value |= IOTools.read(in) << 16;
        value |= IOTools.read(in) << 8;
        value |= IOTools.read(in);

        return value;
    }

    public static int readLittleEndianValue(InputStream in)
            throws IOException {
        int value = IOTools.read(in);
        value |= IOTools.read(in) << 8;
        value |= IOTools.read(in) << 16;
        value |= IOTools.read(in) << 24;

        return value;
    }

    public IntCodec(EndianBits bits) {
        this.bits = bits;
    }

    public void write(Integer data, OutputStream out)
            throws IOException {
        writeValue(data, this.bits, out);
    }

    public Integer read(InputStream in)
            throws IOException {
        return readValue(this.bits, in);
    }

}