diff --git a/benchmark/src/main/java/org/capnproto/benchmark/Packed.java b/benchmark/src/main/java/org/capnproto/benchmark/Packed.java index 302877a..b477570 100644 --- a/benchmark/src/main/java/org/capnproto/benchmark/Packed.java +++ b/benchmark/src/main/java/org/capnproto/benchmark/Packed.java @@ -5,12 +5,12 @@ import java.io.IOException; public final class Packed implements Compression { public void writeBuffered(org.capnproto.BufferedOutputStream writer, org.capnproto.MessageBuilder message) throws IOException { - org.capnproto.SerializePacked.writeMessage(writer, message); + org.capnproto.SerializePacked.write(writer, message); writer.flush(); } public org.capnproto.MessageReader newBufferedReader( org.capnproto.BufferedInputStream inputStream) throws IOException { - return org.capnproto.SerializePacked.newReader(inputStream); + return org.capnproto.SerializePacked.read(inputStream); } } diff --git a/benchmark/src/main/java/org/capnproto/benchmark/Uncompressed.java b/benchmark/src/main/java/org/capnproto/benchmark/Uncompressed.java index df35469..cd88f84 100644 --- a/benchmark/src/main/java/org/capnproto/benchmark/Uncompressed.java +++ b/benchmark/src/main/java/org/capnproto/benchmark/Uncompressed.java @@ -5,12 +5,12 @@ import java.io.IOException; public final class Uncompressed implements Compression { public final void writeBuffered(org.capnproto.BufferedOutputStream writer, org.capnproto.MessageBuilder message) throws IOException { - org.capnproto.Serialize.writeMessage(writer, message); + org.capnproto.Serialize.write(writer, message); writer.flush(); } public final org.capnproto.MessageReader newBufferedReader( org.capnproto.BufferedInputStream inputStream) throws IOException { - return org.capnproto.ByteChannelMessageReader.create(inputStream); + return org.capnproto.Serialize.read(inputStream); } } diff --git a/examples/src/main/java/org/capnproto/examples/AddressbookMain.java b/examples/src/main/java/org/capnproto/examples/AddressbookMain.java index eb9a581..e1474d7 100644 --- a/examples/src/main/java/org/capnproto/examples/AddressbookMain.java +++ b/examples/src/main/java/org/capnproto/examples/AddressbookMain.java @@ -42,12 +42,12 @@ public class AddressbookMain { bobPhones.get(1).setType(Person.PhoneNumber.Type.WORK); bob.getEmployment().setUnemployed(org.capnproto.Void.VOID); - SerializePacked.writeMessageUnbuffered((new FileOutputStream(FileDescriptor.out)).getChannel(), - message); + SerializePacked.writeUnbuffered((new FileOutputStream(FileDescriptor.out)).getChannel(), + message); } public static void printAddressBook() throws java.io.IOException { - MessageReader message = SerializePacked.newReaderUnbuffered( + MessageReader message = SerializePacked.readUnbuffered( (new FileInputStream(FileDescriptor.in)).getChannel()); AddressBook.Reader addressbook = message.getRoot(AddressBook.factory); for(Person.Reader person : addressbook.getPeople()) { diff --git a/runtime/src/main/java/org/capnproto/ByteChannelMessageReader.java b/runtime/src/main/java/org/capnproto/ByteChannelMessageReader.java deleted file mode 100644 index 55a6362..0000000 --- a/runtime/src/main/java/org/capnproto/ByteChannelMessageReader.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.capnproto; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.channels.ReadableByteChannel; -import java.util.ArrayList; - -public final class ByteChannelMessageReader { - - static ByteBuffer makeByteBuffer(int bytes) { - ByteBuffer result = ByteBuffer.allocate(bytes); - result.order(ByteOrder.LITTLE_ENDIAN); - result.mark(); - return result; - } - - public static void fillBuffer(ByteBuffer buffer, ReadableByteChannel bc) throws IOException { - while(buffer.hasRemaining()) { - int r = bc.read(buffer); - if (r < 0) { - throw new IOException("premature EOF"); - } - // TODO check for r == 0 ?. - } - } - - public static MessageReader create(ReadableByteChannel bc) throws IOException { - ByteBuffer firstWord = makeByteBuffer(Constants.BYTES_PER_WORD); - fillBuffer(firstWord, bc); - - int segmentCount = 1 + firstWord.getInt(0); - - int segment0Size = 0; - if (segmentCount > 0) { - segment0Size = firstWord.getInt(4); - } - - int totalWords = segment0Size; - - if (segmentCount > 512) { - throw new IOException("too many segments"); - } - - // in words - ArrayList moreSizes = new ArrayList(); - - if (segmentCount > 1) { - ByteBuffer moreSizesRaw = makeByteBuffer(4 * (segmentCount & ~1)); - fillBuffer(moreSizesRaw, bc); - for (int ii = 0; ii < segmentCount - 1; ++ii) { - int size = moreSizesRaw.getInt(ii * 4); - moreSizes.add(size); - totalWords += size; - } - } - - // TODO check that totalWords is reasonable - - ByteBuffer allSegments = makeByteBuffer(totalWords * Constants.BYTES_PER_WORD); - fillBuffer(allSegments, bc); - - ByteBuffer[] segmentSlices = new ByteBuffer[segmentCount]; - - allSegments.rewind(); - segmentSlices[0] = allSegments.slice(); - segmentSlices[0].limit(segment0Size * Constants.BYTES_PER_WORD); - segmentSlices[0].order(ByteOrder.LITTLE_ENDIAN); - - int offset = segment0Size; - for (int ii = 1; ii < segmentCount; ++ii) { - allSegments.position(offset * Constants.BYTES_PER_WORD); - segmentSlices[ii] = allSegments.slice(); - segmentSlices[ii].limit(moreSizes.get(ii - 1) * Constants.BYTES_PER_WORD); - segmentSlices[ii].order(ByteOrder.LITTLE_ENDIAN); - offset += moreSizes.get(ii - 1); - } - - return new MessageReader(segmentSlices); - } - -} diff --git a/runtime/src/main/java/org/capnproto/Serialize.java b/runtime/src/main/java/org/capnproto/Serialize.java index 0188914..a47b86a 100644 --- a/runtime/src/main/java/org/capnproto/Serialize.java +++ b/runtime/src/main/java/org/capnproto/Serialize.java @@ -1,14 +1,87 @@ package org.capnproto; import java.io.IOException; +import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.util.ArrayList; public final class Serialize { - public static void writeMessage(WritableByteChannel outputChannel, - MessageBuilder message) throws IOException { + static ByteBuffer makeByteBuffer(int bytes) { + ByteBuffer result = ByteBuffer.allocate(bytes); + result.order(ByteOrder.LITTLE_ENDIAN); + result.mark(); + return result; + } + + public static void fillBuffer(ByteBuffer buffer, ReadableByteChannel bc) throws IOException { + while(buffer.hasRemaining()) { + int r = bc.read(buffer); + if (r < 0) { + throw new IOException("premature EOF"); + } + // TODO check for r == 0 ?. + } + } + + public static MessageReader read(ReadableByteChannel bc) throws IOException { + ByteBuffer firstWord = makeByteBuffer(Constants.BYTES_PER_WORD); + fillBuffer(firstWord, bc); + + int segmentCount = 1 + firstWord.getInt(0); + + int segment0Size = 0; + if (segmentCount > 0) { + segment0Size = firstWord.getInt(4); + } + + int totalWords = segment0Size; + + if (segmentCount > 512) { + throw new IOException("too many segments"); + } + + // in words + ArrayList moreSizes = new ArrayList(); + + if (segmentCount > 1) { + ByteBuffer moreSizesRaw = makeByteBuffer(4 * (segmentCount & ~1)); + fillBuffer(moreSizesRaw, bc); + for (int ii = 0; ii < segmentCount - 1; ++ii) { + int size = moreSizesRaw.getInt(ii * 4); + moreSizes.add(size); + totalWords += size; + } + } + + // TODO check that totalWords is reasonable + + ByteBuffer allSegments = makeByteBuffer(totalWords * Constants.BYTES_PER_WORD); + fillBuffer(allSegments, bc); + + ByteBuffer[] segmentSlices = new ByteBuffer[segmentCount]; + + allSegments.rewind(); + segmentSlices[0] = allSegments.slice(); + segmentSlices[0].limit(segment0Size * Constants.BYTES_PER_WORD); + segmentSlices[0].order(ByteOrder.LITTLE_ENDIAN); + + int offset = segment0Size; + for (int ii = 1; ii < segmentCount; ++ii) { + allSegments.position(offset * Constants.BYTES_PER_WORD); + segmentSlices[ii] = allSegments.slice(); + segmentSlices[ii].limit(moreSizes.get(ii - 1) * Constants.BYTES_PER_WORD); + segmentSlices[ii].order(ByteOrder.LITTLE_ENDIAN); + offset += moreSizes.get(ii - 1); + } + + return new MessageReader(segmentSlices); + } + + public static void write(WritableByteChannel outputChannel, + MessageBuilder message) throws IOException { ByteBuffer[] segments = message.getSegmentsForOutput(); int tableSize = (segments.length + 2) & (~1); diff --git a/runtime/src/main/java/org/capnproto/SerializePacked.java b/runtime/src/main/java/org/capnproto/SerializePacked.java index fe03247..6e55d1f 100644 --- a/runtime/src/main/java/org/capnproto/SerializePacked.java +++ b/runtime/src/main/java/org/capnproto/SerializePacked.java @@ -2,26 +2,26 @@ package org.capnproto; public final class SerializePacked { - public static MessageReader newReader(BufferedInputStream input) throws java.io.IOException { + public static MessageReader read(BufferedInputStream input) throws java.io.IOException { PackedInputStream packedInput = new PackedInputStream(input); - return ByteChannelMessageReader.create(packedInput); + return Serialize.read(packedInput); } - public static MessageReader newReaderUnbuffered(java.nio.channels.ReadableByteChannel input) throws java.io.IOException { + public static MessageReader readUnbuffered(java.nio.channels.ReadableByteChannel input) throws java.io.IOException { PackedInputStream packedInput = new PackedInputStream(new BufferedInputStreamWrapper(input)); - return ByteChannelMessageReader.create(packedInput); + return Serialize.read(packedInput); } - public static void writeMessage(BufferedOutputStream output, - MessageBuilder message) throws java.io.IOException { + public static void write(BufferedOutputStream output, + MessageBuilder message) throws java.io.IOException { PackedOutputStream packedOutputStream = new PackedOutputStream(output); - Serialize.writeMessage(packedOutputStream, message); + Serialize.write(packedOutputStream, message); } - public static void writeMessageUnbuffered(java.nio.channels.WritableByteChannel output, - MessageBuilder message) throws java.io.IOException { + public static void writeUnbuffered(java.nio.channels.WritableByteChannel output, + MessageBuilder message) throws java.io.IOException { BufferedOutputStreamWrapper buffered = new BufferedOutputStreamWrapper(output); - writeMessage(buffered, message); + write(buffered, message); buffered.flush(); } }