From 5549d4dbf7371d1a4e84382b807aef441e9bfd18 Mon Sep 17 00:00:00 2001 From: David Renshaw Date: Fri, 26 Sep 2014 13:55:02 -0400 Subject: [PATCH] pass another test --- .../org/capnproto/PackedOutputStream.java | 44 ++++++++++++++++--- .../org/capnproto/SerializePackedTest.scala | 10 +++-- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/runtime/src/main/java/org/capnproto/PackedOutputStream.java b/runtime/src/main/java/org/capnproto/PackedOutputStream.java index ca1dc1f..f0bfbc8 100644 --- a/runtime/src/main/java/org/capnproto/PackedOutputStream.java +++ b/runtime/src/main/java/org/capnproto/PackedOutputStream.java @@ -27,9 +27,11 @@ public final class PackedOutputStream implements WritableByteChannel { //# bounds-check on every byte. if (out == slowBuffer) { + int oldLimit = out.limit(); out.limit(out.position()); out.rewind(); this.inner.write(out); + out.limit(oldLimit); } out = slowBuffer; @@ -103,8 +105,8 @@ public final class PackedOutputStream implements WritableByteChannel { long inWord = inBuf.getLong(); int limit = inEnd; - if (limit - inPtr > 255) { - limit = inPtr + 255; + if (limit - inPtr > 255 * 8) { + limit = inPtr + 255 * 8; } while(inBuf.position() < limit && inWord == 0) { inWord = inBuf.getLong(); @@ -112,7 +114,7 @@ public final class PackedOutputStream implements WritableByteChannel { out.put((byte)((inBuf.position() - inPtr)/8 - 1)); inPtr = inBuf.position() - 8; - } else if (tag == 0xff) { + } else if (tag == (byte)0xff) { //# An all-nonzero word is followed by a count of //# consecutive uncompressed words, followed by the //# uncompressed words themselves. @@ -122,10 +124,42 @@ public final class PackedOutputStream implements WritableByteChannel { //# for at least two zeros because that's the point //# where our compression scheme becomes a net win. + int runStart = inPtr; + int limit = inEnd; + if (limit - inPtr > 255 * 8) { + limit = inPtr + 255 * 8; + } - // TODO + while (inPtr < limit) { + byte c = 0; + for (int ii = 0; ii < 8; ++ii) { + c += (inBuf.get(inPtr) == 0 ? 1 : 0); + inPtr += 1; + } + if (c >= 2) { + //# Un-read the word with multiple zeros, since + //# we'll want to compress that one. + inPtr -= 8; + break; + } + } + + int count = inPtr - runStart; + out.put((byte)(count / 8)); + + if (count <= out.remaining()) { + //# There's enough space to memcpy. + inBuf.position(runStart); + ByteBuffer slice = inBuf.slice(); + slice.limit(count); + out.put(slice); + } else { + //# Input overruns the output buffer. We'll give it + //# to the output stream in one chunk and let it + //# decide what to do. + + } } - } if (out == slowBuffer) { diff --git a/runtime/src/test/scala/org/capnproto/SerializePackedTest.scala b/runtime/src/test/scala/org/capnproto/SerializePackedTest.scala index fca41c0..c164a34 100644 --- a/runtime/src/test/scala/org/capnproto/SerializePackedTest.scala +++ b/runtime/src/test/scala/org/capnproto/SerializePackedTest.scala @@ -26,8 +26,12 @@ class SerializePackedSuite extends FunSuite { expectPacksTo(Array(0,0,0,0,0,0,0,0, 1,3,2,4,5,7,6,8), Array(0,0,0xff.toByte,1,3,2,4,5,7,6,8,0)); expectPacksTo(Array(0,0,12,0,0,34,0,0, 1,3,2,4,5,7,6,8), - Array(0x24, 12, 34, 0xff.toByte,1,3,2,4,5,7,6,8)); - //expectPacksTo(Array(1,3,2,4,5,7,6,8, 8,6,7,4,5,2,3,1), - // Array(0xff.toByte,1,3,2,4,5,7,6,8,1,8,6,7,4,5,2,3,1)); + Array(0x24, 12, 34, 0xff.toByte,1,3,2,4,5,7,6,8,0)); + expectPacksTo(Array(1,3,2,4,5,7,6,8, 8,6,7,4,5,2,3,1), + Array(0xff.toByte,1,3,2,4,5,7,6,8,1,8,6,7,4,5,2,3,1)); + + //expectPacksTo(Array(1,2,3,4,5,6,7,8, 1,2,3,4,5,6,7,8, 1,2,3,4,5,6,7,8, 0,2,4,0,9,0,5,1), + // Array(0xff.toByte,1,2,3,4,5,6,7,8, 3, 1,2,3,4,5,6,7,8, 1,2,3,4,5,6,7,8, 1,2,3,4,5,6,7,8, + // 0xd6.toByte,2,4,9,5,1)); } }