Created
March 8, 2012 02:19
-
-
Save dobesv/1998118 to your computer and use it in GitHub Desktop.
Add Buf subclass supporting any kind of java.nio.ByteBuffer (not just MmapByteBuffer)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package fan.sys; | |
import java.nio.MappedByteBuffer; | |
public class MmapBuf extends NioBuf { | |
MmapBuf(File file, MappedByteBuffer mmap) { | |
super(mmap); | |
this.file = file; | |
this.mmap = mmap; | |
} | |
public Buf flush() { | |
mmap.force(); | |
return this; | |
} | |
public Type typeof() { | |
return Sys.MmapBufType; | |
} | |
private File file; | |
private MappedByteBuffer mmap; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package fan.sys; | |
import java.io.*; | |
import java.nio.*; | |
import fan.sys.Buf; | |
public class NioBuf extends Buf { | |
// //////////////////////////////////////////////////////////////////////// | |
// Constructor | |
// //////////////////////////////////////////////////////////////////////// | |
public NioBuf(ByteBuffer byteBuffer) { | |
this.byteBuffer = byteBuffer; | |
this.out = new NioBufOutStream(); | |
this.in = new NioBufInStream(); | |
} | |
// //////////////////////////////////////////////////////////////////////// | |
// Obj | |
// //////////////////////////////////////////////////////////////////////// | |
public Type typeof() { | |
return Sys.MemBufType; // TODO This is the wrong type here | |
} | |
// //////////////////////////////////////////////////////////////////////// | |
// Buf Support | |
// //////////////////////////////////////////////////////////////////////// | |
public final long size() { | |
return byteBuffer.limit(); | |
} | |
public final void size(long x) { | |
byteBuffer.limit((int) x); | |
} | |
public final long pos() { | |
return byteBuffer.position(); | |
} | |
final void pos(long x) { | |
byteBuffer.position((int) x); | |
} | |
public final int getByte(long pos) { | |
return byteBuffer.get((int) pos) & 0xff; | |
} | |
public final void setByte(long pos, int x) { | |
byteBuffer.put((int) pos, (byte) x); | |
} | |
public final void getBytes(long pos, byte[] dst, int off, int len) { | |
int oldPos = byteBuffer.position(); | |
byteBuffer.position((int) pos); | |
byteBuffer.get(dst, off, len); | |
byteBuffer.position(oldPos); | |
} | |
public final void pipeTo(byte[] dst, int dstPos, int len) { | |
byteBuffer.get(dst, dstPos, len); | |
} | |
public final void pipeTo(OutputStream dst, long lenLong) throws IOException { | |
byte[] temp = temp(); | |
int len = (int) lenLong; | |
int total = 0; | |
while (total < len) { | |
int n = Math.min(temp.length, len - total); | |
byteBuffer.get(temp, 0, n); | |
dst.write(temp, 0, n); | |
total += n; | |
} | |
} | |
public final void pipeTo(RandomAccessFile dst, long lenLong) | |
throws IOException { | |
byte[] temp = temp(); | |
int len = (int) lenLong; | |
int total = 0; | |
while (total < len) { | |
int n = Math.min(temp.length, len - total); | |
byteBuffer.get(temp, 0, n); | |
dst.write(temp, 0, n); | |
total += n; | |
} | |
} | |
public final void pipeTo(ByteBuffer dst, int len) { | |
pipe(byteBuffer, dst, len); | |
} | |
void pipe(ByteBuffer src, ByteBuffer dst, int len) { | |
// NIO has one lame method for bulk transfer | |
// and it doesn't let us pass in a length | |
byte[] temp = temp(); | |
int total = 0; | |
while (total < len) { | |
int n = Math.min(temp.length, len - total); | |
src.get(temp, 0, n); | |
dst.put(temp, 0, n); | |
total += n; | |
} | |
} | |
public final void pipeFrom(byte[] src, int srcPos, int len) { | |
byteBuffer.put(src, srcPos, len); | |
} | |
public final long pipeFrom(InputStream src, long lenLong) | |
throws IOException { | |
byte[] temp = temp(); | |
int len = (int) lenLong; | |
int total = 0; | |
while (total < len) { | |
int n = src.read(temp, 0, Math.min(temp.length, len - total)); | |
if (n < 0) | |
return total == 0 ? -1 : total; | |
byteBuffer.put(temp, 0, n); | |
total += n; | |
} | |
return total; | |
} | |
public final long pipeFrom(RandomAccessFile src, long lenLong) | |
throws IOException { | |
byte[] temp = temp(); | |
int len = (int) lenLong; | |
int total = 0; | |
while (total < len) { | |
int n = src.read(temp, 0, Math.min(temp.length, len - total)); | |
if (n < 0) | |
return total == 0 ? -1 : total; | |
byteBuffer.put(temp, 0, n); | |
total += n; | |
} | |
return total; | |
} | |
public final int pipeFrom(ByteBuffer src, int len) { | |
pipe(src, byteBuffer, len); | |
return len; | |
} | |
// //////////////////////////////////////////////////////////////////////// | |
// Buf API | |
// //////////////////////////////////////////////////////////////////////// | |
public long capacity() { | |
return size(); | |
} | |
public void capacity(long x) { | |
throw UnsupportedErr.make("capacity fixed"); | |
} | |
// For the mmap subclass this would call force() | |
public Buf flush() { | |
return this; | |
} | |
public final boolean close() { | |
return true; | |
} | |
public final String toHex() { | |
throw UnsupportedErr.make(); | |
} | |
public Buf toDigest(String algorithm) { | |
throw UnsupportedErr.make(); | |
} | |
// //////////////////////////////////////////////////////////////////////// | |
// Utils | |
// //////////////////////////////////////////////////////////////////////// | |
final byte[] temp() { | |
if (temp == null) | |
temp = new byte[1024]; | |
return temp; | |
} | |
// //////////////////////////////////////////////////////////////////////// | |
// MmapBufOutStream | |
// //////////////////////////////////////////////////////////////////////// | |
class NioBufOutStream extends OutStream { | |
public final OutStream write(long v) { | |
return w((int) v); | |
} | |
public final OutStream w(int v) { | |
byteBuffer.put((byte) v); | |
return this; | |
} | |
public OutStream writeBuf(Buf other, long n) { | |
other.pipeTo(byteBuffer, (int) n); | |
return this; | |
} | |
public OutStream writeChar(long c) { | |
charsetEncoder.encode((char) c, this); | |
return this; | |
} | |
public OutStream writeChar(char c) { | |
charsetEncoder.encode(c, this); | |
return this; | |
} | |
public OutStream flush() { | |
NioBuf.this.flush(); | |
return this; | |
} | |
} | |
// //////////////////////////////////////////////////////////////////////// | |
// NioBufInStream | |
// //////////////////////////////////////////////////////////////////////// | |
class NioBufInStream extends InStream { | |
public Long read() { | |
int n = r(); | |
return n < 0 ? null : FanInt.pos[n]; | |
} | |
public int r() { | |
if (byteBuffer.remaining() <= 0) | |
return -1; | |
return byteBuffer.get() & 0xff; | |
} | |
public Long readBuf(Buf other, long n) { | |
int left = byteBuffer.remaining(); | |
if (left <= 0) | |
return null; | |
if (left < n) | |
n = left; | |
int read = other.pipeFrom(byteBuffer, (int) n); | |
if (read < 0) | |
return null; | |
return Long.valueOf(read); | |
} | |
public InStream unread(long n) { | |
return unread((int) n); | |
} | |
public InStream unread(int n) { | |
byteBuffer.put(byteBuffer.position() - 1, (byte) n); | |
return this; | |
} | |
public Long peek() { | |
return FanInt.pos[byteBuffer.get(byteBuffer.position())]; | |
} | |
} | |
// //////////////////////////////////////////////////////////////////////// | |
// Fields | |
// //////////////////////////////////////////////////////////////////////// | |
public ByteBuffer byteBuffer; | |
private byte[] temp; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment