package com.revolsys.io;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
public class FileBackedCache implements BaseCloseable {
private byte[] buffer;
private final int maxSize;
private final OutputStream outputStream = new OutputStream() {
@Override
public void close() {
}
@Override
public void flush() {
FileBackedCache.this.flush();
}
@Override
public synchronized void write(final byte[] data, final int offset, final int length) {
FileBackedCache.this.write(data, offset, length);
}
@Override
public synchronized void write(final int b) {
FileBackedCache.this.write(b);
}
};
private int size;
private Writer writer;
public FileBackedCache() {
this(1024 * 1024);
}
public FileBackedCache(final int maxSize) {
this.maxSize = maxSize;
if (maxSize > 4096) {
this.buffer = new byte[4096];
} else {
this.buffer = new byte[maxSize];
}
}
@Override
public void close() {
}
public void flush() {
}
public InputStream getInputStream() {
return new ByteArrayInputStream(this.buffer, 0, this.size);
}
public OutputStream getOutputStream() {
return this.outputStream;
}
public int getSize() {
return this.size;
}
public synchronized Writer getWriter() {
if (this.writer == null) {
this.writer = FileUtil.newUtf8Writer(this.outputStream);
}
return this.writer;
}
@Override
public String toString() {
return new String(this.buffer, 0, this.size, StandardCharsets.UTF_8);
}
public synchronized void write(final byte[] data, final int offset, final int length) {
final int newSize = this.size + length;
if (newSize >= this.buffer.length) {
if (newSize >= this.maxSize) {
throw new RuntimeException("Buffer too large");
} else {
int newLength = this.buffer.length + 4096;
if (newLength < newSize) {
newLength = newSize;
}
if (newLength > this.maxSize) {
newLength = this.maxSize;
}
final byte[] buffer = new byte[newLength];
System.arraycopy(this.buffer, 0, buffer, 0, this.buffer.length);
this.buffer = buffer;
}
}
System.arraycopy(data, offset, this.buffer, this.size, length);
this.size = newSize;
}
public synchronized void write(final int b) {
if (this.size > this.buffer.length) {
if (this.size > this.maxSize) {
throw new RuntimeException("Buffer too large");
} else {
final byte[] buffer = new byte[Math.max(this.maxSize, this.buffer.length + 4096)];
System.arraycopy(this.buffer, 0, buffer, 0, buffer.length);
this.buffer = buffer;
}
}
this.buffer[this.size++] = (byte)b;
}
}