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
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/docs/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "jekyll", "~> 3.10"
4
+ gem "just-the-docs", "~> 0.7.0"
5
+ gem "jekyll-asciidoc", "~> 3.0"
6
+ gem "jekyll-seo-tag", "~> 2.8"
7
+ gem "jekyll-sitemap", "~> 2.4"
data/docs/README.md ADDED
@@ -0,0 +1,85 @@
1
+ # MessagePack Documentation
2
+
3
+ This directory contains the documentation site for the MessagePack Ruby gem, built with Jekyll and the just-the-docs theme.
4
+
5
+ ## Building locally
6
+
7
+ ### Prerequisites
8
+
9
+ - Ruby 3.3 or higher
10
+ - Bundler
11
+
12
+ ### Install dependencies
13
+
14
+ ```bash
15
+ cd docs
16
+ bundle install
17
+ ```
18
+
19
+ ### Build the site
20
+
21
+ ```bash
22
+ bundle exec jekyll build
23
+ ```
24
+
25
+ The built site will be in `_site/`.
26
+
27
+ ### Serve locally
28
+
29
+ ```bash
30
+ bundle exec jekyll serve
31
+ ```
32
+
33
+ Visit `http://localhost:4000/messagepack/` to view the site.
34
+
35
+ ## Running link checker
36
+
37
+ Install lychee:
38
+
39
+ ```bash
40
+ # macOS
41
+ brew install lychee
42
+
43
+ # Or with cargo
44
+ cargo install lychee
45
+
46
+ # Or use Docker
47
+ docker run -v $(pwd):/work lycheeverse/lychee ./docs
48
+ ```
49
+
50
+ Run link checker:
51
+
52
+ ```bash
53
+ # Build the site first
54
+ bundle exec jekyll build
55
+
56
+ # Check links
57
+ lychee --config lychee.toml _site/**/*.html
58
+ ```
59
+
60
+ ## Documentation structure
61
+
62
+ - `index.adoc` - Main entry point
63
+ - `_pages/` - Core topics (fundamental concepts)
64
+ - `_tutorials/` - Step-by-step learning guides
65
+ - `_guides/` - Task-oriented documentation
66
+ - `_references/` - Technical specifications and API docs
67
+
68
+ ## Adding new documentation
69
+
70
+ 1. Create new `.adoc` file in the appropriate collection directory
71
+ 2. Add YAML front matter with `title`, `parent`, and `nav_order`
72
+ 3. Follow the template structure:
73
+ - Purpose section
74
+ - References section
75
+ - Concepts section
76
+ - Examples section
77
+ 4. Update the collection's index.adoc to include the new page
78
+
79
+ ## CI/CD
80
+
81
+ Documentation is automatically built and deployed to GitHub Pages:
82
+ - On push to `main` branch
83
+ - When files in `docs/` change
84
+
85
+ Links are automatically checked with lychee on every push and PR.
data/docs/_config.yml ADDED
@@ -0,0 +1,137 @@
1
+ # Site settings
2
+ title: MessagePack Ruby
3
+ description: >-
4
+ Pure Ruby implementation of the MessagePack binary serialization format
5
+ baseurl: "/messagepack"
6
+ url: "https://lutaml.github.io"
7
+
8
+ # Theme
9
+ theme: just-the-docs
10
+ remote_theme: just-the-docs/just-the-docs@v0.7.0
11
+
12
+ # Color scheme
13
+ color_scheme: light
14
+
15
+ # Search
16
+ search_enabled: true
17
+ search:
18
+ heading_level: 2
19
+ previews: 3
20
+ preview_words_before: 5
21
+ preview_words_after: 10
22
+ tokenizer_separator: /[\s/]+/
23
+ rel_url: true
24
+ button: false
25
+
26
+ # Heading anchors
27
+ heading_anchors: true
28
+
29
+ # Aux links for the upper right navigation
30
+ aux_links:
31
+ "GitHub":
32
+ - "https://github.com/lutaml/messagepack"
33
+ "RubyGems":
34
+ - "https://rubygems.org/gems/messagepack"
35
+
36
+ # Makes Aux links open in a new tab
37
+ aux_links_new_tab: true
38
+
39
+ # Back to top link
40
+ back_to_top: true
41
+ back_to_top_text: "Back to top"
42
+
43
+ # Footer content
44
+ footer_content: >-
45
+ Copyright © 2025 Ribose. Distributed by an
46
+ <a href="https://github.com/lutaml/messagepack/blob/main/LICENSE">MIT license</a>.
47
+
48
+ # Footer last edit timestamp
49
+ last_edit_timestamp: true
50
+ last_edit_time_format: "%b %e %Y at %I:%M %p"
51
+
52
+ # Navigation structure
53
+ nav_sort: order
54
+
55
+ # Collections for organizing content
56
+ collections:
57
+ pages:
58
+ permalink: "/:path/"
59
+ output: true
60
+ tutorials:
61
+ permalink: "/:collection/:path/"
62
+ output: true
63
+ guides:
64
+ permalink: "/:collection/:path/"
65
+ output: true
66
+ references:
67
+ permalink: "/:collection/:path/"
68
+ output: true
69
+
70
+ # Just the Docs collection configuration
71
+ just_the_docs:
72
+ collections:
73
+ pages:
74
+ name: Core topics
75
+ nav_fold: false
76
+ tutorials:
77
+ name: Tutorials
78
+ nav_fold: true
79
+ guides:
80
+ name: Guides
81
+ nav_fold: true
82
+ references:
83
+ name: References
84
+ nav_fold: true
85
+
86
+ # Plugins
87
+ plugins:
88
+ - jekyll-asciidoc
89
+ - jekyll-seo-tag
90
+ - jekyll-sitemap
91
+
92
+ # AsciiDoc configuration
93
+ asciidoc: {}
94
+ asciidoctor:
95
+ attributes:
96
+ - source-highlighter=rouge
97
+ - rouge-style=github
98
+ - icons=font
99
+ - sectanchors=true
100
+ - idprefix=
101
+ - idseparator=-
102
+ - experimental=true
103
+
104
+ include:
105
+ - '*.adoc'
106
+
107
+ # Exclude from processing
108
+ exclude:
109
+ - Gemfile
110
+ - Gemfile.lock
111
+ - _site
112
+ - node_modules
113
+ - vendor/bundle/
114
+ - vendor/cache/
115
+ - vendor/gems/
116
+ - vendor/ruby/
117
+
118
+ # Enable code copy button
119
+ enable_copy_code_button: true
120
+
121
+ # Callouts
122
+ callouts_level: quiet
123
+ callouts:
124
+ highlight:
125
+ color: yellow
126
+ important:
127
+ title: Important
128
+ color: blue
129
+ new:
130
+ title: New
131
+ color: green
132
+ note:
133
+ title: Note
134
+ color: purple
135
+ warning:
136
+ title: Warning
137
+ color: red
@@ -0,0 +1,14 @@
1
+ ---
2
+ title: Guides
3
+ nav_order: 1
4
+ ---
5
+
6
+ == Purpose
7
+
8
+ Guides provide task-oriented documentation for specific use cases.
9
+
10
+ == Guides
11
+
12
+ * link:../guides/performance[Performance optimization] - Techniques for maximizing performance
13
+ * link:../guides/io-streaming[IO streaming] - Working with files and network streams
14
+ * link:../guides/migration[Migration guide] - Migrating from other MessagePack implementations
@@ -0,0 +1,226 @@
1
+ ---
2
+ title: IO streaming
3
+ nav_order: 2
4
+ ---
5
+
6
+ == Purpose
7
+
8
+ This guide explains how to work with IO objects and network streams using
9
+ MessagePack.
10
+
11
+ == References
12
+
13
+ * link:../pages/streaming[Streaming] - Streaming unpacker concepts
14
+ * link:../pages/buffer[Buffer management] - Buffer IO integration
15
+
16
+ == Concepts
17
+
18
+ === IO-based unpacking
19
+
20
+ The unpacker can work directly with IO objects:
21
+
22
+ * Automatically reads data as needed
23
+ * Efficient chunked buffering
24
+ * Suitable for files and network sockets
25
+
26
+ === Streaming unpacker
27
+
28
+ Feed data incrementally:
29
+
30
+ * Parse incomplete data
31
+ * Handle chunked responses
32
+ * Process multiple objects from stream
33
+
34
+ == Working with files
35
+
36
+ === Writing to files
37
+
38
+ [source,ruby]
39
+ ----
40
+ data = { name: "Alice", items: [1, 2, 3] }
41
+
42
+ # Pack and write
43
+ File.open("output.msgpack", "wb") do |file|
44
+ packed = Messagepack.pack(data)
45
+ file.write(packed)
46
+ end
47
+
48
+ # Or use pack with IO directly
49
+ File.open("output.msgpack", "wb") do |file|
50
+ Messagepack.pack(data, file)
51
+ end
52
+ ----
53
+
54
+ === Reading from files
55
+
56
+ [source,ruby]
57
+ ----
58
+ # Read and unpack
59
+ data = File.read("output.msgpack", encoding: Encoding::BINARY)
60
+ result = Messagepack.unpack(data)
61
+
62
+ # Or use unpack with IO directly
63
+ File.open("output.msgpack", "rb") do |file|
64
+ result = Messagepack.unpack(file)
65
+ end
66
+ ----
67
+
68
+ === Processing large files
69
+
70
+ [source,ruby]
71
+ ----
72
+ # For files with multiple objects, use streaming
73
+ unpacker = Messagepack::Unpacker.new(File.open("large.msgpack", "rb"))
74
+
75
+ while obj = unpacker.read
76
+ process(obj)
77
+ end
78
+ ----
79
+
80
+ == Network streaming
81
+
82
+ === TCP server example
83
+
84
+ [source,ruby]
85
+ ----
86
+ require 'socket'
87
+ require 'messagepack'
88
+
89
+ server = TCPServer.new(2000)
90
+
91
+ loop do
92
+ client = server.accept
93
+ unpacker = Messagepack::Unpacker.new(client)
94
+
95
+ while obj = unpacker.read
96
+ # Process each message
97
+ response = handle_message(obj)
98
+
99
+ # Send response
100
+ packed = Messagepack.pack(response)
101
+ client.write(packed)
102
+ end
103
+
104
+ client.close
105
+ end
106
+ ----
107
+
108
+ === TCP client example
109
+
110
+ [source,ruby]
111
+ ----
112
+ require 'socket'
113
+ require 'messagepack'
114
+
115
+ socket = TCPSocket.new('localhost', 2000)
116
+
117
+ # Send request
118
+ request = { action: "ping", data: "hello" }
119
+ socket.write(Messagepack.pack(request))
120
+
121
+ # Read response
122
+ unpacker = Messagepack::Unpacker.new(socket)
123
+ response = unpacker.read
124
+
125
+ puts response.inspect
126
+ socket.close
127
+ ----
128
+
129
+ === HTTP streaming
130
+
131
+ [source,ruby]
132
+ ----
133
+ require 'net/http'
134
+ require 'messagepack'
135
+
136
+ uri = URI('http://example.com/stream')
137
+ http = Net::HTTP.new(uri.host, uri.port)
138
+
139
+ request = Net::HTTP::Get.new(uri.request_uri)
140
+ http.request(request) do |response|
141
+ unpacker = Messagepack::Unpacker.new
142
+
143
+ response.read_body do |chunk|
144
+ unpacker.feed(chunk)
145
+
146
+ while obj = unpacker.read
147
+ process(obj)
148
+ end
149
+ end
150
+ end
151
+ ----
152
+
153
+ == WebSocket streaming
154
+
155
+ [source,ruby]
156
+ ----
157
+ # Using websocket-client-simple gem
158
+ require 'websocket-client-simple'
159
+ require 'messagepack'
160
+
161
+ ws = WebSocket::Client::Simple.connect('ws://example.com/stream')
162
+
163
+ unpacker = Messagepack::Unpacker.new
164
+
165
+ ws.on :message do |msg|
166
+ unpacker.feed(msg.data)
167
+
168
+ while obj = unpacker.read
169
+ puts "Received: #{obj.inspect}"
170
+ end
171
+ end
172
+
173
+ ws.on :open do
174
+ # Send MessagePack data
175
+ ws.send(Messagepack.pack({type: "subscribe", channel: "updates"}))
176
+ end
177
+ ----
178
+
179
+ == Error handling
180
+
181
+ === Handling incomplete data
182
+
183
+ [source,ruby]
184
+ ----
185
+ unpacker = Messagepack::Unpacker.new
186
+
187
+ unpacker.feed(partial_data)
188
+ obj = unpacker.read
189
+
190
+ if obj
191
+ puts "Got object: #{obj.inspect}"
192
+ else
193
+ puts "Need more data"
194
+ end
195
+ ----
196
+
197
+ === Handling malformed data
198
+
199
+ [source,ruby]
200
+ ----
201
+ begin
202
+ result = Messagepack.unpack(invalid_data)
203
+ rescue Messagepack::MalformedFormatError => e
204
+ puts "Invalid MessagePack: #{e.message}"
205
+ rescue Messagepack::UnpackError => e
206
+ puts "Unpack error: #{e.message}"
207
+ end
208
+ ----
209
+
210
+ === Handling IO errors
211
+
212
+ [source,ruby]
213
+ ----
214
+ begin
215
+ File.open("data.msgpack", "rb") do |file|
216
+ unpacker = Messagepack::Unpacker.new(file)
217
+ while obj = unpacker.read
218
+ process(obj)
219
+ end
220
+ end
221
+ rescue Errno::ENOENT
222
+ puts "File not found"
223
+ rescue IOError => e
224
+ puts "IO error: #{e.message}"
225
+ end
226
+ ----
@@ -0,0 +1,218 @@
1
+ ---
2
+ title: Migration guide
3
+ nav_order: 3
4
+ ---
5
+
6
+ == Purpose
7
+
8
+ This guide helps you migrate from other MessagePack implementations to the
9
+ pure Ruby MessagePack library.
10
+
11
+ == References
12
+
13
+ * link:../pages/serialization[Serialization] - Core API
14
+ * link:../references/api[API reference] - Complete API documentation
15
+
16
+ == From msgpack-ruby (C extension)
17
+
18
+ The pure Ruby implementation aims for API compatibility with msgpack-ruby.
19
+
20
+ === Module name
21
+
22
+ [source,ruby]
23
+ ----
24
+ # msgpack-ruby
25
+ MessagePack.pack(data)
26
+
27
+ # messagepack (pure Ruby)
28
+ Messagepack.pack(data)
29
+ ----
30
+
31
+ The pure Ruby version uses `Messagepack` (single word) instead of `MessagePack`.
32
+
33
+ === Compatible APIs
34
+
35
+ Most core APIs are compatible:
36
+
37
+ [source,ruby]
38
+ ----
39
+ # These work the same in both
40
+ Messagepack.pack(data)
41
+ Messagepack.unpack(data)
42
+ Messagepack.load(data)
43
+ Messagepack.dump(data)
44
+ ----
45
+
46
+ === Extension types
47
+
48
+ Extension type registration is similar:
49
+
50
+ [source,ruby]
51
+ ----
52
+ # msgpack-ruby
53
+ factory = MessagePack::Factory.new
54
+ factory.register_type(0x01, MyClass, ...)
55
+
56
+ # messagepack (pure Ruby)
57
+ factory = Messagepack::Factory.new
58
+ factory.register_type(0x01, MyClass, ...)
59
+ ----
60
+
61
+ === Differences
62
+
63
+ * **Performance**: C extension is faster for most operations
64
+ * **Dependencies**: Pure Ruby has no C dependencies
65
+ * **Portability**: Pure Ruby works on any Ruby implementation
66
+
67
+ === Migration steps
68
+
69
+ 1. Update Gemfile:
70
+
71
+ [source,ruby]
72
+ ----
73
+ # Remove
74
+ gem 'msgpack'
75
+
76
+ # Add
77
+ gem 'messagepack'
78
+ ----
79
+
80
+ 2. Update require statements:
81
+
82
+ [source,ruby]
83
+ ----
84
+ # Change
85
+ require 'msgpack'
86
+
87
+ # To
88
+ require 'messagepack'
89
+ ----
90
+
91
+ 3. Update constant references:
92
+
93
+ [source,ruby]
94
+ ----
95
+ # Change
96
+ MessagePack::Factory
97
+ MessagePack::Unpacker
98
+
99
+ # To
100
+ Messagepack::Factory
101
+ Messagepack::Unpacker
102
+ ----
103
+
104
+ == From JSON serialization
105
+
106
+ MessagePack is a binary alternative to JSON.
107
+
108
+ === Encoding data
109
+
110
+ [source,ruby]
111
+ ----
112
+ # JSON
113
+ require 'json'
114
+ JSON.generate({name: "Alice"})
115
+
116
+ # MessagePack
117
+ require 'messagepack'
118
+ Messagepack.pack({name: "Alice"})
119
+ ----
120
+
121
+ === Decoding data
122
+
123
+ [source,ruby]
124
+ ----
125
+ # JSON
126
+ JSON.parse('{"name":"Alice"}')
127
+
128
+ # MessagePack
129
+ Messagepack.unpack(binary_string)
130
+ ----
131
+
132
+ === Type differences
133
+
134
+ [source,ruby]
135
+ ----
136
+ # JSON only supports these types
137
+ null, true, false, number, string, array, object
138
+
139
+ # MessagePack supports additional types
140
+ nil, boolean, integer, float, string, binary, array, map,
141
+ timestamp, extension types
142
+ ----
143
+
144
+ === Migration pattern
145
+
146
+ [source,ruby]
147
+ ----
148
+ # Before (JSON)
149
+ class Cache
150
+ def save(key, value)
151
+ File.write("cache/#{key}", JSON.generate(value))
152
+ end
153
+
154
+ def load(key)
155
+ JSON.parse(File.read("cache/#{key}"))
156
+ end
157
+ end
158
+
159
+ # After (MessagePack)
160
+ class Cache
161
+ def save(key, value)
162
+ File.write("cache/#{key}", Messagepack.pack(value), mode: 'wb')
163
+ end
164
+
165
+ def load(key)
166
+ Messagepack.unpack(File.read("cache/#{key}", encoding: Encoding::BINARY))
167
+ end
168
+ end
169
+ ----
170
+
171
+ == Compatibility mode
172
+
173
+ For compatibility with older MessagePack implementations:
174
+
175
+ [source,ruby]
176
+ ----
177
+ # Use compatibility mode to avoid bin/str8 types
178
+ binary = Messagepack.pack(data, compatibility_mode: true)
179
+ ----
180
+
181
+ This ensures:
182
+ * Binary data uses str16/str32 instead of bin8/bin16/bin32
183
+ * Strings use str16/str32 instead of str8
184
+
185
+ == Testing your migration
186
+
187
+ === Verify serialization
188
+
189
+ [source,ruby]
190
+ ----
191
+ # Test that data round-trips correctly
192
+ def test_serialization(data)
193
+ binary = Messagepack.pack(data)
194
+ result = Messagepack.unpack(binary)
195
+ result == data
196
+ end
197
+
198
+ # Test various types
199
+ test_serialization(nil)
200
+ test_serialization(true)
201
+ test_serialization(42)
202
+ test_serialization(3.14)
203
+ test_serialization("hello")
204
+ test_serialization([1, 2, 3])
205
+ test_serialization({a: 1, b: 2})
206
+ ----
207
+
208
+ === Compare with old implementation
209
+
210
+ [source,ruby]
211
+ ----
212
+ # Verify compatibility by comparing outputs
213
+ old_binary = OldImpl.pack(data)
214
+ new_binary = Messagepack.pack(data)
215
+
216
+ # Results should be identical for standard types
217
+ # (extension types may differ)
218
+ ----