package no.java.incogito;
import fj.F;
import fj.F2;
import static fj.Function.curry;
import fj.P1;
import fj.Unit;
import static fj.Unit.unit;
import fj.control.parallel.Callables;
import fj.data.Either;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.concurrent.Callable;
/**
* @author <a href="mailto:trygvis@java.no">Trygve Laugstøl</a>
* @version $Id$
*/
public class IO {
/*
TODO: Consider writing runFileToFile :: (a -> b) (InputStream -> Callable a) (b -> OutputStream -> Callable Unit)
*/
public static class Writers {
public static F<OutputStream, java.io.Writer> toWriter = new F<OutputStream, java.io.Writer>() {
public java.io.Writer f(OutputStream outputStream) {
return new OutputStreamWriter(outputStream);
}
};
}
public static class ByteArrays {
public static F<InputStream, Callable<byte[]>> streamToByteArray = new F<InputStream, Callable<byte[]>>() {
public Callable<byte[]> f(final InputStream inputStream) {
return new Callable<byte[]>() {
public byte[] call() throws Exception {
ByteArrayOutputStream data = new ByteArrayOutputStream();
byte[] buffer = new byte[1024 * 8];
int read = inputStream.read(buffer);
while (read != -1) {
data.write(buffer, 0, read);
read = inputStream.read(buffer);
}
return data.toByteArray();
}
};
}
};
}
public static class Strings {
public static F<InputStream, Callable<String>> streamToString = new F<InputStream, Callable<String>>() {
public Callable<String> f(final InputStream inputStream) {
return new Callable<String>() {
public String call() throws Exception {
InputStreamReader reader = new InputStreamReader(inputStream);
StringBuilder string = new StringBuilder();
char[] buffer = new char[1024 * 8];
int read = reader.read(buffer);
while (read != -1) {
string.append(buffer, 0, read);
read = reader.read(buffer);
}
return string.toString();
}
};
}
};
public static F<String, F<Writer, Callable<Unit>>> stringToWriter = curry(new F2<String, Writer, Callable<Unit>>() {
public Callable<Unit> f(final String s, final Writer writer) {
return new Callable<Unit>() {
public Unit call() throws Exception {
writer.write(s);
return unit();
}
};
}
});
public static F<String, F<OutputStream, Callable<Unit>>> stringToStream = curry(new F2<String, OutputStream, Callable<Unit>>() {
public Callable<Unit> f(final String s, final OutputStream outputStream) {
return new Callable<Unit>() {
public Unit call() throws Exception {
OutputStreamWriter writer = new OutputStreamWriter(outputStream);
writer.write(s);
writer.flush();
return unit();
}
};
}
});
}
// -----------------------------------------------------------------------
// InputStream
// -----------------------------------------------------------------------
public static <A> Callable<A> runFileInputStream(final F<InputStream, Callable<A>> callableF, final File file) {
return new Callable<A>() {
public A call() throws Exception {
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
return callableF.f(inputStream).call();
}
finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException ignore) {
}
}
}
}
};
}
public static <A> F<F<InputStream, Callable<A>>, F<File, Callable<A>>> runFileInputStream_(){
return curry(new F2<F<InputStream, Callable<A>>, File, Callable<A>>() {
public Callable<A> f(F<InputStream, Callable<A>> inputStreamCallableF, File file) {
return runFileInputStream(inputStreamCallableF, file);
}
});
}
public static <A> P1<Either<Exception, A>> $runFileInputStream(final F<InputStream, Callable<A>> callableF, final File file) {
return Callables.either(runFileInputStream(callableF, file));
}
// -----------------------------------------------------------------------
// OutputStream
// -----------------------------------------------------------------------
public static <A> Callable<A> runFileOutputStream(final F<OutputStream, Callable<A>> callableF, final File file) {
return new Callable<A>() {
public A call() throws Exception {
FileOutputStream outputStream = null;
try {
outputStream = new FileOutputStream(file);
return callableF.f(outputStream).call();
}
finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException ignore) {
}
}
}
}
};
}
public static <A> F<F<OutputStream, Callable<A>>, F<File, Callable<A>>> runFileOutputStream_(){
return curry(new F2<F<OutputStream, Callable<A>>, File, Callable<A>>() {
public Callable<A> f(F<OutputStream, Callable<A>> f, File file) {
return runFileOutputStream(f, file);
}
});
}
public static <A> P1<Either<Exception, A>> $runFileOutputStream(final F<OutputStream, Callable<A>> callableF, final File file) {
return Callables.either(runFileOutputStream(callableF, file));
}
}