qio 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.
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ coverage/*
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.3@qio --create
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in qio.gemspec
4
+ gemspec
@@ -0,0 +1,12 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'bundler/setup'
4
+ Bundler.require(:default)
5
+
6
+ Dir['tasks/*.rake'].sort.each { |task| load task }
7
+
8
+ # Add rake tasks from selected gems
9
+ gem_names = []
10
+ gem_names.each do |gem_name|
11
+ Dir[File.join(Gem.searcher.find(gem_name).full_gem_path, '**', '*.rake')].each{|rake_file| load rake_file }
12
+ end
@@ -0,0 +1,4 @@
1
+ require "thread"
2
+ require "qio/version"
3
+ require "qio/base_io"
4
+ require "qio/queued_input_io"
@@ -0,0 +1,605 @@
1
+ require 'thread'
2
+
3
+ module QIO
4
+
5
+ # Classes that want to mimic IO can acqire much of its functionality simply
6
+ # by including this module and over-riding the following methods:
7
+ #
8
+ # close
9
+ # closed?
10
+ # eof?
11
+ # sysread(maxlen, outbuf=nil)
12
+ # sysseek(offset, whence=IO::SEEK_SET)
13
+ # syswrite(string)
14
+ #
15
+ # The following methds are not provided. If you know what you're doing, and
16
+ # you know that you're going to need it, you may also over-ride:
17
+ #
18
+ # autoclose=(bool)
19
+ # autoclose?
20
+ # close_on_exec=(bool)
21
+ # close_on_exec?
22
+ # close_read
23
+ # close_write
24
+ # fcntl(integer_cmd, arg)
25
+ # fileno
26
+ # flush
27
+ # fsync
28
+ # ioctl(integer_cmd, arg)
29
+ # pid
30
+ # reopen(other_io_or_path, mode_str=nil)
31
+ # stat
32
+ # sync
33
+ # sync=(bool)
34
+ # ungetbyte(string_or_integer)
35
+ # ungetc(string)
36
+ #
37
+ # You get all the following for free, but if that's not good enough for you,
38
+ # and you're sure you can do better, you may over-ride:
39
+ #
40
+ # <<(obj)
41
+ # advise(advice, offset=0, len=0)
42
+ # binmode #TODO!
43
+ # binmode? #TODO!
44
+ # bytes
45
+ # chars
46
+ # codepoints
47
+ # each
48
+ # each_byte
49
+ # each_char
50
+ # each_codepoint
51
+ # each_line
52
+ # eof
53
+ # external_encoding #TODO!
54
+ # fdatasync
55
+ # getbyte
56
+ # getc #TODO!
57
+ # gets(sep=$/, limit=nil)
58
+ # internal_encoding #TODO!
59
+ # isatty
60
+ # lineno
61
+ # lineno=(lineno)
62
+ # lines(sep=$/, limit=nil)
63
+ # pos
64
+ # pos=(pos)
65
+ # print(*args)
66
+ # printf(format_string, *args)
67
+ # putc(obj)
68
+ # puts(*args)
69
+ # read(length=nil, buffer=nil)
70
+ # read_nonblock(maxlen, outbuf=nil)
71
+ # readbyte
72
+ # reachar
73
+ # readline(sep=$/, limit=nil)
74
+ # readlines(sep=$/, limit=nil)
75
+ # readpartial(maxlen, outbuf=nil)
76
+ # rewind
77
+ # seek(amount, whence=IO::SEEK_SET)
78
+ # set_encoding(ext_enc, int_enc=nil, opt=nil) #TODO!
79
+ # tell
80
+ # to_i # if you defined fileno
81
+ # tty?
82
+ # write(string)
83
+ # write_nonblock(string)
84
+ #
85
+ module BaseIO
86
+
87
+ # Implementation relies on: write
88
+ def <<(obj)
89
+ write(obj.to_s)
90
+ self
91
+ end
92
+
93
+ # No-op
94
+ def advise(advice, offset=0, len=0); end
95
+
96
+ # NotImplementedError
97
+ def autoclose=(bool)
98
+ raise NotImplementedError
99
+ end
100
+
101
+ # NotImplementedError
102
+ def autoclose?
103
+ raise NotImplementedError
104
+ end
105
+
106
+ # TODO: Implement binmode.
107
+ def binmode
108
+ end
109
+
110
+ # TODO: Implement: binmode?
111
+ def binmode?
112
+ true
113
+ end
114
+
115
+ # Implementation relies on: getbyte
116
+ def bytes
117
+ return to_enum :bytes unless block_given?
118
+ while b = getbyte
119
+ yield b
120
+ end
121
+ end
122
+ alias :each_byte :bytes
123
+
124
+ # Implementation relies on: getc
125
+ def chars
126
+ return to_enum :chars unless block_given?
127
+ while c = getc
128
+ yield c
129
+ end
130
+ end
131
+ alias :each_char :chars
132
+
133
+ # Over-ride me!
134
+ def close
135
+ raise NotImplementedError, "Subclass should over-ride!"
136
+ end
137
+
138
+ # NotImplementedError
139
+ def close_on_exec=(bool)
140
+ raise NotImplementedError
141
+ end
142
+
143
+ # NotImplementedError
144
+ def close_on_exec?
145
+ raise NotImplementedError
146
+ end
147
+
148
+ # NotImplementedError
149
+ def close_read
150
+ raise NotImplementedError
151
+ end
152
+
153
+ # NotImplementedError
154
+ def close_write
155
+ raise NotImplementedError
156
+ end
157
+
158
+ # Over-ride me!
159
+ def closed?
160
+ raise NotImplementedError, "Subclass should over-ride!"
161
+ end
162
+
163
+ # Implementation relies on: getc
164
+ def codepoints
165
+ return to_enum :codepoints unless block_given?
166
+ while c = getc
167
+ c.codepoints.each do |cp|
168
+ yield cp
169
+ end
170
+ end
171
+ end
172
+ alias :each_codepoint :codepoints
173
+
174
+ # Over-ride me!
175
+ def eof?
176
+ raise NotImplementedError, "Subclass should over-ride!"
177
+ end
178
+ alias :eof :eof?
179
+
180
+ # TODO: Implement external_encoding
181
+ def external_encoding
182
+ raise NotImplementedError
183
+ end
184
+
185
+ # NotImplementedError
186
+ def fcntl(integer_cmd, arg)
187
+ raise NotImplementedError
188
+ end
189
+
190
+ # Implementation relies on: fsync
191
+ def fdatasync
192
+ fsync
193
+ end
194
+
195
+ # NotImplementedError
196
+ def fileno
197
+ raise NotImplementedError
198
+ end
199
+ alias :to_i :fileno
200
+
201
+ # NotImplementedError
202
+ def flush
203
+ raise NotImplementedError
204
+ end
205
+
206
+ # NotImplementedError
207
+ def fsync
208
+ raise NotImplementedError
209
+ end
210
+
211
+ # Implementation relies on: read
212
+ def getbyte
213
+ read(1)
214
+ end
215
+
216
+ # TODO: Implement getc (probably need to know about encoding conversions first)
217
+ def getc
218
+ raise NotImplementedError
219
+ end
220
+
221
+ # Implementation relies on: getc
222
+ # TODO: Maybe it should rely on getbyte instead, so we don't read too many bytes on accident.
223
+ def gets(sep=$/, limit=nil)
224
+ return nil if eof?
225
+ if limit.nil? && sep.is_a?(Integer) #TODO: compare this logic with ::IO#getc
226
+ limit = sep.to_i
227
+ sep = $/
228
+ end
229
+ if !limit.nil? && limit < 0
230
+ raise ArgumentError, ('negative limit %1d given' % limit)
231
+ end
232
+ sep = "\n\n" if sep == ""
233
+ line = ""
234
+ while (c = getc)
235
+ line << c
236
+ break if !sep.nil? && line.end_with?(sep)
237
+ break if !limit.nil? && line.bytesize >= limit
238
+ end
239
+ if !limit.nil? && limit >= 0 && line.bytesize > limit
240
+ leftovers = line.byteslice(limit .. -1) #TODO: what should we do with this?
241
+ line = line.byteslice(0,limit)
242
+ end
243
+ $. = (lineno += 1)
244
+ $_ = line
245
+ end
246
+
247
+ # TODO: Implement internal_encoding
248
+ def internal_encoding
249
+ raise NotImplementedError
250
+ end
251
+
252
+ # NotImplementedError
253
+ def ioctl(integer_cmd, arg)
254
+ raise NotImplementedError
255
+ end
256
+
257
+ # Always returns false
258
+ def isatty
259
+ false
260
+ end
261
+ alias :tty? :isatty
262
+
263
+ # Implementation relies on gets to properly keep this up-to-date.
264
+ def lineno
265
+ @lineno || uninitialized!
266
+ end
267
+
268
+ def lineno=(lineno)
269
+ @lineno = lineno
270
+ end
271
+
272
+ # Implementation relies on: gets
273
+ def lines(sep=$/, limit=nil)
274
+ return to_enum :lines unless block_given?
275
+ while s = gets
276
+ yield s
277
+ end
278
+ end
279
+ alias :each :lines
280
+ alias :each_line :lines
281
+
282
+ # NotImplementedError
283
+ def pid
284
+ raise NotImplementedError
285
+ end
286
+
287
+ # Subclass is responsible for keeping pos up-to-date!
288
+ def pos
289
+ @pos || uninitialized!
290
+ end
291
+ alias :tell :pos
292
+
293
+ # Subclass is responsible for keeping pos up-to-date!
294
+ def pos=(pos)
295
+ @pos = pos
296
+ end
297
+
298
+ # Implementation relies on write.
299
+ def print(*args)
300
+ args = [$_] if args.size == 0
301
+ first_one = true
302
+ args.each do |obj|
303
+ write(obj.to_s)
304
+ write($,) unless first_one || $,.nil?
305
+ first_one = false
306
+ end
307
+ write($\) unless $\.nil?
308
+ nil
309
+ end
310
+
311
+ # Implementation relies on print.
312
+ def printf(format_string, *args)
313
+ print(Kernel.sprintf(format_string, *args))
314
+ end
315
+
316
+ # Implementation relies on write.
317
+ def putc(obj)
318
+ if obj.is_a?(Numeric)
319
+ write((obj.to_i & 0xff).chr)
320
+ else
321
+ write(obj.to_s.byteslice(0))
322
+ end
323
+ end
324
+
325
+ def puts(*args)
326
+ if args.size == 0
327
+ write("\n")
328
+ else
329
+ args.flatten.each do |line|
330
+ line = line.to_s
331
+ write(line)
332
+ write("\n") unless line.end_with?("\n")
333
+ end
334
+ end
335
+ nil
336
+ end
337
+
338
+ def read(length=nil, buffer=nil)
339
+ if !length.nil? && length < 0
340
+ raise ArgumentError, ('negative length %1d given' % length)
341
+ end
342
+
343
+ buffer = buffer.nil? ? "" : buffer.replace("")
344
+ if length.nil?
345
+ begin
346
+ buffer << readpartial until eof?
347
+ rescue EOFError
348
+ end
349
+ # TODO: Apply encoding conversion to buffer.
350
+ buffer
351
+ elsif length == 0
352
+ buffer
353
+ else
354
+ begin
355
+ while buffer.bytesize < length && !eof?
356
+ buffer << readpartial(length - buffer.bytesize)
357
+ # TODO: Code Review - result should be ASCII-8BIT. Is it?
358
+ end
359
+ rescue EOFError
360
+ end
361
+ buffer.empty? ? nil : buffer
362
+ end
363
+ end
364
+
365
+ def read_nonblock(maxlen, outbuf=nil)
366
+ nonblock_readable do
367
+ sysread(maxlen, outbuff)
368
+ end
369
+ end
370
+
371
+ # Implementation relies on getbyte
372
+ def readbyte
373
+ getbyte || raise(EOFError)
374
+ end
375
+
376
+ # Implementation relies on: getc
377
+ def readchar
378
+ getc || raise(EOFError)
379
+ end
380
+
381
+ # Implementation relies on: gets
382
+ def readline(sep=$/, limit=nil)
383
+ gets(sep, limit) || raise(EOFError)
384
+ end
385
+
386
+ # Implementation relies on: gets
387
+ def readlines(sep=$/, limit=nil)
388
+ result = []
389
+ loop do
390
+ if (line = gets(sep, limit))
391
+ break
392
+ else
393
+ result << line
394
+ end
395
+ end
396
+ result
397
+ end
398
+
399
+ # Implementation relies on: read_nonblock
400
+ def readpartial(maxlen, outbuf=nil)
401
+ read_nonblock(maxlen, outbuf)
402
+ rescue IO::WaitReadable
403
+ block_until_readable
404
+ retry
405
+ end
406
+
407
+ # NotImplementedError
408
+ def reopen(other_io_or_path, mode_str=nil)
409
+ raise NotImplementedError
410
+ end
411
+
412
+ # Implementation relies on: seek
413
+ def rewind
414
+ seek(0)
415
+ end
416
+
417
+ # Implementation relies on: sysseek
418
+ def seek(amount, whence=IO::SEEK_SET)
419
+ sysseek(amount, whence)
420
+ end
421
+
422
+ # TODO: Implement set_encoding
423
+ def set_encoding(ext_enc, int_enc=nil, opt=nil)
424
+ raise NotImplementedError
425
+ end
426
+
427
+ # NotImplementedError
428
+ def stat
429
+ raise NotImplementedError
430
+ end
431
+
432
+ # NotImplementedError
433
+ def sync
434
+ raise NotImplementedError
435
+ end
436
+
437
+ # NotImplementedError
438
+ def sync=(bool)
439
+ raise NotImplementedError
440
+ end
441
+
442
+ # Over-ride me!
443
+ # Remember to count *bytes*, not chars.
444
+ # Remember to update pos.
445
+ # Remember to use consume_readable to wrap the atomic part of your update.
446
+ def sysread(maxlen, outbuf=nil)
447
+ raise NotImplementedError
448
+ end
449
+
450
+ # Over-ride me!
451
+ # Remember to count *bytes*, not chars.
452
+ # Remember to update pos.
453
+ def sysseek(offset, whence=IO::SEEK_SET)
454
+ raise NotImplementedError # TODO: provide best-effort implementation for sysseek
455
+ end
456
+
457
+ # Over-ride me!
458
+ # Remember to count *bytes*, not chars.
459
+ # Remember to update pos.
460
+ # Remember to use consume_writable to wrap the atomic part of your update.
461
+ def syswrite(string)
462
+ raise NotImplementedError
463
+ end
464
+
465
+ # NotImplementedError
466
+ def ungetbyte(string_or_integer)
467
+ raise NotImplementedError
468
+ end
469
+
470
+ # NotImplementedError
471
+ def ungetc(string)
472
+ raise NotImplementedError
473
+ end
474
+
475
+ # Implementation relies on: write_nonblock
476
+ def write(string)
477
+ written = 0
478
+ length = string.bytesize
479
+ while written < length
480
+ begin
481
+ written += write_nonblock(string.byteslice(written, length - written))
482
+ rescue IO::WaitWritable, Errno::EINTR
483
+ block_until_writable
484
+ retry
485
+ end
486
+ end
487
+ written
488
+ end
489
+
490
+ # Implementation relies on: syswrite
491
+ def write_nonblock(string)
492
+ nonblock_writable do
493
+ syswrite(string)
494
+ end
495
+ end
496
+
497
+ protected
498
+
499
+ # Subclass should call super in initialize
500
+ def initialize(*args, &callback)
501
+ super(*args, &callback)
502
+ @pos = 0
503
+ @lineno = 0
504
+ @mutex = Mutex.new
505
+ @readable_resource = ConditionVariable.new
506
+ @writable_resource = ConditionVariable.new
507
+ @nonblock_readable = false
508
+ @nonblock_writable = false
509
+ end
510
+
511
+ # Subclass should call me as appropriate. I'll take care of waking threads.
512
+ # Your callback must:
513
+ # * Be quick, you're inside a critical section!
514
+ # * Return true if it's safe to do a non-blocking read, false otherwise.
515
+ def consume_readable(&callback)
516
+ synchronize do
517
+ bool = callback.call
518
+ if @nonblock_readable != bool
519
+ @nonblock_readable = bool
520
+ readable_resource.signal
521
+ end
522
+ end
523
+ end
524
+
525
+ # Subclass should call me as appropriate. I'll take care of waking threads.
526
+ # Your callback must:
527
+ # * Be quick, you're inside a critical section!
528
+ # * Return true if it's safe to do a non-blocking write, false otherwise.
529
+ def consume_writable(&callback)
530
+ synchronize do
531
+ bool = callback.call
532
+ if @nonblock_writable != bool
533
+ @nonblock_writable = bool
534
+ writable_resource.signal
535
+ end
536
+ end
537
+ end
538
+
539
+ alias :provide_readable :consume_readable
540
+ alias :provide_writable :consume_writable
541
+
542
+ private
543
+
544
+ def uninitialized!
545
+ raise "Subclass did not call super in its initialize method!"
546
+ end
547
+
548
+ def mutex
549
+ @mutex || uninitialized!
550
+ end
551
+
552
+ def readable_resource
553
+ @readable_resource || uninitialized!
554
+ end
555
+
556
+ def writable_resource
557
+ @writable_resource || uninitialized!
558
+ end
559
+
560
+ # Don't call this unless you know what you're doing!
561
+ def synchronize
562
+ mutex.synchronize do
563
+ yield
564
+ end
565
+ end
566
+
567
+ def block_until_readable(&callback)
568
+ loop do
569
+ synchronize do
570
+ return if @nonblock_readable
571
+ readable_resource.wait(mutex)
572
+ end
573
+ end
574
+ end
575
+
576
+ def block_until_writable
577
+ loop do
578
+ synchronize do
579
+ return if @nonblock_writable
580
+ writable_resource.wait(mutex)
581
+ end
582
+ end
583
+ end
584
+
585
+ def nonblock_readable(&callback)
586
+ synchronize do
587
+ if @nonblock_readable
588
+ callback.call
589
+ else
590
+ raise(IO::WaitReadable, "read would block")
591
+ end
592
+ end
593
+ end
594
+
595
+ def nonblock_writable(&callback)
596
+ synchronize do
597
+ if @nonblock_writable
598
+ callback.call
599
+ else
600
+ raise(IO::WaitWritable, "write would block")
601
+ end
602
+ end
603
+ end
604
+ end
605
+ end
@@ -0,0 +1,91 @@
1
+ module QIO
2
+ class QueuedInputIO
3
+ include BaseIO
4
+ def initialize
5
+ super
6
+ @deque = [] #TODO: Consider using a real deque.
7
+ @eof = false
8
+ @closed = false
9
+ @queued_eof = false
10
+ end
11
+
12
+ def close
13
+ assert_open
14
+ synchronize do
15
+ @closed = true
16
+ @deque.clear
17
+ @deque = nil
18
+ end
19
+ end
20
+
21
+ def closed?
22
+ @closed
23
+ end
24
+
25
+ def eof?
26
+ assert_open
27
+ @eof ||= (@queued_eof && @deque.length <= 1)
28
+ end
29
+
30
+ def sysread(maxlen, outbuf=nil)
31
+ q = @deque
32
+ raise EOFError if eof?
33
+ outbuf ||= ""
34
+ consume_readable do
35
+ raise EOFError if eof?
36
+ data = @deque.shift
37
+ raise SystemCallError if data.nil? || data.empty?
38
+ if data.bytesize <= maxlen
39
+ outbuf.replace(data)
40
+ pos += outbuf.bytesize
41
+ else
42
+ outbuf.replace(data.byteslice(0, maxlen))
43
+ @deque.unshift(data.byteslice(maxlen .. -1))
44
+ pos += maxlen
45
+ end
46
+ @deque.any?
47
+ end
48
+ outbuf
49
+ end
50
+
51
+ def sysseek(offset, whence=IO::SEEK_SET)
52
+ # TODO: Implement (best-effort) sysseek
53
+ end
54
+
55
+ def add_input(string)
56
+ raise(ArgumentError, 'input must be a string') unless string.is_a?(String)
57
+ assert_open
58
+ assert_accepting_input
59
+ return self if string.empty?
60
+ provide_readable do
61
+ assert_open
62
+ assert_accepting_input
63
+ @deque.push(string)
64
+ true
65
+ end
66
+ self
67
+ end
68
+
69
+ def end_input!
70
+ return self if @queued_eof
71
+ provide_readable do
72
+ unless @queued_eof
73
+ @deque.push(:eof)
74
+ @queued_eof = true
75
+ end
76
+ true
77
+ end
78
+ self
79
+ end
80
+
81
+ private
82
+
83
+ def assert_open
84
+ raise(IOError, "stream is closed!") if @closed
85
+ end
86
+
87
+ def assert_accepting_input
88
+ raise(IOError, "stream was ended!") if @queued_eof
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,3 @@
1
+ module QIO
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "qio/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "qio"
7
+ s.version = QIO::VERSION
8
+ s.authors = ["Chris Johnson"]
9
+ s.email = ["chris@kindkid.com"]
10
+ s.homepage = "https://github.com/kindkid/qio"
11
+ s.summary = "IO facade, backed by a queue."
12
+ s.description = s.summary
13
+
14
+ s.rubyforge_project = "qio"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency "rspec", "~> 2.9.0"
22
+ s.add_development_dependency "simplecov", "~> 0.6.1"
23
+ s.add_development_dependency("rb-fsevent", "~> 0.9.0") if RUBY_PLATFORM =~ /darwin/i
24
+ s.add_development_dependency "guard", "~> 1.0.1"
25
+ s.add_development_dependency "guard-bundler", "~> 0.1.3"
26
+ s.add_development_dependency "guard-rspec", "~> 0.6.0"
27
+ end
@@ -0,0 +1,5 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe QIO do
4
+ it "should have some specs"
5
+ end
@@ -0,0 +1,7 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
4
+ require 'rubygems'
5
+ require 'bundler'
6
+
7
+ Bundler.require(:default, :test, :development)
@@ -0,0 +1,5 @@
1
+ desc "Open development console"
2
+ task :console do
3
+ puts "Loading development console..."
4
+ system "irb -r #{File.join('.', 'lib', 'qio')}"
5
+ end
@@ -0,0 +1,10 @@
1
+ desc "Generate and open coverage report"
2
+ task :coverage do
3
+ system 'rake spec'
4
+ system 'open coverage/index.html'
5
+ end
6
+
7
+ desc "Generate and open coverage report"
8
+ task :rcov do
9
+ system 'rake coverage'
10
+ end
@@ -0,0 +1,4 @@
1
+ desc "Load the environment"
2
+ task :environment do
3
+ require File.expand_path('../../lib/qio', __FILE__)
4
+ end
@@ -0,0 +1,12 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ desc "Run all specs"
4
+ RSpec::Core::RakeTask.new(:spec) do |t|
5
+ t.rspec_opts = [
6
+ '-c',
7
+ '--format documentation',
8
+ '-r ./spec/spec_helper.rb',
9
+ '--backtrace'
10
+ ]
11
+ t.pattern = 'spec/**/*_spec.rb'
12
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: qio
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Chris Johnson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &70139110710660 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.9.0
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70139110710660
25
+ - !ruby/object:Gem::Dependency
26
+ name: simplecov
27
+ requirement: &70139110710020 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.6.1
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70139110710020
36
+ - !ruby/object:Gem::Dependency
37
+ name: rb-fsevent
38
+ requirement: &70139110709260 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 0.9.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70139110709260
47
+ - !ruby/object:Gem::Dependency
48
+ name: guard
49
+ requirement: &70139110708540 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.0.1
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70139110708540
58
+ - !ruby/object:Gem::Dependency
59
+ name: guard-bundler
60
+ requirement: &70139110707940 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 0.1.3
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70139110707940
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-rspec
71
+ requirement: &70139110663080 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 0.6.0
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70139110663080
80
+ description: IO facade, backed by a queue.
81
+ email:
82
+ - chris@kindkid.com
83
+ executables: []
84
+ extensions: []
85
+ extra_rdoc_files: []
86
+ files:
87
+ - .gitignore
88
+ - .rvmrc
89
+ - Gemfile
90
+ - Rakefile
91
+ - lib/qio.rb
92
+ - lib/qio/base_io.rb
93
+ - lib/qio/queued_input_io.rb
94
+ - lib/qio/version.rb
95
+ - qio.gemspec
96
+ - spec/lib/qio_spec.rb
97
+ - spec/spec_helper.rb
98
+ - tasks/console.rake
99
+ - tasks/coverage.rake
100
+ - tasks/environment.rake
101
+ - tasks/spec.rake
102
+ homepage: https://github.com/kindkid/qio
103
+ licenses: []
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ! '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ segments:
115
+ - 0
116
+ hash: -222388549614253970
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ! '>='
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ segments:
124
+ - 0
125
+ hash: -222388549614253970
126
+ requirements: []
127
+ rubyforge_project: qio
128
+ rubygems_version: 1.8.10
129
+ signing_key:
130
+ specification_version: 3
131
+ summary: IO facade, backed by a queue.
132
+ test_files:
133
+ - spec/lib/qio_spec.rb
134
+ - spec/spec_helper.rb