diff --git a/lib/mongo/gridfs/grid_io.rb b/lib/mongo/gridfs/grid_io.rb index d4a3904..7ddbb24 100644 --- a/lib/mongo/gridfs/grid_io.rb +++ b/lib/mongo/gridfs/grid_io.rb @@ -208,43 +208,9 @@ module Mongo elsif separator.is_a?(Integer) read_length(separator) elsif separator.length > 1 - result = '' - len = 0 - match_idx = 0 - match_num = separator.length - 1 - to_match = separator[match_idx].chr - if length - matcher = lambda {|idx, num| idx < num && len < length } - else - matcher = lambda {|idx, num| idx < num} - end - while matcher.call(match_idx, match_num) && char = getc - result << char - len += 1 - if char == to_match - while match_idx < match_num do - match_idx += 1 - to_match = separator[match_idx].chr - char = getc - result << char - if char != to_match - match_idx = 0 - to_match = separator[match_idx].chr - break - end - end - end - end - result + read_to_string(separator, length) else - result = '' - len = 0 - while char = getc - result << char - len += 1 - break if char == separator || (length ? len >= length : false) - end - result + read_to_character(separator, length) end end @@ -359,6 +325,48 @@ module Mongo buf end + def read_to_character(character="\n", length=nil) + result = '' + len = 0 + while char = getc + result << char + len += 1 + break if char == character || (length ? len >= length : false) + end + result.length > 0 ? result : nil + end + + def read_to_string(string="\n", length=nil) + result = '' + len = 0 + match_idx = 0 + match_num = string.length - 1 + to_match = string[match_idx].chr + if length + matcher = lambda {|idx, num| idx < num && len < length } + else + matcher = lambda {|idx, num| idx < num} + end + while matcher.call(match_idx, match_num) && char = getc + result << char + len += 1 + if char == to_match + while match_idx < match_num do + match_idx += 1 + to_match = string[match_idx].chr + char = getc + result << char + if char != to_match + match_idx = 0 + to_match = string[match_idx].chr + break + end + end + end + end + result.length > 0 ? result : nil + end + def cache_chunk_data @current_chunk_data = @current_chunk['data'].to_s if @current_chunk_data.respond_to?(:force_encoding) diff --git a/test/grid_io_test.rb b/test/grid_io_test.rb index 5e166b1..f29547b 100644 --- a/test/grid_io_test.rb +++ b/test/grid_io_test.rb @@ -69,6 +69,24 @@ class GridIOTest < Test::Unit::TestCase assert_equal 10, string.length end + should "read to the end of the file one line at a time" do + file = GridIO.new(@files, @chunks, nil, "r", :query => {:_id => @file.files_id}) + bytes = 0 + while string = file.gets + bytes += string.length + end + assert_equal 1_000_000, bytes + end + + should "read to the end of the file one multi-character separator at a time" do + file = GridIO.new(@files, @chunks, nil, "r", :query => {:_id => @file.files_id}) + bytes = 0 + while string = file.gets("45") + bytes += string.length + end + assert_equal 1_000_000, bytes + end + should "read to a given separator" do file = GridIO.new(@files, @chunks, nil, "r", :query => {:_id => @file.files_id}) string = file.gets("5")