bychar 1.0.1 → 1.1.0

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/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - ruby-head
data/bychar.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "bychar"
8
- s.version = "1.0.1"
8
+ s.version = "1.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Julik Tarkhanov"]
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
18
18
  ]
19
19
  s.files = [
20
20
  ".document",
21
+ ".travis.yml",
21
22
  "Gemfile",
22
23
  "LICENSE.txt",
23
24
  "README.rdoc",
data/lib/bychar.rb CHANGED
@@ -2,11 +2,15 @@
2
2
  require 'stringio'
3
3
 
4
4
  module Bychar
5
- VERSION = '1.0.1'
5
+ VERSION = '1.1.0'
6
6
 
7
7
  # Default buffer size is 512k
8
8
  DEFAULT_BUFFER_SIZE = 512 * 1024
9
9
 
10
+ # Gets raised when you have exhausted the underlying IO
11
+ class EOFError < RuntimeError #:nodoc: all
12
+ end
13
+
10
14
  # This object helps you build parsers that parse an IO byte by byte without having to
11
15
  # read byte by byte.
12
16
  # Reading byte by byte is very inefficient, but we want to parse byte by byte since
@@ -15,7 +19,6 @@ module Bychar
15
19
  # and ad infinitum until the passed buffer is exhausted
16
20
  class Reader
17
21
 
18
-
19
22
  def initialize(with_io, buffer_size = DEFAULT_BUFFER_SIZE)
20
23
  @io = with_io
21
24
  @bufsize = buffer_size
@@ -38,9 +41,19 @@ module Bychar
38
41
  def eof?
39
42
  (@buf && @buf.eos?) && @io.eof?
40
43
  end
41
-
44
+
45
+ # Since you parse char by char, you will be tempted to do it in a tight loop
46
+ # and to call eof? on each iteration. Don't. Instead. allow it to raise and do not check.
47
+ # This takes the profile time down from 36 seconds to 30 seconds for a large file.
48
+ def read_one_byte!
49
+ cache if @buf.eos?
50
+ raise EOFError if @buf.eos?
51
+
52
+ @buf.getch
53
+ end
54
+
42
55
  private
43
-
56
+
44
57
  def cache
45
58
  data = @io.read(@bufsize)
46
59
  @buf = StringScanner.new(data.to_s) # Make nil become ""
data/test/test_bychar.rb CHANGED
@@ -45,4 +45,16 @@ class TestBychar < Test::Unit::TestCase
45
45
  assert reader.eof?
46
46
  end
47
47
 
48
+ def test_read_one_byte_and_raise_at_eof
49
+ str = "Frobobo"
50
+
51
+ bytes = []
52
+ assert_raise(Bychar::EOFError) do
53
+ s = Bychar::Reader.new(StringIO.new(str))
54
+ loop { bytes << s.read_one_byte! }
55
+ end
56
+
57
+ assert_equal %w( F r o b o b o ), bytes
58
+ end
59
+
48
60
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bychar
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -84,6 +84,7 @@ extra_rdoc_files:
84
84
  - README.rdoc
85
85
  files:
86
86
  - .document
87
+ - .travis.yml
87
88
  - Gemfile
88
89
  - LICENSE.txt
89
90
  - README.rdoc
@@ -107,7 +108,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
107
108
  version: '0'
108
109
  segments:
109
110
  - 0
110
- hash: 1325391043988314358
111
+ hash: -1419412971002679734
111
112
  required_rubygems_version: !ruby/object:Gem::Requirement
112
113
  none: false
113
114
  requirements: