PROTON-1876 Expose the encode / decode methods using buffers
Expose the encode and decode methods that use WritableBuffer and
ReadableBuffer on the Message interface to allow clients to use newer
no-copy variants of the API easier.
diff --git a/proton-j/src/main/java/org/apache/qpid/proton/message/Message.java b/proton-j/src/main/java/org/apache/qpid/proton/message/Message.java
index 41945fa..db290e3 100644
--- a/proton-j/src/main/java/org/apache/qpid/proton/message/Message.java
+++ b/proton-j/src/main/java/org/apache/qpid/proton/message/Message.java
@@ -27,7 +27,8 @@
import org.apache.qpid.proton.amqp.messaging.MessageAnnotations;
import org.apache.qpid.proton.amqp.messaging.Properties;
import org.apache.qpid.proton.amqp.messaging.Section;
-
+import org.apache.qpid.proton.codec.ReadableBuffer;
+import org.apache.qpid.proton.codec.WritableBuffer;
import org.apache.qpid.proton.message.impl.MessageImpl;
/**
@@ -169,6 +170,18 @@
int decode(byte[] data, int offset, int length);
/**
+ * Decodes the Message from the given {@link ReadableBuffer}.
+ * <p>
+ * If the buffer given does not contain the fully encoded Message bytes for decode
+ * this method will throw an exception to indicate the buffer underflow condition and
+ * the message object will be left in an undefined state.
+ *
+ * @param buffer
+ * A {@link ReadableBuffer} that contains the complete message bytes.
+ */
+ void decode(ReadableBuffer buffer);
+
+ /**
* Encodes up to {@code length} bytes of the message into the provided byte array,
* starting at position {@code offset}.
*
@@ -179,6 +192,21 @@
*/
int encode(byte[] data, int offset, int length);
+ /**
+ * Encodes the current Message contents into the given {@link WritableBuffer} instance.
+ * <p>
+ * This method attempts to encode all message data into the {@link WritableBuffer} and
+ * if the buffer has insufficient space it will throw an exception to indicate the buffer
+ * overflow condition. If successful the method returns the number of bytes written to
+ * the provided buffer to fully encode the message.
+ *
+ * @param buffer
+ * The {@link WritableBuffer} instance to encode the message contents into.
+ *
+ * @return the number of bytes written to fully encode the message.
+ */
+ int encode(WritableBuffer buffer);
+
void clear();
MessageError getError();
diff --git a/proton-j/src/test/java/org/apache/qpid/proton/message/impl/MessageImplTest.java b/proton-j/src/test/java/org/apache/qpid/proton/message/impl/MessageImplTest.java
index 6070745..0c0c003 100644
--- a/proton-j/src/test/java/org/apache/qpid/proton/message/impl/MessageImplTest.java
+++ b/proton-j/src/test/java/org/apache/qpid/proton/message/impl/MessageImplTest.java
@@ -27,6 +27,8 @@
import org.apache.qpid.proton.amqp.Binary;
import org.apache.qpid.proton.amqp.messaging.Data;
+import org.apache.qpid.proton.codec.WritableBuffer;
+import org.apache.qpid.proton.codec.WritableBuffer.ByteBufferWrapper;
import org.apache.qpid.proton.message.Message;
import org.junit.Test;
@@ -62,6 +64,34 @@
assertEquals("Encoded length different than expected length", encodedLength, encodedBytes.length);
}
+ @Test
+ public void testEncodeOfMessageWithSmallDataBodyOnlyUsingWritableBuffer()
+ {
+ doMessageEncodingWithDataBodySectionTestImpl(5);
+ }
+
+ @Test
+ public void testEncodeOfMessageWithLargerDataBodyOnlyUsingWritableBuffer()
+ {
+ doMessageEncodingWithDataBodySectionTestImpl(1024);
+ }
+
+ void doMessageEncodingWithDataBodySectionTestImplUsingWritableBuffer(int bytesLength)
+ {
+ byte[] bytes = generateByteArray(bytesLength);
+
+ byte[] expectedBytes = generateExpectedDataSectionBytes(bytes);
+ ByteBufferWrapper encodedBytes = WritableBuffer.ByteBufferWrapper.allocate(expectedBytes.length);
+
+ Message msg = Message.Factory.create();
+ msg.setBody(new Data(new Binary(bytes)));
+
+ int encodedLength = msg.encode(encodedBytes);
+
+ assertArrayEquals("Encoded bytes do not match expectation", expectedBytes, encodedBytes.byteBuffer().array());
+ assertEquals("Encoded length different than expected length", encodedLength, encodedBytes.position());
+ }
+
private byte[] generateByteArray(int bytesLength)
{
byte[] bytes = new byte[bytesLength];