package com.jscape.util.io.primitive;

import com.jscape.util.BigEndianBits;
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 IntByteArrayCodec
        implements DataCodec<byte[]> {

    private final EndianBits bits;

    public static void writeValue(byte[] value, int offset, int length, EndianBits bits, OutputStream out)
            throws IOException {
        IntCodec.writeValue(length, bits, out);
        out.write(value, offset, length);
    }

    public static void writeValue(byte[] value, EndianBits bits, OutputStream out)
            throws IOException {
        writeValue(value, 0, value.length, bits, out);
    }

    public static void writeBigEndianValue(byte[] value, int offset, int length, OutputStream out)
            throws IOException {
//        IntCodec.writeBigEndianValue(length, out);
//        out.write(value, offset, length);
        writeValue(value, offset, length, BigEndianBits.INSTANCE, out);
    }

    public static void writeBigEndianValue(byte[] value, OutputStream out)
            throws IOException {
        writeBigEndianValue(value, 0, value.length, out);
    }

    public static void writeLittleEndianValue(byte[] value, int offset, int length, OutputStream out)
            throws IOException {
        IntCodec.writeLittleEndianValue(length, out);
        out.write(value, offset, length);
    }

    public static void writeLittleEndianValue(byte[] value, OutputStream out)
            throws IOException {
        writeLittleEndianValue(value, 0, value.length, out);
    }

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

    public static byte[] readBigEndianValue(InputStream in)
            throws IOException {
//        int length = IntCodec.readBigEndianValue(in);
//        return IOTools.read(new byte[length], in);
        return readValue(BigEndianBits.INSTANCE, in);
    }

    public static byte[] readLittleEndianValue(InputStream in)
            throws IOException {
        int length = IntCodec.readLittleEndianValue(in);
        return IOTools.read(new byte[length], in);
    }

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

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

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

}