msgpack 1.2.10-x86-mingw32 → 1.3.0-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/ChangeLog +4 -0
- data/README.rdoc +16 -0
- data/doclib/msgpack/time.rb +22 -0
- data/doclib/msgpack/timestamp.rb +44 -0
- data/lib/msgpack.rb +2 -0
- data/lib/msgpack/time.rb +29 -0
- data/lib/msgpack/timestamp.rb +76 -0
- data/lib/msgpack/version.rb +1 -1
- data/spec/timestamp_spec.rb +117 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 341c09816e2d926baf67c2fce87da0090c1aa40fe59fe43387df8e7a0cbf405f
|
4
|
+
data.tar.gz: 59f202ef6c3c0a7d01c89a91e3d74ca9615b2dc317e6ea37d1c38f2706948b0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc3436e8a665f731a38fa51372961c5e0a5196668d323d6813622b6e4c1d46d88bc3cc70bb62f9a7137fc56449c873e880f413f3c57b7bc3246c3a750917a86d
|
7
|
+
data.tar.gz: 34931cf70954b0a375ae240bef2786da5787a79566fe64bf0f5376123e9810f8a201028b846c085c7bc94b879d963f15f4b2a966ec1969787501abdd3d4b95a2
|
data/.rubocop.yml
CHANGED
data/ChangeLog
CHANGED
data/README.rdoc
CHANGED
@@ -121,6 +121,22 @@ being serialized altogether by throwing an exception:
|
|
121
121
|
|
122
122
|
[1, :symbol, 'string'].to_msgpack # => RuntimeError: Serialization of symbols prohibited
|
123
123
|
|
124
|
+
= Serializing and deserializing Time instances
|
125
|
+
|
126
|
+
There are the timestamp extension type in MessagePack,
|
127
|
+
but it is not registered by default.
|
128
|
+
|
129
|
+
To map Ruby's Time to MessagePack's timestamp for the default factory:
|
130
|
+
|
131
|
+
MessagePack::DefaultFactory.register_type(
|
132
|
+
MessagePack::Timestamp::TYPE, # or just -1
|
133
|
+
Time,
|
134
|
+
packer: MessagePack::Time::Packer,
|
135
|
+
unpacker: MessagePack::Time::Unpacker
|
136
|
+
)
|
137
|
+
|
138
|
+
See {API reference}[http://ruby.msgpack.org/] for details.
|
139
|
+
|
124
140
|
= Extension Types
|
125
141
|
|
126
142
|
Packer and Unpacker support {Extension types of MessagePack}[https://github.com/msgpack/msgpack/blob/master/spec.md#types-extension-type].
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module MessagePack
|
2
|
+
|
3
|
+
# MessagePack::Time provides packer and unpacker functions for a timestamp type.
|
4
|
+
# @example Setup for DefaultFactory
|
5
|
+
# MessagePack::DefaultFactory.register_type(
|
6
|
+
# MessagePack::Timestamp::TYPE,
|
7
|
+
# Time,
|
8
|
+
# packer: MessagePack::Time::Packer,
|
9
|
+
# unpacker: MessagePack::Time::Unpacker
|
10
|
+
# )
|
11
|
+
class Time
|
12
|
+
# A packer function that packs a Time instance to a MessagePack timestamp.
|
13
|
+
Packer = lambda { |payload|
|
14
|
+
# ...
|
15
|
+
}
|
16
|
+
|
17
|
+
# An unpacker function that unpacks a MessagePack timestamp to a Time instance.
|
18
|
+
Unpcker = lambda { |time|
|
19
|
+
# ...
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module MessagePack
|
2
|
+
# A utility class for MessagePack timestamp type
|
3
|
+
class Timestamp
|
4
|
+
#
|
5
|
+
# The timestamp extension type defined in the MessagePack spec.
|
6
|
+
#
|
7
|
+
# See https://github.com/msgpack/msgpack/blob/master/spec.md#timestamp-extension-type for details.
|
8
|
+
#
|
9
|
+
TYPE = -1
|
10
|
+
|
11
|
+
# @return [Integer] Second part of the timestamp.
|
12
|
+
attr_reader :sec
|
13
|
+
|
14
|
+
# @return [Integer] Nanosecond part of the timestamp.
|
15
|
+
attr_reader :nsec
|
16
|
+
|
17
|
+
# @param [Integer] sec
|
18
|
+
# @param [Integer] nsec
|
19
|
+
def initialize(sec, nsec)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @example An unpacker implementation for the Time class
|
23
|
+
# lambda do |payload|
|
24
|
+
# tv = MessagePack::Timestamp.from_msgpack_ext(payload)
|
25
|
+
# Time.at(tv.sec, tv.nsec, :nanosecond)
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# @param [String] data
|
29
|
+
# @return [MessagePack::Timestamp]
|
30
|
+
def self.from_msgpack_ext(data)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @example A packer implementation for the Time class
|
34
|
+
# unpacker = lambda do |time|
|
35
|
+
# MessagePack::Timestamp.to_msgpack_ext(time.tv_sec, time.tv_nsec)
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# @param [Integer] sec
|
39
|
+
# @param [Integer] nsec
|
40
|
+
# @return [String]
|
41
|
+
def self.to_msgpack_ext(sec, nsec)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/msgpack.rb
CHANGED
data/lib/msgpack/time.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# MessagePack extention packer and unpacker for built-in Time class
|
4
|
+
module MessagePack
|
5
|
+
module Time
|
6
|
+
# 3-arg Time.at is available Ruby >= 2.5
|
7
|
+
TIME_AT_3_AVAILABLE = begin
|
8
|
+
!!::Time.at(0, 0, :nanosecond)
|
9
|
+
rescue ArgumentError
|
10
|
+
false
|
11
|
+
end
|
12
|
+
|
13
|
+
Unpacker = if TIME_AT_3_AVAILABLE
|
14
|
+
lambda do |payload|
|
15
|
+
tv = MessagePack::Timestamp.from_msgpack_ext(payload)
|
16
|
+
::Time.at(tv.sec, tv.nsec, :nanosecond)
|
17
|
+
end
|
18
|
+
else
|
19
|
+
lambda do |payload|
|
20
|
+
tv = MessagePack::Timestamp.from_msgpack_ext(payload)
|
21
|
+
::Time.at(tv.sec, tv.nsec / 1000.0)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
Packer = lambda { |time|
|
26
|
+
MessagePack::Timestamp.to_msgpack_ext(time.tv_sec, time.tv_nsec)
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MessagePack
|
4
|
+
class Timestamp # a.k.a. "TimeSpec"
|
5
|
+
# Because the byte-order of MessagePack is big-endian in,
|
6
|
+
# pack() and unpack() specifies ">".
|
7
|
+
# See https://docs.ruby-lang.org/en/trunk/Array.html#method-i-pack for details.
|
8
|
+
|
9
|
+
# The timestamp extension type defined in the MessagePack spec.
|
10
|
+
# See https://github.com/msgpack/msgpack/blob/master/spec.md#timestamp-extension-type for details.
|
11
|
+
TYPE = -1
|
12
|
+
|
13
|
+
TIMESTAMP32_MAX_SEC = (1 << 32) - 1
|
14
|
+
TIMESTAMP64_MAX_SEC = (1 << 34) - 1
|
15
|
+
|
16
|
+
# @return [Integer]
|
17
|
+
attr_reader :sec
|
18
|
+
|
19
|
+
# @return [Integer]
|
20
|
+
attr_reader :nsec
|
21
|
+
|
22
|
+
# @param [Integer] sec
|
23
|
+
# @param [Integer] nsec
|
24
|
+
def initialize(sec, nsec)
|
25
|
+
@sec = sec
|
26
|
+
@nsec = nsec
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.from_msgpack_ext(data)
|
30
|
+
case data.length
|
31
|
+
when 4
|
32
|
+
# timestamp32 (sec: uint32be)
|
33
|
+
sec, = data.unpack('L>')
|
34
|
+
new(sec, 0)
|
35
|
+
when 8
|
36
|
+
# timestamp64 (nsec: uint30be, sec: uint34be)
|
37
|
+
n, s = data.unpack('L>2')
|
38
|
+
sec = ((n & 0b11) << 32) | s
|
39
|
+
nsec = n >> 2
|
40
|
+
new(sec, nsec)
|
41
|
+
when 12
|
42
|
+
# timestam96 (nsec: uint32be, sec: int64be)
|
43
|
+
nsec, sec = data.unpack('L>q>')
|
44
|
+
new(sec, nsec)
|
45
|
+
else
|
46
|
+
raise MalformedFormatError, "Invalid timestamp data size: #{data.length}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.to_msgpack_ext(sec, nsec)
|
51
|
+
if sec >= 0 && nsec >= 0 && sec <= TIMESTAMP64_MAX_SEC
|
52
|
+
if nsec === 0 && sec <= TIMESTAMP32_MAX_SEC
|
53
|
+
# timestamp32 = (sec: uint32be)
|
54
|
+
[sec].pack('L>')
|
55
|
+
else
|
56
|
+
# timestamp64 (nsec: uint30be, sec: uint34be)
|
57
|
+
nsec30 = nsec << 2
|
58
|
+
sec_high2 = sec << 32 # high 2 bits (`x & 0b11` is redandunt)
|
59
|
+
sec_low32 = sec & 0xffffffff # low 32 bits
|
60
|
+
[nsec30 | sec_high2, sec_low32].pack('L>2')
|
61
|
+
end
|
62
|
+
else
|
63
|
+
# timestamp96 (nsec: uint32be, sec: int64be)
|
64
|
+
[nsec, sec].pack('L>q>')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_msgpack_ext
|
69
|
+
self.class.to_msgpack_ext(sec, nsec)
|
70
|
+
end
|
71
|
+
|
72
|
+
def ==(other)
|
73
|
+
other.class == self.class && sec == other.sec && nsec == other.nsec
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/msgpack/version.rb
CHANGED
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe MessagePack::Timestamp do
|
6
|
+
describe 'malformed format' do
|
7
|
+
it do
|
8
|
+
expect do
|
9
|
+
MessagePack::Timestamp.from_msgpack_ext([0xd4, 0x00].pack("C*"))
|
10
|
+
end.to raise_error(MessagePack::MalformedFormatError)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'register_type with Time' do
|
15
|
+
let(:factory) do
|
16
|
+
factory = MessagePack::Factory.new
|
17
|
+
factory.register_type(
|
18
|
+
MessagePack::Timestamp::TYPE,
|
19
|
+
Time,
|
20
|
+
packer: MessagePack::Time::Packer,
|
21
|
+
unpacker: MessagePack::Time::Unpacker
|
22
|
+
)
|
23
|
+
factory
|
24
|
+
end
|
25
|
+
|
26
|
+
let(:time) { Time.local(2019, 6, 17, 1, 2, 3, 123_456_789 / 1000.0) }
|
27
|
+
it 'serializes and deserializes Time' do
|
28
|
+
prefix_fixext8_with_type_id = [0xd7, -1].pack("c*")
|
29
|
+
|
30
|
+
packed = factory.pack(time)
|
31
|
+
expect(packed).to start_with(prefix_fixext8_with_type_id)
|
32
|
+
expect(packed.size).to eq(10)
|
33
|
+
unpacked = factory.unpack(packed)
|
34
|
+
expect(unpacked.to_i).to eq(time.to_i)
|
35
|
+
expect(unpacked.to_f).to eq(time.to_f)
|
36
|
+
# expect(unpacked).to eq(time) # we can't do it because of nsec (rational vs float?)
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:time_without_nsec) { Time.local(2019, 6, 17, 1, 2, 3, 0) }
|
40
|
+
it 'serializes time without nanosec as fixext4' do
|
41
|
+
prefix_fixext4_with_type_id = [0xd6, -1].pack("c*")
|
42
|
+
|
43
|
+
packed = factory.pack(time_without_nsec)
|
44
|
+
expect(packed).to start_with(prefix_fixext4_with_type_id)
|
45
|
+
expect(packed.size).to eq(6)
|
46
|
+
unpacked = factory.unpack(packed)
|
47
|
+
expect(unpacked).to eq(time_without_nsec)
|
48
|
+
end
|
49
|
+
|
50
|
+
let(:time_after_2514) { Time.at(1 << 34) } # the max num of 34bit int means 2514-05-30 01:53:04 UTC
|
51
|
+
it 'serializes time after 2038 as ext8' do
|
52
|
+
prefix_ext8_with_12bytes_payload_and_type_id = [0xc7, 12, -1].pack("c*")
|
53
|
+
|
54
|
+
expect(time_after_2514.to_i).to be > 0xffffffff
|
55
|
+
packed = factory.pack(time_after_2514)
|
56
|
+
expect(packed).to start_with(prefix_ext8_with_12bytes_payload_and_type_id)
|
57
|
+
expect(packed.size).to eq(15)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe 'register_type with MessagePack::Timestamp' do
|
62
|
+
let(:factory) do
|
63
|
+
factory = MessagePack::Factory.new
|
64
|
+
factory.register_type(MessagePack::Timestamp::TYPE, MessagePack::Timestamp)
|
65
|
+
factory
|
66
|
+
end
|
67
|
+
|
68
|
+
let(:timestamp) { MessagePack::Timestamp.new(Time.now.tv_sec, 123_456_789) }
|
69
|
+
it 'serializes and deserializes MessagePack::Timestamp' do
|
70
|
+
packed = factory.pack(timestamp)
|
71
|
+
unpacked = factory.unpack(packed)
|
72
|
+
expect(unpacked).to eq(timestamp)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe 'timestamp32' do
|
77
|
+
it 'handles [1, 0]' do
|
78
|
+
t = MessagePack::Timestamp.new(1, 0)
|
79
|
+
|
80
|
+
payload = t.to_msgpack_ext
|
81
|
+
unpacked = MessagePack::Timestamp.from_msgpack_ext(payload)
|
82
|
+
|
83
|
+
expect(unpacked).to eq(t)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe 'timestamp64' do
|
88
|
+
it 'handles [1, 1]' do
|
89
|
+
t = MessagePack::Timestamp.new(1, 1)
|
90
|
+
|
91
|
+
payload = t.to_msgpack_ext
|
92
|
+
unpacked = MessagePack::Timestamp.from_msgpack_ext(payload)
|
93
|
+
|
94
|
+
expect(unpacked).to eq(t)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe 'timestamp96' do
|
99
|
+
it 'handles [-1, 0]' do
|
100
|
+
t = MessagePack::Timestamp.new(-1, 0)
|
101
|
+
|
102
|
+
payload = t.to_msgpack_ext
|
103
|
+
unpacked = MessagePack::Timestamp.from_msgpack_ext(payload)
|
104
|
+
|
105
|
+
expect(unpacked).to eq(t)
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'handles [-1, 999_999_999]' do
|
109
|
+
t = MessagePack::Timestamp.new(-1, 999_999_999)
|
110
|
+
|
111
|
+
payload = t.to_msgpack_ext
|
112
|
+
unpacked = MessagePack::Timestamp.from_msgpack_ext(payload)
|
113
|
+
|
114
|
+
expect(unpacked).to eq(t)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: msgpack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: x86-mingw32
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2019-
|
13
|
+
date: 2019-06-20 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -147,6 +147,8 @@ files:
|
|
147
147
|
- doclib/msgpack/extension_value.rb
|
148
148
|
- doclib/msgpack/factory.rb
|
149
149
|
- doclib/msgpack/packer.rb
|
150
|
+
- doclib/msgpack/time.rb
|
151
|
+
- doclib/msgpack/timestamp.rb
|
150
152
|
- doclib/msgpack/unpacker.rb
|
151
153
|
- ext/java/org/msgpack/jruby/Buffer.java
|
152
154
|
- ext/java/org/msgpack/jruby/Decoder.java
|
@@ -196,6 +198,8 @@ files:
|
|
196
198
|
- lib/msgpack/factory.rb
|
197
199
|
- lib/msgpack/packer.rb
|
198
200
|
- lib/msgpack/symbol.rb
|
201
|
+
- lib/msgpack/time.rb
|
202
|
+
- lib/msgpack/timestamp.rb
|
199
203
|
- lib/msgpack/unpacker.rb
|
200
204
|
- lib/msgpack/version.rb
|
201
205
|
- msgpack.gemspec
|
@@ -221,6 +225,7 @@ files:
|
|
221
225
|
- spec/packer_spec.rb
|
222
226
|
- spec/random_compat.rb
|
223
227
|
- spec/spec_helper.rb
|
228
|
+
- spec/timestamp_spec.rb
|
224
229
|
- spec/unpack_spec.rb
|
225
230
|
- spec/unpacker_spec.rb
|
226
231
|
homepage: http://msgpack.org/
|