messagepack 1.0.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 (47) hide show
  1. checksums.yaml +7 -0
  2. data/README.adoc +773 -0
  3. data/Rakefile +8 -0
  4. data/docs/Gemfile +7 -0
  5. data/docs/README.md +85 -0
  6. data/docs/_config.yml +137 -0
  7. data/docs/_guides/index.adoc +14 -0
  8. data/docs/_guides/io-streaming.adoc +226 -0
  9. data/docs/_guides/migration.adoc +218 -0
  10. data/docs/_guides/performance.adoc +189 -0
  11. data/docs/_pages/buffer.adoc +85 -0
  12. data/docs/_pages/extension-types.adoc +117 -0
  13. data/docs/_pages/factory-pattern.adoc +115 -0
  14. data/docs/_pages/index.adoc +20 -0
  15. data/docs/_pages/serialization.adoc +159 -0
  16. data/docs/_pages/streaming.adoc +97 -0
  17. data/docs/_pages/symbol-extension.adoc +69 -0
  18. data/docs/_pages/timestamp-extension.adoc +88 -0
  19. data/docs/_references/api.adoc +360 -0
  20. data/docs/_references/extensions.adoc +198 -0
  21. data/docs/_references/format.adoc +301 -0
  22. data/docs/_references/index.adoc +14 -0
  23. data/docs/_tutorials/extension-types.adoc +170 -0
  24. data/docs/_tutorials/getting-started.adoc +165 -0
  25. data/docs/_tutorials/index.adoc +14 -0
  26. data/docs/_tutorials/thread-safety.adoc +157 -0
  27. data/docs/index.adoc +77 -0
  28. data/docs/lychee.toml +42 -0
  29. data/lib/messagepack/bigint.rb +131 -0
  30. data/lib/messagepack/buffer.rb +534 -0
  31. data/lib/messagepack/core_ext.rb +34 -0
  32. data/lib/messagepack/error.rb +24 -0
  33. data/lib/messagepack/extensions/base.rb +55 -0
  34. data/lib/messagepack/extensions/registry.rb +154 -0
  35. data/lib/messagepack/extensions/symbol.rb +38 -0
  36. data/lib/messagepack/extensions/timestamp.rb +110 -0
  37. data/lib/messagepack/extensions/value.rb +38 -0
  38. data/lib/messagepack/factory.rb +349 -0
  39. data/lib/messagepack/format.rb +99 -0
  40. data/lib/messagepack/packer.rb +702 -0
  41. data/lib/messagepack/symbol.rb +4 -0
  42. data/lib/messagepack/time.rb +29 -0
  43. data/lib/messagepack/timestamp.rb +4 -0
  44. data/lib/messagepack/unpacker.rb +1418 -0
  45. data/lib/messagepack/version.rb +5 -0
  46. data/lib/messagepack.rb +81 -0
  47. metadata +94 -0
