nayutaya-msgpack-pure 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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