/*
 * Written by Dawid Kurzyniec and released to the public domain, as explained
 * at http://creativecommons.org/licenses/publicdomain
 */

package edu.emory.mathcs.util.remote.io.server.impl;

import java.io.*;
import edu.emory.mathcs.util.remote.io.server.*;

/**
 * Server-side remote handle to an input stream.
 *
 * @see edu.emory.mathcs.util.remote.io.RemoteInputStream
 *
 * @author Dawid Kurzyniec
 * @version 1.0
 */
public class RemoteInputStreamSrvImpl implements RemoteInputStreamSrv {
    final InputStream in;
    final int maxblock;
    public RemoteInputStreamSrvImpl(InputStream in) {
        this(in, 256*1024);
    }
    public RemoteInputStreamSrvImpl(InputStream in, int maxblock) {
        if (in == null) {
            throw new NullPointerException("in");
        }
        if (maxblock <= 0) {
            throw new IllegalArgumentException("maxblock <= 0");
        }
        this.in = in;
        this.maxblock = maxblock;
    }
    public byte[] read(int maxbytes) throws IOException {
        int avail = in.available();
        int toRead;
        // if no data currently available, block and try to read some chunk
        if (avail == 0) {
            toRead = maxbytes > 0 ? maxbytes : 1024;
        } else {
            toRead = maxbytes > 0 ? Math.min(avail, maxbytes) : avail;
            if (toRead > maxblock) toRead = maxblock;
        }
        byte[] buf = new byte[toRead];
        int read = in.read(buf);
        if (read == toRead) {
            // common case if available data was > 1024
            return buf;
        } else if (read < 0) {
            // EOF
            return null;
        } else {
            byte[] newbuf = new byte[read];
            System.arraycopy(buf, 0, newbuf, 0, read);
            return newbuf;
        }
    }
    public long skip(long n) throws IOException {
        return in.skip(n);
    }

    public int available() throws IOException {
        return in.available();
    }
    public void close() throws IOException {
        in.close();
    }
}