@@ -0,0 +1,198 @@
1
+ ---
2
+ title: Extension types reference
3
+ nav_order: 3
4
+ ---
5
+
6
+ == Purpose
7
+
8
+ Reference for built-in and custom extension types in MessagePack Ruby.
9
+
10
+ == Concepts
11
+
12
+ Extension types allow serialization of objects that don't have native MessagePack
13
+ representations. Each extension type has:
14
+
15
+ * **Type ID** - An integer from -128 to 127
16
+ * **Packer** - Method to convert object to binary
17
+ * **Unpacker** - Method to reconstruct object from binary
18
+
19
+ == Built-in extension types
20
+
21
+ === Timestamp (-1)
22
+
23
+ Type ID: -1 (reserved by MessagePack specification)
24
+
25
+ Serializes Time objects with nanosecond precision.
26
+
27
+ ==== Format selection
28
+
29
+ The implementation automatically selects the most compact format:
30
+
31
+ * **Timestamp32** (4 bytes) - Seconds only, fits in 32 bits
32
+ * **Timestamp64** (8 bytes) - Seconds + nanoseconds, fits in 64 bits
33
+ * **Timestamp96** (12 bytes) - Full precision
34
+
35
+ [source,ruby]
36
+ ----
37
+ factory.register_type(-1, Time,
38
+ packer: Messagepack::Time::Packer,
39
+ unpacker: Messagepack::Time::Unpacker
40
+ )
41
+ ----
42
+
43
+ ==== Registration
44
+
45
+ The default factory includes timestamp registration:
46
+
47
+ [source,ruby]
48
+ ----
49
+ # Already registered in DefaultFactory
50
+ Messagepack::DefaultFactory.register_type(-1, Time,
51
+ packer: Messagepack::Time::Packer,
52
+ unpacker: Messagepack::Time::Unpacker
53
+ )
54
+ ----
55
+
56
+ ==== Example
57
+
58
+ [source,ruby]
59
+ ----
60
+ # Current time with nanoseconds
61
+ now = Time.now
62
+ binary = factory.pack(now)
63
+ restored = factory.unpack(binary)
64
+
65
+ # Nanoseconds are preserved
66
+ puts restored.tv_nsec
67
+ ----
68
+
69
+ === Symbol (0)
70
+
71
+ Type ID: 0 (common convention, not reserved)
72
+
73
+ Efficiently serializes Ruby symbols.
74
+
75
+ [source,ruby]
76
+ ----
77
+ factory.register_type(0, Symbol,
78
+ packer: ->(sym) { sym.to_s },
79
+ unpacker: ->(str) { str.to_sym }
80
+ )
81
+ ----
82
+
83
+ NOTE: The symbol extension is not registered by default.
84
+
85
+ ==== Example
86
+
87
+ [source,ruby]
88
+ ----
89
+ factory = Messagepack::Factory.new
90
+ factory.register_type(0, Symbol)
91
+
92
+ data = { status: :active, tags: [:urgent, :important] }
93
+ binary = factory.pack(data)
94
+ result = factory.unpack(binary)
95
+ # => {:status=>:active, :tags=>[:urgent, :important]}
96
+ ----
97
+
98
+ == Custom extension types
99
+
100
+ === Type ID ranges
101
+
102
+ * `-128 to -1` - Reserved for future MessagePack specifications
103
+ * `0` - Convention for symbol extension
104
+ * `1 to 127` - Available for application-specific types
105
+
106
+ === Registration patterns
107
+
108
+ ==== Method name (simple)
109
+
110
+ [source,ruby]
111
+ ----
112
+ class MyClass
113
+ def to_msgpack_ext
114
+ # Return binary string
115
+ [value].pack("I")
116
+ end
117
+
118
+ def self.from_msgpack_ext(data)
119
+ # Parse and return instance
120
+ new(data.unpack("I").first)
121
+ end
122
+ end
123
+
124
+ factory.register_type(0x10, MyClass,
125
+ packer: :to_msgpack_ext,
126
+ unpacker: :from_msgpack_ext
127
+ )
128
+ ----
129
+
130
+ ==== Proc (flexible)
131
+
132
+ [source,ruby]
133
+ ----
134
+ factory.register_type(0x11, URI,
135
+ packer: ->(uri) { uri.to_s },
136
+ unpacker: ->(str) { URI.parse(str) }
137
+ )
138
+ ----
139
+
140
+ ==== Recursive (nested structures)
141
+
142
+ [source,ruby]
143
+ ----
144
+ factory.register_type(0x12, TreeNode,
145
+ packer: ->(obj, packer) {
146
+ packer.write({ value: obj.value, left: obj.left, right: obj.right })
147
+ },
148
+ unpacker: ->(unpacker) {
149
+ data = unpacker.read
150
+ TreeNode.new(data[:value], data[:left], data[:right])
151
+ },
152
+ recursive: true
153
+ )
154
+ ----
155
+
156
+ == Extension value class
157
+
158
+ The `Messagepack::ExtensionValue` class represents raw extension types.
159
+
160
+ === Accessing extension data
161
+
162
+ [source,ruby]
163
+ ----
164
+ # Register extension that produces ExtensionValue
165
+ factory.register_type(0x20, MyClass, ...)
166
+
167
+ # When unpacking, access raw extension data
168
+ obj = factory.unpack(binary)
169
+ if obj.is_a?(Messagepack::ExtensionValue)
170
+ puts "Type: #{obj.type}"
171
+ puts "Data: #{obj.data.inspect}"
172
+ end
173
+ ----
174
+
175
+ === Creating extension values
176
+
177
+ [source,ruby]
178
+ ----
179
+ ext = Messagepack::ExtensionValue.new(0x20, "payload")
180
+ binary = factory.pack(ext)
181
+ ----
182
+
183
+ == Type ID registry
184
+
185
+ This table tracks commonly used type IDs:
186
+
187
+ [width="40%",options="header"]
188
+ |===
189
+ |Type ID |Type |Status
190
+ |-128 to -1|Reserved|MessagePack specification
191
+ |0|Symbol|Convention
192
+ |1-127|Application|Available
193
+ |===
194
+
195
+ When creating custom extension types:
196
+ * Check existing registrations for conflicts
197
+ * Document your type IDs
198
+ * Consider using a registry for distributed applications
@@ -0,0 +1,301 @@
1
+ ---
2
+ title: Format specification
3
+ nav_order: 2
4
+ ---
5
+
6
+ == Purpose
7
+
8
+ Detailed specification of the MessagePack binary format.
9
+
10
+ == References
11
+
12
+ * https://github.com/msgpack/msgpack/blob/master/spec.md[Official MessagePack specification]
13
+
14
+ == Format overview
15
+
16
+ MessagePack uses a compact binary format where the first byte contains both
17
+ format information and often the value itself.
18
+
19
+ == Integer types
20
+
21
+ === Positive fixint (0x00 - 0x7F)
22
+
23
+ Stores integers 0-127 in a single byte.
24
+
25
+ [source]
26
+ ----
27
+ +--------+
28
+ |0XXXXXXX|
29
+ +--------+
30
+
31
+ stores 0-127 in one byte
32
+ ----
33
+
34
+ === Negative fixint (0xE0 - 0xFF)
35
+
36
+ Stores integers -1 to -32 in a single byte.
37
+
38
+ [source]
39
+ ----
40
+ +--------+
41
+ |111XXXXX|
42
+ +--------+
43
+
44
+ stores -32 to -1 in one byte
45
+ ----
46
+
47
+ === uint8 (0xCC)
48
+
49
+ Stores unsigned 8-bit integer.
50
+
51
+ [source]
52
+ ----
53
+ +--------+--------+
54
+ | 0xCC |XXXXXXX|
55
+ +--------+--------+
56
+
57
+ stores 0-255 in two bytes
58
+ ----
59
+
60
+ === uint16 (0xCD)
61
+
62
+ Stores unsigned 16-bit integer (big-endian).
63
+
64
+ [source]
65
+ ----
66
+ +--------+--------+--------+
67
+ | 0xCD |ZZZZZZZZ|ZZZZZZZZ|
68
+ +--------+--------+--------+
69
+
70
+ stores 0-65535 in three bytes
71
+ ----
72
+
73
+ === uint32 (0xCE)
74
+
75
+ Stores unsigned 32-bit integer (big-endian).
76
+
77
+ [source]
78
+ ----
79
+ +--------+--------+--------+--------+--------+
80
+ | 0xCE |AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA|
81
+ +--------+--------+--------+--------+--------+
82
+
83
+ stores 0-4294967295 in five bytes
84
+ ----
85
+
86
+ === uint64 (0xCF)
87
+
88
+ Stores unsigned 64-bit integer (big-endian).
89
+
90
+ [source]
91
+ ----
92
+ +--------+--------+--------+--------+--------+--------+--------+--------+--------+
93
+ | 0xCF |AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA|
94
+ +--------+--------+--------+--------+--------+--------+--------+--------+--------+
95
+
96
+ stores 0-18446744073709551615 in nine bytes
97
+ ----
98
+
99
+ === int8 (0xD0)
100
+
101
+ Stores signed 8-bit integer.
102
+
103
+ [source]
104
+ ----
105
+ +--------+--------+
106
+ | 0xD0 |ZZZZZZZZ|
107
+ +--------+--------+
108
+
109
+ stores -128 to 127 in two bytes
110
+ ----
111
+
112
+ === int16 (0xD1)
113
+
114
+ Stores signed 16-bit integer (big-endian).
115
+
116
+ === int32 (0xD2)
117
+
118
+ Stores signed 32-bit integer (big-endian).
119
+
120
+ === int64 (0xD3)
121
+
122
+ Stores signed 64-bit integer (big-endian).
123
+
124
+ == Floating point types
125
+
126
+ === float32 (0xCA)
127
+
128
+ Stores IEEE 754 single precision floating point (big-endian).
129
+
130
+ [source]
131
+ ----
132
+ +--------+--------+--------+--------+--------+
133
+ | 0xCA |FFFFFFFF|FFFFFFFF|FFFFFFFF|FFFFFFFF|
134
+ +--------+--------+--------+--------+--------+
135
+
136
+ stores float32 in five bytes
137
+ ----
138
+
139
+ === float64 (0xCB)
140
+
141
+ Stores IEEE 754 double precision floating point (big-endian).
142
+
143
+ [source]
144
+ ----
145
+ +--------+--------+--------+--------+--------+--------+--------+--------+--------+
146
+ | 0xCB |FFFFFFFF|FFFFFFFF|FFFFFFFF|FFFFFFFF|FFFFFFFF|FFFFFFFF|FFFFFFFF|FFFFFFFF|
147
+ +--------+--------+--------+--------+--------+--------+--------+--------+--------+
148
+
149
+ stores float64 in nine bytes
150
+ ----
151
+
152
+ == String types
153
+
154
+ === fixstr (0xA0 - 0xBF)
155
+
156
+ Stores strings with length 0-31.
157
+
158
+ [source]
159
+ ----
160
+ +--------+========+
161
+ |101XXXXX| data |
162
+ +--------+========+
163
+
164
+ stores 0-31 byte strings in 2-32 bytes
165
+ ----
166
+
167
+ === str8 (0xD9)
168
+
169
+ Stores strings with length 0-255.
170
+
171
+ [source]
172
+ ----
173
+ +--------+--------+========+
174
+ | 0xD9 |YYYYYYYY| data |
175
+ +--------+--------+========+
176
+
177
+ stores 0-255 byte strings in 2-257 bytes
178
+ ----
179
+
180
+ === str16 (0xDA)
181
+
182
+ Stores strings with length 0-65535.
183
+
184
+ [source]
185
+ ----
186
+ +--------+--------+--------+========+
187
+ | 0xDA |ZZZZZZZZ|ZZZZZZZZ| data |
188
+ +--------+--------+--------+========+
189
+
190
+ stores 0-65535 byte strings in 4-65539 bytes
191
+ ----
192
+
193
+ === str32 (0xDB)
194
+
195
+ Stores strings with length 0-4294967295.
196
+
197
+ == Binary types
198
+
199
+ === bin8 (0xC4)
200
+
201
+ Stores binary data with length 0-255.
202
+
203
+ === bin16 (0xC5)
204
+
205
+ Stores binary data with length 0-65535.
206
+
207
+ === bin32 (0xC6)
208
+
209
+ Stores binary data with length 0-4294967295.
210
+
211
+ == Array types
212
+
213
+ === fixarray (0x90 - 0x9F)
214
+
215
+ Stores arrays with 0-15 elements.
216
+
217
+ [source]
218
+ ----
219
+ +--------+~~~~~~~~~~~~~~~~~+
220
+ |1001XXXX| N objects |
221
+ +--------+~~~~~~~~~~~~~~~~~+
222
+
223
+ stores 0-15 element arrays
224
+ ----
225
+
226
+ === array16 (0xDC)
227
+
228
+ Stores arrays with 0-65535 elements.
229
+
230
+ === array32 (0xDD)
231
+
232
+ Stores arrays with 0-4294967295 elements.
233
+
234
+ == Map types
235
+
236
+ === fixmap (0x80 - 0x8F)
237
+
238
+ Stores maps with 0-15 key-value pairs.
239
+
240
+ === map16 (0xDE)
241
+
242
+ Stores maps with 0-65535 key-value pairs.
243
+
244
+ === map32 (0xDF)
245
+
246
+ Stores maps with 0-4294967295 key-value pairs.
247
+
248
+ == Extension types
249
+
250
+ === fixext1 (0xD4)
251
+
252
+ Stores extension with 1 byte data.
253
+
254
+ === fixext2 (0xD5)
255
+
256
+ Stores extension with 2 bytes data.
257
+
258
+ === fixext4 (0xD6)
259
+
260
+ Stores extension with 4 bytes data.
261
+
262
+ === fixext8 (0xD7)
263
+
264
+ Stores extension with 8 bytes data.
265
+
266
+ === fixext16 (0xD8)
267
+
268
+ Stores extension with 16 bytes data.
269
+
270
+ === ext8 (0xC7)
271
+
272
+ Stores extension with length 0-255.
273
+
274
+ === ext16 (0xC8)
275
+
276
+ Stores extension with length 0-65535.
277
+
278
+ === ext32 (0xC9)
279
+
280
+ Stores extension with length 0-4294967295.
281
+
282
+ == Reserved types
283
+
284
+ === nil (0xC0)
285
+
286
+ Represents nil/null.
287
+
288
+ [source]
289
+ ----
290
+ +--------+
291
+ | 0xC0 |
292
+ +--------+
293
+ ----
294
+
295
+ === false (0xC2)
296
+
297
+ Represents boolean false.
298
+
299
+ === true (0xC3)
300
+
301
+ Represents boolean true.
@@ -0,0 +1,14 @@
1
+ ---
2
+ title: References
3
+ nav_order: 1
4
+ ---
5
+
6
+ == Purpose
7
+
8
+ References provide detailed technical specifications and API documentation.
9
+
10
+ == References
11
+
12
+ * link:../references/api[API reference] - Complete API documentation
13
+ * link:../references/format[Format specification] - MessagePack binary format details
14
+ * link:../references/extensions[Extension types reference] - Built-in and custom extension types
@@ -0,0 +1,170 @@
1
+ ---
2
+ title: Custom extension types
3
+ nav_order: 2
4
+ ---
5
+
6
+ == Purpose
7
+
8
+ This tutorial shows how to create custom extension types for serializing objects
9
+ that don't have native MessagePack support.
10
+
11
+ == References
12
+
13
+ * link:../pages/extension-types[Extension types] - Extension type concepts
14
+ * link:../references/extensions[Extension types reference] - Detailed documentation
15
+
16
+ == Prerequisites
17
+
18
+ * Completed link:../tutorials/getting-started[Getting started] tutorial
19
+
20
+ == Understanding extension types
21
+
22
+ MessagePack defines a set of built-in types (nil, boolean, integer, float, string,
23
+ array, map). For custom Ruby classes, you need to register an extension type.
24
+
25
+ An extension type requires:
26
+
27
+ * A type ID (-128 to 127)
28
+ * A packing method that converts your object to binary
29
+ * An unpacking method that reconstructs your object from binary
30
+
31
+ == Simple example: Point class
32
+
33
+ === Define the class
34
+
35
+ [source,ruby]
36
+ ----
37
+ class Point
38
+ attr_reader :x, :y
39
+
40
+ def initialize(x, y)
41
+ @x = x
42
+ @y = y
43
+ end
44
+
45
+ def to_msgpack_ext
46
+ # Pack as two 32-bit integers
47
+ [@x, @y].pack("ll")
48
+ end
49
+
50
+ def self.from_msgpack_ext(data)
51
+ x, y = data.unpack("ll")
52
+ new(x, y)
53
+ end
54
+
55
+ def to_s
56
+ "(#{@x}, #{@y})"
57
+ end
58
+ end
59
+ ----
60
+
61
+ === Register with factory
62
+
63
+ [source,ruby]
64
+ ----
65
+ factory = Messagepack::Factory.new
66
+ factory.register_type(0x01, Point,
67
+ packer: :to_msgpack_ext,
68
+ unpacker: :from_msgpack_ext
69
+ )
70
+ ----
71
+
72
+ === Use it
73
+
74
+ [source,ruby]
75
+ ----
76
+ point = Point.new(10, 20)
77
+ binary = factory.pack(point)
78
+ result = factory.unpack(binary)
79
+ puts result # => "(10, 20)"
80
+ ----
81
+
82
+ == Complex example: Nested objects
83
+
84
+ === Define a container class
85
+
86
+ [source,ruby]
87
+ ----
88
+ class TreeNode
89
+ attr_reader :value, :left, :right
90
+
91
+ def initialize(value, left = nil, right = nil)
92
+ @value = value
93
+ @left = left
94
+ @right = right
95
+ end
96
+
97
+ def to_msgpack_ext(packer)
98
+ # Serialize as hash with recursive packing
99
+ packer.write({
100
+ value: @value,
101
+ left: @left,
102
+ right: @right
103
+ })
104
+ end
105
+
106
+ def self.from_msgpack_ext(unpacker)
107
+ # Recursively deserialize
108
+ data = unpacker.read
109
+ new(
110
+ data[:value],
111
+ data[:left],
112
+ data[:right]
113
+ )
114
+ end
115
+ end
116
+ ----
117
+
118
+ === Register as recursive
119
+
120
+ [source,ruby]
121
+ ----
122
+ factory = Messagepack::Factory.new
123
+ factory.register_type(0x02, TreeNode,
124
+ packer: ->(obj, packer) { obj.to_msgpack_ext(packer) },
125
+ unpacker: ->(unpacker) { TreeNode.from_msgpack_ext(unpacker) },
126
+ recursive: true
127
+ )
128
+ ----
129
+
130
+ === Use it
131
+
132
+ [source,ruby]
133
+ ----
134
+ tree = TreeNode.new(
135
+ 1,
136
+ TreeNode.new(2),
137
+ TreeNode.new(3, TreeNode.new(4))
138
+ )
139
+
140
+ binary = factory.pack(tree)
141
+ result = factory.unpack(binary)
142
+ puts result.value # => 1
143
+ puts result.left.value # => 2
144
+ puts result.right.left.value # => 4
145
+ ----
146
+
147
+ == Using procs for simple types
148
+
149
+ For simple classes, you can use procs directly:
150
+
151
+ [source,ruby]
152
+ ----
153
+ require 'uri'
154
+
155
+ factory = Messagepack::Factory.new
156
+ factory.register_type(0x10, URI,
157
+ packer: ->(uri) { uri.to_s },
158
+ unpacker: ->(str) { URI.parse(str) }
159
+ )
160
+
161
+ uri = URI.parse("https://example.com")
162
+ binary = factory.pack(uri)
163
+ result = factory.unpack(binary)
164
+ # => #<URI::HTTPS https://example.com>
165
+ ----
166
+
167
+ == Next steps
168
+
169
+ * link:../tutorials/thread-safety[Thread-safe usage] - Use factories in multi-threaded applications
170
+ * link:../guides/io-streaming[IO streaming] - Work with streams and networks