ed-precompiled_msgpack 1.8.0

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.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/ChangeLog +368 -0
  3. data/LICENSE +177 -0
  4. data/README.md +302 -0
  5. data/ext/java/org/msgpack/jruby/Buffer.java +233 -0
  6. data/ext/java/org/msgpack/jruby/Decoder.java +307 -0
  7. data/ext/java/org/msgpack/jruby/Encoder.java +456 -0
  8. data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +167 -0
  9. data/ext/java/org/msgpack/jruby/ExtensionValue.java +128 -0
  10. data/ext/java/org/msgpack/jruby/Factory.java +130 -0
  11. data/ext/java/org/msgpack/jruby/MessagePackLibrary.java +45 -0
  12. data/ext/java/org/msgpack/jruby/Packer.java +266 -0
  13. data/ext/java/org/msgpack/jruby/Types.java +37 -0
  14. data/ext/java/org/msgpack/jruby/Unpacker.java +336 -0
  15. data/ext/msgpack/buffer.c +669 -0
  16. data/ext/msgpack/buffer.h +604 -0
  17. data/ext/msgpack/buffer_class.c +616 -0
  18. data/ext/msgpack/buffer_class.h +33 -0
  19. data/ext/msgpack/compat.h +26 -0
  20. data/ext/msgpack/extconf.rb +53 -0
  21. data/ext/msgpack/extension_value_class.c +34 -0
  22. data/ext/msgpack/extension_value_class.h +31 -0
  23. data/ext/msgpack/factory_class.c +276 -0
  24. data/ext/msgpack/factory_class.h +33 -0
  25. data/ext/msgpack/packer.c +199 -0
  26. data/ext/msgpack/packer.h +513 -0
  27. data/ext/msgpack/packer_class.c +442 -0
  28. data/ext/msgpack/packer_class.h +43 -0
  29. data/ext/msgpack/packer_ext_registry.c +74 -0
  30. data/ext/msgpack/packer_ext_registry.h +140 -0
  31. data/ext/msgpack/rbinit.c +35 -0
  32. data/ext/msgpack/rmem.c +93 -0
  33. data/ext/msgpack/rmem.h +109 -0
  34. data/ext/msgpack/sysdep.h +118 -0
  35. data/ext/msgpack/sysdep_endian.h +50 -0
  36. data/ext/msgpack/sysdep_types.h +46 -0
  37. data/ext/msgpack/unpacker.c +986 -0
  38. data/ext/msgpack/unpacker.h +152 -0
  39. data/ext/msgpack/unpacker_class.c +447 -0
  40. data/ext/msgpack/unpacker_class.h +43 -0
  41. data/ext/msgpack/unpacker_ext_registry.c +74 -0
  42. data/ext/msgpack/unpacker_ext_registry.h +62 -0
  43. data/lib/msgpack/bigint.rb +69 -0
  44. data/lib/msgpack/buffer.rb +9 -0
  45. data/lib/msgpack/core_ext.rb +139 -0
  46. data/lib/msgpack/factory.rb +211 -0
  47. data/lib/msgpack/packer.rb +37 -0
  48. data/lib/msgpack/symbol.rb +26 -0
  49. data/lib/msgpack/time.rb +29 -0
  50. data/lib/msgpack/timestamp.rb +76 -0
  51. data/lib/msgpack/unpacker.rb +41 -0
  52. data/lib/msgpack/version.rb +6 -0
  53. data/lib/msgpack.rb +53 -0
  54. data/msgpack.gemspec +41 -0
  55. metadata +216 -0
