Skip to content
Merged
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
Add MessageUnpacker.tryUnpackNil() method
When a code deals with an Optional<T> value, a common way is to
serialize a Nil value if the value is absent. To deserialize it, we
check whether the next value is nil or not first. If it is nil, skip the
byte. Otherwise, read a value. For this common use case, tryUnpackNil
simplifies the deserialization code. It does "check whether the next
value is nil or not first. If it is nil, skip the byte" in one method
call.
  • Loading branch information
frsyuki committed Oct 14, 2017
commit 55c3346a0a5cf58fff361c359da7c325f2a611b2
27 changes: 26 additions & 1 deletion msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ private boolean ensureBuffer()
public MessageFormat getNextFormat()
throws IOException
{
// makes sure that buffer has at leat 1 byte
// makes sure that buffer has at least 1 byte
if (!ensureBuffer()) {
throw new MessageInsufficientBufferException();
}
Expand Down Expand Up @@ -731,6 +731,31 @@ public void unpackNil()
throw unexpected("Nil", b);
}

/**
* Peeks a Nil byte and reads it if next byte is a nil value.
*
* The difference from {@link unpackNil} is that unpackNil throws an exception if the next byte is not nil value
* while this tryUnpackNil method returns false without changing position.
*
* @return true if a nil value is read
* @throws MessageInsufficientBufferException when the end of file reached
* @throws IOException when underlying input throws IOException
*/
public boolean tryUnpackNil()
throws IOException
{
// makes sure that buffer has at least 1 byte
if (!ensureBuffer()) {
throw new MessageInsufficientBufferException();
}
byte b = buffer.getByte(position);
if (b == Code.NIL) {
readByte();
return true;
}
return false;
}

/**
* Reads true or false.
*
Expand Down
13 changes: 13 additions & 0 deletions msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,19 @@ class MessagePackTest extends MessagePackSpec {
check(null, _.packNil, { unpacker => unpacker.unpackNil(); null })
}

"skipping a nil value" taggedAs ("try") in {
check(true, _.packNil, _.tryUnpackNil)
check(false, { packer => packer.packString("val") }, { unpacker => unpacker.tryUnpackNil() })
check("val", { packer => packer.packString("val") }, { unpacker => unpacker.tryUnpackNil(); unpacker.unpackString() })
check("val", { packer => packer.packNil(); packer.packString("val") }, { unpacker => unpacker.tryUnpackNil(); unpacker.unpackString() })
try {
checkException(null, { _ => }, _.tryUnpackNil)
}
catch {
case e: MessageInsufficientBufferException => // OK
}
}

"pack/unpack integer values" taggedAs ("int") in {
val sampleData = Seq[Long](Int.MinValue.toLong -
10, -65535, -8191, -1024, -255, -127, -63, -31, -15, -7, -3, -1, 0, 2, 4, 8, 16, 32, 64, 128, 256, 1024, 8192, 65536,
Expand Down