buffered_io 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/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in buffered_io.gemspec
4
+ gemspec
5
+
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Scott M. Kroll
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,34 @@
1
+ = BufferedIO
2
+
3
+ Library for buffering Ruby IO objects.
4
+
5
+ == Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'buffered_io'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install buffered_io
18
+
19
+ == Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ == Contributing
24
+
25
+ 1. Fork it
26
+
27
+ 1. Create your feature branch (`git checkout -b my-new-feature`)
28
+
29
+ 1. Commit your changes (`git commit -am 'Add some feature'`)
30
+
31
+ 1. Push to the branch (`git push origin my-new-feature`)
32
+
33
+ 1. Create new Pull Request
34
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rdoc/task'
3
+
4
+ RDoc::Task.new do |rdoc|
5
+ rdoc.title = 'BufferedIO'
6
+ rdoc.main = 'README.rdoc'
7
+ rdoc.rdoc_dir = 'rdoc'
8
+ rdoc.rdoc_files.include('README.rdoc', 'lib/**/*.rb')
9
+ end
10
+
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'buffered_io/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'buffered_io'
8
+ gem.version = BufferedIO::VERSION
9
+ gem.authors = ['Scott M. Kroll']
10
+ gem.email = ['skroll@gmail.com']
11
+ gem.summary = %q{Library to buffer IO objects for efficient reading.}
12
+ gem.description = gem.summary
13
+ gem.homepage = 'https://github.com/skroll/ruby-buffered_io'
14
+ gem.has_rdoc = true
15
+ gem.rdoc_options = ['--line-numbers', '--inline-source', '--title', 'BufferedIO', '--main', 'README.rdoc']
16
+
17
+ gem.files = `git ls-files`.split($/)
18
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
19
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
20
+ gem.require_paths = ['lib']
21
+ end
22
+
@@ -0,0 +1,6 @@
1
+ require 'buffered_io/version'
2
+ require 'buffered_io/io_buffer'
3
+
4
+ module BufferedIO # :nodoc:
5
+ end
6
+
@@ -0,0 +1,153 @@
1
+ require 'buffered_io/read_buffer'
2
+
3
+ module BufferedIO
4
+ # An +IOBuffer+ object wraps an +IO+ object and buffers read data for
5
+ # efficient +IO+ manipulation.
6
+ #
7
+ # === Example
8
+ #
9
+ # io_buffer = IOBuffer.new(io)
10
+ #
11
+ # puts io_buffer.readline # => Read until a newline
12
+ # puts io_buffer.read(64) # => Read 64 bytes
13
+ #
14
+ class IOBuffer
15
+ # Returns a new +IOBuffer+ object wrapping +io+.
16
+ def initialize(io)
17
+ @io = io
18
+ @read_buffer = ReadBuffer.new(io)
19
+ end
20
+
21
+ # Read bytes from the underlying +IO+ object.
22
+ #
23
+ # === Parameters
24
+ #
25
+ # +length+ is the number of bytes to read.
26
+ #
27
+ # +dest+ is the buffer to append to.
28
+ #
29
+ # +ignore_eof+ indicates whether or not to ignore +EOFError+ exceptions.
30
+ #
31
+ # === Errors
32
+ #
33
+ # This method may raise:
34
+ #
35
+ # * +EOFError+
36
+ #
37
+ def read(length, dest = '', ignore_eof = false)
38
+ read_bytes = 0
39
+ begin
40
+ while read_bytes + @read_buffer.size < length
41
+ dest << (s = @read_buffer.consume(@read_buffer.size))
42
+ read_bytes += s.size
43
+ @read_buffer.fill
44
+ end
45
+ dest << (s = @read_buffer.consume(length - read_bytes))
46
+ read_bytes += s.size
47
+ rescue EOFError
48
+ raise unless ignore_eof
49
+ end
50
+ dest
51
+ end
52
+
53
+ # Read all data from the underlying +IO+ object until an +EOFError+ is
54
+ # raised by the +IO+ object.
55
+ #
56
+ # === Parameters
57
+ #
58
+ # +dest+ is the buffer to append to.
59
+ #
60
+ def read_all(dest = '')
61
+ read_bytes = 0
62
+ begin
63
+ while true
64
+ dest << (s = @read_buffer.consume(@read_buffer.size))
65
+ read_bytes += s.size
66
+ @read_buffer.fill
67
+ end
68
+ rescue EOFError
69
+ ;
70
+ end
71
+ dest
72
+ end
73
+
74
+ # Read from the underlying +IO+ object until a specified terminator
75
+ # is reached.
76
+ #
77
+ # === Parameters
78
+ #
79
+ # +terminator+ is the terminator to read until.
80
+ #
81
+ # +ignore_eof+ indicates whether or not to ignore +EOFError+ exceptions.
82
+ #
83
+ # === Errors
84
+ #
85
+ # This method may raise:
86
+ #
87
+ # * +EOFError+
88
+ #
89
+ def readuntil(terminator, ignore_eof = false)
90
+ begin
91
+ until idx = @read_buffer.index(terminator)
92
+ @read_buffer.fill
93
+ end
94
+ return @read_buffer.consume(idx + terminator.size)
95
+ rescue EOFError
96
+ raise unless ignore_eof
97
+ return @read_buffer.consume(@read_buffer.size)
98
+ end
99
+ end
100
+
101
+ # Read a line from the underlying +IO+ object.
102
+ #
103
+ # === Parameters
104
+ #
105
+ # +chop+ indicates whether or not to strip the newline character from
106
+ # the read data.
107
+ #
108
+ # === Errors
109
+ #
110
+ # This method may raise:
111
+ #
112
+ # * +EOFError+
113
+ def readline(chop = true)
114
+ s = readuntil("\n")
115
+ return chop ? s.chop : s
116
+ end
117
+
118
+ # Writes bytes to the underlying +IO+ object.
119
+ #
120
+ # === Parameters
121
+ #
122
+ # +str+ is the data to write.
123
+ def write(str)
124
+ writing { write0 str }
125
+ end
126
+
127
+ # Appends a newline to a string and writes it to the underlying +IO+
128
+ # object.
129
+ #
130
+ # === Parameters
131
+ #
132
+ # +str+ is the data to write.
133
+ def writeline(str)
134
+ writing { write0 str + "\r\n" }
135
+ end
136
+
137
+ private
138
+ def writing
139
+ @written_bytes = 0
140
+ yield
141
+ bytes = @written_bytes
142
+ @written_bytes = nil
143
+ bytes
144
+ end
145
+
146
+ def write0(str)
147
+ length = @io.write(str)
148
+ @written_bytes += length
149
+ length
150
+ end
151
+ end
152
+ end
153
+
@@ -0,0 +1,43 @@
1
+ module BufferedIO
2
+ # Maintains a read buffer for an IO object.
3
+ class ReadBuffer # :nodoc:
4
+ # :nodoc:
5
+ DEFAULT_BUFFER_SIZE = 1024 * 16
6
+
7
+ def initialize(io)
8
+ @io = io
9
+ @buffer = ''
10
+ @read_timeout = 60
11
+ @buffer_size = DEFAULT_BUFFER_SIZE
12
+ end
13
+
14
+ attr_reader :io
15
+ attr_accessor :read_timeout
16
+
17
+ # Attempt to fill the IOBuffer
18
+ def fill
19
+ begin
20
+ @buffer << @io.read_nonblock(@buffer_size)
21
+ rescue ::IO::WaitReadable
22
+ IO.select([@io], nil, nil, @read_timeout) ? retry : (raise ::Timeout::Error)
23
+ rescue ::IO::WaitWritable
24
+ IO.select(nil, [@io], nil, @read_timeout) ? retry : (raise ::Timeout::Error)
25
+ end
26
+ end
27
+
28
+ # Consume bytes from the IOBuffer
29
+ def consume(len)
30
+ return @buffer.slice!(0, len)
31
+ end
32
+
33
+ # Number of bytes in the buffer
34
+ def size
35
+ @buffer.size
36
+ end
37
+
38
+ def index(i)
39
+ @buffer.index(i)
40
+ end
41
+ end
42
+ end
43
+
@@ -0,0 +1,5 @@
1
+ module BufferedIO
2
+ # The version of the BufferedIO library.
3
+ VERSION = "0.0.1"
4
+ end
5
+
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: buffered_io
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Scott M. Kroll
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-20 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Library to buffer IO objects for efficient reading.
15
+ email:
16
+ - skroll@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - Gemfile
23
+ - LICENSE.txt
24
+ - README.rdoc
25
+ - Rakefile
26
+ - buffered_io.gemspec
27
+ - lib/buffered_io.rb
28
+ - lib/buffered_io/io_buffer.rb
29
+ - lib/buffered_io/read_buffer.rb
30
+ - lib/buffered_io/version.rb
31
+ homepage: https://github.com/skroll/ruby-buffered_io
32
+ licenses: []
33
+ post_install_message:
34
+ rdoc_options:
35
+ - --line-numbers
36
+ - --inline-source
37
+ - --title
38
+ - BufferedIO
39
+ - --main
40
+ - README.rdoc
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubyforge_project:
57
+ rubygems_version: 1.8.23
58
+ signing_key:
59
+ specification_version: 3
60
+ summary: Library to buffer IO objects for efficient reading.
61
+ test_files: []