Skip to content

Commit

Permalink
Add changes for suppressing output when binary output is encountered
Browse files Browse the repository at this point in the history
  • Loading branch information
buty4649 committed Dec 31, 2023
1 parent 67bc965 commit 22c4607
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 20 deletions.
4 changes: 4 additions & 0 deletions mrblib/rf/00filter/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ def gets
raise NotImplementedError
end

def binary?
@io.binary?
end

def self.format(val, record)
raise NotImplementedError
end
Expand Down
61 changes: 61 additions & 0 deletions mrblib/rf/buffered_io.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
module Rf
class BufferedIO
BUFFER_SIZE = 96 * 1024 # 96KB

def initialize(file_name, mode = 'r')
@file = file_name == '-' ? $stdin : File.open(file_name, mode)
@buffer = ''
@end_of_file = false
@binary = false
end

def binary?
@binary
end

def gets
return if @end_of_file

line = ''
loop do
fill_buffer if @buffer.empty?
break if @buffer.empty?

newline_index = @buffer.index("\n")
if newline_index
line << @buffer.slice!(0..newline_index)
break
else
line << @buffer.slice!(0..-1)
@buffer.clear
end
end

line.empty? ? nil : line
end

def read
return if @end_of_file

fill_buffer(nil)
@buffer.empty? ? nil : @buffer.slice!(0..-1)
end

def close
@file.close
end

private

def fill_buffer(size = BUFFER_SIZE)
read_data = @file.read(size)
if read_data.nil? || read_data.empty?
@end_of_file = true
else
@binary = true if /(?![\r\n])\p{Cntrl}/.match?(read_data)

@buffer << read_data
end
end
end
end
41 changes: 21 additions & 20 deletions mrblib/rf/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,14 @@ def run # rubocop:disable Metrics/AbcSize
tempfile = write_file if in_place.empty?
end

records = Record.read(filter.new(input))
if slurp?
r = records.to_a
do_action(r, 1, r)
else
records.each_with_index do |record, index|
index += 1
do_action(record, index, split(record))
end
reader = filter.new(input)
records = Record.read(reader)
records = [records.to_a] if slurp?

records.each_with_index do |record, index|
index += 1
result = do_action(record, index, split(record))
render result, record, reader.binary?
end
post_action

Expand All @@ -76,10 +75,9 @@ def run # rubocop:disable Metrics/AbcSize
end

def read_open(file)
return $stdin if file == '-'
raise IsDirectory, file if File.directory?(file)

File.open(file)
BufferedIO.new(file)
rescue Errno::ENOENT
raise NotFound, file
rescue Errno::EACCES
Expand Down Expand Up @@ -111,27 +109,30 @@ def split(val)
end
end

def do_action(record, index, fields) # rubocop:disable Metrics/AbcSize
def do_action(record, index, fields)
container.record = record
container.fields = fields
bind.eval("NR = $. = #{index}") # index is Integer

result = if grep_mode
Regexp.new(command)
else
bind.eval(command)
end
render result, record
if grep_mode
Regexp.new(command)
else
bind.eval(command)
end
rescue ::SyntaxError => e
msg = e.message.delete_prefix('file (eval) ')
raise Rf::SyntaxError, msg
end

def render(val, record)
def render(val, record, binary_match)
return if quiet?
return unless output = filter.format(val, record)

@container.puts output
if binary_match
puts 'Binary file matches.'
else
@container.puts output
end
end

def post_action
Expand Down
21 changes: 21 additions & 0 deletions spec/binary_file_match_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
describe 'Binary file match' do
context 'when input is from stdin' do
let(:input) { "hello\x00world\n" }
let(:args) { '_' }
let(:expect_output) { 'Binary file matches.' }

it_behaves_like 'a successful exec'
end

context 'when input is from file' do
let(:file) { 'binary_file' }
let(:args) { "_ #{file}" }
let(:expect_output) { 'Binary file matches.' }

before do
write_file(file, "hello\x00world\n")
end

it_behaves_like 'a successful exec'
end
end

0 comments on commit 22c4607

Please sign in to comment.