msgpack 0.4.7 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/.gitignore +17 -0
  2. data/ChangeLog +47 -0
  3. data/README.rdoc +102 -0
  4. data/Rakefile +88 -0
  5. data/doclib/msgpack.rb +55 -0
  6. data/doclib/msgpack/buffer.rb +193 -0
  7. data/doclib/msgpack/core_ext.rb +101 -0
  8. data/doclib/msgpack/error.rb +14 -0
  9. data/doclib/msgpack/packer.rb +131 -0
  10. data/doclib/msgpack/unpacker.rb +130 -0
  11. data/ext/msgpack/buffer.c +679 -0
  12. data/ext/msgpack/buffer.h +442 -0
  13. data/ext/msgpack/buffer_class.c +507 -0
  14. data/ext/msgpack/buffer_class.h +32 -0
  15. data/ext/msgpack/compat.h +112 -0
  16. data/ext/msgpack/core_ext.c +129 -0
  17. data/ext/{pack.h → msgpack/core_ext.h} +7 -7
  18. data/ext/msgpack/extconf.rb +17 -0
  19. data/ext/msgpack/packer.c +137 -0
  20. data/ext/msgpack/packer.h +319 -0
  21. data/ext/msgpack/packer_class.c +285 -0
  22. data/ext/{unpack.h → msgpack/packer_class.h} +11 -7
  23. data/ext/msgpack/rbinit.c +33 -0
  24. data/ext/msgpack/rmem.c +110 -0
  25. data/ext/msgpack/rmem.h +100 -0
  26. data/ext/msgpack/sysdep.h +115 -0
  27. data/ext/msgpack/sysdep_endian.h +50 -0
  28. data/ext/msgpack/sysdep_types.h +46 -0
  29. data/ext/msgpack/unpacker.c +669 -0
  30. data/ext/msgpack/unpacker.h +112 -0
  31. data/ext/msgpack/unpacker_class.c +376 -0
  32. data/{msgpack/pack_define.h → ext/msgpack/unpacker_class.h} +12 -8
  33. data/lib/msgpack.rb +10 -0
  34. data/{ext → lib/msgpack}/version.rb +1 -1
  35. data/msgpack.gemspec +25 -0
  36. data/spec/buffer_io_spec.rb +237 -0
  37. data/spec/buffer_spec.rb +572 -0
  38. data/{test → spec}/cases.json +0 -0
  39. data/{test/cases.mpac → spec/cases.msg} +0 -0
  40. data/{test/cases_compact.mpac → spec/cases_compact.msg} +0 -0
  41. data/spec/cases_spec.rb +39 -0
  42. data/spec/format_spec.rb +225 -0
  43. data/spec/packer_spec.rb +127 -0
  44. data/spec/random_compat.rb +24 -0
  45. data/spec/spec_helper.rb +21 -0
  46. data/spec/unpacker_spec.rb +128 -0
  47. metadata +171 -34
  48. data/ext/compat.h +0 -99
  49. data/ext/extconf.rb +0 -7
  50. data/ext/pack.c +0 -314
  51. data/ext/rbinit.c +0 -66
  52. data/ext/unpack.c +0 -1001
  53. data/msgpack/pack_template.h +0 -771
  54. data/msgpack/sysdep.h +0 -195
  55. data/msgpack/unpack_define.h +0 -93
  56. data/msgpack/unpack_template.h +0 -413
  57. data/test/test_cases.rb +0 -46
  58. data/test/test_encoding.rb +0 -68
  59. data/test/test_helper.rb +0 -10
  60. data/test/test_pack_unpack.rb +0 -308
