Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
325 changes: 176 additions & 149 deletions msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,21 @@ public class ChannelBufferOutput
private MessageBuffer buffer;

public ChannelBufferOutput(WritableByteChannel channel)
{
this(channel, 8192);
}

public ChannelBufferOutput(WritableByteChannel channel, int bufferSize)
{
this.channel = checkNotNull(channel, "output channel is null");
this.buffer = MessageBuffer.newBuffer(bufferSize);
}

/**
* Reset channel. This method doesn't close the old resource.
* Reset channel. This method doesn't close the old channel.
*
* @param channel new channel
* @return the old resource
* @return the old channel
*/
public WritableByteChannel reset(WritableByteChannel channel)
throws IOException
Expand All @@ -50,21 +56,40 @@ public WritableByteChannel reset(WritableByteChannel channel)
}

@Override
public MessageBuffer next(int bufferSize)
public MessageBuffer next(int mimimumSize)
throws IOException
{
if (buffer == null || buffer.size() != bufferSize) {
buffer = MessageBuffer.newBuffer(bufferSize);
if (buffer.size() < mimimumSize) {
buffer = MessageBuffer.newBuffer(mimimumSize);
}
return buffer;
}

@Override
public void flush(MessageBuffer buf)
public void writeBuffer(int length)
throws IOException
{
ByteBuffer bb = buffer.toByteBuffer(0, length);
while (bb.hasRemaining()) {
channel.write(bb);
}
}

@Override
public void write(byte[] buffer, int offset, int length)
throws IOException
{
ByteBuffer bb = buf.toByteBuffer();
channel.write(bb);
ByteBuffer bb = ByteBuffer.wrap(buffer, offset, length);
while (bb.hasRemaining()) {
channel.write(bb);
}
}

@Override
public void add(byte[] buffer, int offset, int length)
throws IOException
{
write(buffer, offset, length);
}

@Override
Expand All @@ -73,4 +98,9 @@ public void close()
{
channel.close();
}

@Override
public void flush()
throws IOException
{ }
}
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,11 @@ public static MessageBuffer wrap(byte[] array)
return newMessageBuffer(array);
}

public static MessageBuffer wrap(byte[] array, int offset, int length)
{
return newMessageBuffer(array).slice(offset, length);
}

