/*
 * @(#)FileInputStream.java
 *
 * Copyright (c) 2002-2003 JSCAPE
 * 1147 S. 53rd Pl., Mesa, Arizona, 85206, U.S.A.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * JSCAPE. ("Confidential Information").  You shall not disclose such
 * Confidential Information and shall use it only in accordance with
 * the terms of the license agreement you entered into with JSCAPE.
 */

/*
 * Classname: FileInputStream
 *
 * Version: 1.0
 *
 * Author: Alex Usun
 */
package com.jscape.util.io;

import com.jscape.util.ExceptionTools;
import com.jscape.util.IOTools;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.nio.file.Path;
import java.nio.file.Paths;

import static com.jscape.util.Parameters.assertNotNull;

/**
 * The file input stream.
 *
 * @author Alex Usun
 */
public class FileInputStream
        extends InputStream {

    private final RandomAccessFile base;

    public static FileInputStream streamFor(File file, long offset)
            throws IOException {
        RandomAccessFile base = new RandomAccessFile(file, "r");

        try {
            base.seek(offset);
            return new FileInputStream(base);
        } catch (Exception e) {
            IOTools.close(base);
            throw ExceptionTools.ioException(e);
        }
    }

    public static FileInputStream streamFor(Path file, long offset)
            throws IOException {
        return streamFor(file.toFile(), offset);
    }

    public static FileInputStream streamFor(String file, long offset)
            throws IOException {
        return streamFor(Paths.get(file), offset);
    }

    public FileInputStream(RandomAccessFile base) {
        assertNotNull(base);
        this.base = base;
    }

    public int available()
            throws IOException {
        return (int) (this.base.length() - this.base.getFilePointer());
    }

    public int read()
            throws IOException {
        return this.base.read();
    }

    public int read(byte[] buffer, int offset, int length)
            throws IOException {
        return this.base.read(buffer, offset, length);
    }

    public long skip(long n)
            throws IOException {
        n = Math.min(Math.max(0, n), this.base.length() - this.base.getFilePointer());
        this.base.seek(this.base.getFilePointer() + n);

        return n;
    }

    public void close() {
        IOTools.close(this.base);
    }

}
