package org.nutz.lang.stream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import org.nutz.lang.Encoding;
import org.nutz.lang.Lang;
import org.nutz.lang.Streams;
public class StreamBuffer extends InputStream {
private static class OutputStreamBuffer extends OutputStream {
private ArrayList<byte[]> bytes = new ArrayList<byte[]>();
private int width = 1024;
private int index = 0;
private int cursor = 0;
@Override
public void write(int b) throws IOException {
if (cursor >= width)
index++;
byte[] row = bytes.size() > index ? bytes.get(index) : null;
if (null == row) {
row = new byte[width];
bytes.add(row);
cursor = 0;
}
row[cursor++] = (byte)b;
}
private int size() {
return index > 0 ? width * (index - 1) + cursor : cursor;
}
}
private OutputStreamBuffer buffer = new OutputStreamBuffer();
private int index = 0;
private int cursor = 0;
public OutputStream getBuffer() {
return buffer;
}
public void write(int b) throws IOException {
buffer.write(b);
}
@Override
public int read() throws IOException {
if (cursor > buffer.width) {
index++;
cursor = 0;
}
if (index > buffer.index)
return -1;
if (index < buffer.bytes.size()) {
byte[] cs = buffer.bytes.get(index);
if (cursor < buffer.cursor)
return cs[cursor++];
}
return -1;
}
@Override
public int available() throws IOException {
return buffer.size();
}
@Override
public synchronized void reset() throws IOException {
index = 0;
cursor = 0;
}
@Override
public String toString() {
try {
return toString(Encoding.defaultEncoding());
}
catch (IOException e) {
throw Lang.wrapThrow(e);
}
}
public String toString(String charset) throws IOException {
index = 0;
cursor = 0;
StringBuilder sb = new StringBuilder();
StringOutputStream sos = new StringOutputStream(sb, charset);
byte c;
while ((c = (byte) this.read()) != -1)
sos.write(c);
Streams.safeFlush(sos);
Streams.safeClose(sos);
return sb.toString();
}
}