nayutaya-msgpack-pure 0.0.1

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.
data/README.md ADDED
@@ -0,0 +1,10 @@
1
+
2
+ # msgpack_pure
3
+
4
+ msgpack_pureは、MessagePackのPure Rubyによる実装です。
5
+
6
+ ## インストール
7
+
8
+ ↓まだgemパッケージは作っていないため、下記はできません
9
+
10
+ $ gem install nayutaya-msgpack_pure
data/Rakefile ADDED
@@ -0,0 +1,58 @@
1
+
2
+ require "rake/testtask"
3
+ require "lib/msgpack_pure/version"
4
+
5
+ NAME = "nayutaya-msgpack-pure"
6
+
7
+ task :default => :test
8
+
9
+ Rake::TestTask.new do |test|
10
+ test.libs << "test"
11
+ test.test_files = Dir.glob("test/**/*_test.rb")
12
+ test.verbose = true
13
+ end
14
+
15
+ desc "bump version"
16
+ task :bump do
17
+ cur_version = MessagePackPure::VERSION
18
+ next_version = cur_version.succ
19
+ puts("#{cur_version} -> #{next_version}")
20
+
21
+ filename = File.join(File.dirname(__FILE__), "lib", "msgpack_pure", "version.rb")
22
+ File.open(filename, "wb") { |file|
23
+ file.puts(%|# coding: utf-8|)
24
+ file.puts(%||)
25
+ file.puts(%|module MessagePackPure|)
26
+ file.puts(%| VERSION = "#{next_version}"|)
27
+ file.puts(%|end|)
28
+ }
29
+ end
30
+
31
+ desc "generate gemspec"
32
+ task :gemspec do
33
+ require "erb"
34
+
35
+ src = File.open("#{NAME}.gemspec.erb", "rb") { |file| file.read }
36
+ erb = ERB.new(src, nil, "-")
37
+
38
+ version = MessagePackPure::VERSION
39
+ date = Time.now.strftime("%Y-%m-%d")
40
+
41
+ files = Dir.glob("**/*").select { |s| File.file?(s) }.reject { |s| /\.gem\z/ =~ s }
42
+ test_files = Dir.glob("test/**").select { |s| File.file?(s) }
43
+
44
+ File.open("#{NAME}.gemspec", "wb") { |file|
45
+ file.write(erb.result(binding))
46
+ }
47
+ end
48
+
49
+ desc "build gem"
50
+ task :build do
51
+ sh "gem build #{NAME}.gemspec"
52
+ end
53
+
54
+ desc "push gem"
55
+ task :push do
56
+ target = "#{NAME}-#{MessagePackPure::VERSION}.gem"
57
+ sh "gem push #{target}"
58
+ end
@@ -0,0 +1,18 @@
1
+ # coding: utf-8
2
+
3
+ require "stringio"
4
+ require "msgpack_pure/packer"
5
+ require "msgpack_pure/unpacker"
6
+
7
+ module MessagePackPure
8
+ def self.pack(value)
9
+ io = StringIO.new
10
+ Packer.write(io, value)
11
+ return io.string
12
+ end
13
+
14
+ def self.unpack(binary)
15
+ io = StringIO.new(binary, "r")
16
+ return Unpacker.read(io)
17
+ end
18
+ end
@@ -0,0 +1,192 @@
1
+ # coding: utf-8
2
+
3
+ # MessagePack format specification
4
+ # http://msgpack.sourceforge.jp/spec
5
+
6
+ module MessagePackPure
7
+ module Packer
8
+ end
9
+ end
10
+
11
+ module MessagePackPure::Packer
12
+ def self.write(io, value)
13
+ case value
14
+ when Integer then self.write_integer(io, value)
15
+ when NilClass then self.write_nil(io)
16
+ when TrueClass then self.write_true(io)
17
+ when FalseClass then self.write_false(io)
18
+ when Float then self.write_float(io, value)
19
+ when String then self.write_string(io, value)
20
+ when Array then self.write_array(io, value)
21
+ when Hash then self.write_hash(io, value)
22
+ else raise("unknown type")
23
+ end
24
+ return io
25
+ end
26
+
27
+ def self.write_integer(io, num)
28
+ case num
29
+ when (-0x20..0x7F)
30
+ # positive fixnum, negative fixnum
31
+ io.write(self.pack_int8(num))
32
+ when (0x00..0xFF)
33
+ # uint8
34
+ io.write("\xCC")
35
+ io.write(self.pack_uint8(num))
36
+ when (-0x80..0x7F)
37
+ # int8
38
+ io.write("\xD0")
39
+ io.write(self.pack_int8(num))
40
+ when (0x0000..0xFFFF)
41
+ # uint16
42
+ io.write("\xCD")
43
+ io.write(self.pack_uint16(num))
44
+ when (-0x8000..0x7FFF)
45
+ # int16
46
+ io.write("\xD1")
47
+ io.write(self.pack_int16(num))
48
+ when (0x00000000..0xFFFFFFFF)
49
+ # uint32
50
+ io.write("\xCE")
51
+ io.write(self.pack_uint32(num))
52
+ when (-0x80000000..0x7FFFFFFF)
53
+ # int32
54
+ io.write("\xD2")
55
+ io.write(self.pack_int32(num))
56
+ when (0x0000000000000000..0xFFFFFFFFFFFFFFFF)
57
+ # uint64
58
+ io.write("\xCF")
59
+ io.write(self.pack_uint64(num))
60
+ when (-0x8000000000000000..0x7FFFFFFFFFFFFFFF)
61
+ # int64
62
+ io.write("\xD3")
63
+ io.write(self.pack_int64(num))
64
+ else
65
+ raise("invalid integer")
66
+ end
67
+ end
68
+
69
+ def self.write_nil(io)
70
+ io.write("\xC0")
71
+ end
72
+
73
+ def self.write_true(io)
74
+ io.write("\xC3")
75
+ end
76
+
77
+ def self.write_false(io)
78
+ io.write("\xC2")
79
+ end
80
+
81
+ def self.write_float(io, value)
82
+ io.write("\xCB")
83
+ io.write(self.pack_double(value))
84
+ end
85
+
86
+ def self.write_string(io, value)
87
+ case value.size
88
+ when (0x00..0x1F)
89
+ # fixraw
90
+ io.write(self.pack_uint8(0b10100000 + value.size))
91
+ io.write(value)
92
+ when (0x0000..0xFFFF)
93
+ # raw16
94
+ io.write("\xDA")
95
+ io.write(self.pack_uint16(value.size))
96
+ io.write(value)
97
+ when (0x00000000..0xFFFFFFFF)
98
+ # raw32
99
+ io.write("\xDB")
100
+ io.write(self.pack_uint32(value.size))
101
+ io.write(value)
102
+ else
103
+ raise("invalid length")
104
+ end
105
+ end
106
+
107
+ def self.write_array(io, value)
108
+ case value.size
109
+ when (0x00..0x0F)
110
+ # fixarray
111
+ io.write(self.pack_uint8(0b10010000 + value.size))
112
+ when (0x0000..0xFFFF)
113
+ # array16
114
+ io.write("\xDC")
115
+ io.write(self.pack_uint16(value.size))
116
+ when (0x00000000..0xFFFFFFFF)
117
+ # array32
118
+ io.write("\xDD")
119
+ io.write(self.pack_uint32(value.size))
120
+ else
121
+ raise("invalid length")
122
+ end
123
+
124
+ value.each { |item|
125
+ self.write(io, item)
126
+ }
127
+ end
128
+
129
+ def self.write_hash(io, value)
130
+ case value.size
131
+ when (0x00..0x0F)
132
+ # fixmap
133
+ io.write(self.pack_uint8(0b10000000 + value.size))
134
+ when (0x0000..0xFFFF)
135
+ # map16
136
+ io.write("\xDE")
137
+ io.write(self.pack_uint16(value.size))
138
+ when (0x00000000..0xFFFFFFFF)
139
+ # map32
140
+ io.write("\xDF")
141
+ io.write(self.pack_uint32(value.size))
142
+ else
143
+ raise("invalid length")
144
+ end
145
+
146
+ value.sort_by { |key, value| key }.each { |key, value|
147
+ self.write(io, key)
148
+ self.write(io, value)
149
+ }
150
+ end
151
+
152
+ def self.pack_uint8(value)
153
+ return [value].pack("C")
154
+ end
155
+
156
+ def self.pack_int8(value)
157
+ return [value].pack("c")
158
+ end
159
+
160
+ def self.pack_uint16(value)
161
+ return [value].pack("n")
162
+ end
163
+
164
+ def self.pack_int16(value)
165
+ value += (2 ** 16) if value < 0
166
+ return self.pack_uint16(value)
167
+ end
168
+
169
+ def self.pack_uint32(value)
170
+ return [value].pack("N")
171
+ end
172
+
173
+ def self.pack_int32(value)
174
+ value += (2 ** 32) if value < 0
175
+ return self.pack_uint32(value)
176
+ end
177
+
178
+ def self.pack_uint64(value)
179
+ high = (value >> 32)
180
+ low = (value & 0xFFFFFFFF)
181
+ return self.pack_uint32(high) + self.pack_uint32(low)
182
+ end
183
+
184
+ def self.pack_int64(value)
185
+ value += (2 ** 64) if value < 0
186
+ return self.pack_uint64(value)
187
+ end
188
+
189
+ def self.pack_double(value)
190
+ return [value].pack("G")
191
+ end
192
+ end
@@ -0,0 +1,136 @@
1
+ # coding: utf-8
2
+
3
+ # MessagePack format specification
4
+ # http://msgpack.sourceforge.jp/spec
5
+
6
+ module MessagePackPure
7
+ module Unpacker
8
+ end
9
+ end
10
+
11
+ module MessagePackPure::Unpacker
12
+ def self.read(io)
13
+ type = self.unpack_uint8(io)
14
+
15
+ case
16
+ when (type & 0b10000000) == 0b00000000 # positive fixnum
17
+ return type
18
+ when (type & 0b11100000) == 0b11100000 # negative fixnum
19
+ return (type & 0b00011111) - (2 ** 5)
20
+ when (type & 0b11100000) == 0b10100000 # fixraw
21
+ size = (type & 0b00011111)
22
+ return io.read(size)
23
+ when (type & 0b11110000) == 0b10010000 # fixarray
24
+ size = (type & 0b00001111)
25
+ return self.read_array(io, size)
26
+ when (type & 0b11110000) == 0b10000000 # fixmap
27
+ size = (type & 0b00001111)
28
+ return self.read_hash(io, size)
29
+ end
30
+
31
+ case type
32
+ when 0xC0 # nil
33
+ return nil
34
+ when 0xC2 # false
35
+ return false
36
+ when 0xC3 # true
37
+ return true
38
+ when 0xCA # float
39
+ return self.unpack_float(io)
40
+ when 0xCB # double
41
+ return self.unpack_double(io)
42
+ when 0xCC # uint8
43
+ return self.unpack_uint8(io)
44
+ when 0xCD # uint16
45
+ return self.unpack_uint16(io)
46
+ when 0xCE # uint32
47
+ return self.unpack_uint32(io)
48
+ when 0xCF # uint64
49
+ return self.unpack_uint64(io)
50
+ when 0xD0 # int8
51
+ return self.unpack_int8(io)
52
+ when 0xD1 # int16
53
+ return self.unpack_int16(io)
54
+ when 0xD2 # int32
55
+ return self.unpack_int32(io)
56
+ when 0xD3 # int64
57
+ return self.unpack_int64(io)
58
+ when 0xDA # raw16
59
+ size = self.unpack_uint16(io)
60
+ return io.read(size)
61
+ when 0xDB # raw32
62
+ size = self.unpack_uint32(io)
63
+ return io.read(size)
64
+ when 0xDC # array16
65
+ size = self.unpack_uint16(io)
66
+ return self.read_array(io, size)
67
+ when 0xDD # array32
68
+ size = self.unpack_uint32(io)
69
+ return self.read_array(io, size)
70
+ when 0xDE # map16
71
+ size = self.unpack_uint16(io)
72
+ return self.read_hash(io, size)
73
+ when 0xDF # map32
74
+ size = self.unpack_uint32(io)
75
+ return self.read_hash(io, size)
76
+ else
77
+ raise("Unknown Type -- #{'0x%02X' % type}")
78
+ end
79
+ end
80
+
81
+ def self.read_array(io, size)
82
+ return size.times.map { self.read(io) }
83
+ end
84
+
85
+ def self.read_hash(io, size)
86
+ return size.times.inject({}) { |memo,|
87
+ memo[self.read(io)] = self.read(io)
88
+ memo
89
+ }
90
+ end
91
+
92
+ def self.unpack_uint8(io)
93
+ return io.read(1).unpack("C")[0]
94
+ end
95
+
96
+ def self.unpack_int8(io)
97
+ return io.read(1).unpack("c")[0]
98
+ end
99
+
100
+ def self.unpack_uint16(io)
101
+ return io.read(2).unpack("n")[0]
102
+ end
103
+
104
+ def self.unpack_int16(io)
105
+ num = self.unpack_uint16(io)
106
+ return (num < 2 ** 15 ? num : num - (2 ** 16))
107
+ end
108
+
109
+ def self.unpack_uint32(io)
110
+ return io.read(4).unpack("N")[0]
111
+ end
112
+
113
+ def self.unpack_int32(io)
114
+ num = self.unpack_uint32(io)
115
+ return (num < 2 ** 31 ? num : num - (2 ** 32))
116
+ end
117
+
118
+ def self.unpack_uint64(io)
119
+ high = self.unpack_uint32(io)
120
+ low = self.unpack_uint32(io)
121
+ return (high << 32) + low
122
+ end
123
+
124
+ def self.unpack_int64(io)
125
+ num = self.unpack_uint64(io)
126
+ return (num < 2 ** 63 ? num : num - (2 ** 64))
127
+ end
128
+
129
+ def self.unpack_float(io)
130
+ return io.read(4).unpack("g")[0]
131
+ end
132
+
133
+ def self.unpack_double(io)
134
+ return io.read(8).unpack("G")[0]
135
+ end
136
+ end
@@ -0,0 +1,5 @@
1
+ # coding: utf-8
2
+
3
+ module MessagePackPure
4
+ VERSION = "0.0.1"
5
+ end
@@ -0,0 +1,4 @@
1
+ # coding: utf-8
2
+
3
+ require "msgpack_pure/version"
4
+ require "msgpack_pure/core"
@@ -0,0 +1,44 @@
1
+
2
+ Gem::Specification.new do |s|
3
+ s.specification_version = 2
4
+ s.required_rubygems_version = Gem::Requirement.new(">= 0")
5
+ s.required_ruby_version = Gem::Requirement.new(">= 1.8.6")
6
+
7
+ s.name = "nayutaya-msgpack-pure"
8
+ s.version = "0.0.1"
9
+ s.date = "2010-03-08"
10
+
11
+ s.authors = ["Yuya Kato"]
12
+ s.email = "yuyakato@gmail.com"
13
+
14
+ s.summary = "MessagePack"
15
+ s.description = "pure ruby implementation of MessagePack"
16
+ s.homepage = "http://github.com/nayutaya/msgpack-pure/"
17
+
18
+ s.rubyforge_project = nil
19
+ s.has_rdoc = false
20
+ s.require_paths = ["lib"]
21
+
22
+ s.files = [
23
+ "lib/msgpack_pure/core.rb",
24
+ "lib/msgpack_pure/packer.rb",
25
+ "lib/msgpack_pure/unpacker.rb",
26
+ "lib/msgpack_pure/version.rb",
27
+ "lib/msgpack_pure.rb",
28
+ "nayutaya-msgpack-pure.gemspec",
29
+ "nayutaya-msgpack-pure.gemspec.erb",
30
+ "Rakefile",
31
+ "README.md",
32
+ "test/core_test.rb",
33
+ "test/packer_test.rb",
34
+ "test/test_helper.rb",
35
+ "test/unpacker_test.rb",
36
+ ]
37
+ s.test_files = [
38
+ "test/core_test.rb",
39
+ "test/packer_test.rb",
40
+ "test/test_helper.rb",
41
+ "test/unpacker_test.rb",
42
+ ]
43
+ s.extra_rdoc_files = []
44
+ end
@@ -0,0 +1,33 @@
1
+
2
+ Gem::Specification.new do |s|
3
+ s.specification_version = 2
4
+ s.required_rubygems_version = Gem::Requirement.new(">= 0")
5
+ s.required_ruby_version = Gem::Requirement.new(">= 1.8.6")
6
+
7
+ s.name = <%= NAME.dump %>
8
+ s.version = <%= version.dump %>
9
+ s.date = <%= date.dump %>
10
+
11
+ s.authors = ["Yuya Kato"]
12
+ s.email = "yuyakato@gmail.com"
13
+
14
+ s.summary = "MessagePack"
15
+ s.description = "pure ruby implementation of MessagePack"
16
+ s.homepage = "http://github.com/nayutaya/msgpack-pure/"
17
+
18
+ s.rubyforge_project = nil
19
+ s.has_rdoc = false
20
+ s.require_paths = ["lib"]
21
+
22
+ s.files = [
23
+ <%- files.each { |path| -%>
24
+ <%= path.dump %>,
25
+ <%- } -%>
26
+ ]
27
+ s.test_files = [
28
+ <%- test_files.each { |path| -%>
29
+ <%= path.dump %>,
30
+ <%- } -%>
31
+ ]
32
+ s.extra_rdoc_files = []
33
+ end
data/test/core_test.rb ADDED
@@ -0,0 +1,73 @@
1
+ #! ruby -Ku
2
+ # coding: utf-8
3
+
4
+ require "test_helper"
5
+ require "msgpack_pure/core"
6
+ require "rubygems"
7
+ require "msgpack"
8
+
9
+ class CoreTest < Test::Unit::TestCase
10
+ def setup
11
+ @module = MessagePackPure
12
+ end
13
+
14
+ def test_pack
15
+ assert_equal("\x00", @module.pack(0))
16
+ assert_equal("\xC0", @module.pack(nil))
17
+ end
18
+
19
+ def test_unpack
20
+ assert_equal(0, @module.unpack("\x00"))
21
+ assert_equal(nil, @module.unpack("\xC0"))
22
+ end
23
+
24
+ def test_cross__primitive
25
+ [
26
+ 0, # positive fixnum
27
+ -1, # negative fixnum
28
+ 0xFF, # uint8
29
+ 0xFFFF, # uint16
30
+ 0xFFFFFFFF, # uint32
31
+ 0xFFFFFFFFFFFFFFFF, # uint64
32
+ -0x80, # int8
33
+ -0x8000, # int16
34
+ -0x80000000, # int32
35
+ -0x8000000000000000, # int64
36
+ nil, # nil
37
+ true, # true
38
+ false, # false
39
+ 0.5, # double
40
+ "", # fixraw
41
+ "A" * 0xFFFF, # raw16
42
+ "A" * 0x00010000, # raw32
43
+ [], # fixarray
44
+ {}, # fixmap
45
+ ].each { |value|
46
+ bin1 = MessagePack.pack(value)
47
+ bin2 = MessagePackPure.pack(value)
48
+ value1 = MessagePackPure.unpack(bin1)
49
+ value2 = MessagePack.unpack(bin2)
50
+ assert_equal(value, value1)
51
+ assert_equal(value, value2)
52
+ assert_equal(bin1, bin2)
53
+ }
54
+ end
55
+
56
+ def test_cross__collection
57
+ [
58
+ (0.. 0x0F).to_a, # fixarray
59
+ (0.. 0xFFFF).to_a, # array16
60
+ (0..0x00010000).to_a, # array32
61
+ (0.. 0x0F).inject({}) { |memo, i| memo[i] = i; memo }, # fixmap
62
+ (0.. 0xFFFF).inject({}) { |memo, i| memo[i] = i; memo }, # map16
63
+ (0..0x00010000).inject({}) { |memo, i| memo[i] = i; memo }, # map32
64
+ ].each { |value|
65
+ bin1 = MessagePack.pack(value)
66
+ bin2 = MessagePackPure.pack(value)
67
+ value1 = MessagePackPure.unpack(bin1)
68
+ value2 = MessagePack.unpack(bin2)
69
+ assert_equal(value, value1)
70
+ assert_equal(value, value2)
71
+ }
72
+ end
73
+ end
@@ -0,0 +1,198 @@
1
+ #! ruby -Ku
2
+ # coding: utf-8
3
+
4
+ require "test_helper"
5
+ require "stringio"
6
+ require "msgpack_pure/packer"
7
+
8
+ class PackerTest < Test::Unit::TestCase
9
+ def setup
10
+ @module = MessagePackPure::Packer
11
+ end
12
+
13
+ def test_write__positive_fixnum
14
+ assert_equal("\x00", @module.write(sio, 0x00).string)
15
+ assert_equal("\x01", @module.write(sio, 0x01).string)
16
+ assert_equal("\x7F", @module.write(sio, 0x7F).string)
17
+ end
18
+
19
+ def test_write__negative_fixnum
20
+ assert_equal("\xFF", @module.write(sio, -0x01).string)
21
+ assert_equal("\xE0", @module.write(sio, -0x20).string)
22
+ end
23
+
24
+ def test_write__uint8
25
+ assert_equal("\xCC\x80", @module.write(sio, 0x80).string)
26
+ assert_equal("\xCC\xFF", @module.write(sio, 0xFF).string)
27
+ end
28
+
29
+ def test_write__uint16
30
+ assert_equal("\xCD\x01\x00", @module.write(sio, 0x0100).string)
31
+ assert_equal("\xCD\xFF\xFF", @module.write(sio, 0xFFFF).string)
32
+ end
33
+
34
+ def test_write__uint32
35
+ assert_equal("\xCE\x00\x01\x00\x00", @module.write(sio, 0x00010000).string)
36
+ assert_equal("\xCE\xFF\xFF\xFF\xFF", @module.write(sio, 0xFFFFFFFF).string)
37
+ end
38
+
39
+ def test_write__uint64
40
+ assert_equal("\xCF\x00\x00\x00\x01\x00\x00\x00\x00", @module.write(sio, 0x0000000100000000).string)
41
+ assert_equal("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", @module.write(sio, 0xFFFFFFFFFFFFFFFF).string)
42
+ end
43
+
44
+ def test_write__int8
45
+ assert_equal("\xD0\xDF", @module.write(sio, -0x21).string)
46
+ assert_equal("\xD0\x80", @module.write(sio, -0x80).string)
47
+ end
48
+
49
+ def test_write__int16
50
+ assert_equal("\xD1\xFF\x7F", @module.write(sio, -0x0081).string)
51
+ assert_equal("\xD1\x80\x00", @module.write(sio, -0x8000).string)
52
+ end
53
+
54
+ def test_write__int32
55
+ assert_equal("\xD2\xFF\xFF\x7F\xFF", @module.write(sio, -0x00008001).string)
56
+ assert_equal("\xD2\x80\x00\x00\x00", @module.write(sio, -0x80000000).string)
57
+ end
58
+
59
+ def test_write__int64
60
+ assert_equal("\xD3\xFF\xFF\xFF\xFF\x7F\xFF\xFF\xFF", @module.write(sio, -0x0000000080000001).string)
61
+ assert_equal("\xD3\x80\x00\x00\x00\x00\x00\x00\x00", @module.write(sio, -0x8000000000000000).string)
62
+ end
63
+
64
+ def test_write__nil
65
+ assert_equal("\xC0", @module.write(sio, nil).string)
66
+ end
67
+
68
+ def test_write__true
69
+ assert_equal("\xC3", @module.write(sio, true).string)
70
+ end
71
+
72
+ def test_write__false
73
+ assert_equal("\xC2", @module.write(sio, false).string)
74
+ end
75
+
76
+ def test_write__float
77
+ assert_equal("\xCB\x00\x00\x00\x00\x00\x00\x00\x00", @module.write(sio, +0.0).string)
78
+ assert_equal("\xCB\x3F\xE0\x00\x00\x00\x00\x00\x00", @module.write(sio, +0.5).string)
79
+ assert_equal("\xCB\xBF\xE0\x00\x00\x00\x00\x00\x00", @module.write(sio, -0.5).string)
80
+ end
81
+
82
+ def test_write__fixraw
83
+ assert_equal("\xA0", @module.write(sio, "").string)
84
+ assert_equal("\xA3ABC", @module.write(sio, "ABC").string)
85
+ assert_equal(
86
+ "\xBF" + "A" * 31,
87
+ @module.write(sio, "A" * 31).string)
88
+ end
89
+
90
+ def test_write__raw16
91
+ assert_equal(
92
+ "\xDA\x00\x20" + "A" * 0x0020,
93
+ @module.write(sio, "A" * 0x0020).string)
94
+ assert_equal(
95
+ "\xDA\xFF\xFF" + "A" * 0xFFFF,
96
+ @module.write(sio, "A" * 0xFFFF).string)
97
+ end
98
+
99
+ def test_write__raw32
100
+ assert_equal(
101
+ "\xDB\x00\x01\x00\x00" + "A" * 0x00010000,
102
+ @module.write(sio, "A" * 0x00010000).string)
103
+ end
104
+
105
+ def test_write__fixarray
106
+ assert_equal("\x90", @module.write(sio, []).string)
107
+ assert_equal("\x93\x00\x01\x02", @module.write(sio, [0, 1, 2]).string)
108
+
109
+ io = StringIO.new("\x9F", "a+")
110
+ array = 0x0F.times.map { |i|
111
+ @module.write(io, i)
112
+ i
113
+ }
114
+ assert_equal(io.string, @module.write(sio, array).string)
115
+ end
116
+
117
+ def test_write__array16_min
118
+ io = StringIO.new("\xDC\x00\x10", "a+")
119
+ array = 0x0010.times.map { |i|
120
+ @module.write(io, i)
121
+ i
122
+ }
123
+ assert_equal(io.string, @module.write(sio, array).string)
124
+ end
125
+
126
+ def test_write__array16_max
127
+ io = StringIO.new("\xDC\xFF\xFF", "a+")
128
+ array = 0xFFFF.times.map { |i|
129
+ @module.write(io, i)
130
+ i
131
+ }
132
+ assert_equal(io.string, @module.write(sio, array).string)
133
+ end
134
+
135
+ def test_write__array32_min
136
+ io = StringIO.new("\xDD\x00\x01\x00\x00", "a+")
137
+ array = 0x00010000.times.map { |i|
138
+ @module.write(io, i)
139
+ i
140
+ }
141
+ assert_equal(io.string, @module.write(sio, array).string)
142
+ end
143
+
144
+ def test_write__fixmap
145
+ assert_equal("\x80", @module.write(sio, {}).string)
146
+ assert_equal(
147
+ "\x82\x00\x01\x02\x03",
148
+ @module.write(sio, {0 => 1, 2 => 3}).string)
149
+
150
+ io = StringIO.new("\x8F", "a+")
151
+ hash = 0x0F.times.inject({}) { |memo, i|
152
+ @module.write(io, i)
153
+ @module.write(io, 0)
154
+ memo[i] = 0
155
+ memo
156
+ }
157
+ assert_equal(io.string, @module.write(sio, hash).string)
158
+ end
159
+
160
+ def test_write__map16_min
161
+ io = StringIO.new("\xDE\x00\x10", "a+")
162
+ hash = 0x0010.times.inject({}) { |memo, i|
163
+ @module.write(io, i)
164
+ @module.write(io, 0)
165
+ memo[i] = 0
166
+ memo
167
+ }
168
+ assert_equal(io.string, @module.write(sio, hash).string)
169
+ end
170
+
171
+ def test_write__map16_max
172
+ io = StringIO.new("\xDE\xFF\xFF", "a+")
173
+ hash = 0xFFFF.times.inject({}) { |memo, i|
174
+ @module.write(io, i)
175
+ @module.write(io, 0)
176
+ memo[i] = 0
177
+ memo
178
+ }
179
+ assert_equal(io.string, @module.write(sio, hash).string)
180
+ end
181
+
182
+ def test_write__map32_min
183
+ io = StringIO.new("\xDF\x00\x01\x00\x00", "a+")
184
+ hash = 0x00010000.times.inject({}) { |memo, i|
185
+ @module.write(io, i)
186
+ @module.write(io, 0)
187
+ memo[i] = 0
188
+ memo
189
+ }
190
+ assert_equal(io.string, @module.write(sio, hash).string)
191
+ end
192
+
193
+ private
194
+
195
+ def sio
196
+ return StringIO.new
197
+ end
198
+ end
@@ -0,0 +1,13 @@
1
+ # coding: utf-8
2
+
3
+ $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
4
+
5
+ require "test/unit"
6
+
7
+ begin
8
+ require "rubygems"
9
+ require "redgreen"
10
+ require "win32console" if /win32/ =~ RUBY_PLATFORM
11
+ rescue LoadError
12
+ # nop
13
+ end
@@ -0,0 +1,215 @@
1
+ #! ruby -Ku
2
+ # coding: utf-8
3
+
4
+ require "test_helper"
5
+ require "stringio"
6
+ require "msgpack_pure/unpacker"
7
+
8
+ class UnpackerTest < Test::Unit::TestCase
9
+ def setup
10
+ @module = MessagePackPure::Unpacker
11
+ end
12
+
13
+ def test_read__positive_fixnum
14
+ assert_equal(+0x00, read("\x00"))
15
+ assert_equal(+0x7F, read("\x7F"))
16
+ end
17
+
18
+ def test_read__negative_fixnum
19
+ assert_equal(-0x01, read("\xFF"))
20
+ assert_equal(-0x20, read("\xE0"))
21
+ end
22
+
23
+ def test_read__uint8
24
+ assert_equal(+0x00, read("\xCC\x00"))
25
+ assert_equal(+0xFF, read("\xCC\xFF"))
26
+ end
27
+
28
+ def test_read__uint16
29
+ assert_equal(+0x0000, read("\xCD\x00\x00"))
30
+ assert_equal(+0x0001, read("\xCD\x00\x01"))
31
+ assert_equal(+0xFFFF, read("\xCD\xFF\xFF"))
32
+ end
33
+
34
+ def test_read__uint32
35
+ assert_equal(+0x00000000, read("\xCE\x00\x00\x00\x00"))
36
+ assert_equal(+0x00000001, read("\xCE\x00\x00\x00\x01"))
37
+ assert_equal(+0xFFFFFFFF, read("\xCE\xFF\xFF\xFF\xFF"))
38
+ end
39
+
40
+ def test_read__uint64
41
+ assert_equal(+0x0000000000000000, read("\xCF\x00\x00\x00\x00\x00\x00\x00\x00"))
42
+ assert_equal(+0x0000000000000001, read("\xCF\x00\x00\x00\x00\x00\x00\x00\x01"))
43
+ assert_equal(+0xFFFFFFFFFFFFFFFF, read("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"))
44
+ end
45
+
46
+ def test_read__int8
47
+ assert_equal(+0x00, read("\xD0\x00"))
48
+ assert_equal(+0x7F, read("\xD0\x7F"))
49
+ assert_equal(-0x01, read("\xD0\xFF"))
50
+ assert_equal(-0x80, read("\xD0\x80"))
51
+ end
52
+
53
+ def test_read__int16
54
+ assert_equal(+0x0000, read("\xD1\x00\x00"))
55
+ assert_equal(+0x7FFF, read("\xD1\x7F\xFF"))
56
+ assert_equal(-0x0001, read("\xD1\xFF\xFF"))
57
+ assert_equal(-0x8000, read("\xD1\x80\x00"))
58
+ end
59
+
60
+ def test_read__int32
61
+ assert_equal(+0x00000000, read("\xD2\x00\x00\x00\x00"))
62
+ assert_equal(+0x7FFFFFFF, read("\xD2\x7F\xFF\xFF\xFF"))
63
+ assert_equal(-0x00000001, read("\xD2\xFF\xFF\xFF\xFF"))
64
+ assert_equal(-0x80000000, read("\xD2\x80\x00\x00\x00"))
65
+ end
66
+
67
+ def test_read__int64
68
+ assert_equal(+0x0000000000000000, read("\xD3\x00\x00\x00\x00\x00\x00\x00\x00"))
69
+ assert_equal(+0x7FFFFFFFFFFFFFFF, read("\xD3\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF"))
70
+ assert_equal(-0x0000000000000001, read("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"))
71
+ assert_equal(-0x8000000000000000, read("\xD3\x80\x00\x00\x00\x00\x00\x00\x00"))
72
+ end
73
+
74
+ def test_read__nil
75
+ assert_equal(nil, read("\xC0"))
76
+ end
77
+
78
+ def test_read__true
79
+ assert_equal(true, read("\xC3"))
80
+ end
81
+
82
+ def test_read__false
83
+ assert_equal(false, read("\xC2"))
84
+ end
85
+
86
+ def test_read__float
87
+ assert_equal(+0.0, read("\xCA\x00\x00\x00\x00"))
88
+ assert_equal(+0.5, read("\xCA\x3F\x00\x00\x00"))
89
+ assert_equal(-0.5, read("\xCA\xBF\x00\x00\x00"))
90
+ end
91
+
92
+ def test_read__double
93
+ assert_equal(+0.0, read("\xCB\x00\x00\x00\x00\x00\x00\x00\x00"))
94
+ assert_equal(+0.5, read("\xCB\x3F\xE0\x00\x00\x00\x00\x00\x00"))
95
+ assert_equal(-0.5, read("\xCB\xBF\xE0\x00\x00\x00\x00\x00\x00"))
96
+ end
97
+
98
+ def test_read__fixraw
99
+ assert_equal("", read("\xA0"))
100
+ assert_equal("ABC", read("\xA3ABC"))
101
+ assert_equal("A" * 31, read("\xBF" + "A" * 31))
102
+ end
103
+
104
+ def test_read__raw16
105
+ assert_equal("", read("\xDA\x00\x00"))
106
+ assert_equal("ABC", read("\xDA\x00\x03ABC"))
107
+ assert_equal(
108
+ "A" * 0xFFFF,
109
+ read("\xDA\xFF\xFF" + "A" * 0xFFFF))
110
+ end
111
+
112
+ def test_read__raw32
113
+ assert_equal("", read("\xDB\x00\x00\x00\x00"))
114
+ assert_equal("ABC", read("\xDB\x00\x00\x00\x03ABC"))
115
+ assert_equal(
116
+ "A" * 0x10000,
117
+ read("\xDB\x00\x01\x00\x00" + "A" * 0x10000))
118
+ end
119
+
120
+ def test_read__fixarray
121
+ assert_equal([], read("\x90"))
122
+ assert_equal([0, 1, 2], read("\x93\x00\x01\x02"))
123
+
124
+ io = StringIO.new("\x9F", "a+")
125
+ array = 15.times.map { |i|
126
+ io.write("\xCD" + [i].pack("n")) # uint16: i
127
+ i
128
+ }
129
+ io.rewind
130
+ assert_equal(array, @module.read(io))
131
+ end
132
+
133
+ def test_read__array16
134
+ assert_equal([], read("\xDC\x00\x00"))
135
+ assert_equal([0, 1, 2], read("\xDC\x00\x03\x00\x01\x02"))
136
+
137
+ io = StringIO.new("\xDC\xFF\xFF", "a+")
138
+ array = 0xFFFF.times.map { |i|
139
+ io.write("\xCD" + [i].pack("n")) # uint16: i
140
+ i
141
+ }
142
+ io.rewind
143
+ assert_equal(array, @module.read(io))
144
+ end
145
+
146
+ def test_read__array32
147
+ assert_equal([], read("\xDD\x00\x00\x00\x00"))
148
+ assert_equal([0, 1, 2], read("\xDD\x00\x00\x00\x03\x00\x01\x02"))
149
+
150
+ io = StringIO.new("\xDD\x00\x01\x00\x00", "a+")
151
+ array = 0x10000.times.map { |i|
152
+ io.write("\xCD" + [i].pack("n")) # uint16: i
153
+ i
154
+ }
155
+ io.rewind
156
+ assert_equal(array, @module.read(io))
157
+ end
158
+
159
+ def test_read__fixmap
160
+ assert_equal({}, read("\x80"))
161
+ assert_equal(
162
+ {0 => 1, 2 => 3},
163
+ read("\x82\x00\x01\x02\x03"))
164
+
165
+ io = StringIO.new("\x8F", "a+")
166
+ hash = 15.times.inject({}) { |memo, i|
167
+ io.write("\xCD" + [i].pack("n")) # uint16: i
168
+ io.write("\x00") # fixnum: 0
169
+ memo[i] = 0
170
+ memo
171
+ }
172
+ io.rewind
173
+ assert_equal(hash, @module.read(io))
174
+ end
175
+
176
+ def test_read__map16
177
+ assert_equal({}, read("\xDE\x00\x00"))
178
+ assert_equal(
179
+ {0 => 1, 2 => 3},
180
+ read("\xDE\x00\x02\x00\x01\x02\x03"))
181
+
182
+ io = StringIO.new("\xDE\xFF\xFF", "a+")
183
+ hash = 0xFFFF.times.inject({}) { |memo, i|
184
+ io.write("\xCD" + [i].pack("n")) # uint16: i
185
+ io.write("\x00") # fixnum: 0
186
+ memo[i] = 0
187
+ memo
188
+ }
189
+ io.rewind
190
+ assert_equal(hash, @module.read(io))
191
+ end
192
+
193
+ def test_read__map32
194
+ assert_equal({}, read("\xDF\x00\x00\x00\x00"))
195
+ assert_equal(
196
+ {0 => 1, 2 => 3},
197
+ read("\xDF\x00\x00\x00\x02\x00\x01\x02\x03"))
198
+
199
+ io = StringIO.new("\xDF\x00\x01\x00\x00", "a+")
200
+ hash = 0x10000.times.inject({}) { |memo, i|
201
+ io.write("\xCD" + [i].pack("n")) # uint16: i
202
+ io.write("\x00") # fixnum: 0
203
+ memo[i] = 0
204
+ memo
205
+ }
206
+ io.rewind
207
+ assert_equal(hash, @module.read(io))
208
+ end
209
+
210
+ private
211
+
212
+ def read(binary)
213
+ return @module.read(StringIO.new(binary, "r"))
214
+ end
215
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nayutaya-msgpack-pure
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Yuya Kato
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-03-08 00:00:00 +09:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: pure ruby implementation of MessagePack
17
+ email: yuyakato@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/msgpack_pure/core.rb
26
+ - lib/msgpack_pure/packer.rb
27
+ - lib/msgpack_pure/unpacker.rb
28
+ - lib/msgpack_pure/version.rb
29
+ - lib/msgpack_pure.rb
30
+ - nayutaya-msgpack-pure.gemspec
31
+ - nayutaya-msgpack-pure.gemspec.erb
32
+ - Rakefile
33
+ - README.md
34
+ - test/core_test.rb
35
+ - test/packer_test.rb
36
+ - test/test_helper.rb
37
+ - test/unpacker_test.rb
38
+ has_rdoc: true
39
+ homepage: http://github.com/nayutaya/msgpack-pure/
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: 1.8.6
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.3.5
63
+ signing_key:
64
+ specification_version: 2
65
+ summary: MessagePack
66
+ test_files:
67
+ - test/core_test.rb
68
+ - test/packer_test.rb
69
+ - test/test_helper.rb
70
+ - test/unpacker_test.rb