@@ -1,7 +1,7 @@
1
1
  /*
2
- * MessagePack unpacking routine template
2
+ * MessagePack for Ruby
3
3
  *
4
- * Copyright (C) 2008-2010 FURUHASHI Sadayuki
4
+ * Copyright (C) 2008-2012 FURUHASHI Sadayuki
5
5
  *
6
6
  * Licensed under the Apache License, Version 2.0 (the "License");
7
7
  * you may not use this file except in compliance with the License.
@@ -15,12 +15,16 @@
15
15
  * See the License for the specific language governing permissions and
16
16
  * limitations under the License.
17
17
  */
18
- #ifndef MSGPACK_PACK_DEFINE_H__
19
- #define MSGPACK_PACK_DEFINE_H__
18
+ #ifndef MSGPACK_RUBY_UNPACKER_CLASS_H__
19
+ #define MSGPACK_RUBY_UNPACKER_CLASS_H__
20
20
 
21
- #include "msgpack/sysdep.h"
22
- #include <limits.h>
23
- #include <string.h>
21
+ #include "unpacker.h"
24
22
 
25
- #endif /* msgpack/pack_define.h */
23
+ extern VALUE cMessagePack_Unpacker;
24
+
25
+ void MessagePack_Unpacker_module_init(VALUE mMessagePack);
26
+
27
+ VALUE MessagePack_unpack(int argc, VALUE* argv);
28
+
29
+ #endif
26
30
 
@@ -0,0 +1,10 @@
1
+ here = File.expand_path(File.dirname(__FILE__))
2
+ require File.join(here, 'msgpack', 'version')
3
+ begin
4
+ m = /(\d+.\d+)/.match(RUBY_VERSION)
5
+ ver = m[1]
6
+ ver = '1.9' if ver == '2.0'
7
+ require File.join(here, 'msgpack', ver, 'msgpack')
8
+ rescue LoadError
9
+ require File.join(here, 'msgpack', 'msgpack')
10
+ end
@@ -1,3 +1,3 @@
1
1
  module MessagePack
