-
Notifications
You must be signed in to change notification settings - Fork 323
[WIP] Add add support for Timestamp type #431
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// | ||
// MessagePack for Java | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
package org.msgpack.core; | ||
|
||
/** | ||
* Thrown when format of an extension type is invalid | ||
*/ | ||
public class MessageExtensionFormatException | ||
extends MessageFormatException | ||
{ | ||
public MessageExtensionFormatException(Throwable e) | ||
{ | ||
super(e); | ||
} | ||
|
||
public MessageExtensionFormatException(String message) | ||
{ | ||
super(message); | ||
} | ||
|
||
public MessageExtensionFormatException(String message, Throwable cause) | ||
{ | ||
super(message, cause); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,11 +32,14 @@ | |
import java.nio.charset.CharsetDecoder; | ||
import java.nio.charset.CoderResult; | ||
import java.nio.charset.CodingErrorAction; | ||
import java.time.Instant; | ||
import java.util.ArrayList; | ||
import java.util.Date; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import static org.msgpack.core.MessagePack.Code.EXT_TIMESTAMP; | ||
import static org.msgpack.core.Preconditions.checkNotNull; | ||
|
||
/** | ||
|
@@ -596,6 +599,12 @@ private static MessagePackException unexpected(String expected, byte b) | |
} | ||
} | ||
|
||
private static MessagePackException unexpectedExtension(String expected, int expectedType, int actualType) | ||
{ | ||
return new MessageTypeException(String.format("Expected extension type %s (%d), but got extension type %d", | ||
expected, expectedType, actualType)); | ||
} | ||
|
||
public ImmutableValue unpackValue() | ||
throws IOException | ||
{ | ||
|
@@ -644,7 +653,12 @@ public ImmutableValue unpackValue() | |
} | ||
case EXTENSION: { | ||
ExtensionTypeHeader extHeader = unpackExtensionTypeHeader(); | ||
return ValueFactory.newExtension(extHeader.getType(), readPayload(extHeader.getLength())); | ||
switch (extHeader.getType()) { | ||
case EXT_TIMESTAMP: | ||
return ValueFactory.newTimestamp(readPayload(extHeader.getLength())); | ||
default: | ||
return ValueFactory.newExtension(extHeader.getType(), readPayload(extHeader.getLength())); | ||
} | ||
} | ||
default: | ||
throw new MessageNeverUsedFormatException("Unknown value type"); | ||
|
@@ -1232,6 +1246,70 @@ private String decodeStringFastPath(int length) | |
} | ||
} | ||
|
||
public Instant unpackInstant() | ||
throws IOException | ||
{ | ||
ExtensionTypeHeader ext = unpackExtensionTypeHeader(); | ||
if (ext.getType() != EXT_TIMESTAMP) { | ||
throw unexpectedExtension("Timestamp", EXT_TIMESTAMP, ext.getType()); | ||
} | ||
switch (ext.getLength()) { | ||
case 4: { | ||
int u32 = readInt(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @frsyuki Need to convert to uint32 by applying 0xFFFFFFFFL mask |
||
return Instant.ofEpochSecond(u32); | ||
} | ||
case 8: { | ||
long data64 = readLong(); | ||
int nsec = (int) (data64 >>> 34); | ||
long sec = data64 & 0x00000003ffffffffL; | ||
return Instant.ofEpochSecond(sec, nsec); | ||
} | ||
case 12: { | ||
int nsec = readInt(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This also needs to be converted to uint32 with 0xFFFFFFFFL mask |
||
long sec = readLong(); | ||
return Instant.ofEpochSecond(sec, nsec); | ||
} | ||
default: | ||
throw new MessageExtensionFormatException(String.format("Timestamp extension type (%d) expects 4, 8, or 12 bytes of payload but got %d bytes", | ||
EXT_TIMESTAMP, ext.getLength())); | ||
} | ||
} | ||
|
||
public Date unpackDate() | ||
throws IOException | ||
{ | ||
return new Date(unpackTimestampMillis()); | ||
} | ||
|
||
public long unpackTimestampMillis() | ||
throws IOException | ||
{ | ||
ExtensionTypeHeader ext = unpackExtensionTypeHeader(); | ||
if (ext.getType() != EXT_TIMESTAMP) { | ||
throw unexpectedExtension("Timestamp", EXT_TIMESTAMP, ext.getType()); | ||
} | ||
switch (ext.getLength()) { | ||
case 4: { | ||
int u32 = readInt(); | ||
return (u32 & 0xffffffffL) * 1000L; | ||
} | ||
case 8: { | ||
long data64 = readLong(); | ||
int nsec = (int) (data64 >>> 34); | ||
long sec = data64 & 0x00000003ffffffffL; | ||
return sec * 1000L + nsec / 1000L; | ||
} | ||
case 12: { | ||
int nsec = readInt(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @frsyuki nsec is uint32, so &xffffffffL mask is necessary to convert negative int32 to uint32 |
||
long sec = readLong(); | ||
return sec * 1000L + nsec / 1000L; | ||
} | ||
default: | ||
throw new MessageExtensionFormatException(String.format("Timestamp extension type (%d) expects 4, 8, or 12 bytes of payload but got %d bytes", | ||
EXT_TIMESTAMP, ext.getLength())); | ||
} | ||
} | ||
|
||
/** | ||
* Reads header of an array. | ||
* | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// | ||
// MessagePack for Java | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
package org.msgpack.value; | ||
|
||
/** | ||
* Immutable representation of MessagePack's Timestamp type. | ||
* | ||
* @see org.msgpack.value.TimestampValue | ||
*/ | ||
public interface ImmutableTimestampValue | ||
extends TimestampValue, ImmutableValue | ||
{ | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// | ||
// MessagePack for Java | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
package org.msgpack.value; | ||
|
||
import java.time.Instant; | ||
import java.util.Date; | ||
|
||
/** | ||
* Representation of MessagePack's Timestamp type. | ||
* | ||
* MessagePack's Timestamp type can represent a timestamp. | ||
*/ | ||
public interface TimestampValue | ||
extends ExtensionValue | ||
{ | ||
long getEpochSecond(); | ||
|
||
int getNano(); | ||
|
||
long toEpochMilli(); | ||
|
||
Instant toInstant(); | ||
|
||
Date toDate(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
drop Java 7 support ?
msgpack-java/.travis.yml
Lines 12 to 13 in 81d540d
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@frsyuki has confirmed it works in Java6 and Java7 even if Instant class is in the import statement. Only programs that use Instance related methods will fail to compile.