init_separators(col_sep, row_sep, quote_char, force_quotes)
private
Stores the indicated separators for later use.
If auto-discovery was requested for @row_sep, this method will read ahead in the @io and try to find
one. ARGF, STDIN,
STDOUT, STDERR and any stream open for output only with a default
@row_sep of $INPUT_RECORD_SEPARATOR ($/).
This method also establishes the quoting rules used for CSV output.
Show source
def init_separators(col_sep, row_sep, quote_char, force_quotes)
@col_sep = col_sep.to_s.encode(@encoding)
@row_sep = row_sep
@quote_char = quote_char.to_s.encode(@encoding)
@double_quote_char = @quote_char * 2
if @quote_char.length != 1
raise ArgumentError, ":quote_char has to be a single character String"
end
if @row_sep == :auto
if [ARGF, STDIN, STDOUT, STDERR].include?(@io) or
(defined?(Zlib) and @io.class == Zlib::GzipWriter)
@row_sep = $INPUT_RECORD_SEPARATOR
else
begin
saved_pos = @io.pos
while @row_sep == :auto
break unless sample = @io.gets(nil, 1024)
if sample.end_with? encode_str("\r")
sample << (@io.gets(nil, 1) || "")
end
if sample =~ encode_re("\r\n?|\n")
@row_sep = $&
break
end
end
@io.rewind
while saved_pos > 1024
@io.read(1024)
saved_pos -= 1024
end
@io.read(saved_pos) if saved_pos.nonzero?
rescue IOError
rescue NoMethodError
rescue SystemCallError
ensure
@row_sep = $INPUT_RECORD_SEPARATOR if @row_sep == :auto
end
end
end
@row_sep = @row_sep.to_s.encode(@encoding)
@force_quotes = force_quotes
do_quote = lambda do |field|
field = String(field)
encoded_quote = @quote_char.encode(field.encoding)
encoded_quote + field.gsub(encoded_quote, encoded_quote * 2) + encoded_quote
end
quotable_chars = encode_str("\r\n", @col_sep, @quote_char)
@quote = if @force_quotes
do_quote
else
lambda do |field|
if field.nil?
""
else
field = String(field)
if field.empty? or
field.count(quotable_chars).nonzero?
do_quote.call(field)
else
field
end
end
end
end
end