2
- VERSION = "0.4.7"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -0,0 +1,25 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require 'msgpack/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "msgpack"
6
+ s.version = MessagePack::VERSION
7
+ s.summary = "MessagePack, a binary-based efficient data interchange format."
8
+ s.description = %q{MessagePack is a binary-based efficient object serialization library. It enables to exchange structured objects between many languages like JSON. But unlike JSON, it is very fast and small.}
9
+ s.author = "FURUHASHI Sadayuki"
10
+ s.email = "frsyuki@gmail.com"
11
+ s.homepage = "http://msgpack.org/"
12
+ s.rubyforge_project = "msgpack"
13
+ s.has_rdoc = false
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec}/*`.split("\n")
16
+ s.require_paths = ["lib"]
17
+ s.extensions = ["ext/msgpack/extconf.rb"]
18
+
19
+ s.add_development_dependency 'bundler', ['~> 1.0']
20
+ s.add_development_dependency 'rake', ['~> 0.9.2']
21
+ s.add_development_dependency 'rake-compiler', ['~> 0.8.1']
22
+ s.add_development_dependency 'rspec', ['~> 2.11']
23
+ s.add_development_dependency 'json', ['~> 1.7']
24
+ s.add_development_dependency 'yard', ['~> 0.8.2']
25
+ end
@@ -0,0 +1,237 @@
1
+ require 'spec_helper'
2
+ require 'random_compat'
3
+
4
+ require 'stringio'
5
+ if defined?(Encoding)
6
+ Encoding.default_external = 'ASCII-8BIT'
7
+ end
8
+
9
+ describe Buffer do
10
+ r = Random.new
11
+ random_seed = r.seed
12
+ puts "buffer_io random seed: 0x#{random_seed.to_s(16)}"
13
+
14
+ let :source do
15
+ ''
16
+ end
17
+
18
+ def set_source(s)
19
+ source.replace(s)
20
+ end
21
+
22
+ let :io do
23
+ StringIO.new(source.dup)
24
+ end
25
+
26
+ let :buffer do
27
+ Buffer.new(io)
28
+ end
29
+
30
+ it 'io returns internal io' do
31
+ buffer.io.should == io
32
+ end
33
+
34
+ it 'close closes internal io' do
35
+ io.should_receive(:close)
36
+ buffer.close
37
+ end
38
+
39
+ it 'short feed and read all' do
40
+ set_source 'aa'
41
+ buffer.read.should == 'aa'
42
+ end
43
+
44
+ it 'short feed and read short' do
45
+ set_source 'aa'
46
+ buffer.read(1).should == 'a'
47
+ buffer.read(1).should == 'a'
48
+ buffer.read(1).should == nil
49
+ end
50
+
51
+ it 'long feed and read all' do
52
+ set_source ' '*(1024*1024)
53
+ s = buffer.read
54
+ s.size.should == source.size
55
+ s.should == source
56
+ end
57
+
58
+ it 'long feed and read mixed' do
59
+ set_source ' '*(1024*1024)
60
+ buffer.read(10).should == source.slice!(0, 10)
61
+ buffer.read(10).should == source.slice!(0, 10)
62
+ buffer.read(10).should == source.slice!(0, 10)
63
+ s = buffer.read
64
+ s.size.should == source.size
65
+ s.should == source
66
+ end
67
+
68
+ it 'eof' do
69
+ set_source ''
70
+ buffer.read.should == ''
71
+ end
72
+
73
+ it 'eof 2' do
74
+ set_source 'a'
75
+ buffer.read.should == 'a'
76
+ buffer.read.should == ''
77
+ end
78
+
79
+ it 'write short once and flush' do
80
+ buffer.write('aa')
81
+ buffer.flush
82
+ io.string.should == 'aa'
83
+ end
84
+
85
+ it 'write short twice and flush' do
86
+ buffer.write('a')
87
+ buffer.write('a')
88
+ buffer.flush
89
+ io.string.should == 'aa'
90
+ end
91
+
92
+ it 'write long once and flush' do
93
+ s = ' '*(1024*1024)
94
+ buffer.write s
95
+ buffer.flush
96
+ io.string.size.should == s.size
97
+ io.string.should == s
98
+ end
99
+
100
+ it 'write short multi and flush' do
101
+ s = ' '*(1024*1024)
102
+ 1024.times {
103
+ buffer.write ' '*1024
104
+ }
105
+ buffer.flush
106
+ io.string.size.should == s.size
107
+ io.string.should == s
108
+ end
109
+
110
+ it 'random read' do
111
+ r = Random.new(random_seed)
112
+
113
+ 50.times {
114
+ fragments = []
115
+
116
+ r.rand(4).times do
117
+ n = r.rand(1024*1400)
118
+ s = r.bytes(n)
119
+ fragments << s
120
+ end
121
+
122
+ io = StringIO.new(fragments.join)
123
+ b = Buffer.new(io)
124
+
125
+ fragments.each {|s|
126
+ x = b.read(s.size)
127
+ x.size.should == s.size
128
+ x.should == s
129
+ }
130
+ b.empty?.should == true
131
+ b.read.should == ''
132
+ }
133
+ end
134
+
135
+ it 'random read_all' do
136
+ r = Random.new(random_seed)
137
+
138
+ 50.times {
139
+ fragments = []
140
+ sx = r.bytes(0)
141
+
142
+ r.rand(4).times do
143
+ n = r.rand(1024*1400)
144
+ s = r.bytes(n)
145
+ fragments << s
146
+ end
147
+
148
+ io = StringIO.new(fragments.join)
149
+ b = Buffer.new(io)
150
+
151
+ fragments.each {|s|
152
+ x = b.read_all(s.size)
153
+ x.size.should == s.size
154
+ x.should == s
155
+ }
156
+ b.empty?.should == true
157
+ lambda {
158
+ b.read_all(1)
159
+ }.should raise_error(EOFError)
160
+ }
161
+ end
162
+
163
+ it 'random skip' do
164
+ r = Random.new(random_seed)
165
+
166
+ 50.times {
167
+ fragments = []
168
+
169
+ r.rand(4).times do
170
+ n = r.rand(1024*1400)
171
+ s = r.bytes(n)
172
+ fragments << s
173
+ end
174
+
175
+ io = StringIO.new(fragments.join)
176
+ b = Buffer.new(io)
177
+
178
+ fragments.each {|s|
179
+ b.skip(s.size).should == s.size
180
+ }
181
+ b.empty?.should == true
182
+ b.skip(1).should == 0
183
+ }
184
+ end
185
+
186
+ it 'random skip_all' do
187
+ r = Random.new(random_seed)
188
+
189
+ 50.times {
190
+ fragments = []
191
+
192
+ r.rand(4).times do
193
+ n = r.rand(1024*1400)
194
+ s = r.bytes(n)
195
+ fragments << s
196
+ end
197
+
198
+ io = StringIO.new(fragments.join)
199
+ b = Buffer.new(io)
200
+
201
+ fragments.each {|s|
202
+ lambda {
203
+ b.skip_all(s.size)
204
+ }.should_not raise_error(EOFError)
205
+ }
206
+ b.empty?.should == true
207
+ lambda {
208
+ b.skip_all(1)
209
+ }.should raise_error(EOFError)
210
+ }
211
+ end
212
+
213
+ it 'random write' do
214
+ r = Random.new(random_seed)
215
+
216
+ 50.times {
217
+ s = r.bytes(0)
218
+ io = StringIO.new
219
+ b = Buffer.new(io)
220
+
221
+ r.rand(4).times do
222
+ n = r.rand(1024*1400)
223
+ x = r.bytes(n)
224
+ s << x
225
+ b.write(x)
226
+ end
227
+
228
+ (io.string.size + b.size).should == s.size
229
+
230
+ b.flush
231
+
232
+ io.string.size.should == s.size
233
+ io.string.should == s
234
+ }
235
+ end
236
+ end
237
+
@@ -0,0 +1,572 @@
1
+ require 'spec_helper'
2
+ require 'random_compat'
3
+
4
+ describe Buffer do
5
+ STATIC_EXAMPLES = {}
6
+ STATIC_EXAMPLES[:empty01] = ''
7
+ STATIC_EXAMPLES[:empty02] = ''
8
+ STATIC_EXAMPLES[:copy01] = 'short'
9
+ STATIC_EXAMPLES[:copy02] = 'short'*2
10
+ STATIC_EXAMPLES[:ref01] = 'short'*128
11
+ STATIC_EXAMPLES[:ref02] = 'short'*128*2
12
+ STATIC_EXAMPLES[:ref03] = 'a'*((1024*1024+2)*2)
13
+ STATIC_EXAMPLES[:refcopy01] = 'short'*128
14
+ STATIC_EXAMPLES[:expand01] = 'short'*1024
15
+ STATIC_EXAMPLES[:expand02] = 'short'*(127+1024)
16
+ STATIC_EXAMPLES[:offset01] = 'ort'+'short'
17
+ STATIC_EXAMPLES[:offset02] = 'ort'+'short'*127
18
+ STATIC_EXAMPLES[:offset03] = 'ort'+'short'*(126+1024)
19
+
20
+ if ''.respond_to?(:force_encoding)
21
+ STATIC_EXAMPLES.each_value {|v| v.force_encoding('ASCII-8BIT') }
22
+ end
23
+ STATIC_EXAMPLES.each_value {|v| v.freeze }
24
+
25
+ r = Random.new
26
+ random_seed = r.seed
27
+ puts "buffer random seed: 0x#{random_seed.to_s(16)}"
28
+
29
+ let :random_cases_examples do
30
+ r = Random.new(random_seed)
31
+ cases = {}
32
+ examples = {}
33
+
34
+ 10.times do |i|
35
+ b = Buffer.new
36
+ s = r.bytes(0)
37
+ r.rand(3).times do
38
+ n = r.rand(1024*1400)
39
+ x = r.bytes(n)
40
+ s << x
41
+ b << x
42
+ end
43
+ r.rand(2).times do
44
+ n = r.rand(1024*1400)
45
+ b.read(n)
46
+ s.slice!(0, n)
47
+ end
48
+ key = :"random#{"%02d"%i}"
49
+ cases[key] = b
50
+ examples[key] = s
51
+ end
52
+
53
+ [cases, examples]
54
+ end
55
+
56
+ let :static_cases do
57
+ map = {}
58
+ map[:empty01] = empty01
59
+ map[:empty02] = empty02
60
+ map[:copy01] = copy01
61
+ map[:copy02] = copy02
62
+ map[:ref01] = ref01
63
+ map[:ref02] = ref02
64
+ map[:ref03] = ref03
65
+ map[:refcopy01] = refcopy01
66
+ map[:expand01] = expand01
67
+ map[:expand02] = expand02
68
+ map[:offset01] = offset01
69
+ map[:offset02] = offset02
70
+ map[:offset03] = offset03
71
+ map
72
+ end
73
+
74
+ let :static_examples do
75
+ STATIC_EXAMPLES
76
+ end
77
+
78
+ let :random_cases do
79
+ random_cases_examples[0]
80
+ end
81
+
82
+ let :random_examples do
83
+ random_cases_examples[1]
84
+ end
85
+
86
+ let :cases do
87
+ static_cases.merge(random_cases)
88
+ end
89
+
90
+ let :examples do
91
+ static_examples.merge(random_examples)
92
+ end
93
+
94
+ let :case_keys do
95
+ examples.keys
96
+ end
97
+
98
+ let :empty01 do
99
+ Buffer.new
100
+ end
101
+
102
+ let :empty02 do
103
+ b = Buffer.new
104
+ b << 'a'
105
+ b.read_all(1)
106
+ b
107
+ end
108
+
109
+ let :copy01 do
110
+ # one copy chunk
111
+ b = Buffer.new
112
+ b << 'short'
113
+ b
114
+ end
115
+
116
+ let :copy02 do
117
+ # one copy chunk
118
+ b = Buffer.new
119
+ b << 'short'
120
+ b << 'short'
121
+ b
122
+ end
123
+
124
+ let :expand02 do
125
+ # one copy chunk / expanded
126
+ b = Buffer.new
127
+ 1024.times do
128
+ b << 'short'
129
+ end
130
+ b
131
+ end
132
+
133
+ let :ref01 do
134
+ # one reference chunk
135
+ b = Buffer.new
136
+ b << 'short'*128
137
+ b.to_s
138
+ b
139
+ end
140
+
141
+ let :ref02 do
142
+ # two reference chunks
143
+ b = Buffer.new
144
+ b << 'short'*128
145
+ b.to_s
146
+ b << 'short'*128
147
+ b.to_a
148
+ b
149
+ end
150
+
151
+ let :ref03 do
152
+ # two reference chunks
153
+ b = Buffer.new
154
+ b << 'a'*(1024*1024+2)
155
+ b << 'a'*(1024*1024+2)
156
+ b
157
+ end
158
+
159
+ let :refcopy01 do
160
+ # one reference chunk + one copy chunk
161
+ b = Buffer.new
162
+ b << 'short'*127
163
+ b.to_s
164
+ b << 'short'
165
+ b
166
+ end
167
+
168
+ let :expand01 do
169
+ # one copy chunk / expanded
170
+ b = Buffer.new
171
+ 1024.times do
172
+ b << 'short'
173
+ end
174
+ b
175
+ end
176
+
177
+ let :expand02 do
178
+ # one reference chunk + one copy chunk / expanded
179
+ b = Buffer.new
180
+ b << 'short'*127
181
+ b.to_s
182
+ 1024.times do
183
+ b << 'short'
184
+ end
185
+ b
186
+ end
187
+
188
+ let :offset01 do
189
+ # one copy chunk / offset
190
+ b = Buffer.new
191
+ b << 'short'
192
+ b << 'short'
193
+ b.skip(2)
194
+ b
195
+ end
196
+
197
+ let :offset02 do
198
+ # one reference chunk / offset
199
+ b = Buffer.new
200
+ b << 'short'*127
201
+ b.to_s
202
+ b.skip(2)
203
+ b << 'short'
204
+ b
205
+ end
206
+
207
+ let :offset03 do
208
+ # one reference chunk / offset + one copy chunk / expanded
209
+ b = Buffer.new
210
+ b << 'short'*127
211
+ b.to_s
212
+ 1024.times do
213
+ b << 'short'
214
+ end
215
+ b.skip(2)
216
+ b
217
+ end
218
+
219
+ it 'empty?' do
220
+ empty01.empty?.should == true
221
+ empty02.empty?.should == true
222
+ end
223
+
224
+ it 'size' do
225
+ case_keys.each {|k|
226
+ cases[k].size.should == examples[k].size
227
+ }
228
+ end
229
+
230
+ it 'short write increments size' do
231
+ case_keys.each {|k|
232
+ sz = examples[k].size
233
+ 10.times do |i|
234
+ cases[k].write 'short'
235
+ sz += 'short'.size
236
+ cases[k].size.should == sz
237
+ end
238
+ }
239
+ end
240
+
241
+ it 'read with limit decrements size' do
242
+ case_keys.each {|k|
243
+ sz = examples[k].size
244
+ next if sz < 2
245
+
246
+ cases[k].read(1).should == examples[k][0,1]
247
+ sz -= 1
248
+ cases[k].size.should == sz
249
+
250
+ cases[k].read(1).should == examples[k][1,1]
251
+ sz -= 1
252
+ cases[k].size.should == sz
253
+ }
254
+ end
255
+
256
+ it 'read_all with limit decrements size' do
257
+ case_keys.each {|k|
258
+ sz = examples[k].size
259
+ next if sz < 2
260
+
261
+ cases[k].read_all(1).should == examples[k][0,1]
262
+ sz -= 1
263
+ cases[k].size.should == sz
264
+
265
+ cases[k].read_all(1).should == examples[k][1,1]
266
+ sz -= 1
267
+ cases[k].size.should == sz
268
+ }
269
+ end
270
+
271
+ it 'skip decrements size' do
272
+ case_keys.each {|k|
273
+ sz = examples[k].size
274
+ next if sz < 2
275
+
276
+ cases[k].skip(1).should == 1
277
+ sz -= 1
278
+ cases[k].size.should == sz
279
+
280
+ cases[k].skip(1).should == 1
281
+ sz -= 1
282
+ cases[k].size.should == sz
283
+ }
284
+ end
285
+
286
+ it 'skip_all decrements size' do
287
+ case_keys.each {|k|
288
+ sz = examples[k].size
289
+ next if sz < 2
290
+
291
+ cases[k].skip_all(1)
292
+ sz -= 1
293
+ cases[k].size.should == sz
294
+
295
+ cases[k].skip_all(1)
296
+ sz -= 1
297
+ cases[k].size.should == sz
298
+ }
299
+ end
300
+
301
+ it 'read_all against insufficient buffer raises EOFError and consumes nothing' do
302
+ case_keys.each {|k|
303
+ sz = examples[k].size
304
+ lambda {
305
+ cases[k].read_all(sz+1)
306
+ }.should raise_error(EOFError)
307
+ cases[k].size.should == sz
308
+ }
309
+ end
310
+
311
+ it 'skip_all against insufficient buffer raises EOFError and consumes nothing' do
312
+ case_keys.each {|k|
313
+ sz = examples[k].size
314
+ lambda {
315
+ cases[k].skip_all(sz+1)
316
+ }.should raise_error(EOFError)
317
+ cases[k].size.should == sz
318
+ }
319
+ end
320
+
321
+ it 'read against insufficient buffer consumes all buffer or return nil' do
322
+ case_keys.each {|k|
323
+ sz = examples[k].size
324
+ if sz == 0
325
+ cases[k].read(sz+1).should == nil
326
+ else
327
+ cases[k].read(sz+1).should == examples[k]
328
+ end
329
+ cases[k].size.should == 0
330
+ }
331
+ end
332
+
333
+ it 'skip against insufficient buffer consumes all buffer' do
334
+ case_keys.each {|k|
335
+ sz = examples[k].size
336
+ cases[k].skip(sz+1).should == examples[k].size
337
+ cases[k].size.should == 0
338
+ }
339
+ end
340
+
341
+ it 'read with no arguments consumes all buffer and returns string and do not return nil' do
342
+ case_keys.each {|k|
343
+ cases[k].read_all.should == examples[k]
344
+ cases[k].size.should == 0
345
+ }
346
+ end
347
+
348
+ it 'read_all with no arguments consumes all buffer and returns string' do
349
+ case_keys.each {|k|
350
+ cases[k].read_all.should == examples[k]
351
+ cases[k].size.should == 0
352
+ }
353
+ end
354
+
355
+ it 'to_s returns a string and consume nothing' do
356
+ case_keys.each {|k|
357
+ cases[k].to_s.should == examples[k]
358
+ cases[k].size.should == examples[k].size
359
+ }
360
+ end
361
+
362
+ it 'to_s and modify' do
363
+ case_keys.each {|k|
364
+ s = cases[k].to_s
365
+ s << 'x'
366
+ cases[k].to_s.should == examples[k]
367
+ }
368
+ end
369
+
370
+ it 'big write and modify reference' do
371
+ big2 = "a" * (1024*1024 + 2)
372
+
373
+ case_keys.each {|k|
374
+ big1 = "a" * (1024*1024 + 2)
375
+ cases[k].write(big1)
376
+ big1 << 'x'
377
+ cases[k].read.should == examples[k] + big2
378
+ }
379
+ end
380
+
381
+ it 'big write -> short write' do
382
+ biglen = 1024*1024 + 2
383
+ big1 = "a" * (1024*1024 + 2)
384
+
385
+ case_keys.each {|k|
386
+ sz = examples[k].size
387
+
388
+ cases[k].write big1
389
+ cases[k].size.should == sz + big1.size
390
+
391
+ cases[k].write("c")
392
+ cases[k].size.should == sz + big1.size + 1
393
+
394
+ cases[k].read_all.should == examples[k] + big1 + "c"
395
+ cases[k].size.should == 0
396
+ cases[k].empty?.should == true
397
+ }
398
+ end
399
+
400
+ it 'big write 2'do
401
+ big1 = "a" * (1024*1024 + 2)
402
+ big2 = "b" * (1024*1024 + 2)
403
+
404
+ case_keys.each {|k|
405
+ sz = examples[k].size
406
+
407
+ cases[k].write big1
408
+ cases[k].write big2
409
+ cases[k].size.should == sz + big1.size + big2.size
410
+
411
+ cases[k].read_all(sz + big1.size).should == examples[k] + big1
412
+ cases[k].size.should == big2.size
413
+
414
+ cases[k].read.should == big2
415
+ cases[k].size.should == 0
416
+ cases[k].empty?.should == true
417
+ }
418
+ end
419
+
420
+ it 'read 0' do
421
+ case_keys.each {|k|
422
+ cases[k].read(0).should == ''
423
+ cases[k].read.should == examples[k]
424
+ }
425
+ end
426
+
427
+ it 'skip 0' do
428
+ case_keys.each {|k|
429
+ cases[k].skip(0).should == 0
430
+ cases[k].read.should == examples[k]
431
+ }
432
+ end
433
+
434
+ it 'read_all 0' do
435
+ case_keys.each {|k|
436
+ cases[k].read_all(0).should == ''
437
+ cases[k].read_all.should == examples[k]
438
+ }
439
+ end
440
+
441
+ it 'skip_all 0' do
442
+ case_keys.each {|k|
443
+ cases[k].skip_all(0)
444
+ cases[k].read_all.should == examples[k]
445
+ }
446
+ end
447
+
448
+ it 'write_to' do
449
+ case_keys.each {|k|
450
+ sio = StringIO.new
451
+ cases[k].write_to(sio).should == examples[k].size
452
+ cases[k].size.should == 0
453
+ sio.string.should == examples[k]
454
+ }
455
+ end
456
+
457
+ it 'random read/write' do
458
+ r = Random.new(random_seed)
459
+ s = r.bytes(0)
460
+ b = Buffer.new
461
+
462
+ 10.times {
463
+ # write
464
+ r.rand(4).times do
465
+ n = r.rand(1024*1400)
466
+ x = r.bytes(n)
467
+ s << x
468
+ b.write(x)
469
+ end
470
+
471
+ # read
472
+ r.rand(3).times do
473
+ n = r.rand(1024*1400)
474
+ ex = s.slice!(0, n)
475
+ ex = nil if ex.empty?
476
+ x = b.read(n)
477
+ x.size == ex.size if x != nil
478
+ x.should == ex
479
+ b.size.should == s.size
480
+ end
481
+ }
482
+ end
483
+
484
+ it 'random read_all/write' do
485
+ r = Random.new(random_seed)
486
+ s = r.bytes(0)
487
+ b = Buffer.new
488
+
489
+ 10.times {
490
+ # write
491
+ r.rand(4).times do
492
+ n = r.rand(1024*1400)
493
+ x = r.bytes(n)
494
+ s << x
495
+ b.write(x)
496
+ end
497
+
498
+ # read_all
499
+ r.rand(3).times do
500
+ n = r.rand(1024*1400)
501
+ begin
502
+ x = b.read_all(n)
503
+ ex = s.slice!(0, n)
504
+ x.size == n
505
+ x.should == ex
506
+ b.size.should == s.size
507
+ rescue EOFError
508
+ b.size.should == s.size
509
+ b.read.should == s
510
+ s.clear
511
+ break
512
+ end
513
+ end
514
+ }
515
+ end
516
+
517
+ it 'random skip write' do
518
+ r = Random.new(random_seed)
519
+ s = r.bytes(0)
520
+ b = Buffer.new
521
+
522
+ 10.times {
523
+ # write
524
+ r.rand(4).times do
525
+ n = r.rand(1024*1400)
526
+ x = r.bytes(n)
527
+ s << x
528
+ b.write(x)
529
+ end
530
+
531
+ # skip
532
+ r.rand(3).times do
533
+ n = r.rand(1024*1400)
534
+ ex = s.slice!(0, n)
535
+ b.skip(n).should == ex.size
536
+ b.size.should == s.size
537
+ end
538
+ }
539
+ end
540
+
541
+ it 'random skip_all write' do
542
+ r = Random.new(random_seed)
543
+ s = r.bytes(0)
544
+ b = Buffer.new
545
+
546
+ 10.times {
547
+ # write
548
+ r.rand(4).times do
549
+ n = r.rand(1024*1400)
550
+ x = r.bytes(n)
551
+ s << x
552
+ b.write(x)
553
+ end
554
+
555
+ # skip_all
556
+ r.rand(3).times do
557
+ n = r.rand(1024*1400)
558
+ begin
559
+ b.skip_all(n)
560
+ ex = s.slice!(0, n)
561
+ b.size.should == s.size
562
+ ensure EOFError
563
+ b.size.should == s.size
564
+ b.read.should == s
565
+ s.clear
566
+ break
567
+ end
568
+ end
569
+ }
570
+ end
571
+ end
572
+