@@ -0,0 +1,62 @@
1
+ /*
2
+ * MessagePack for Ruby
3
+ *
4
+ * Copyright (C) 2008-2015 Sadayuki Furuhashi
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+ #ifndef MSGPACK_RUBY_UNPACKER_EXT_REGISTRY_H__
19
+ #define MSGPACK_RUBY_UNPACKER_EXT_REGISTRY_H__
20
+
21
+ #include "compat.h"
22
+ #include "ruby.h"
23
+
24
+ #define MSGPACK_EXT_RECURSIVE 0b0001
25
+
26
+ struct msgpack_unpacker_ext_registry_t;
27
+ typedef struct msgpack_unpacker_ext_registry_t msgpack_unpacker_ext_registry_t;
28
+
29
+ struct msgpack_unpacker_ext_registry_t {
30
+ unsigned int borrow_count;
31
+ VALUE array[256];
32
+ };
33
+
34
+ void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg);
35
+
36
+ static inline void msgpack_unpacker_ext_registry_borrow(msgpack_unpacker_ext_registry_t* src, msgpack_unpacker_ext_registry_t** dst)
37
+ {
38
+ if (src) {
39
+ src->borrow_count++;
40
+ *dst = src;
41
+ }
42
+ }
43
+
44
+ void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg);
45
+
46
+ void msgpack_unpacker_ext_registry_put(VALUE owner, msgpack_unpacker_ext_registry_t** ukrg,
47
+ VALUE ext_module, int ext_type, int flags, VALUE proc);
48
+
49
+ static inline VALUE msgpack_unpacker_ext_registry_lookup(msgpack_unpacker_ext_registry_t* ukrg,
50
+ int ext_type, int* ext_flags_result)
51
+ {
52
+ if (ukrg) {
53
+ VALUE entry = ukrg->array[ext_type + 128];
54
+ if (entry != Qnil) {
55
+ *ext_flags_result = FIX2INT(rb_ary_entry(entry, 2));
56
+ return rb_ary_entry(entry, 1);
57
+ }
58
+ }
59
+ return Qnil;
60
+ }
61
+
62
+ #endif
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MessagePack
4
+ module Bigint
5
+ # We split the bigint in 32bits chunks so that individual part fits into
6
+ # a MRI immediate Integer.
7
+ CHUNK_BITLENGTH = 32
8
+ FORMAT = 'CL>*'
9
+
10
+ if Integer.instance_method(:[]).arity != 1 # Ruby 2.7 and newer
11
+ # Starting from Ruby 2.7 we can address arbitrary bitranges inside an Integer with Integer#[]
12
+ # This allows to not allocate any Integer.
13
+ def self.to_msgpack_ext(bigint)
14
+ members = []
15
+
16
+ if bigint < 0
17
+ bigint = -bigint
18
+ members << 1
19
+ else
20
+ members << 0
21
+ end
22
+
23
+ offset = 0
24
+ length = bigint.bit_length
25
+ while offset < length
26
+ members << bigint[offset, CHUNK_BITLENGTH]
27
+ offset += CHUNK_BITLENGTH
28
+ end
29
+
30
+ members.pack(FORMAT)
31
+ end
32
+ else
33
+ # On 2.6 and older since we can't address arbitrary bitranges, so we fallback to shifting the bigint.
34
+ # This means that after each shift, we may allocate another Integer instance.
35
+ BASE = (2**CHUNK_BITLENGTH) - 1
36
+ def self.to_msgpack_ext(bigint)
37
+ members = []
38
+
39
+ if bigint < 0
40
+ bigint = -bigint
41
+ members << 1
42
+ else
43
+ members << 0
44
+ end
45
+
46
+ while bigint > 0
47
+ members << (bigint & BASE)
48
+ bigint = bigint >> CHUNK_BITLENGTH
49
+ end
50
+
51
+ members.pack(FORMAT)
52
+ end
53
+ end
54
+
55
+ def self.from_msgpack_ext(data)
56
+ parts = data.unpack(FORMAT)
57
+
58
+ sign = parts.shift
59
+ sum = parts.pop.to_i
60
+
61
+ parts.reverse_each do |part|
62
+ sum = sum << CHUNK_BITLENGTH
63
+ sum += part
64
+ end
65
+
66
+ sign == 0 ? sum : -sum
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,9 @@
1
+ module MessagePack
2
+ class Buffer
3
+ # see ext for other methods
4
+
5
+ # The semantic of duping a buffer is just too weird.
6
+ undef_method :dup
7
+ undef_method :clone
8
+ end
9
+ end
@@ -0,0 +1,139 @@
1
+ module MessagePack
2
+ module CoreExt
3
+ def to_msgpack(packer_or_io = nil)
4
+ if packer_or_io
5
+ if packer_or_io.is_a?(MessagePack::Packer)
6
+ to_msgpack_with_packer packer_or_io
7
+ else
8
+ MessagePack.pack(self, packer_or_io)
9
+ end
10
+ else
11
+ MessagePack.pack(self)
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ class NilClass
18
+ include MessagePack::CoreExt
19
+
20
+ private
21
+ def to_msgpack_with_packer(packer)
22
+ packer.write_nil
23
+ packer
24
+ end
25
+ end
26
+
27
+ class TrueClass
28
+ include MessagePack::CoreExt
29
+
30
+ private
31
+ def to_msgpack_with_packer(packer)
32
+ packer.write_true
33
+ packer
34
+ end
35
+ end
36
+
37
+ class FalseClass
38
+ include MessagePack::CoreExt
39
+
40
+ private
41
+ def to_msgpack_with_packer(packer)
42
+ packer.write_false
43
+ packer
44
+ end
45
+ end
46
+
47
+ class Float
48
+ include MessagePack::CoreExt
49
+
50
+ private
51
+ def to_msgpack_with_packer(packer)
52
+ packer.write_float self
53
+ packer
54
+ end
55
+ end
56
+
57
+ class String
58
+ include MessagePack::CoreExt
59
+
60
+ private
61
+ def to_msgpack_with_packer(packer)
62
+ packer.write_string self
63
+ packer
64
+ end
65
+ end
66
+
67
+ class Array
68
+ include MessagePack::CoreExt
69
+
70
+ private
71
+ def to_msgpack_with_packer(packer)
72
+ packer.write_array self
73
+ packer
74
+ end
75
+ end
76
+
77
+ class Hash
78
+ include MessagePack::CoreExt
79
+
80
+ private
81
+ def to_msgpack_with_packer(packer)
82
+ packer.write_hash self
83
+ packer
84
+ end
85
+ end
86
+
87
+ class Symbol
88
+ include MessagePack::CoreExt
89
+
90
+ private
91
+ def to_msgpack_with_packer(packer)
92
+ packer.write_symbol self
93
+ packer
94
+ end
95
+ end
96
+
97
+ if 1.class.name == "Integer"
98
+ class Integer
99
+ include MessagePack::CoreExt
100
+
101
+ private
102
+ def to_msgpack_with_packer(packer)
103
+ packer.write_int self
104
+ packer
105
+ end
106
+ end
107
+ else
108
+ class Fixnum
109
+ include MessagePack::CoreExt
110
+
111
+ private
112
+ def to_msgpack_with_packer(packer)
113
+ packer.write_int self
114
+ packer
115
+ end
116
+ end
117
+
118
+ class Bignum
119
+ include MessagePack::CoreExt
120
+
121
+ private
122
+ def to_msgpack_with_packer(packer)
123
+ packer.write_int self
124
+ packer
125
+ end
126
+ end
127
+ end
128
+
129
+ module MessagePack
130
+ class ExtensionValue
131
+ include CoreExt
132
+
133
+ private
134
+ def to_msgpack_with_packer(packer)
135
+ packer.write_extension self
136
+ packer
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,211 @@
1
+ module MessagePack
2
+ class Factory
3
+ # see ext for other methods
4
+
5
+ def register_type(type, klass, options = { packer: :to_msgpack_ext, unpacker: :from_msgpack_ext })
6
+ raise FrozenError, "can't modify frozen MessagePack::Factory" if frozen?
7
+
8
+ if options
9
+ options = options.dup
10
+ case packer = options[:packer]
11
+ when nil, Proc
12
+ # all good
13
+ when String, Symbol
14
+ options[:packer] = packer.to_sym.to_proc
15
+ when Method
16
+ options[:packer] = packer.to_proc
17
+ when packer.respond_to?(:call)
18
+ options[:packer] = packer.method(:call).to_proc
19
+ else
20
+ raise ::TypeError, "expected :packer argument to be a callable object, got: #{packer.inspect}"
21
+ end
22
+
23
+ case unpacker = options[:unpacker]
24
+ when nil, Proc
25
+ # all good
26
+ when String, Symbol
27
+ options[:unpacker] = klass.method(unpacker).to_proc
28
+ when Method
29
+ options[:unpacker] = unpacker.to_proc
30
+ when packer.respond_to?(:call)
31
+ options[:unpacker] = unpacker.method(:call).to_proc
32
+ else
33
+ raise ::TypeError, "expected :unpacker argument to be a callable object, got: #{unpacker.inspect}"
34
+ end
35
+ end
36
+
37
+ register_type_internal(type, klass, options)
38
+ end
39
+
40
+ # [ {type: id, class: Class(or nil), packer: arg, unpacker: arg}, ... ]
41
+ def registered_types(selector=:both)
42
+ packer, unpacker = registered_types_internal
43
+ # packer: Class -> [tid, proc, _flags]
44
+ # unpacker: tid -> [klass, proc, _flags]
45
+
46
+ list = []
47
+
48
+ case selector
49
+ when :both
50
+ packer.each_pair do |klass, ary|
51
+ type = ary[0]
52
+ packer_proc = ary[1]
53
+ unpacker_proc = nil
54
+ if unpacker.has_key?(type)
55
+ unpacker_proc = unpacker.delete(type)[1]
56
+ end
57
+ list << {type: type, class: klass, packer: packer_proc, unpacker: unpacker_proc}
58
+ end
59
+
60
+ # unpacker definition only
61
+ unpacker.each_pair do |type, ary|
62
+ list << {type: type, class: ary[0], packer: nil, unpacker: ary[1]}
63
+ end
64
+
65
+ when :packer
66
+ packer.each_pair do |klass, ary|
67
+ if ary[1]
68
+ list << {type: ary[0], class: klass, packer: ary[1]}
69
+ end
70
+ end
71
+
72
+ when :unpacker
73
+ unpacker.each_pair do |type, ary|
74
+ if ary[1]
75
+ list << {type: type, class: ary[0], unpacker: ary[1]}
76
+ end
77
+ end
78
+
79
+ else
80
+ raise ArgumentError, "invalid selector #{selector}"
81
+ end
82
+
83
+ list.sort{|a, b| a[:type] <=> b[:type] }
84
+ end
85
+
86
+ def type_registered?(klass_or_type, selector=:both)
87
+ case klass_or_type
88
+ when Class
89
+ klass = klass_or_type
90
+ registered_types(selector).any?{|entry| klass <= entry[:class] }
91
+ when Integer
92
+ type = klass_or_type
93
+ registered_types(selector).any?{|entry| type == entry[:type] }
94
+ else
95
+ raise ArgumentError, "class or type id"
96
+ end
97
+ end
98
+
99
+ def load(src, param = nil)
100
+ unpacker = nil
101
+
102
+ if src.is_a? String
103
+ unpacker = unpacker(param)
104
+ unpacker.feed(src)
105
+ else
106
+ unpacker = unpacker(src, param)
107
+ end
108
+
109
+ unpacker.full_unpack
110
+ end
111
+ alias :unpack :load
112
+
113
+ def dump(v, *rest)
114
+ packer = packer(*rest)
115
+ packer.write(v)
116
+ packer.full_pack
117
+ end
118
+ alias :pack :dump
119
+
120
+ def pool(size = 1, **options)
121
+ Pool.new(
122
+ frozen? ? self : dup.freeze,
123
+ size,
124
+ options.empty? ? nil : options,
125
+ )
126
+ end
127
+
128
+ class Pool
129
+ if RUBY_ENGINE == "ruby"
130
+ class MemberPool
131
+ def initialize(size, &block)
132
+ @size = size
133
+ @new_member = block
134
+ @members = []
135
+ end
136
+
137
+ def with
138
+ member = @members.pop || @new_member.call
139
+ begin
140
+ yield member
141
+ ensure
142
+ # If the pool is already full, we simply drop the extra member.
143
+ # This is because contrary to a connection pool, creating an extra instance
144
+ # is extremely unlikely to cause some kind of resource exhaustion.
145
+ #
146
+ # We could cycle the members (keep the newer one) but first It's more work and second
147
+ # the older member might have been created pre-fork, so it might be at least partially
148
+ # in shared memory.
149
+ if member && @members.size < @size
150
+ member.reset
151
+ @members << member
152
+ end
153
+ end
154
+ end
155
+ end
156
+ else
157
+ class MemberPool
158
+ def initialize(size, &block)
159
+ @size = size
160
+ @new_member = block
161
+ @members = []
162
+ @mutex = Mutex.new
163
+ end
164
+
165
+ def with
166
+ member = @mutex.synchronize { @members.pop } || @new_member.call
167
+ begin
168
+ yield member
169
+ ensure
170
+ member.reset
171
+ @mutex.synchronize do
172
+ if member && @members.size < @size
173
+ @members << member
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
180
+
181
+ def initialize(factory, size, options = nil)
182
+ options = nil if !options || options.empty?
183
+ @factory = factory
184
+ @packers = MemberPool.new(size) { factory.packer(options).freeze }
185
+ @unpackers = MemberPool.new(size) { factory.unpacker(options).freeze }
186
+ end
187
+
188
+ def load(data)
189
+ @unpackers.with do |unpacker|
190
+ unpacker.feed(data)
191
+ unpacker.full_unpack
192
+ end
193
+ end
194
+
195
+ def dump(object)
196
+ @packers.with do |packer|
197
+ packer.write(object)
198
+ packer.full_pack
199
+ end
200
+ end
201
+
202
+ def unpacker(&block)
203
+ @unpackers.with(&block)
204
+ end
205
+
206
+ def packer(&block)
207
+ @packers.with(&block)
208
+ end
209
+ end
210
+ end
211
+ end
@@ -0,0 +1,37 @@
1
+ module MessagePack
2
+ class Packer
3
+ # see ext for other methods
4
+
5
+ # The semantic of duping a packer is just too weird.
6
+ undef_method :dup
7
+ undef_method :clone
8
+
9
+ def register_type(type, klass, method_name = nil, &block)
10
+ raise ArgumentError, "expected Module/Class got: #{klass.inspect}" unless klass.is_a?(Module)
11
+ register_type_internal(type, klass, block || method_name.to_proc)
12
+ end
13
+
14
+ def registered_types
15
+ list = []
16
+
17
+ registered_types_internal.each_pair do |klass, ary|
18
+ list << {type: ary[0], class: klass, packer: ary[1]}
19
+ end
20
+
21
+ list.sort{|a, b| a[:type] <=> b[:type] }
22
+ end
23
+
24
+ def type_registered?(klass_or_type)
25
+ case klass_or_type
26
+ when Class
27
+ klass = klass_or_type
28
+ registered_types.any?{|entry| klass <= entry[:class] }
29
+ when Integer
30
+ type = klass_or_type
31
+ registered_types.any?{|entry| type == entry[:type] }
32
+ else
33
+ raise ArgumentError, "class or type id"
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,26 @@
1
+ class Symbol
2
+ # to_msgpack_ext is supposed to return a binary string.
3
+ # The canonical way to do it for symbols would be:
4
+ # [to_s].pack('A*')
5
+ # However in this instance we can take a shortcut
6
+ if method_defined?(:name)
7
+ alias_method :to_msgpack_ext, :name
8
+ else
9
+ alias_method :to_msgpack_ext, :to_s
10
+ end
11
+
12
+ def self.from_msgpack_ext(data)
13
+ # from_msgpack_ext is supposed to parse a binary string.
14
+ # The canonical way to do it for symbols would be:
15
+ # data.unpack1('A*').to_sym
16
+ # However in this instance we can take a shortcut
17
+
18
+ # We assume the string encoding is UTF-8, and let Ruby create either
19
+ # an ASCII symbol or UTF-8 symbol.
20
+ data.force_encoding(Encoding::UTF_8).to_sym
21
+ rescue EncodingError
22
+ # If somehow the string wasn't valid UTF-8 not valid ASCII, we fallback
23
+ # to what has been the historical behavior of creating a binary symbol
24
+ data.force_encoding(Encoding::BINARY).to_sym
25
+ end
26
+ end
@@ -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.0r)
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
@@ -0,0 +1,41 @@
1
+ module MessagePack
2
+ class Unpacker
3
+ # see ext for other methods
4
+
5
+ # The semantic of duping an unpacker is just too weird.
6
+ undef_method :dup
7
+ undef_method :clone
8
+
9
+ def register_type(type, klass = nil, method_name = nil, &block)
10
+ if klass && method_name
11
+ block = klass.method(method_name).to_proc
12
+ elsif !block_given?
13
+ raise ArgumentError, "register_type takes either 3 arguments or a block"
14
+ end
15
+ register_type_internal(type, klass, block)
16
+ end
17
+
18
+ def registered_types
19
+ list = []
20
+
21
+ registered_types_internal.each_pair do |type, ary|
22
+ list << {type: type, class: ary[0], unpacker: ary[1]}
23
+ end
24
+
25
+ list.sort{|a, b| a[:type] <=> b[:type] }
26
+ end
27
+
28
+ def type_registered?(klass_or_type)
29
+ case klass_or_type
30
+ when Class
31
+ klass = klass_or_type
32
+ registered_types.any?{|entry| klass == entry[:class] }
33
+ when Integer
34
+ type = klass_or_type
35
+ registered_types.any?{|entry| type == entry[:type] }
36
+ else
37
+ raise ArgumentError, "class or type id"
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,6 @@
1
+ module MessagePack
2
+ VERSION = "1.8.0"
3
+ # Note for maintainers:
4
+ # Don't miss building/releasing the JRuby version (rake buld:java)
5
+ # See "How to build -java rubygems" in README for more details.
6
+ end