Skip to content

Commit 55c3346

Browse files
committed
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.
1 parent 81d540d commit 55c3346

2 files changed

Lines changed: 39 additions & 1 deletion

File tree

msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ private boolean ensureBuffer()
389389
public MessageFormat getNextFormat()
390390
throws IOException
391391
{
392-
// makes sure that buffer has at leat 1 byte
392+
// makes sure that buffer has at least 1 byte
393393
if (!ensureBuffer()) {
394394
throw new MessageInsufficientBufferException();
395395
}
@@ -731,6 +731,31 @@ public void unpackNil()
731731
throw unexpected("Nil", b);
732732
}
733733

734+
/**
735+
* Peeks a Nil byte and reads it if next byte is a nil value.
736+
*
737+
* The difference from {@link unpackNil} is that unpackNil throws an exception if the next byte is not nil value
738+
* while this tryUnpackNil method returns false without changing position.
739+
*
740+
* @return true if a nil value is read
741+
* @throws MessageInsufficientBufferException when the end of file reached
742+
* @throws IOException when underlying input throws IOException
743+
*/
744+
public boolean tryUnpackNil()
745+
throws IOException
746+
{
747+
// makes sure that buffer has at least 1 byte
748+
if (!ensureBuffer()) {
749+
throw new MessageInsufficientBufferException();
750+
}
751+
byte b = buffer.getByte(position);
752+
if (b == Code.NIL) {
753+
readByte();
754+
return true;
755+
}
756+
return false;
757+
}
758+
734759
/**
735760
* Reads true or false.
736761
*

msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,19 @@ class MessagePackTest extends MessagePackSpec {
240240
check(null, _.packNil, { unpacker => unpacker.unpackNil(); null })
241241
}
242242

243+
"skipping a nil value" taggedAs ("try") in {
244+
check(true, _.packNil, _.tryUnpackNil)
245+
check(false, { packer => packer.packString("val") }, { unpacker => unpacker.tryUnpackNil() })
246+
check("val", { packer => packer.packString("val") }, { unpacker => unpacker.tryUnpackNil(); unpacker.unpackString() })
247+
check("val", { packer => packer.packNil(); packer.packString("val") }, { unpacker => unpacker.tryUnpackNil(); unpacker.unpackString() })
248+
try {
249+
checkException(null, { _ => }, _.tryUnpackNil)
250+
}
251+
catch {
252+
case e: MessageInsufficientBufferException => // OK
253+
}
254+
}
255+
243256
"pack/unpack integer values" taggedAs ("int") in {
244257
val sampleData = Seq[Long](Int.MinValue.toLong -
245258
10, -65535, -8191, -1024, -255, -127, -63, -31, -15, -7, -3, -1, 0, 2, 4, 8, 16, 32, 64, 128, 256, 1024, 8192, 65536,

0 commit comments

Comments
 (0)