add support for directly serializing a MessageReader
Previously, you would need to copy the message into a MessageBuilder first.
This commit is contained in:
parent
d310db1e88
commit
a078df7e4d
3 changed files with 67 additions and 3 deletions
|
@ -28,6 +28,10 @@ import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialization using the standard (unpacked) stream encoding:
|
||||||
|
* https://capnproto.org/encoding.html#serialization-over-a-stream
|
||||||
|
*/
|
||||||
public final class Serialize {
|
public final class Serialize {
|
||||||
|
|
||||||
static ByteBuffer makeByteBuffer(int bytes) {
|
static ByteBuffer makeByteBuffer(int bytes) {
|
||||||
|
@ -186,9 +190,8 @@ public final class Serialize {
|
||||||
return bytes / Constants.BYTES_PER_WORD;
|
return bytes / Constants.BYTES_PER_WORD;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void write(WritableByteChannel outputChannel,
|
private static void writeSegmentTable(WritableByteChannel outputChannel,
|
||||||
MessageBuilder message) throws IOException {
|
ByteBuffer[] segments) throws IOException {
|
||||||
ByteBuffer[] segments = message.getSegmentsForOutput();
|
|
||||||
int tableSize = (segments.length + 2) & (~1);
|
int tableSize = (segments.length + 2) & (~1);
|
||||||
|
|
||||||
ByteBuffer table = ByteBuffer.allocate(4 * tableSize);
|
ByteBuffer table = ByteBuffer.allocate(4 * tableSize);
|
||||||
|
@ -204,6 +207,34 @@ public final class Serialize {
|
||||||
while (table.hasRemaining()) {
|
while (table.hasRemaining()) {
|
||||||
outputChannel.write(table);
|
outputChannel.write(table);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes a MessageBuilder to a WritableByteChannel.
|
||||||
|
*/
|
||||||
|
public static void write(WritableByteChannel outputChannel,
|
||||||
|
MessageBuilder message) throws IOException {
|
||||||
|
ByteBuffer[] segments = message.getSegmentsForOutput();
|
||||||
|
writeSegmentTable(outputChannel, segments);
|
||||||
|
|
||||||
|
for (ByteBuffer buffer : segments) {
|
||||||
|
while(buffer.hasRemaining()) {
|
||||||
|
outputChannel.write(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes a MessageReader to a WritableByteChannel.
|
||||||
|
*/
|
||||||
|
public static void write(WritableByteChannel outputChannel,
|
||||||
|
MessageReader message) throws IOException {
|
||||||
|
ByteBuffer[] segments = new ByteBuffer[message.arena.segments.size()];
|
||||||
|
for (int ii = 0 ; ii < message.arena.segments.size(); ++ii) {
|
||||||
|
segments[ii] = message.arena.segments.get(ii).buffer.duplicate();
|
||||||
|
}
|
||||||
|
|
||||||
|
writeSegmentTable(outputChannel, segments);
|
||||||
|
|
||||||
for (ByteBuffer buffer : segments) {
|
for (ByteBuffer buffer : segments) {
|
||||||
while(buffer.hasRemaining()) {
|
while(buffer.hasRemaining()) {
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
|
|
||||||
package org.capnproto;
|
package org.capnproto;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialization using the packed encoding: https://capnproto.org/encoding.html#packing
|
||||||
|
*/
|
||||||
public final class SerializePacked {
|
public final class SerializePacked {
|
||||||
|
|
||||||
public static MessageReader read(BufferedInputStream input) throws java.io.IOException {
|
public static MessageReader read(BufferedInputStream input) throws java.io.IOException {
|
||||||
|
@ -42,16 +45,42 @@ public final class SerializePacked {
|
||||||
return Serialize.read(packedInput, options);
|
return Serialize.read(packedInput, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes a MessageBuilder to a BufferedOutputStream.
|
||||||
|
*/
|
||||||
public static void write(BufferedOutputStream output,
|
public static void write(BufferedOutputStream output,
|
||||||
MessageBuilder message) throws java.io.IOException {
|
MessageBuilder message) throws java.io.IOException {
|
||||||
PackedOutputStream packedOutputStream = new PackedOutputStream(output);
|
PackedOutputStream packedOutputStream = new PackedOutputStream(output);
|
||||||
Serialize.write(packedOutputStream, message);
|
Serialize.write(packedOutputStream, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes a MessageReader to a BufferedOutputStream.
|
||||||
|
*/
|
||||||
|
public static void write(BufferedOutputStream output,
|
||||||
|
MessageReader message) throws java.io.IOException {
|
||||||
|
PackedOutputStream packedOutputStream = new PackedOutputStream(output);
|
||||||
|
Serialize.write(packedOutputStream, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes a MessageBuilder to an unbuffered output stream.
|
||||||
|
*/
|
||||||
public static void writeToUnbuffered(java.nio.channels.WritableByteChannel output,
|
public static void writeToUnbuffered(java.nio.channels.WritableByteChannel output,
|
||||||
MessageBuilder message) throws java.io.IOException {
|
MessageBuilder message) throws java.io.IOException {
|
||||||
BufferedOutputStreamWrapper buffered = new BufferedOutputStreamWrapper(output);
|
BufferedOutputStreamWrapper buffered = new BufferedOutputStreamWrapper(output);
|
||||||
write(buffered, message);
|
write(buffered, message);
|
||||||
buffered.flush();
|
buffered.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes a MessageReader to an unbuffered output stream.
|
||||||
|
*/
|
||||||
|
public static void writeToUnbuffered(java.nio.channels.WritableByteChannel output,
|
||||||
|
MessageReader message) throws java.io.IOException {
|
||||||
|
BufferedOutputStreamWrapper buffered = new BufferedOutputStreamWrapper(output);
|
||||||
|
write(buffered, message);
|
||||||
|
buffered.flush();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,10 @@ public class SerializeTest {
|
||||||
{
|
{
|
||||||
MessageReader messageReader = Serialize.read(new ArrayInputStream(ByteBuffer.wrap(exampleBytes)));
|
MessageReader messageReader = Serialize.read(new ArrayInputStream(ByteBuffer.wrap(exampleBytes)));
|
||||||
checkSegmentContents(exampleSegmentCount, messageReader.arena);
|
checkSegmentContents(exampleSegmentCount, messageReader.arena);
|
||||||
|
|
||||||
|
byte[] outputBytes = new byte[exampleBytes.length];
|
||||||
|
Serialize.write(new ArrayOutputStream(ByteBuffer.wrap(outputBytes)), messageReader);
|
||||||
|
Assert.assertArrayEquals(exampleBytes, outputBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------
|
// ------
|
||||||
|
|
Loading…
Reference in a new issue