Class: CSV

Inherits:
Object
  • Object
show all
Defined in:
lib/csv.rb

Defined Under Namespace

Classes: BasicWriter, Cell, IOBuf, IOReader, IllegalFormatError, Reader, Row, StreamBuf, StringReader, Writer

Class Method Summary collapse

Class Method Details

.foreach(path, rs = nil, &block) ⇒ Object



93
94
95
# File 'lib/csv.rb', line 93

def CSV.foreach(path, rs = nil, &block)
  open_reader(path, 'r', ',', rs, &block)
end

.generate(path, fs = nil, rs = nil, &block) ⇒ Object



110
111
112
# File 'lib/csv.rb', line 110

def CSV.generate(path, fs = nil, rs = nil, &block)
  open_writer(path, 'w', fs, rs, &block)
end

.generate_line(row, fs = nil, rs = nil) ⇒ Object

Create a line from cells. each cell is stringified by to_s.



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/csv.rb', line 160

def CSV.generate_line(row, fs = nil, rs = nil)
  if row.size == 0
    return ''
  end
  fs ||= ','
  if fs.is_a?(Fixnum)
    fs = fs.chr
  end
  if !rs.nil? and rs.is_a?(Fixnum)
    rs = rs.chr
  end
  res_type = :DT_COLSEP
  result_str = ''
  idx = 0
  while true
    generate_body(row[idx], result_str, fs, rs)
    idx += 1
    if (idx == row.size)
      break
    end
    generate_separator(:DT_COLSEP, result_str, fs, rs)
  end
  result_str
end

.generate_row(src, cells, out_dev, fs = nil, rs = nil) ⇒ Object

Convert a line from cells data to string. Consider using CSV.generate_line instead. To generate multi-row CSV string, see EXAMPLE below.

EXAMPLE

row1 = ['a', 'b']
row2 = ['c', 'd']
row3 = ['e', 'f']
src = [row1, row2, row3]
buf = ''
src.each do |row|
  parsed_cells = CSV.generate_row(row, 2, buf)
  puts "Created #{ parsed_cells } cells."
end
p buf

ARGS

src: an Array of String to be converted to CSV string.  Must respond to
  'size' and '[](idx)'.  src[idx] must return String.
cells: num of cells in a line.
out_dev: buffer for generated CSV string.  Must respond to '<<(string)'.
col_sep: Column separator.  ?, by default.  If you want to separate
  fields with semicolon, give ?; here.
row_sep: Row separator.  nil by default.  nil means "\r\n or \n".  If you
  want to separate records with \r, give ?\r here.

RETURNS

parsed_cells: num of converted cells.


271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'lib/csv.rb', line 271

def CSV.generate_row(src, cells, out_dev, fs = nil, rs = nil)
  fs ||= ','
  if fs.is_a?(Fixnum)
    fs = fs.chr
  end
  if !rs.nil? and rs.is_a?(Fixnum)
    rs = rs.chr
  end
  src_size = src.size
  if (src_size == 0)
    if cells == 0
      generate_separator(:DT_ROWSEP, out_dev, fs, rs)
    end
    return 0
  end
  res_type = :DT_COLSEP
  parsed_cells = 0
  generate_body(src[parsed_cells], out_dev, fs, rs)
  parsed_cells += 1
  while ((parsed_cells < cells) and (parsed_cells != src_size))
    generate_separator(:DT_COLSEP, out_dev, fs, rs)
    generate_body(src[parsed_cells], out_dev, fs, rs)
    parsed_cells += 1
  end
  if (parsed_cells == cells)
    generate_separator(:DT_ROWSEP, out_dev, fs, rs)
  else
    generate_separator(:DT_COLSEP, out_dev, fs, rs)
  end
  parsed_cells
end

.open(path, mode, fs = nil, rs = nil, &block) ⇒ Object

Open a CSV formatted file for reading or writing.

For reading.

EXAMPLE 1

CSV.open('csvfile.csv', 'r') do |row|
  p row
end

EXAMPLE 2

reader = CSV.open('csvfile.csv', 'r')
row1 = reader.shift
row2 = reader.shift
if row2.empty?
  p 'row2 not find.'
end
reader.close

ARGS

filename: filename to parse.
col_sep: Column separator.  ?, by default.  If you want to separate
  fields with semicolon, give ?; here.
row_sep: Row separator.  nil by default.  nil means "\r\n or \n".  If you
  want to separate records with \r, give ?\r here.

RETURNS

reader instance.  To get parse result, see CSV::Reader#each.

For writing.

EXAMPLE 1

CSV.open('csvfile.csv', 'w') do |writer|
  writer << ['r1c1', 'r1c2']
  writer << ['r2c1', 'r2c2']
  writer << [nil, nil]
end

EXAMPLE 2

writer = CSV.open('csvfile.csv', 'w')
writer << ['r1c1', 'r1c2'] << ['r2c1', 'r2c2'] << [nil, nil]
writer.close

ARGS

filename: filename to generate.
col_sep: Column separator.  ?, by default.  If you want to separate
  fields with semicolon, give ?; here.
