packsnap 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/.gitignore +17 -0
  2. data/ChangeLog +29 -0
  3. data/README.rdoc +26 -0
  4. data/Rakefile +150 -0
  5. data/doclib/msgpack.rb +54 -0
  6. data/doclib/packsnap/buffer.rb +177 -0
  7. data/doclib/packsnap/error.rb +14 -0
  8. data/doclib/packsnap/packer.rb +131 -0
  9. data/doclib/packsnap/unpacker.rb +130 -0
  10. data/ext/packsnap/buffer.cc +684 -0
  11. data/ext/packsnap/buffer.hh +439 -0
  12. data/ext/packsnap/buffer_class.cc +490 -0
  13. data/ext/packsnap/buffer_class.hh +32 -0
  14. data/ext/packsnap/compat.h +128 -0
  15. data/ext/packsnap/extconf.rb +94 -0
  16. data/ext/packsnap/packer.cc +137 -0
  17. data/ext/packsnap/packer.h +334 -0
  18. data/ext/packsnap/packer_class.cc +288 -0
  19. data/ext/packsnap/packer_class.hh +32 -0
  20. data/ext/packsnap/packsnap.h +4 -0
  21. data/ext/packsnap/rbinit.cc +52 -0
  22. data/ext/packsnap/rmem.cc +110 -0
  23. data/ext/packsnap/rmem.h +100 -0
  24. data/ext/packsnap/sysdep.h +112 -0
  25. data/ext/packsnap/sysdep_endian.h +50 -0
  26. data/ext/packsnap/sysdep_types.h +46 -0
  27. data/ext/packsnap/unpacker.cc +654 -0
  28. data/ext/packsnap/unpacker.hh +108 -0
  29. data/ext/packsnap/unpacker_class.cc +392 -0
  30. data/ext/packsnap/unpacker_class.hh +32 -0
  31. data/lib/packsnap.rb +12 -0
  32. data/lib/packsnap/version.rb +3 -0
  33. data/packsnap.gemspec +23 -0
  34. data/spec/buffer_io_spec.rb +228 -0
  35. data/spec/buffer_spec.rb +572 -0
  36. data/spec/cases.json +1 -0
  37. data/spec/cases.msg +0 -0
  38. data/spec/cases_compact.msg +0 -0
  39. data/spec/cases_spec.rb +39 -0
  40. data/spec/format_spec.rb +225 -0
  41. data/spec/packer_spec.rb +127 -0
  42. data/spec/random_compat.rb +24 -0
  43. data/spec/spec_helper.rb +21 -0
  44. data/spec/unpacker_spec.rb +128 -0
  45. metadata +183 -0
