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

package edu.emory.mathcs.util.net.compressed;

import java.io.*;
import java.net.*;

import edu.emory.mathcs.util.io.*;
import edu.emory.mathcs.util.net.*;

/**
 * Socket wrappper that enables data compression over an established socket
 * connection. The output stream associated with this socket guarantees
 * that flush sends out all the data that has been written so far. Hence,
 * this kind of socket can be used as a transport for request-response-based
 * protocols, like RMI or RPC.
 *
 * @see edu.emory.mathcs.util.io.CompressedOutputStream
 *
 * @author Dawid Kurzyniec
 */
public class CompressedSocketWrapper extends SocketWrapper
    implements DecoratingSocket
{
    /**
     * Buffer size used for compression/decompression.
     */
    protected final int bufSize;

    /**
     * Creates new compression wrapper over an existing, bound socket.
     * @param delegate the socket to enable compression for
     * @throws SocketException if a socket exception occurs
     */
    public CompressedSocketWrapper(Socket delegate) throws SocketException {
        this(delegate, -1);
    }

    /**
     * Creates new compression wrapper over an existing, bound socket, using
     * specified buffer size for compression/decompression.
     *
     * @param delegate the socket to enable compression for
     * @param bufSize buffer size used for compression/decompression
     * @throws SocketException if a socket exception occurs
     */
    public CompressedSocketWrapper(Socket delegate, int bufSize) throws SocketException {
        super(delegate);
        this.bufSize = bufSize;
    }

    public Socket getBaseSocket() {
        return delegate;
    }

    public InputStream getInputStream() throws IOException {
        InputStream is = super.getInputStream();
        if (bufSize > 0) {
            return new CompressedInputStream(is, bufSize);
        }
        else {
            return new CompressedInputStream(is);
        }
    }

    public OutputStream getOutputStream() throws IOException {
        OutputStream out = super.getOutputStream();
        if (bufSize > 0) {
            return new CompressedOutputStream(out, bufSize);
        }
        else {
            return new CompressedOutputStream(out);
        }
    }
}