row_sep: Row separator.  nil by default.  nil means "\r\n or \n".  If you
  want to separate records with \r, give ?\r here.

RETURNS

writer instance.  See CSV::Writer#<< and CSV::Writer#add_row to know how
to generate CSV string.


83
84
85
86
87
88
89
90
91
# File 'lib/csv.rb', line 83

def CSV.open(path, mode, fs = nil, rs = nil, &block)
  if mode == 'r' or mode == 'rb'
    open_reader(path, mode, fs, rs, &block)
  elsif mode == 'w' or mode == 'wb'
    open_writer(path, mode, fs, rs, &block)
  else
    raise ArgumentError.new("'mode' must be 'r', 'rb', 'w', or 'wb'")
  end
end

.parse(str_or_readable, fs = nil, rs = nil, &block) ⇒ Object

Parse lines from given string or stream. Return rows as an Array of Arrays.



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/csv.rb', line 115

def CSV.parse(str_or_readable, fs = nil, rs = nil, &block)
  if File.exist?(str_or_readable)
    STDERR.puts("CSV.parse(filename) is deprecated." +
      "  Use CSV.open(filename, 'r') instead.")
    return open_reader(str_or_readable, 'r', fs, rs, &block)
  end
  if block
    CSV::Reader.parse(str_or_readable, fs, rs) do |row|
      yield(row)
    end
    nil
  else
    CSV::Reader.create(str_or_readable, fs, rs).collect { |row| row }
  end
end

.parse_line(src, fs = nil, rs = nil) ⇒ Object

Parse a line from given string. Bear in mind it parses ONE LINE. Rest of the string is ignored for example “a,brnc,d” => [‘a’, ‘b’] and the second line ‘c,d’ is ignored.

If you don’t know whether a target string to parse is exactly 1 line or not, use CSV.parse_row instead of this method.



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/csv.rb', line 137

def CSV.parse_line(src, fs = nil, rs = nil)
  fs ||= ','
  if fs.is_a?(Fixnum)
    fs = fs.chr
  end
  if !rs.nil? and rs.is_a?(Fixnum)
    rs = rs.chr
  end
  idx = 0
  res_type = :DT_COLSEP
  row = []
  begin
    while res_type == :DT_COLSEP
      res_type, idx, cell = parse_body(src, idx, fs, rs)
      row << cell
    end
  rescue IllegalFormatError
    return []
  end
  row
end

.parse_row(src, idx, out_dev, fs = nil, rs = nil) ⇒ Object

Parse a line from string. Consider using CSV.parse_line instead. To parse lines in CSV string, see EXAMPLE below.

EXAMPLE

src = "a,b\r\nc,d\r\ne,f"
idx = 0
begin
  parsed = []
  parsed_cells, idx = CSV.parse_row(src, idx, parsed)
  puts "Parsed #{ parsed_cells } cells."
  p parsed
end while parsed_cells > 0

ARGS

src: a CSV data to be parsed.  Must respond '[](idx)'.
  src[](idx) must return a char. (Not a string such as 'a', but 97).
  src[](idx_out_of_bounds) must return nil.  A String satisfies this
  requirement.
idx: index of parsing location of 'src'.  0 origin.
out_dev: buffer for parsed cells.  Must respond '<<(aString)'.
col_sep: Column separator.  ?, by default.  If you want to separate
  fields with semicolon, give ?; here.
row_sep: Row separator.  nil by default.  nil means "\r\n or \n".  If you
  want to separate records with \r, give ?\r here.

RETURNS

parsed_cells: num of parsed cells.
idx: index of next parsing location of 'src'.


214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/csv.rb', line 214

def CSV.parse_row(src, idx, out_dev, fs = nil, rs = nil)
  fs ||= ','
  if fs.is_a?(Fixnum)
    fs = fs.chr
  end
  if !rs.nil? and rs.is_a?(Fixnum)
    rs = rs.chr
  end
  idx_backup = idx
  parsed_cells = 0
  res_type = :DT_COLSEP
  begin
    while res_type != :DT_ROWSEP
      res_type, idx, cell = parse_body(src, idx, fs, rs)
      if res_type == :DT_EOS
        if idx == idx_backup #((parsed_cells == 0) and cell.nil?)
          return 0, 0
        end
        res_type = :DT_ROWSEP
      end
      parsed_cells += 1
      out_dev << cell
    end
  rescue IllegalFormatError
    return 0, 0
  end
  return parsed_cells, idx
end

.read(path, length = nil, offset = nil) ⇒ Object



97
98
99
# File 'lib/csv.rb', line 97

def CSV.read(path, length = nil, offset = nil)
  CSV.parse(IO.read(path, length, offset))
end

.readlines(path, rs = nil) ⇒ Object



101
102
103
104
105
106
107
108
# File 'lib/csv.rb', line 101

def CSV.readlines(path, rs = nil)
  reader = open_reader(path, 'r', ',', rs)
  begin
    reader.collect { |row| row }
  ensure
    reader.close
  end
end