public static MessageBuffer wrap(ByteBuffer bb)
{
return newMessageBuffer(bb).slice(bb.position(), bb.remaining());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,60 @@

import java.io.Closeable;
import java.io.IOException;
import java.io.Flushable;

/**
* Provides a sequence of MessageBuffers for packing the input data
* Provides a buffered output stream for packing objects
*/
public interface MessageBufferOutput
extends Closeable
extends Closeable, Flushable
{
/**
* Retrieves the next buffer for writing message packed data
* Allocates the next buffer for writing message packed data.
* If the previously allocated buffer is not flushed yet, this next method should discard
* it without writing it.
*
* @param bufferSize the buffer size to retrieve
* @param mimimumSize the mimium required buffer size to allocate
* @return
* @throws IOException
*/
public MessageBuffer next(int bufferSize)
public MessageBuffer next(int mimimumSize)
throws IOException;

/**
* Output the buffer contents. If you need to output a part of the
* buffer use {@link MessageBuffer#slice(int, int)}
* Flushes the previously allocated buffer.
* This method is not always called because next method also flushes previously allocated buffer.
* This method is called when write method is called or application wants to control the timing of flush.
*
* @param buf
* @param length the size of buffer to flush
* @throws IOException
*/
public void flush(MessageBuffer buf)
public void writeBuffer(int length)
throws IOException;

/**
* Writes an external payload data.
* This method should follow semantics of OutputStream.
*
* @param buffer the data to write
* @param offset the start offset in the data
* @param length the number of bytes to write
* @return
* @throws IOException
*/
public void write(byte[] buffer, int offset, int length)
throws IOException;

/**
* Writes an external payload data.
* This buffer is given - this MessageBufferOutput owns the buffer and may modify contents of the buffer. Contents of this buffer won't be modified by the caller.
*
* @param buffer the data to add
* @param offset the start offset in the data
* @param length the number of bytes to add
* @return
* @throws IOException
*/
public void add(byte[] buffer, int offset, int length)
throws IOException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,23 @@ public class OutputStreamBufferOutput
{
private OutputStream out;
private MessageBuffer buffer;
private byte[] tmpBuf;

public OutputStreamBufferOutput(OutputStream out)
{
this(out, 8192);
}

public OutputStreamBufferOutput(OutputStream out, int bufferSize)
{
this.out = checkNotNull(out, "output is null");
this.buffer = MessageBuffer.newBuffer(bufferSize);
}

/**
* Reset Stream. This method doesn't close the old resource.
* Reset Stream. This method doesn't close the old stream.
*
* @param out new stream
* @return the old resource
* @return the old stream
*/
public OutputStream reset(OutputStream out)
throws IOException
Expand All @@ -50,41 +55,47 @@ public OutputStream reset(OutputStream out)
}

@Override
public MessageBuffer next(int bufferSize)
public MessageBuffer next(int mimimumSize)
throws IOException
{
if (buffer == null || buffer.size != bufferSize) {
buffer = MessageBuffer.newBuffer(bufferSize);
if (buffer.size() < mimimumSize) {
buffer = MessageBuffer.newBuffer(mimimumSize);
}
return buffer;
}

@Override
public void flush(MessageBuffer buf)
public void writeBuffer(int length)
throws IOException
{
int writeLen = buf.size();
if (buf.hasArray()) {
out.write(buf.getArray(), buf.offset(), writeLen);
}
else {
if (tmpBuf == null || tmpBuf.length < writeLen) {
tmpBuf = new byte[writeLen];
}
buf.getBytes(0, tmpBuf, 0, writeLen);
out.write(tmpBuf, 0, writeLen);
}
write(buffer.getArray(), buffer.offset(), length);
}

@Override
public void write(byte[] buffer, int offset, int length)
throws IOException
{
out.write(buffer, offset, length);
}

@Override
public void add(byte[] buffer, int offset, int length)
throws IOException
{
write(buffer, offset, length);
}

@Override
public void close()
throws IOException
{
try {
out.flush();
}
finally {
out.close();
}
out.close();
}

@Override
public void flush()
throws IOException
{
out.flush();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,6 @@ public static void packer()
.packArrayHeader(2)
.packString("xxx-xxxx")
.packString("yyy-yyyy");

// [Advanced] write data using ByteBuffer
ByteBuffer bb = ByteBuffer.wrap(new byte[] {'b', 'i', 'n', 'a', 'r', 'y', 'd', 'a', 't', 'a'});
packer.packBinaryHeader(bb.remaining());
packer.writePayload(bb);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,12 +283,11 @@ class MessagePackerTest

"support read-only buffer" taggedAs ("read-only") in {
val payload = Array[Byte](1)
val buffer = ByteBuffer.wrap(payload).asReadOnlyBuffer()
val out = new
ByteArrayOutputStream()
val packer = MessagePack.newDefaultPacker(out)
.packBinaryHeader(1)
.writePayload(buffer)
.writePayload(payload)
.close()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class MessageBufferOutputTest
def writeIntToBuf(buf: MessageBufferOutput) = {
val mb0 = buf.next(8)
mb0.putInt(0, 42)
buf.flush(mb0)
buf.writeBuffer(4)
buf.close
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,17 @@ else if (v instanceof Integer) {
}
else if (v instanceof ByteBuffer) {
ByteBuffer bb = (ByteBuffer) v;
messagePacker.packBinaryHeader(bb.limit());
messagePacker.writePayload(bb);
int len = bb.remaining();
if (bb.hasArray()) {
messagePacker.packBinaryHeader(len);
messagePacker.writePayload(bb.array(), bb.arrayOffset(), len);
}
else {
byte[] data = new byte[len];
bb.get(data);
messagePacker.packBinaryHeader(len);
messagePacker.addPayload(data);
}
}
else if (v instanceof String) {
messagePacker.packString((String) v);
Expand Down