basics in place for PackedInputStream
This commit is contained in:
parent
cea3c9740a
commit
8f34106347
4 changed files with 53 additions and 17 deletions
|
@ -4,5 +4,5 @@ import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.ReadableByteChannel;
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
|
||||||
public interface BufferedInputStream extends ReadableByteChannel {
|
public interface BufferedInputStream extends ReadableByteChannel {
|
||||||
public ByteBuffer getReadBuffer();
|
public ByteBuffer getReadBuffer() throws java.io.IOException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,11 @@ public final class BufferedInputStreamWrapper implements BufferedInputStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final ByteBuffer getReadBuffer() {
|
public final ByteBuffer getReadBuffer() throws IOException {
|
||||||
|
if (this.cap - this.buf.position() == 0) {
|
||||||
|
this.buf.rewind();
|
||||||
|
this.cap = readAtLeast(this.inner, this.buf, 1);
|
||||||
|
}
|
||||||
return this.buf;
|
return this.buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@ public final class PackedInputStream implements ReadableByteChannel {
|
||||||
throw new Error("PackedInputStream reads must be word-aligned");
|
throw new Error("PackedInputStream reads must be word-aligned");
|
||||||
}
|
}
|
||||||
|
|
||||||
int out = outBuf.position();
|
int outPtr = outBuf.position();
|
||||||
int outEnd = out + len;
|
int outEnd = outPtr + len;
|
||||||
|
|
||||||
ByteBuffer inBuf = this.inner.getReadBuffer();
|
ByteBuffer inBuf = this.inner.getReadBuffer();
|
||||||
|
|
||||||
|
@ -33,27 +33,42 @@ public final class PackedInputStream implements ReadableByteChannel {
|
||||||
//if (outBuf
|
//if (outBuf
|
||||||
|
|
||||||
if (inBuf.remaining() < 10) {
|
if (inBuf.remaining() < 10) {
|
||||||
if (out >= outEnd) {
|
if (outBuf.remaining() == 0) {
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inBuf.remaining() == 0) {
|
if (inBuf.remaining() == 0) {
|
||||||
// refresh buffer...
|
inBuf = this.inner.getReadBuffer();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//# We have at least 1, but not 10, bytes available. We need to read
|
//# We have at least 1, but not 10, bytes available. We need to read
|
||||||
//# slowly, doing a bounds check on each byte.
|
//# slowly, doing a bounds check on each byte.
|
||||||
|
|
||||||
// TODO
|
tag = inBuf.get();
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; ++i) {
|
||||||
|
if ((tag & (1 << i)) != 0) {
|
||||||
|
if (inBuf.remaining() == 0) {
|
||||||
|
inBuf = this.inner.getReadBuffer();
|
||||||
|
}
|
||||||
|
outBuf.put(inBuf.get());
|
||||||
|
} else {
|
||||||
|
outBuf.put((byte)0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inBuf.remaining() ==0 && (tag == 0 || tag == (byte)0xff)) {
|
||||||
|
inBuf = this.inner.getReadBuffer();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
tag = inBuf.get();
|
tag = inBuf.get();
|
||||||
for (int n = 0; n < 8; ++n) {
|
for (int n = 0; n < 8; ++n) {
|
||||||
boolean isNonzero = (tag & (1 << n)) != 0;
|
boolean isNonzero = (tag & (1 << n)) != 0;
|
||||||
// ...
|
outBuf.put((byte)(inBuf.get() & (isNonzero ? -1 : 0)));
|
||||||
|
inBuf.position(inBuf.position() + (isNonzero ? 0 : -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tag == 0) {
|
if (tag == 0) {
|
||||||
|
@ -63,11 +78,13 @@ public final class PackedInputStream implements ReadableByteChannel {
|
||||||
|
|
||||||
int runLength = inBuf.get() * 8;
|
int runLength = inBuf.get() * 8;
|
||||||
|
|
||||||
if (runLength > outEnd - out) {
|
if (runLength > outEnd - outPtr) {
|
||||||
throw new Error("Packed input did not end cleanly on a segment boundary");
|
throw new Error("Packed input did not end cleanly on a segment boundary");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < runLength; ++i) {
|
||||||
|
outBuf.put((byte) 0);
|
||||||
|
}
|
||||||
} else if (tag == (byte)0xff) {
|
} else if (tag == (byte)0xff) {
|
||||||
|
|
||||||
int runLength = inBuf.get() * 8;
|
int runLength = inBuf.get() * 8;
|
||||||
|
@ -81,7 +98,7 @@ public final class PackedInputStream implements ReadableByteChannel {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out == outEnd) {
|
if (outBuf.remaining() == 0) {
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,13 +9,28 @@ class SerializePackedSuite extends FunSuite {
|
||||||
def expectPacksTo(unpacked : Array[Byte], packed : Array[Byte]) {
|
def expectPacksTo(unpacked : Array[Byte], packed : Array[Byte]) {
|
||||||
// ----
|
// ----
|
||||||
// write
|
// write
|
||||||
|
{
|
||||||
val bytes = new Array[Byte](packed.length);
|
val bytes = new Array[Byte](packed.length);
|
||||||
val writer = new ArrayOutputStream(ByteBuffer.wrap(bytes));
|
val writer = new ArrayOutputStream(ByteBuffer.wrap(bytes));
|
||||||
val packedOutputStream = new PackedOutputStream (writer);
|
val packedOutputStream = new PackedOutputStream(writer);
|
||||||
packedOutputStream.write(ByteBuffer.wrap(unpacked));
|
packedOutputStream.write(ByteBuffer.wrap(unpacked));
|
||||||
|
|
||||||
(bytes) should equal (packed);
|
(bytes) should equal (packed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------
|
||||||
|
// read
|
||||||
|
{
|
||||||
|
val reader = new ArrayInputStream(ByteBuffer.wrap(packed));
|
||||||
|
val packedInputStream = new PackedInputStream(reader);
|
||||||
|
val bytes = new Array[Byte](unpacked.length);
|
||||||
|
val n = packedInputStream.read(ByteBuffer.wrap(bytes));
|
||||||
|
|
||||||
|
//(n) should equal (unpacked.length);
|
||||||
|
|
||||||
|
//(bytes) should equal (unpacked);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue