diff --git a/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java index 73e92035a..c27287882 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java +++ b/msgpack-core/src/main/java/org/msgpack/core/ExtensionTypeHeader.java @@ -59,6 +59,11 @@ public byte getType() return type; } + public boolean isTimestampType() + { + return type == MessagePack.Code.EXT_TIMESTAMP; + } + public int getLength() { return length; diff --git a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java index b43204beb..c59b742ac 100644 --- a/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java +++ b/msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java @@ -1284,9 +1284,9 @@ public Instant unpackTimestamp() } /** - * Internal method that can be used only when the extension type header is already read. + * Unpack timestamp that can be used after reading the extension type header with unpackExtensionTypeHeader. */ - private Instant unpackTimestamp(ExtensionTypeHeader ext) throws IOException + public Instant unpackTimestamp(ExtensionTypeHeader ext) throws IOException { if (ext.getType() != EXT_TIMESTAMP) { throw unexpectedExtension("Timestamp", EXT_TIMESTAMP, ext.getType()); diff --git a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java index 5feb15dbc..7764e2d25 100644 --- a/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java +++ b/msgpack-core/src/test/java/org/msgpack/core/example/MessagePackExample.java @@ -26,6 +26,7 @@ import org.msgpack.value.ExtensionValue; import org.msgpack.value.FloatValue; import org.msgpack.value.IntegerValue; +import org.msgpack.value.TimestampValue; import org.msgpack.value.Value; import java.io.File; @@ -33,6 +34,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.math.BigInteger; +import java.time.Instant; /** * This class describes the usage of MessagePack @@ -145,6 +147,9 @@ public static void packer() packer.packExtensionTypeHeader((byte) 1, 10); // type number [0, 127], data byte length packer.writePayload(extData); + // Pack timestamp + packer.packTimestamp(Instant.now()); + // Succinct syntax for packing packer .packInt(1) @@ -228,8 +233,15 @@ else if (iv.isInLongRange()) { break; case EXTENSION: ExtensionValue ev = v.asExtensionValue(); - byte extType = ev.getType(); - byte[] extValue = ev.getData(); + if (ev.isTimestampValue()) { + // Reading the value as a timestamp + TimestampValue ts = ev.asTimestampValue(); + Instant tsValue = ts.toInstant(); + } + else { + byte extType = ev.getType(); + byte[] extValue = ev.getData(); + } break; } } diff --git a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala index c2d32eccb..4f6949bd3 100644 --- a/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala +++ b/msgpack-core/src/test/scala/org/msgpack/core/MessagePackTest.scala @@ -662,6 +662,24 @@ class MessagePackTest extends AirSpec with PropertyCheck with Benchmark { } } + test("pack/unpack timestamp through ExtValue") { + val posLong = Gen.chooseNum[Long](-31557014167219200L, 31556889864403199L) + forAll(posLong) { (millis: Long) => + val v = Instant.ofEpochMilli(millis) + check(v, { _.packTimestamp(millis) }, + { u => + val extHeader = u.unpackExtensionTypeHeader() + if(extHeader.isTimestampType) { + u.unpackTimestamp(extHeader) + } + else { + fail("Cannot reach here") + } + } + ) + } + } + test("MessagePack.PackerConfig") { test("should be immutable") { val a = new MessagePack.PackerConfig()