1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
#!/usr/bin/env ruby
# frozen_string_literal: true
#
# A simple command-line tool to de- and encode Ascii85, modeled after `base64`
# from the GNU Coreutils.
#
require 'optparse'
require 'ascii85'
class CLI
attr_reader :options
def initialize(argv, stdin: $stdin, stdout: $stdout)
@in = stdin
@out = stdout
@options = {
wrap: 80,
action: :encode
}
parse_options(argv)
end
def parse_options(argv)
@parser = OptionParser.new do |opts|
opts.banner = "Usage: #{File.basename($PROGRAM_NAME)} [OPTIONS] [FILE]\n" \
'Encodes or decodes FILE or STDIN using Ascii85 and writes to STDOUT.'
opts.on('-w', '--wrap COLUMN', Integer,
'Wrap lines at COLUMN. Default is 80, use 0 for no wrapping') do |opt|
@options[:wrap] = opt.abs
@options[:wrap] = false if opt.zero?
end
opts.on('-d', '--decode', 'Decode the input') do
@options[:action] = :decode
end
opts.on('-h', '--help', 'Display this help and exit') do
@options[:action] = :help
end
opts.on('-V', '--version', 'Output version information') do |_opt|
@options[:action] = :version
end
end
remaining_args = @parser.parse!(argv)
case remaining_args.size
when 0
@options[:file] = '-'
when 1
@options[:file] = remaining_args.first
else
raise(OptionParser::ParseError, "Superfluous operand(s): \"#{remaining_args[1..].join('", "')}\"")
end
end
def input
fn = @options[:file]
return @in.binmode if fn == '-'
raise(StandardError, "File not found: \"#{fn}\"") unless File.exist?(fn)
raise(StandardError, "File is not readable: \"#{fn}\"") unless File.readable_real?(fn)
File.new(fn, 'rb')
end
def decode
Ascii85.decode(input.read, out: @out)
end
def encode
Ascii85.encode(input, @options[:wrap], out: @out)
end
def version
"Ascii85 v#{Ascii85::VERSION},\nwritten by Johannes HolzfuĆ"
end
def help
@parser
end
def call
case @options[:action]
when :help then @out.puts help
when :version then @out.puts version
when :encode then encode
when :decode then decode
end
end
end
if File.basename($PROGRAM_NAME) == "ascii85"
begin
CLI.new(ARGV).call
rescue OptionParser::ParseError => e
abort e.message
rescue Ascii85::DecodingError => e
abort "Decoding Error: #{e.message}"
rescue StandardError => e
abort "Error: #{e.message}"
end
end
|