/*
 * Class: DataReader
 *
 * Author: Alex Usun
 *
 * Date: 31/8/2005
 */
package com.jscape.inet.ssh.util.keyreader.openssh;

import com.jscape.util.Assert;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;

/**
 * OpenSSH format data reader.
 *
 * @author Alex Usun
 * @version 1.0
 * @see <a href="DataReader.java.html">Source code</a>
 */
public class DataReader {

    private final DataInputStream in;

    /**
     * Creates a new reader instance.
     *
     * @param in underlayed input stream
     */
    public DataReader(InputStream in) {
        Assert.notNull(in);
        this.in = new DataInputStream(in);
    }

    /**
     * Reads one byte value.
     *
     * @return readed value
     *
     * @throws java.io.IOException if an I/O error occurs
     */
    public int readByte()
            throws IOException {
        return (this.in.readByte() & 0xFF);
    }

    /**
     * Reads big integer value.
     *
     * @return readed value
     *
     * @throws IOException if an I/O error occurs
     */
    public BigInteger readBigInteger()
            throws IOException {
        int len = readLength();

        try {
            byte[] data = new byte[len];
            this.in.readFully(data);

            return new BigInteger(data);
        } catch (NegativeArraySizeException e) {
            throw new IOException("file corrupted or bad passphrase");
        } catch (OutOfMemoryError e) {
            throw new IOException("file corrupted or bad passphrase");
        }
    }


    /**
     * Reads following data length.
     *
     * @return readed data length
     *
     * @throws java.io.IOException if I/O error occurs
     */
    public int readLength()
            throws IOException {
        int res = readByte();

        if ((res & 0x80) != 0) {
            int length = 0;

            for (int bytes = res % 0x80; bytes > 0; bytes--) {
                length <<= 8;
                length |= readByte();
            }

            res = length;
        }

        return res;
    }
}