@@ -0,0 +1 @@
1
+ [false,true,null,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,127,127,255,65535,4294967295,-32,-32,-128,-32768,-2147483648,0.0,-0.0,1.0,-1.0,"a","a","a","","","",[0],[0],[0],[],[],[],{},{},{},{"a":97},{"a":97},{"a":97},[[]],[["a"]]]
Binary file
Binary file
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+ require 'json'
3
+
4
+ describe MessagePack do
5
+ here = File.dirname(__FILE__)
6
+ CASES = File.read("#{here}/cases.msg")
7
+ CASES_JSON = File.read("#{here}/cases.json")
8
+ CASES_COMPACT = File.read("#{here}/cases_compact.msg")
9
+
10
+ it 'compare with json' do
11
+ ms = []
12
+ MessagePack::Unpacker.new.feed_each(CASES) {|m|
13
+ ms << m
14
+ }
15
+
16
+ js = JSON.load(CASES_JSON)
17
+
18
+ ms.zip(js) {|m,j|
19
+ m.should == j
20
+ }
21
+ end
22
+
23
+ it 'compare with compat' do
24
+ ms = []
25
+ MessagePack::Unpacker.new.feed_each(CASES) {|m|
26
+ ms << m
27
+ }
28
+
29
+ cs = []
30
+ MessagePack::Unpacker.new.feed_each(CASES_COMPACT) {|c|
31
+ cs << c
32
+ }
33
+
34
+ ms.zip(cs) {|m,c|
35
+ m.should == c
36
+ }
37
+ end
38
+ end
39
+
@@ -0,0 +1,225 @@
1
+ # encoding: ascii-8bit
2
+ require 'spec_helper'
3
+
4
+ describe MessagePack do
5
+ it "nil" do
6
+ check 1, nil
7
+ end
8
+
9
+ it "true" do
10
+ check 1, true
11
+ end
12
+
13
+ it "false" do
14
+ check 1, false
15
+ end
16
+
17
+ it "zero" do
18
+ check 1, 0
19
+ end
20
+
21
+ it "positive fixnum" do
22
+ check 1, 1
23
+ check 1, (1<<6)
24
+ check 1, (1<<7)-1
25
+ end
26
+
27
+ it "positive int 8" do
28
+ check 1, -1
29
+ check 2, (1<<7)
30
+ check 2, (1<<8)-1
31
+ end
32
+
33
+ it "positive int 16" do
34
+ check 3, (1<<8)
35
+ check 3, (1<<16)-1
36
+ end
37
+
38
+ it "positive int 32" do
39
+ check 5, (1<<16)
40
+ check 5, (1<<32)-1
41
+ end
42
+
43
+ it "positive int 64" do
44
+ check 9, (1<<32)
45
+ #check 9, (1<<64)-1
46
+ end
47
+
48
+ it "negative fixnum" do
49
+ check 1, -1
50
+ check 1, -((1<<5)-1)
51
+ check 1, -(1<<5)
52
+ end
53
+
54
+ it "negative int 8" do
55
+ check 2, -((1<<5)+1)
56
+ check 2, -(1<<7)
57
+ end
58
+
59
+ it "negative int 16" do
60
+ check 3, -((1<<7)+1)
61
+ check 3, -(1<<15)
62
+ end
63
+
64
+ it "negative int 32" do
65
+ check 5, -((1<<15)+1)
66
+ check 5, -(1<<31)
67
+ end
68
+
69
+ it "negative int 64" do
70
+ check 9, -((1<<31)+1)
71
+ check 9, -(1<<63)
72
+ end
73
+
74
+ it "double" do
75
+ check 9, 1.0
76
+ check 9, 0.1
77
+ check 9, -0.1
78
+ check 9, -1.0
79
+ end
80
+
81
+ it "fixraw" do
82
+ check_raw 1, 0
83
+ check_raw 1, (1<<5)-1
84
+ end
85
+
86
+ it "raw 16" do
87
+ check_raw 3, (1<<5)
88
+ check_raw 3, (1<<16)-1
89
+ end
90
+
91
+ it "raw 32" do
92
+ check_raw 5, (1<<16)
93
+ #check_raw 5, (1<<32)-1 # memory error
94
+ end
95
+
96
+ it "fixarray" do
97
+ check_array 1, 0
98
+ check_array 1, (1<<4)-1
99
+ end
100
+
101
+ it "array 16" do
102
+ check_array 3, (1<<4)
103
+ #check_array 3, (1<<16)-1
104
+ end
105
+
106
+ it "array 32" do
107
+ #check_array 5, (1<<16)
108
+ #check_array 5, (1<<32)-1 # memory error
109
+ end
110
+
111
+ it "nil" do
112
+ match nil, "\xc0"
113
+ end
114
+
115
+ it "false" do
116
+ match false, "\xc2"
117
+ end
118
+
119
+ it "true" do
120
+ match true, "\xc3"
121
+ end
122
+
123
+ it "0" do
124
+ match 0, "\x00"
125
+ end
126
+
127
+ it "127" do
128
+ match 127, "\x7f"
129
+ end
130
+
131
+ it "128" do
132
+ match 128, "\xcc\x80"
133
+ end
134
+
135
+ it "256" do
136
+ match 256, "\xcd\x01\x00"
137
+ end
138
+
139
+ it "-1" do
140
+ match -1, "\xff"
141
+ end
142
+
143
+ it "-33" do
144
+ match -33, "\xd0\xdf"
145
+ end
146
+
147
+ it "-129" do
148
+ match -129, "\xd1\xff\x7f"
149
+ end
150
+
151
+ it "{1=>1}" do
152
+ obj = {1=>1}
153
+ match obj, "\x81\x01\x01"
154
+ end
155
+
156
+ it "1.0" do
157
+ match 1.0, "\xcb\x3f\xf0\x00\x00\x00\x00\x00\x00"
158
+ end
159
+
160
+ it "[]" do
161
+ match [], "\x90"
162
+ end
163
+
164
+ it "[0, 1, ..., 14]" do
165
+ obj = (0..14).to_a
166
+ match obj, "\x9f\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e"
167
+ end
168
+
169
+ it "[0, 1, ..., 15]" do
170
+ obj = (0..15).to_a
171
+ match obj, "\xdc\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
172
+ end
173
+
174
+ it "{}" do
175
+ obj = {}
176
+ match obj, "\x80"
177
+ end
178
+
179
+ ## FIXME
180
+ # it "{0=>0, 1=>1, ..., 14=>14}" do
181
+ # a = (0..14).to_a;
182
+ # match Hash[*a.zip(a).flatten], "\x8f\x05\x05\x0b\x0b\x00\x00\x06\x06\x0c\x0c\x01\x01\x07\x07\x0d\x0d\x02\x02\x08\x08\x0e\x0e\x03\x03\x09\x09\x04\x04\x0a\x0a"
183
+ # end
184
+ #
185
+ # it "{0=>0, 1=>1, ..., 15=>15}" do
186
+ # a = (0..15).to_a;
187
+ # match Hash[*a.zip(a).flatten], "\xde\x00\x10\x05\x05\x0b\x0b\x00\x00\x06\x06\x0c\x0c\x01\x01\x07\x07\x0d\x0d\x02\x02\x08\x08\x0e\x0e\x03\x03\x09\x09\x0f\x0f\x04\x04\x0a\x0a"
188
+ # end
189
+
190
+ ## FIXME
191
+ # it "fixmap" do
192
+ # check_map 1, 0
193
+ # check_map 1, (1<<4)-1
194
+ # end
195
+ #
196
+ # it "map 16" do
197
+ # check_map 3, (1<<4)
198
+ # check_map 3, (1<<16)-1
199
+ # end
200
+ #
201
+ # it "map 32" do
202
+ # check_map 5, (1<<16)
203
+ # #check_map 5, (1<<32)-1 # memory error
204
+ # end
205
+
206
+ def check(len, obj)
207
+ raw = obj.to_msgpack.to_s
208
+ raw.length.should == len
209
+ MessagePack.unpack(raw).should == obj
210
+ end
211
+
212
+ def check_raw(overhead, num)
213
+ check num+overhead, " "*num
214
+ end
215
+
216
+ def check_array(overhead, num)
217
+ check num+overhead, Array.new(num)
218
+ end
219
+
220
+ def match(obj, buf)
221
+ raw = obj.to_msgpack.to_s
222
+ raw.should == buf
223
+ end
224
+ end
225
+
@@ -0,0 +1,127 @@
1
+ # encoding: ascii-8bit
2
+ require 'spec_helper'
3
+
4
+ require 'stringio'
5
+ if defined?(Encoding)
6
+ Encoding.default_external = 'ASCII-8BIT'
7
+ end
8
+
9
+ describe Packer do
10
+ let :packer do
11
+ Packer.new
12
+ end
13
+
14
+ it 'initialize' do
15
+ Packer.new
16
+ Packer.new(nil)
17
+ Packer.new(StringIO.new)
18
+ Packer.new({})
19
+ Packer.new(StringIO.new, {})
20
+ end
21
+
22
+ #it 'Packer' do
23
+ # Packer(packer).object_id.should == packer.object_id
24
+ # Packer(nil).class.should == Packer
25
+ # Packer('').class.should == Packer
26
+ # Packer('initbuf').to_s.should == 'initbuf'
27
+ #end
28
+
29
+ it 'write' do
30
+ packer.write([])
31
+ packer.to_s.should == "\x90"
32
+ end
33
+
34
+ it 'write_nil' do
35
+ packer.write_nil
36
+ packer.to_s.should == "\xc0"
37
+ end
38
+
39
+ it 'write_array_header 0' do
40
+ packer.write_array_header(0)
41
+ packer.to_s.should == "\x90"
42
+ end
43
+
44
+ it 'write_array_header 1' do
45
+ packer.write_array_header(1)
46
+ packer.to_s.should == "\x91"
47
+ end
48
+
49
+ it 'write_map_header 0' do
50
+ packer.write_map_header(0)
51
+ packer.to_s.should == "\x80"
52
+ end
53
+
54
+ it 'write_map_header 1' do
55
+ packer.write_map_header(1)
56
+ packer.to_s.should == "\x81"
57
+ end
58
+
59
+ it 'flush' do
60
+ io = StringIO.new
61
+ pk = Packer.new(io)
62
+ pk.write_nil
63
+ pk.flush
64
+ pk.to_s.should == ''
65
+ io.string.should == "\xc0"
66
+ end
67
+
68
+ it 'buffer' do
69
+ o1 = packer.buffer.object_id
70
+ packer.buffer << 'frsyuki'
71
+ packer.buffer.to_s.should == 'frsyuki'
72
+ packer.buffer.object_id.should == o1
73
+ end
74
+
75
+ it 'to_msgpack returns String' do
76
+ nil.to_msgpack.class.should == String
77
+ true.to_msgpack.class.should == String
78
+ false.to_msgpack.class.should == String
79
+ 1.to_msgpack.class.should == String
80
+ 1.0.to_msgpack.class.should == String
81
+ "".to_msgpack.class.should == String
82
+ Hash.new.to_msgpack.class.should == String
83
+ Array.new.to_msgpack.class.should == String
84
+ end
85
+
86
+ class CustomPack01
87
+ def to_msgpack(pk=nil)
88
+ return MessagePack.pack(self, pk) unless pk.class == MessagePack::Packer
89
+ pk.write_array_header(2)
90
+ pk.write(1)
91
+ pk.write(2)
92
+ return pk
93
+ end
94
+ end
95
+
96
+ class CustomPack02
97
+ def to_msgpack(pk=nil)
98
+ [1,2].to_msgpack(pk)
99
+ end
100
+ end
101
+
102
+ it 'calls custom to_msgpack method' do
103
+ MessagePack.pack(CustomPack01.new).should == [1,2].to_msgpack
104
+ MessagePack.pack(CustomPack02.new).should == [1,2].to_msgpack
105
+ CustomPack01.new.to_msgpack.should == [1,2].to_msgpack
106
+ CustomPack02.new.to_msgpack.should == [1,2].to_msgpack
107
+ end
108
+
109
+ it 'calls custom to_msgpack method with io' do
110
+ s01 = StringIO.new
111
+ MessagePack.pack(CustomPack01.new, s01)
112
+ s01.string.should == [1,2].to_msgpack
113
+
114
+ s02 = StringIO.new
115
+ MessagePack.pack(CustomPack02.new, s02)
116
+ s02.string.should == [1,2].to_msgpack
117
+
118
+ s03 = StringIO.new
119
+ CustomPack01.new.to_msgpack(s03)
120
+ s03.string.should == [1,2].to_msgpack
121
+
122
+ s04 = StringIO.new
123
+ CustomPack02.new.to_msgpack(s04)
124
+ s04.string.should == [1,2].to_msgpack
125
+ end
126
+ end
127
+
@@ -0,0 +1,24 @@
1
+
2
+ unless defined? Random
3
+ class Random
4
+ def initialize(seed=Time.now.to_i)
5
+ Kernel.srand(seed)
6
+ @seed = seed
7
+ end
8
+
9
+ attr_reader :seed
10
+
11
+ def rand(arg)
12
+ Kernel.rand(arg)
13
+ end
14
+
15
+ def bytes(n)
16
+ array = []
17
+ n.times do
18
+ array << rand(256)
19
+ end
20
+ array.pack('C*')
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,21 @@
1
+
2
+ if ENV['SIMPLE_COV']
3
+ require 'simplecov'
4
+ SimpleCov.start do
5
+ add_filter 'spec/'
6
+ add_filter 'pkg/'
7
+ add_filter 'vendor/'
8
+ end
9
+ end
10
+
11
+ if ENV['GC_STRESS']
12
+ puts "enable GC.stress"
13
+ GC.stress = true
14
+ end
15
+
16
+ require 'msgpack'
17
+
18
+ Packer = MessagePack::Packer
19
+ Unpacker = MessagePack::Unpacker
20
+ Buffer = MessagePack::Buffer
21
+
@@ -0,0 +1,128 @@
1
+ # encoding: ascii-8bit
2
+ require 'spec_helper'
3
+
4
+ describe Unpacker do
5
+ let :unpacker do
6
+ Unpacker.new
7
+ end
8
+
9
+ # TODO initialize
10
+
11
+ it 'read_array_header succeeds' do
12
+ unpacker.feed("\x91")
13
+ unpacker.read_array_header.should == 1
14
+ end
15
+
16
+ it 'read_array_header fails' do
17
+ unpacker.feed("\x81")
18
+ lambda {
19
+ unpacker.read_array_header
20
+ }.should raise_error(MessagePack::TypeError)
21
+ end
22
+
23
+ it 'read_map_header succeeds' do
24
+ unpacker.feed("\x81")
25
+ unpacker.read_map_header.should == 1
26
+ end
27
+
28
+ it 'read_map_header fails' do
29
+ unpacker.feed("\x91")
30
+ lambda {
31
+ unpacker.read_map_header
32
+ }.should raise_error(MessagePack::TypeError)
33
+ end
34
+
35
+ it 'skip_nil succeeds' do
36
+ unpacker.feed("\xc0")
37
+ unpacker.skip_nil.should == true
38
+ end
39
+
40
+ it 'skip_nil fails' do
41
+ unpacker.feed("\x90")
42
+ unpacker.skip_nil.should == false
43
+ end
44
+
45
+ it 'skip_nil raises EOFError' do
46
+ lambda {
47
+ unpacker.skip_nil
48
+ }.should raise_error(EOFError)
49
+ end
50
+
51
+ # TODO skip methods
52
+ # TODO feed
53
+ # TODO each
54
+ # TODO feed_each
55
+
56
+ it 'buffer' do
57
+ o1 = unpacker.buffer.object_id
58
+ unpacker.buffer << 'frsyuki'
59
+ unpacker.buffer.to_s.should == 'frsyuki'
60
+ unpacker.buffer.object_id.should == o1
61
+ end
62
+
63
+ it 'raises level stack too deep error' do
64
+ packer = Packer.new
65
+ 512.times do
66
+ packer.write_array_header(1)
67
+ end
68
+ packer.write(nil)
69
+
70
+ unpacker = Unpacker.new(packer.buffer)
71
+ lambda {
72
+ unpacker.read
73
+ }.should raise_error(MessagePack::StackError)
74
+ end
75
+
76
+ it 'raises invalid byte error' do
77
+ unpacker.feed("\xc6")
78
+ lambda {
79
+ unpacker.read
80
+ }.should raise_error(MessagePack::MalformedFormatError)
81
+ end
82
+
83
+ it "gc mark" do
84
+ obj = [1024, {["a","b"]=>["c","d"]}, ["e","f"], "d", 70000, 4.12, 1.5, 1.5, 1.5]
85
+ raw = obj.to_msgpack.to_s * 4
86
+
87
+ n = 0
88
+ raw.split(//).each do |b|
89
+ GC.start
90
+ unpacker.feed_each(b) {|o|
91
+ GC.start
92
+ o.should == obj
93
+ n += 1
94
+ }
95
+ GC.start
96
+ end
97
+
98
+ n.should == 4
99
+ end
100
+
101
+ it "buffer" do
102
+ orig = "a"*32*1024*4
103
+ raw = orig.to_msgpack.to_s
104
+
105
+ n = 655
106
+ times = raw.size / n
107
+ times += 1 unless raw.size % n == 0
108
+
109
+ off = 0
110
+ parsed = false
111
+
112
+ times.times do
113
+ parsed.should == false
114
+
115
+ seg = raw[off, n]
116
+ off += seg.length
117
+
118
+ unpacker.feed_each(seg) {|obj|
119
+ parsed.should == false
120
+ obj.should == orig
121
+ parsed = true
122
+ }
123
+ end
124
+
125
+ parsed.should == true
126
+ end
127
+ end
128
+