msgpack 1.2.10-x64-mingw32 → 1.3.0-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- 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: f02fb78200e1afb098812d88cb84aa76df6fd9d3c28fdd14acb42557c08560c7
|
4
|
+
data.tar.gz: 9f82b32730e35a8fbe990056ace8486992e9d9c4bf2497a438c298d238493371
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8223073414f1801fd29f7a4725340e71c683e3d6b8c3864e3de66d095eb57b54c7f43acb2419baf9199b90f713a625a6f55d00a9d233f763c69258512aebc440
|
7
|
+
data.tar.gz: e7f776e5234ca5eab8890d39db2a2f73aece0f1db42b70436cd39e0bd305287af68459765881b6e9200707dd79b2fe0dca0c84379a175879b1e518f3ecbef462
|
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: x64-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/
|