* include/ruby/io.h (rb_io_t): new fields: writeconv,
[ruby-svn.git] / lib / csv.rb
blobf60d5b1cb00e8f557196b35d611cb7e23293403e
1 #!/usr/local/bin/ruby -w
3 # = csv.rb -- CSV Reading and Writing
5 #  Created by James Edward Gray II on 2005-10-31.
6 #  Copyright 2005 James Edward Gray II. You can redistribute or modify this code
7 #  under the terms of Ruby's license.
8
9 # See CSV for documentation.
10
11 # == Description
12
13 # Welcome to the new and improved CSV.
14
15 # This version of the CSV library began its life as FasterCSV.  FasterCSV was
16 # intended as a replacement to Ruby's then standard CSV library.  It was
17 # designed to address concerns users of that library had and it had three
18 # primary goals:
19
20 # 1.  Be significantly faster than CSV while remaining a pure Ruby library.
21 # 2.  Use a smaller and easier to maintain code base.  (FasterCSV eventually
22 #     grew larger, was also but considerably richer in features.  The parsing
23 #     core remains quite small.)
24 # 3.  Improve on the CSV interface.
25
26 # Obviously, the last one is subjective.  I did try to defer to the original
27 # interface whenever I didn't have a compelling reason to change it though, so
28 # hopefully this won't be too radically different.
29
30 # We must have met our goals because FasterCSV was renamed to CSV and replaced
31 # the original library.
32
33 # == What's Different From the Old CSV?
34
35 # I'm sure I'll miss something, but I'll try to mention most of the major
36 # differences I am aware of, to help others quickly get up to speed:
37
38 # === CSV Parsing
39
40 # * This library has a stricter parser and will throw MalformedCSVErrors on
41 #   problematic data.
42 # * This library has a less liberal idea of a line ending than CSV.  What you
43 #   set as the <tt>:row_sep</tt> is law.  It can auto-detect your line endings
44 #   though.
45 # * The old library returned empty lines as <tt>[nil]</tt>.  This library calls
46 #   them <tt>[]</tt>.
47 # * This library has a much faster parser.
48
49 # === Interface
50
51 # * CSV now uses Hash-style parameters to set options.
52 # * CSV no longer has generate_row() or parse_row().
53 # * The old CSV's Reader and Writer classes have been dropped.
54 # * CSV::open() is now more like Ruby's open().
55 # * CSV objects now support most standard IO methods.
56 # * CSV now has a new() method used to wrap objects like String and IO for
57 #   reading and writing.
58 # * CSV::generate() is different from the old method.
59 # * CSV no longer supports partial reads.  It works line-by-line.
60 # * CSV no longer allows the instance methods to override the separators for
61 #   performance reasons.  They must be set in the constructor.
62
63 # If you use this library and find yourself missing any functionality I have
64 # trimmed, please {let me know}[mailto:james@grayproductions.net].
65
66 # == Documentation
67
68 # See CSV for documentation.
69
70 # == What is CSV, really?
71
72 # CSV maintains a pretty strict definition of CSV taken directly from
73 # {the RFC}[http://www.ietf.org/rfc/rfc4180.txt].  I relax the rules in only one
74 # place and that is to make using this library easier.  CSV will parse all valid
75 # CSV.
76
77 # What you don't want to do is feed CSV invalid data.  Because of the way the
78 # CSV format works, it's common for a parser to need to read until the end of
79 # the file to be sure a field is invalid.  This eats a lot of time and memory.
80
81 # Luckily, when working with invalid CSV, Ruby's built-in methods will almost
82 # always be superior in every way.  For example, parsing non-quoted fields is as
83 # easy as:
84
85 #   data.split(",")
86
87 # == Questions and/or Comments
88
89 # Feel free to email {James Edward Gray II}[mailto:james@grayproductions.net]
90 # with any questions.
92 require "forwardable"
93 require "English"
94 require "enumerator"
95 require "date"
96 require "stringio"
98
99 # This class provides a complete interface to CSV files and data.  It offers
100 # tools to enable you to read and write to and from Strings or IO objects, as
101 # needed.
103 # == Reading
105 # === From a File
107 # ==== A Line at a Time
109 #   CSV.foreach("path/to/file.csv") do |row|
110 #     # use row here...
111 #   end
113 # ==== All at Once
115 #   arr_of_arrs = CSV.read("path/to/file.csv")
117 # === From a String
119 # ==== A Line at a Time
121 #   CSV.parse("CSV,data,String") do |row|
122 #     # use row here...
123 #   end
125 # ==== All at Once
127 #   arr_of_arrs = CSV.parse("CSV,data,String")
129 # == Writing
131 # === To a File
133 #   CSV.open("path/to/file.csv", "w") do |csv|
134 #     csv << ["row", "of", "CSV", "data"]
135 #     csv << ["another", "row"]
136 #     # ...
137 #   end
139 # === To a String
141 #   csv_string = CSV.generate do |csv|
142 #     csv << ["row", "of", "CSV", "data"]
143 #     csv << ["another", "row"]
144 #     # ...
145 #   end
147 # == Convert a Single Line
149 #   csv_string = ["CSV", "data"].to_csv   # to CSV
150 #   csv_array  = "CSV,String".parse_csv   # from CSV
152 # == Shortcut Interface
154 #   CSV             { |csv_out| csv_out << %w{my data here} }  # to $stdout
155 #   CSV(csv = "")   { |csv_str| csv_str << %w{my data here} }  # to a String
156 #   CSV($stderr)    { |csv_err| csv_err << %w{my data here} }  # to $stderr
158 class CSV
159   # The version of the installed library.
160   VERSION = "2.0.0".freeze
161   
162   # 
163   # A CSV::Row is part Array and part Hash.  It retains an order for the fields
164   # and allows duplicates just as an Array would, but also allows you to access
165   # fields by name just as you could if they were in a Hash.
166   # 
167   # All rows returned by CSV will be constructed from this class, if header row
168   # processing is activated.
169   # 
170   class Row
171     # 
172     # Construct a new CSV::Row from +headers+ and +fields+, which are expected
173     # to be Arrays.  If one Array is shorter than the other, it will be padded
174     # with +nil+ objects.
175     # 
176     # The optional +header_row+ parameter can be set to +true+ to indicate, via
177     # CSV::Row.header_row?() and CSV::Row.field_row?(), that this is a header
178     # row.  Otherwise, the row is assumes to be a field row.
179     # 
180     # A CSV::Row object supports the following Array methods through delegation:
181     # 
182     # * empty?()
183     # * length()
184     # * size()
185     # 
186     def initialize(headers, fields, header_row = false)
187       @header_row = header_row
188       
189       # handle extra headers or fields
190       @row = if headers.size > fields.size
191         headers.each_with_index.map { |header, i| [header, fields[i]] }
192       else
193         fields.each_with_index.map { |field, i| [headers[i], field] }
194       end
195     end
196     
197     # Internal data format used to compare equality.
198     attr_reader :row
199     protected   :row
201     ### Array Delegation ###
203     extend Forwardable
204     def_delegators :@row, :empty?, :length, :size
205     
206     # Returns +true+ if this is a header row.
207     def header_row?
208       @header_row
209     end
210     
211     # Returns +true+ if this is a field row.
212     def field_row?
213       not header_row?
214     end
215     
216     # Returns the headers of this row.
217     def headers
218       @row.map { |pair| pair.first }
219     end
220     
221     # 
222     # :call-seq:
223     #   field( header )
224     #   field( header, offset )
225     #   field( index )
226     # 
227     # This method will fetch the field value by +header+ or +index+.  If a field
228     # is not found, +nil+ is returned.
229     # 
230     # When provided, +offset+ ensures that a header match occurrs on or later
231     # than the +offset+ index.  You can use this to find duplicate headers, 
232     # without resorting to hard-coding exact indices.
233     # 
234     def field(header_or_index, minimum_index = 0)
235       # locate the pair
236       finder = header_or_index.is_a?(Integer) ? :[] : :assoc
237       pair   = @row[minimum_index..-1].send(finder, header_or_index)
239       # return the field if we have a pair
240       pair.nil? ? nil : pair.last
241     end
242     alias_method :[], :field
243     
244     # 
245     # :call-seq:
246     #   []=( header, value )
247     #   []=( header, offset, value )
248     #   []=( index, value )
249     # 
250     # Looks up the field by the semantics described in CSV::Row.field() and
251     # assigns the +value+.
252     # 
253     # Assigning past the end of the row with an index will set all pairs between
254     # to <tt>[nil, nil]</tt>.  Assigning to an unused header appends the new
255     # pair.
256     # 
257     def []=(*args)
258       value = args.pop
259       
260       if args.first.is_a? Integer
261         if @row[args.first].nil?  # extending past the end with index
262           @row[args.first] = [nil, value]
263           @row.map! { |pair| pair.nil? ? [nil, nil] : pair }
264         else                      # normal index assignment
265           @row[args.first][1] = value
266         end
267       else
268         index = index(*args)
269         if index.nil?             # appending a field
270           self << [args.first, value]
271         else                      # normal header assignment
272           @row[index][1] = value
273         end
274       end
275     end
276     
277     # 
278     # :call-seq:
279     #   <<( field )
280     #   <<( header_and_field_array )
281     #   <<( header_and_field_hash )
282     # 
283     # If a two-element Array is provided, it is assumed to be a header and field
284     # and the pair is appended.  A Hash works the same way with the key being
285     # the header and the value being the field.  Anything else is assumed to be
286     # a lone field which is appended with a +nil+ header.
287     # 
288     # This method returns the row for chaining.
289     # 
290     def <<(arg)
291       if arg.is_a?(Array) and arg.size == 2  # appending a header and name
292         @row << arg
293       elsif arg.is_a?(Hash)                  # append header and name pairs
294         arg.each { |pair| @row << pair }
295       else                                   # append field value
296         @row << [nil, arg]
297       end
298       
299       self  # for chaining
300     end
301     
302     # 
303     # A shortcut for appending multiple fields.  Equivalent to:
304     # 
305     #   args.each { |arg| csv_row << arg }
306     # 
307     # This method returns the row for chaining.
308     # 
309     def push(*args)
310       args.each { |arg| self << arg }
311       
312       self  # for chaining
313     end
314     
315     # 
316     # :call-seq:
317     #   delete( header )
318     #   delete( header, offset )
319     #   delete( index )
320     # 
321     # Used to remove a pair from the row by +header+ or +index+.  The pair is
322     # located as described in CSV::Row.field().  The deleted pair is returned,
323     # or +nil+ if a pair could not be found.
324     # 
325     def delete(header_or_index, minimum_index = 0)
326       if header_or_index.is_a? Integer  # by index
327         @row.delete_at(header_or_index)
328       else                              # by header
329         @row.delete_at(index(header_or_index, minimum_index))
330       end
331     end
332     
333     # 
334     # The provided +block+ is passed a header and field for each pair in the row
335     # and expected to return +true+ or +false+, depending on whether the pair
336     # should be deleted.
337     # 
338     # This method returns the row for chaining.
339     # 
340     def delete_if(&block)
341       @row.delete_if(&block)
342       
343       self  # for chaining
344     end
345     
346     # 
347     # This method accepts any number of arguments which can be headers, indices,
348     # Ranges of either, or two-element Arrays containing a header and offset.  
349     # Each argument will be replaced with a field lookup as described in
350     # CSV::Row.field().
351     # 
352     # If called with no arguments, all fields are returned.
353     # 
354     def fields(*headers_and_or_indices)
355       if headers_and_or_indices.empty?  # return all fields--no arguments
356         @row.map { |pair| pair.last }
357       else                              # or work like values_at()
358         headers_and_or_indices.inject(Array.new) do |all, h_or_i|
359           all + if h_or_i.is_a? Range
360             index_begin = h_or_i.begin.is_a?(Integer) ? h_or_i.begin :
361                                                         index(h_or_i.begin)
362             index_end   = h_or_i.end.is_a?(Integer)   ? h_or_i.end :
363                                                         index(h_or_i.end)
364             new_range   = h_or_i.exclude_end? ? (index_begin...index_end) :
365                                                 (index_begin..index_end)
366             fields.values_at(new_range)
367           else
368             [field(*Array(h_or_i))]
369           end
370         end
371       end
372     end
373     alias_method :values_at, :fields
374     
375     # 
376     # :call-seq:
377     #   index( header )
378     #   index( header, offset )
379     # 
380     # This method will return the index of a field with the provided +header+.
381     # The +offset+ can be used to locate duplicate header names, as described in
382     # CSV::Row.field().
383     # 
384     def index(header, minimum_index = 0)
385       # find the pair
386       index = headers[minimum_index..-1].index(header)
387       # return the index at the right offset, if we found one
388       index.nil? ? nil : index + minimum_index
389     end
390     
391     # Returns +true+ if +name+ is a header for this row, and +false+ otherwise.
392     def header?(name)
393       headers.include? name
394     end
395     alias_method :include?, :header?
396     
397     # 
398     # Returns +true+ if +data+ matches a field in this row, and +false+
399     # otherwise.
400     # 
401     def field?(data)
402       fields.include? data
403     end
405     include Enumerable
406     
407     # 
408     # Yields each pair of the row as header and field tuples (much like
409     # iterating over a Hash).
410     # 
411     # Support for Enumerable.
412     # 
413     # This method returns the row for chaining.
414     # 
415     def each(&block)
416       @row.each(&block)
417       
418       self  # for chaining
419     end
420     
421     # 
422     # Returns +true+ if this row contains the same headers and fields in the 
423     # same order as +other+.
424     # 
425     def ==(other)
426       @row == other.row
427     end
428     
429     # 
430     # Collapses the row into a simple Hash.  Be warning that this discards field
431     # order and clobbers duplicate fields.
432     # 
433     def to_hash
434       # flatten just one level of the internal Array
435       Hash[*@row.inject(Array.new) { |ary, pair| ary.push(*pair) }]
436     end
437     
438     # 
439     # Returns the row as a CSV String.  Headers are not used.  Equivalent to:
440     # 
441     #   csv_row.fields.to_csv( options )
442     # 
443     def to_csv(options = Hash.new)
444       fields.to_csv(options)
445     end
446     alias_method :to_s, :to_csv
447   end
448   
449   # 
450   # A CSV::Table is a two-dimensional data structure for representing CSV
451   # documents.  Tables allow you to work with the data by row or column, 
452   # manipulate the data, and even convert the results back to CSV, if needed.
453   # 
454   # All tables returned by CSV will be constructed from this class, if header
455   # row processing is activated.
456   # 
457   class Table
458     # 
459     # Construct a new CSV::Table from +array_of_rows+, which are expected
460     # to be CSV::Row objects.  All rows are assumed to have the same headers.
461     # 
462     # A CSV::Table object supports the following Array methods through
463     # delegation:
464     # 
465     # * empty?()
466     # * length()
467     # * size()
468     # 
469     def initialize(array_of_rows)
470       @table = array_of_rows
471       @mode  = :col_or_row
472     end
473     
474     # The current access mode for indexing and iteration.
475     attr_reader :mode
476     
477     # Internal data format used to compare equality.
478     attr_reader :table
479     protected   :table
481     ### Array Delegation ###
483     extend Forwardable
484     def_delegators :@table, :empty?, :length, :size
485     
486     # 
487     # Returns a duplicate table object, in column mode.  This is handy for 
488     # chaining in a single call without changing the table mode, but be aware 
489     # that this method can consume a fair amount of memory for bigger data sets.
490     # 
491     # This method returns the duplicate table for chaining.  Don't chain
492     # destructive methods (like []=()) this way though, since you are working
493     # with a duplicate.
494     # 
495     def by_col
496       self.class.new(@table.dup).by_col!
497     end
498     
499     # 
500     # Switches the mode of this table to column mode.  All calls to indexing and
501     # iteration methods will work with columns until the mode is changed again.
502     # 
503     # This method returns the table and is safe to chain.
504     # 
505     def by_col!
506       @mode = :col
507       
508       self
509     end
510     
511     # 
512     # Returns a duplicate table object, in mixed mode.  This is handy for 
513     # chaining in a single call without changing the table mode, but be aware 
514     # that this method can consume a fair amount of memory for bigger data sets.
515     # 
516     # This method returns the duplicate table for chaining.  Don't chain
517     # destructive methods (like []=()) this way though, since you are working
518     # with a duplicate.
519     # 
520     def by_col_or_row
521       self.class.new(@table.dup).by_col_or_row!
522     end
523     
524     # 
525     # Switches the mode of this table to mixed mode.  All calls to indexing and
526     # iteration methods will use the default intelligent indexing system until
527     # the mode is changed again.  In mixed mode an index is assumed to be a row
528     # reference while anything else is assumed to be column access by headers.
529     # 
530     # This method returns the table and is safe to chain.
531     # 
532     def by_col_or_row!
533       @mode = :col_or_row
534       
535       self
536     end
537     
538     # 
539     # Returns a duplicate table object, in row mode.  This is handy for chaining
540     # in a single call without changing the table mode, but be aware that this
541     # method can consume a fair amount of memory for bigger data sets.
542     # 
543     # This method returns the duplicate table for chaining.  Don't chain
544     # destructive methods (like []=()) this way though, since you are working
545     # with a duplicate.
546     # 
547     def by_row
548       self.class.new(@table.dup).by_row!
549     end
550     
551     # 
552     # Switches the mode of this table to row mode.  All calls to indexing and
553     # iteration methods will work with rows until the mode is changed again.
554     # 
555     # This method returns the table and is safe to chain.
556     # 
557     def by_row!
558       @mode = :row
559       
560       self
561     end
562     
563     # 
564     # Returns the headers for the first row of this table (assumed to match all
565     # other rows).  An empty Array is returned for empty tables.
566     # 
567     def headers
568       if @table.empty?
569         Array.new
570       else
571         @table.first.headers
572       end
573     end
574     
575     # 
576     # In the default mixed mode, this method returns rows for index access and
577     # columns for header access.  You can force the index association by first
578     # calling by_col!() or by_row!().
579     # 
580     # Columns are returned as an Array of values.  Altering that Array has no
581     # effect on the table.
582     # 
583     def [](index_or_header)
584       if @mode == :row or  # by index
585          (@mode == :col_or_row and index_or_header.is_a? Integer)
586         @table[index_or_header]
587       else                 # by header
588         @table.map { |row| row[index_or_header] }
589       end
590     end
591     
592     # 
593     # In the default mixed mode, this method assigns rows for index access and
594     # columns for header access.  You can force the index association by first
595     # calling by_col!() or by_row!().
596     # 
597     # Rows may be set to an Array of values (which will inherit the table's
598     # headers()) or a CSV::Row.
599     # 
600     # Columns may be set to a single value, which is copied to each row of the 
601     # column, or an Array of values.  Arrays of values are assigned to rows top
602     # to bottom in row major order.  Excess values are ignored and if the Array
603     # does not have a value for each row the extra rows will receive a +nil+.
604     # 
605     # Assigning to an existing column or row clobbers the data.  Assigning to
606     # new columns creates them at the right end of the table.
607     # 
608     def []=(index_or_header, value)
609       if @mode == :row or  # by index
610          (@mode == :col_or_row and index_or_header.is_a? Integer)
611         if value.is_a? Array
612           @table[index_or_header] = Row.new(headers, value)
613         else
614           @table[index_or_header] = value
615         end
616       else                 # set column
617         if value.is_a? Array  # multiple values
618           @table.each_with_index do |row, i|
619             if row.header_row?
620               row[index_or_header] = index_or_header
621             else
622               row[index_or_header] = value[i]
623             end
624           end
625         else                  # repeated value
626           @table.each do |row|
627             if row.header_row?
628               row[index_or_header] = index_or_header
629             else
630               row[index_or_header] = value
631             end
632           end
633         end
634       end
635     end
636     
637     # 
638     # The mixed mode default is to treat a list of indices as row access,
639     # returning the rows indicated.  Anything else is considered columnar
640     # access.  For columnar access, the return set has an Array for each row
641     # with the values indicated by the headers in each Array.  You can force
642     # column or row mode using by_col!() or by_row!().
643     # 
644     # You cannot mix column and row access.
645     # 
646     def values_at(*indices_or_headers)
647       if @mode == :row or  # by indices
648          ( @mode == :col_or_row and indices_or_headers.all? do |index|
649                                       index.is_a?(Integer)         or
650                                       ( index.is_a?(Range)         and
651                                         index.first.is_a?(Integer) and
652                                         index.last.is_a?(Integer) )
653                                     end )
654         @table.values_at(*indices_or_headers)
655       else                 # by headers
656         @table.map { |row| row.values_at(*indices_or_headers) }
657       end
658     end
660     # 
661     # Adds a new row to the bottom end of this table.  You can provide an Array,
662     # which will be converted to a CSV::Row (inheriting the table's headers()),
663     # or a CSV::Row.
664     # 
665     # This method returns the table for chaining.
666     # 
667     def <<(row_or_array)
668       if row_or_array.is_a? Array  # append Array
669         @table << Row.new(headers, row_or_array)
670       else                         # append Row
671         @table << row_or_array
672       end
673       
674       self  # for chaining
675     end
676     
677     # 
678     # A shortcut for appending multiple rows.  Equivalent to:
679     # 
680     #   rows.each { |row| self << row }
681     # 
682     # This method returns the table for chaining.
683     # 
684     def push(*rows)
685       rows.each { |row| self << row }
686       
687       self  # for chaining
688     end
690     # 
691     # Removes and returns the indicated column or row.  In the default mixed
692     # mode indices refer to rows and everything else is assumed to be a column
693     # header.  Use by_col!() or by_row!() to force the lookup.
694     # 
695     def delete(index_or_header)
696       if @mode == :row or  # by index
697          (@mode == :col_or_row and index_or_header.is_a? Integer)
698         @table.delete_at(index_or_header)
699       else                 # by header
700         @table.map { |row| row.delete(index_or_header).last }
701       end
702     end
703     
704     # 
705     # Removes any column or row for which the block returns +true+.  In the
706     # default mixed mode or row mode, iteration is the standard row major
707     # walking of rows.  In column mode, interation will +yield+ two element
708     # tuples containing the column name and an Array of values for that column.
709     # 
710     # This method returns the table for chaining.
711     # 
712     def delete_if(&block)
713       if @mode == :row or @mode == :col_or_row  # by index
714         @table.delete_if(&block)
715       else                                      # by header
716         to_delete = Array.new
717         headers.each_with_index do |header, i|
718           to_delete << header if block[[header, self[header]]]
719         end
720         to_delete.map { |header| delete(header) }
721       end
722       
723       self  # for chaining
724     end
725     
726     include Enumerable
727     
728     # 
729     # In the default mixed mode or row mode, iteration is the standard row major
730     # walking of rows.  In column mode, interation will +yield+ two element
731     # tuples containing the column name and an Array of values for that column.
732     # 
733     # This method returns the table for chaining.
734     # 
735     def each(&block)
736       if @mode == :col
737         headers.each { |header| block[[header, self[header]]] }
738       else
739         @table.each(&block)
740       end
741       
742       self  # for chaining
743     end
744     
745     # Returns +true+ if all rows of this table ==() +other+'s rows.
746     def ==(other)
747       @table == other.table
748     end
749     
750     # 
751     # Returns the table as an Array of Arrays.  Headers will be the first row,
752     # then all of the field rows will follow.
753     # 
754     def to_a
755       @table.inject([headers]) do |array, row|
756         if row.header_row?
757           array
758         else
759           array + [row.fields]
760         end
761       end
762     end
763     
764     # 
765     # Returns the table as a complete CSV String.  Headers will be listed first,
766     # then all of the field rows.
767     # 
768     def to_csv(options = Hash.new)
769       @table.inject([headers.to_csv(options)]) do |rows, row|
770         if row.header_row?
771           rows
772         else
773           rows + [row.fields.to_csv(options)]
774         end
775       end.join
776     end
777     alias_method :to_s, :to_csv
778   end
780   # The error thrown when the parser encounters illegal CSV formatting.
781   class MalformedCSVError < RuntimeError; end
782   
783   # 
784   # A FieldInfo Struct contains details about a field's position in the data
785   # source it was read from.  CSV will pass this Struct to some blocks that make
786   # decisions based on field structure.  See CSV.convert_fields() for an
787   # example.
788   # 
789   # <b><tt>index</tt></b>::  The zero-based index of the field in its row.
790   # <b><tt>line</tt></b>::   The line of the data source this row is from.
791   # <b><tt>header</tt></b>:: The header for the column, when available.
792   # 
793   FieldInfo = Struct.new(:index, :line, :header)
794   
795   # A Regexp used to find and convert some common Date formats.
796   DateMatcher     = / \A(?: (\w+,?\s+)?\w+\s+\d{1,2},?\s+\d{2,4} |
797                             \d{4}-\d{2}-\d{2} )\z /x
798   # A Regexp used to find and convert some common DateTime formats.
799   DateTimeMatcher =
800     / \A(?: (\w+,?\s+)?\w+\s+\d{1,2}\s+\d{1,2}:\d{1,2}:\d{1,2},?\s+\d{2,4} |
801             \d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2} )\z /x
802   # 
803   # This Hash holds the built-in converters of CSV that can be accessed by name.
804   # You can select Converters with CSV.convert() or through the +options+ Hash
805   # passed to CSV::new().
806   # 
807   # <b><tt>:integer</tt></b>::    Converts any field Integer() accepts.
808   # <b><tt>:float</tt></b>::      Converts any field Float() accepts.
809   # <b><tt>:numeric</tt></b>::    A combination of <tt>:integer</tt> 
810   #                               and <tt>:float</tt>.
811   # <b><tt>:date</tt></b>::       Converts any field Date::parse() accepts.
812   # <b><tt>:date_time</tt></b>::  Converts any field DateTime::parse() accepts.
813   # <b><tt>:all</tt></b>::        All built-in converters.  A combination of 
814   #                               <tt>:date_time</tt> and <tt>:numeric</tt>.
815   # 
816   # This Hash is intentionally left unfrozen and users should feel free to add
817   # values to it that can be accessed by all CSV objects.
818   # 
819   # To add a combo field, the value should be an Array of names.  Combo fields
820   # can be nested with other combo fields.
821   # 
822   Converters  = { :integer   => lambda { |f| Integer(f)        rescue f },
823                   :float     => lambda { |f| Float(f)          rescue f },
824                   :numeric   => [:integer, :float],
825                   :date      => lambda { |f|
826                     f =~ DateMatcher ? (Date.parse(f) rescue f) : f
827                   },
828                   :date_time => lambda { |f|
829                     f =~ DateTimeMatcher ? (DateTime.parse(f) rescue f) : f
830                   },
831                   :all       => [:date_time, :numeric] }
833   # 
834   # This Hash holds the built-in header converters of CSV that can be accessed
835   # by name.  You can select HeaderConverters with CSV.header_convert() or
836   # through the +options+ Hash passed to CSV::new().
837   # 
838   # <b><tt>:downcase</tt></b>::  Calls downcase() on the header String.
839   # <b><tt>:symbol</tt></b>::    The header String is downcased, spaces are
840   #                              replaced with underscores, non-word characters
841   #                              are dropped, and finally to_sym() is called.
842   # 
843   # This Hash is intetionally left unfrozen and users should feel free to add
844   # values to it that can be accessed by all CSV objects.
845   # 
846   # To add a combo field, the value should be an Array of names.  Combo fields
847   # can be nested with other combo fields.
848   # 
849   HeaderConverters = {
850     :downcase => lambda { |h| h.downcase },
851     :symbol   => lambda { |h|
852       h.downcase.tr(" ", "_").delete("^a-z0-9_").to_sym
853     }
854   }
855   
856   # 
857   # The options used when no overrides are given by calling code.  They are:
858   # 
859   # <b><tt>:col_sep</tt></b>::            <tt>","</tt>
860   # <b><tt>:row_sep</tt></b>::            <tt>:auto</tt>
861   # <b><tt>:quote_char</tt></b>::         <tt>'"'</tt>
862   # <b><tt>:converters</tt></b>::         +nil+
863   # <b><tt>:unconverted_fields</tt></b>:: +nil+
864   # <b><tt>:headers</tt></b>::            +false+
865   # <b><tt>:return_headers</tt></b>::     +false+
866   # <b><tt>:header_converters</tt></b>::  +nil+
867   # <b><tt>:skip_blanks</tt></b>::        +false+
868   # <b><tt>:force_quotes</tt></b>::       +false+
869   # 
870   DEFAULT_OPTIONS = { :col_sep            => ",",
871                       :row_sep            => :auto,
872                       :quote_char         => '"', 
873                       :converters         => nil,
874                       :unconverted_fields => nil,
875                       :headers            => false,
876                       :return_headers     => false,
877                       :header_converters  => nil,
878                       :skip_blanks        => false,
879                       :force_quotes       => false }.freeze
880   
881   # 
882   # This method allows you to serialize an Array of Ruby objects to a String or
883   # File of CSV data.  This is not as powerful as Marshal or YAML, but perhaps
884   # useful for spreadsheet and database interaction.
885   # 
886   # Out of the box, this method is intended to work with simple data objects or
887   # Structs.  It will serialize a list of instance variables and/or
888   # Struct.members().
889   # 
890   # If you need need more complicated serialization, you can control the process
891   # by adding methods to the class to be serialized.
892   # 
893   # A class method csv_meta() is responsible for returning the first row of the
894   # document (as an Array).  This row is considered to be a Hash of the form
895   # key_1,value_1,key_2,value_2,...  CSV::load() expects to find a class key
896   # with a value of the stringified class name and CSV::dump() will create this,
897   # if you do not define this method.  This method is only called on the first
898   # object of the Array.
899   # 
900   # The next method you can provide is an instance method called csv_headers().
901   # This method is expected to return the second line of the document (again as
902   # an Array), which is to be used to give each column a header.  By default,
903   # CSV::load() will set an instance variable if the field header starts with an
904   # @ character or call send() passing the header as the method name and
905   # the field value as an argument.  This method is only called on the first
906   # object of the Array.
907   # 
908   # Finally, you can provide an instance method called csv_dump(), which will
909   # be passed the headers.  This should return an Array of fields that can be
910   # serialized for this object.  This method is called once for every object in
911   # the Array.
912   # 
913   # The +io+ parameter can be used to serialize to a File, and +options+ can be
914   # anything CSV::new() accepts.
915   # 
916   def self.dump(ary_of_objs, io = "", options = Hash.new)
917     obj_template = ary_of_objs.first
918     
919     csv = new(io, options)
920     
921     # write meta information
922     begin
923       csv << obj_template.class.csv_meta
924     rescue NoMethodError
925       csv << [:class, obj_template.class]
926     end
928     # write headers
929     begin
930       headers = obj_template.csv_headers
931     rescue NoMethodError
932       headers = obj_template.instance_variables.sort
933       if obj_template.class.ancestors.find { |cls| cls.to_s =~ /\AStruct\b/ }
934         headers += obj_template.members.map { |mem| "#{mem}=" }.sort
935       end
936     end
937     csv << headers
938     
939     # serialize each object
940     ary_of_objs.each do |obj|
941       begin
942         csv << obj.csv_dump(headers)
943       rescue NoMethodError
944         csv << headers.map do |var|
945           if var[0] == ?@
946             obj.instance_variable_get(var)
947           else
948             obj[var[0..-2]]
949           end
950         end
951       end
952     end
953     
954     if io.is_a? String
955       csv.string
956     else
957       csv.close
958     end
959   end
960   
961   # 
962   # :call-seq:
963   #   filter( options = Hash.new ) { |row| ... }
964   #   filter( input, options = Hash.new ) { |row| ... }
965   #   filter( input, output, options = Hash.new ) { |row| ... }
966   # 
967   # This method is a convenience for building Unix-like filters for CSV data.
968   # Each row is yielded to the provided block which can alter it as needed.  
969   # After the block returns, the row is appended to +output+ altered or not.
970   # 
971   # The +input+ and +output+ arguments can be anything CSV::new() accepts
972   # (generally String or IO objects).  If not given, they default to 
973   # <tt>ARGF</tt> and <tt>$stdout</tt>.
974   # 
975   # The +options+ parameter is also filtered down to CSV::new() after some
976   # clever key parsing.  Any key beginning with <tt>:in_</tt> or 
977   # <tt>:input_</tt> will have that leading identifier stripped and will only
978   # be used in the +options+ Hash for the +input+ object.  Keys starting with
979   # <tt>:out_</tt> or <tt>:output_</tt> affect only +output+.  All other keys 
980   # are assigned to both objects.
981   # 
982   # The <tt>:output_row_sep</tt> +option+ defaults to
983   # <tt>$INPUT_RECORD_SEPARATOR</tt> (<tt>$/</tt>).
984   # 
985   def self.filter(*args)
986     # parse options for input, output, or both
987     in_options, out_options = Hash.new, {:row_sep => $INPUT_RECORD_SEPARATOR}
988     if args.last.is_a? Hash
989       args.pop.each do |key, value|
990         case key.to_s
991         when /\Ain(?:put)?_(.+)\Z/
992           in_options[$1.to_sym] = value
993         when /\Aout(?:put)?_(.+)\Z/
994           out_options[$1.to_sym] = value
995         else
996           in_options[key]  = value
997           out_options[key] = value
998         end
999       end
1000     end
1001     # build input and output wrappers
1002     input  = new(args.shift || ARGF,    in_options)
1003     output = new(args.shift || $stdout, out_options)
1004     
1005     # read, yield, write
1006     input.each do |row|
1007       yield row
1008       output << row
1009     end
1010   end
1011   
1012   # 
1013   # This method is intended as the primary interface for reading CSV files.  You
1014   # pass a +path+ and any +options+ you wish to set for the read.  Each row of
1015   # file will be passed to the provided +block+ in turn.
1016   # 
1017   # The +options+ parameter can be anything CSV::new() understands.
1018   # 
1019   def self.foreach(path, options = Hash.new, &block)
1020     open(path, options) do |csv|
1021       csv.each(&block)
1022     end
1023   end
1025   # 
1026   # :call-seq:
1027   #   generate( str, options = Hash.new ) { |csv| ... }
1028   #   generate( options = Hash.new ) { |csv| ... }
1029   # 
1030   # This method wraps a String you provide, or an empty default String, in a 
1031   # CSV object which is passed to the provided block.  You can use the block to
1032   # append CSV rows to the String and when the block exits, the final String
1033   # will be returned.
1034   # 
1035   # Note that a passed String *is* modfied by this method.  Call dup() before
1036   # passing if you need a new String.
1037   # 
1038   # The +options+ parameter can be anthing CSV::new() understands.
1039   # 
1040   def self.generate(*args)
1041     # add a default empty String, if none was given
1042     if args.first.is_a? String
1043       io = StringIO.new(args.shift)
1044       io.seek(0, IO::SEEK_END)
1045       args.unshift(io)
1046     else
1047       args.unshift("")
1048     end
1049     csv = new(*args)  # wrap
1050     yield csv         # yield for appending
1051     csv.string        # return final String
1052   end
1054   # 
1055   # This method is a shortcut for converting a single row (Array) into a CSV 
1056   # String.
1057   # 
1058   # The +options+ parameter can be anthing CSV::new() understands.
1059   # 
1060   # The <tt>:row_sep</tt> +option+ defaults to <tt>$INPUT_RECORD_SEPARATOR</tt>
1061   # (<tt>$/</tt>) when calling this method.
1062   # 
1063   def self.generate_line(row, options = Hash.new)
1064     options = {:row_sep => $INPUT_RECORD_SEPARATOR}.merge(options)
1065     (new("", options) << row).string
1066   end
1067   
1068   # 
1069   # This method will return a CSV instance, just like CSV::new(), but the
1070   # instance will be cached and returned for all future calls to this method for
1071   # the same +data+ object (tested by Object#object_id()) with the same
1072   # +options+.
1073   # 
1074   # If a block is given, the instance is passed to the block and the return
1075   # value becomes the return value of the block.
1076   # 
1077   def self.instance(data = $stdout, options = Hash.new)
1078     # create a _signature_ for this method call, data object and options
1079     sig = [data.object_id] +
1080           options.values_at(*DEFAULT_OPTIONS.keys.sort_by { |sym| sym.to_s })
1081     
1082     # fetch or create the instance for this signature
1083     @@instances ||= Hash.new
1084     instance    =   (@@instances[sig] ||= new(data, options))
1086     if block_given?
1087       yield instance  # run block, if given, returning result
1088     else
1089       instance        # or return the instance
1090     end
1091   end
1092   
1093   # 
1094   # This method is the reading counterpart to CSV::dump().  See that method for
1095   # a detailed description of the process.
1096   # 
1097   # You can customize loading by adding a class method called csv_load() which 
1098   # will be passed a Hash of meta information, an Array of headers, and an Array
1099   # of fields for the object the method is expected to return.
1100   # 
1101   # Remember that all fields will be Strings after this load.  If you need
1102   # something else, use +options+ to setup converters or provide a custom
1103   # csv_load() implementation.
1104   # 
1105   def self.load(io_or_str, options = Hash.new)
1106     csv = new(io_or_str, options)
1107     
1108     # load meta information
1109     meta = Hash[*csv.shift]
1110     cls  = meta["class"].split("::").inject(Object) do |c, const|
1111       c.const_get(const)
1112     end
1113     
1114     # load headers
1115     headers = csv.shift
1116     
1117     # unserialize each object stored in the file
1118     results = csv.inject(Array.new) do |all, row|
1119       begin
1120         obj = cls.csv_load(meta, headers, row)
1121       rescue NoMethodError
1122         obj = cls.allocate
1123         headers.zip(row) do |name, value|
1124           if name[0] == ?@
1125             obj.instance_variable_set(name, value)
1126           else
1127             obj.send(name, value)
1128           end
1129         end
1130       end
1131       all << obj
1132     end
1133     
1134     csv.close unless io_or_str.is_a? String
1135     
1136     results
1137   end
1138   
1139   # 
1140   # :call-seq:
1141   #   open( filename, mode="r", options = Hash.new ) { |csv| ... }
1142   #   open( filename, mode="r", options = Hash.new )
1143   # 
1144   # This method opens an IO object, and wraps that with CSV.  This is intended
1145   # as the primary interface for writing a CSV file.
1146   # 
1147   # You may pass any +args+ Ruby's open() understands followed by an optional
1148   # Hash containing any +options+ CSV::new() understands.
1149   # 
1150   # This method works like Ruby's open() call, in that it will pass a CSV object
1151   # to a provided block and close it when the block terminates, or it will
1152   # return the CSV object when no block is provided.  (*Note*: This is different
1153   # from the Ruby 1.8 CSV library which passed rows to the block.  Use
1154   # CSV::foreach() for that behavior.)
1155   # 
1156   # An opened CSV object will delegate to many IO methods, for convenience.  You
1157   # may call:
1158   # 
1159   # * binmode()
1160   # * close()
1161   # * close_read()
1162   # * close_write()
1163   # * closed?()
1164   # * eof()
1165   # * eof?()
1166   # * fcntl()
1167   # * fileno()
1168   # * flush()
1169   # * fsync()
1170   # * ioctl()
1171   # * isatty()
1172   # * pid()
1173   # * pos()
1174   # * reopen()
1175   # * seek()
1176   # * stat()
1177   # * sync()
1178   # * sync=()
1179   # * tell()
1180   # * to_i()
1181   # * to_io()
1182   # * tty?()
1183   # 
1184   def self.open(*args)
1185     # find the +options+ Hash
1186     options = if args.last.is_a? Hash then args.pop else Hash.new end
1187     # wrap a File opened with the remaining +args+
1188     csv     = new(File.open(*args), options)
1189     
1190     # handle blocks like Ruby's open(), not like the CSV library
1191     if block_given?
1192       begin
1193         yield csv
1194       ensure
1195         csv.close
1196       end
1197     else
1198       csv
1199     end
1200   end
1201   
1202   # 
1203   # :call-seq:
1204   #   parse( str, options = Hash.new ) { |row| ... }
1205   #   parse( str, options = Hash.new )
1206   # 
1207   # This method can be used to easily parse CSV out of a String.  You may either
1208   # provide a +block+ which will be called with each row of the String in turn,
1209   # or just use the returned Array of Arrays (when no +block+ is given).
1210   # 
1211   # You pass your +str+ to read from, and an optional +options+ Hash containing
1212   # anything CSV::new() understands.
1213   # 
1214   def self.parse(*args, &block)
1215     csv = new(*args)
1216     if block.nil?  # slurp contents, if no block is given
1217       begin
1218         csv.read
1219       ensure
1220         csv.close
1221       end
1222     else           # or pass each row to a provided block
1223       csv.each(&block)
1224     end
1225   end
1226   
1227   # 
1228   # This method is a shortcut for converting a single line of a CSV String into 
1229   # a into an Array.  Note that if +line+ contains multiple rows, anything 
1230   # beyond the first row is ignored.
1231   # 
1232   # The +options+ parameter can be anthing CSV::new() understands.
1233   # 
1234   def self.parse_line(line, options = Hash.new)
1235     new(line, options).shift
1236   end
1237   
1238   # 
1239   # Use to slurp a CSV file into an Array of Arrays.  Pass the +path+ to the 
1240   # file and any +options+ CSV::new() understands.
1241   # 
1242   def self.read(path, options = Hash.new)
1243     open(path, options) { |csv| csv.read }
1244   end
1245   
1246   # Alias for CSV::read().
1247   def self.readlines(*args)
1248     read(*args)
1249   end
1250   
1251   # 
1252   # A shortcut for:
1253   # 
1254   #   CSV.read( path, { :headers           => true,
1255   #                     :converters        => :numeric,
1256   #                     :header_converters => :symbol }.merge(options) )
1257   # 
1258   def self.table(path, options = Hash.new)
1259     read( path, { :headers           => true,
1260                   :converters        => :numeric,
1261                   :header_converters => :symbol }.merge(options) )
1262   end
1263   
1264   # 
1265   # This constructor will wrap either a String or IO object passed in +data+ for
1266   # reading and/or writing.  In addition to the CSV instance methods, several IO
1267   # methods are delegated.  (See CSV::open() for a complete list.)  If you pass
1268   # a String for +data+, you can later retrieve it (after writing to it, for
1269   # example) with CSV.string().
1270   # 
1271   # Note that a wrapped String will be positioned at at the beginning (for 
1272   # reading).  If you want it at the end (for writing), use CSV::generate().
1273   # If you want any other positioning, pass a preset StringIO object instead.
1274   # 
1275   # You may set any reading and/or writing preferences in the +options+ Hash.  
1276   # Available options are:
1277   # 
1278   # <b><tt>:col_sep</tt></b>::            The String placed between each field.
1279   # <b><tt>:row_sep</tt></b>::            The String appended to the end of each
1280   #                                       row.  This can be set to the special
1281   #                                       <tt>:auto</tt> setting, which requests
1282   #                                       that CSV automatically discover this
1283   #                                       from the data.  Auto-discovery reads
1284   #                                       ahead in the data looking for the next
1285   #                                       <tt>"\r\n"</tt>, <tt>"\n"</tt>, or
1286   #                                       <tt>"\r"</tt> sequence.  A sequence
1287   #                                       will be selected even if it occurs in
1288   #                                       a quoted field, assuming that you
1289   #                                       would have the same line endings
1290   #                                       there.  If none of those sequences is
1291   #                                       found, +data+ is <tt>ARGF</tt>,
1292   #                                       <tt>STDIN</tt>, <tt>STDOUT</tt>, or
1293   #                                       <tt>STDERR</tt>, or the stream is only
1294   #                                       available for output, the default
1295   #                                       <tt>$INPUT_RECORD_SEPARATOR</tt>
1296   #                                       (<tt>$/</tt>) is used.  Obviously,
1297   #                                       discovery takes a little time.  Set
1298   #                                       manually if speed is important.
1299   # <b><tt>:quote_char</tt></b>::         The character used to quote fields.
1300   #                                       This has to be a single character
1301   #                                       String.  This is useful for
1302   #                                       application that incorrectly use
1303   #                                       <tt>'</tt> as the quote character
1304   #                                       instead of the correct <tt>"</tt>.
1305   #                                       CSV will always consider a double
1306   #                                       sequence this character to be an
1307   #                                       escaped quote.
1308   # <b><tt>:converters</tt></b>::         An Array of names from the Converters
1309   #                                       Hash and/or lambdas that handle custom
1310   #                                       conversion.  A single converter
1311   #                                       doesn't have to be in an Array.
1312   # <b><tt>:unconverted_fields</tt></b>:: If set to +true+, an
1313   #                                       unconverted_fields() method will be
1314   #                                       added to all returned rows (Array or
1315   #                                       CSV::Row) that will return the fields
1316   #                                       as they were before conversion.  Note
1317   #                                       that <tt>:headers</tt> supplied by
1318   #                                       Array or String were not fields of the
1319   #                                       document and thus will have an empty
1320   #                                       Array attached.
1321   # <b><tt>:headers</tt></b>::            If set to <tt>:first_row</tt> or 
1322   #                                       +true+, the initial row of the CSV
1323   #                                       file will be treated as a row of
1324   #                                       headers.  If set to an Array, the
1325   #                                       contents will be used as the headers.
1326   #                                       If set to a String, the String is run
1327   #                                       through a call of CSV::parse_line() to
1328   #                                       produce an Array of headers.  This
1329   #                                       setting causes CSV.shift() to return
1330   #                                       rows as CSV::Row objects instead of
1331   #                                       Arrays and CSV.read() to return
1332   #                                       CSV::Table objects instead of an Array
1333   #                                       of Arrays.
1334   # <b><tt>:return_headers</tt></b>::     When +false+, header rows are silently
1335   #                                       swallowed.  If set to +true+, header
1336   #                                       rows are returned in a CSV::Row object
1337   #                                       with identical headers and
1338   #                                       fields (save that the fields do not go
1339   #                                       through the converters).
1340   # <b><tt>:header_converters</tt></b>::  Identical in functionality to
1341   #                                       <tt>:converters</tt> save that the
1342   #                                       conversions are only made to header
1343   #                                       rows.
1344   # <b><tt>:skip_blanks</tt></b>::        When set to a +true+ value, CSV will
1345   #                                       skip over any rows with no content.
1346   # <b><tt>:force_quotes</tt></b>::       When set to a +true+ value, CSV will
1347   #                                       quote all CSV fields it creates.
1348   # 
1349   # See CSV::DEFAULT_OPTIONS for the default settings.
1350   # 
1351   # Options cannot be overriden in the instance methods for performance reasons,
1352   # so be sure to set what you want here.
1353   # 
1354   def initialize(data, options = Hash.new)
1355     # build the options for this read/write
1356     options = DEFAULT_OPTIONS.merge(options)
1357     
1358     # create the IO object we will read from
1359     @io = if data.is_a? String then StringIO.new(data) else data end
1360     
1361     init_separators(options)
1362     init_parsers(options)
1363     init_converters(options)
1364     init_headers(options)
1365     
1366     unless options.empty?
1367       raise ArgumentError, "Unknown options:  #{options.keys.join(', ')}."
1368     end
1369     
1370     # track our own lineno since IO gets confused about line-ends is CSV fields
1371     @lineno = 0
1372   end
1373   
1374   # 
1375   # The line number of the last row read from this file.  Fields with nested 
1376   # line-end characters will not affect this count.
1377   # 
1378   attr_reader :lineno
1379   
1380   ### IO and StringIO Delegation ###
1381   
1382   extend Forwardable
1383   def_delegators :@io, :binmode, :close, :close_read, :close_write, :closed?,
1384                        :eof, :eof?, :fcntl, :fileno, :flush, :fsync, :ioctl,
1385                        :isatty, :pid, :pos, :reopen, :seek, :stat, :string,
1386                        :sync, :sync=, :tell, :to_i, :to_io, :tty?
1387   
1388   # Rewinds the underlying IO object and resets CSV's lineno() counter.
1389   def rewind
1390     @headers = nil
1391     @lineno  = 0
1392     
1393     @io.rewind
1394   end
1396   ### End Delegation ###
1397   
1398   # 
1399   # The primary write method for wrapped Strings and IOs, +row+ (an Array or
1400   # CSV::Row) is converted to CSV and appended to the data source.  When a
1401   # CSV::Row is passed, only the row's fields() are appended to the output.
1402   # 
1403   # The data source must be open for writing.
1404   # 
1405   def <<(row)
1406     # handle CSV::Row objects and Hashes
1407     row = case row
1408       when self.class::Row then row.fields
1409       when Hash            then @headers.map { |header| row[header] }
1410       else                      row
1411     end
1413     @headers =  row if header_row?
1414     @lineno  += 1
1416     @io << row.map(&@quote).join(@col_sep) + @row_sep  # quote and separate
1417     
1418     self  # for chaining
1419   end
1420   alias_method :add_row, :<<
1421   alias_method :puts,    :<<
1422   
1423   # 
1424   # :call-seq:
1425   #   convert( name )
1426   #   convert { |field| ... }
1427   #   convert { |field, field_info| ... }
1428   # 
1429   # You can use this method to install a CSV::Converters built-in, or provide a
1430   # block that handles a custom conversion.
1431   # 
1432   # If you provide a block that takes one argument, it will be passed the field
1433   # and is expected to return the converted value or the field itself.  If your
1434   # block takes two arguments, it will also be passed a FieldInfo Struct, 
1435   # containing details about the field.  Again, the block should return a 
1436   # converted field or the field itself.
1437   # 
1438   def convert(name = nil, &converter)
1439     add_converter(:converters, self.class::Converters, name, &converter)
1440   end
1442   # 
1443   # :call-seq:
1444   #   header_convert( name )
1445   #   header_convert { |field| ... }
1446   #   header_convert { |field, field_info| ... }
1447   # 
1448   # Identical to CSV.convert(), but for header rows.
1449   # 
1450   # Note that this method must be called before header rows are read to have any
1451   # effect.
1452   # 
1453   def header_convert(name = nil, &converter)
1454     add_converter( :header_converters,
1455                    self.class::HeaderConverters,
1456                    name,
1457                    &converter )
1458   end
1459   
1460   include Enumerable
1461   
1462   # 
1463   # Yields each row of the data source in turn.
1464   # 
1465   # Support for Enumerable.
1466   # 
1467   # The data source must be open for reading.
1468   # 
1469   def each
1470     while row = shift
1471       yield row
1472     end
1473   end
1474   
1475   # 
1476   # Slurps the remaining rows and returns an Array of Arrays.
1477   # 
1478   # The data source must be open for reading.
1479   # 
1480   def read
1481     rows = to_a
1482     if @use_headers
1483       Table.new(rows)
1484     else
1485       rows
1486     end
1487   end
1488   alias_method :readlines, :read
1489   
1490   # Returns +true+ if the next row read will be a header row.
1491   def header_row?
1492     @use_headers and @headers.nil?
1493   end
1494   
1495   # 
1496   # The primary read method for wrapped Strings and IOs, a single row is pulled
1497   # from the data source, parsed and returned as an Array of fields (if header
1498   # rows are not used) or a CSV::Row (when header rows are used).
1499   # 
1500   # The data source must be open for reading.
1501   # 
1502   def shift
1503     #########################################################################
1504     ### This method is purposefully kept a bit long as simple conditional ###
1505     ### checks are faster than numerous (expensive) method calls.         ###
1506     #########################################################################
1507     
1508     # handle headers not based on document content
1509     if header_row? and @return_headers and
1510        [Array, String].include? @use_headers.class
1511       if @unconverted_fields
1512         return add_unconverted_fields(parse_headers, Array.new)
1513       else
1514         return parse_headers
1515       end
1516     end
1517     
1518     # begin with a blank line, so we can always add to it
1519     line = ""
1521     # 
1522     # it can take multiple calls to <tt>@io.gets()</tt> to get a full line,
1523     # because of \r and/or \n characters embedded in quoted fields
1524     # 
1525     loop do
1526       # add another read to the line
1527       (line += @io.gets(@row_sep)) rescue return nil
1528       # copy the line so we can chop it up in parsing
1529       parse = line.dup
1530       parse.sub!(@parsers[:line_end], "")
1531       
1532       # 
1533       # I believe a blank line should be an <tt>Array.new</tt>, not Ruby 1.8
1534       # CSV's <tt>[nil]</tt>
1535       # 
1536       if parse.empty?
1537         @lineno += 1
1538         if @skip_blanks
1539           line = ""
1540           next
1541         elsif @unconverted_fields
1542           return add_unconverted_fields(Array.new, Array.new)
1543         elsif @use_headers
1544           return self.class::Row.new(Array.new, Array.new)
1545         else
1546           return Array.new
1547         end
1548       end
1550       # 
1551       # shave leading empty fields if needed, because the main parser chokes 
1552       # on these
1553       # 
1554       csv = if parse.sub!(@parsers[:leading_fields], "")
1555         [nil] * ($&.length / @col_sep.length)
1556       else
1557         Array.new
1558       end
1559       # 
1560       # then parse the main fields with a hyper-tuned Regexp from 
1561       # Mastering Regular Expressions, Second Edition
1562       # 
1563       parse.gsub!(@parsers[:csv_row]) do
1564         csv << if $1.nil?     # we found an unquoted field
1565           if $2.empty?        # switch empty unquoted fields to +nil+...
1566             nil               # for Ruby 1.8 CSV compatibility
1567           else
1568             # I decided to take a strict approach to CSV parsing...
1569             if $2.count("\r\n").zero?  # verify correctness of field...
1570               $2
1571             else
1572               # or throw an Exception
1573               raise MalformedCSVError, "Unquoted fields do not allow " +
1574                                        "\\r or \\n (line #{lineno + 1})."
1575             end
1576           end
1577         else                  # we found a quoted field...
1578           $1.gsub(@quote_char * 2, @quote_char)  # unescape contents
1579         end
1580         ""  # gsub!'s replacement, clear the field
1581       end
1583       # if parse is empty?(), we found all the fields on the line...
1584       if parse.empty?
1585         @lineno += 1
1587         # save fields unconverted fields, if needed...
1588         unconverted = csv.dup if @unconverted_fields
1590         # convert fields, if needed...
1591         csv = convert_fields(csv) unless @use_headers or @converters.empty?
1592         # parse out header rows and handle CSV::Row conversions...
1593         csv = parse_headers(csv)  if     @use_headers
1595         # inject unconverted fields and accessor, if requested...
1596         if @unconverted_fields and not csv.respond_to? :unconverted_fields
1597           add_unconverted_fields(csv, unconverted)
1598         end
1600         # return the results
1601         break csv
1602       end
1603       # if we're not empty?() but at eof?(), a quoted field wasn't closed...
1604       if @io.eof?
1605         raise MalformedCSVError, "Unclosed quoted field on line #{lineno + 1}."
1606       end
1607       # otherwise, we need to loop and pull some more data to complete the row
1608     end
1609   end
1610   alias_method :gets,     :shift
1611   alias_method :readline, :shift
1612   
1613   private
1614   
1615   # 
1616   # Stores the indicated separators for later use.
1617   # 
1618   # If auto-discovery was requested for <tt>@row_sep</tt>, this method will read
1619   # ahead in the <tt>@io</tt> and try to find one.  +ARGF+, +STDIN+, +STDOUT+,
1620   # +STDERR+ and any stream open for output only with a default
1621   # <tt>@row_sep</tt> of <tt>$INPUT_RECORD_SEPARATOR</tt> (<tt>$/</tt>).
1622   # 
1623   # This method also establishes the quoting rules used for CSV output.
1624   # 
1625   def init_separators(options)
1626     # store the selected separators
1627     @col_sep    = options.delete(:col_sep)
1628     @row_sep    = options.delete(:row_sep)
1629     @quote_char = options.delete(:quote_char)
1631     if @quote_char.length != 1
1632       raise ArgumentError, ":quote_char has to be a single character String"
1633     end
1634     
1635     # automatically discover row separator when requested
1636     if @row_sep == :auto
1637       if [ARGF, STDIN, STDOUT, STDERR].include?(@io) or
1638          (defined?(Zlib) and @io.class == Zlib::GzipWriter)
1639         @row_sep = $INPUT_RECORD_SEPARATOR
1640       else
1641         begin
1642           saved_pos = @io.pos  # remember where we were
1643           while @row_sep == :auto
1644             # 
1645             # if we run out of data, it's probably a single line 
1646             # (use a sensible default)
1647             # 
1648             if @io.eof?
1649               @row_sep = $INPUT_RECORD_SEPARATOR
1650               break
1651             end
1652       
1653             # read ahead a bit
1654             sample =  @io.read(1024)
1655             sample += @io.read(1) if sample[-1..-1] == "\r" and not @io.eof?
1656       
1657             # try to find a standard separator
1658             if sample =~ /\r\n?|\n/
1659               @row_sep = $&
1660               break
1661             end
1662           end
1663           # tricky seek() clone to work around GzipReader's lack of seek()
1664           @io.rewind
1665           # reset back to the remembered position
1666           while saved_pos > 1024  # avoid loading a lot of data into memory
1667             @io.read(1024)
1668             saved_pos -= 1024
1669           end
1670           @io.read(saved_pos) if saved_pos.nonzero?
1671         rescue IOError  # stream not opened for reading
1672           @row_sep = $INPUT_RECORD_SEPARATOR
1673         end
1674       end
1675     end
1676     
1677     # establish quoting rules
1678     do_quote = lambda do |field|
1679       @quote_char                                      +
1680       String(field).gsub(@quote_char, @quote_char * 2) +
1681       @quote_char
1682     end
1683     @quote = if options.delete(:force_quotes)
1684       do_quote
1685     else
1686       lambda do |field|
1687         if field.nil?  # represent +nil+ fields as empty unquoted fields
1688           ""
1689         else
1690           field = String(field)  # Stringify fields
1691           # represent empty fields as empty quoted fields
1692           if field.empty? or
1693              field.count("\r\n#{@col_sep}#{@quote_char}").nonzero?
1694             do_quote.call(field)
1695           else
1696             field  # unquoted field
1697           end
1698         end
1699       end
1700     end
1701   end
1702   
1703   # Pre-compiles parsers and stores them by name for access during reads.
1704   def init_parsers(options)
1705     # store the parser behaviors
1706     @skip_blanks = options.delete(:skip_blanks)
1707     
1708     # prebuild Regexps for faster parsing
1709     esc_col_sep = Regexp.escape(@col_sep)
1710     esc_row_sep = Regexp.escape(@row_sep)
1711     esc_quote   = Regexp.escape(@quote_char)
1712     @parsers = {
1713       :leading_fields =>
1714         /\A(?:#{esc_col_sep})+/,                 # for empty leading fields
1715       :csv_row        =>
1716         ### The Primary Parser ###
1717         / \G(?:^|#{esc_col_sep})                 # anchor the match
1718           (?: #{esc_quote}( (?>[^#{esc_quote}]*) # find quoted fields
1719                             (?> #{esc_quote*2}
1720                                 [^#{esc_quote}]* )* )#{esc_quote}
1721               |                                  # ... or ...
1722               ([^#{esc_quote}#{esc_col_sep}]*)   # unquoted fields
1723               )/x,
1724         ### End Primary Parser ###
1725       :line_end       =>
1726         /#{esc_row_sep}\z/                       # safer than chomp!()
1727     }
1728   end
1729   
1730   # 
1731   # Loads any converters requested during construction.
1732   # 
1733   # If +field_name+ is set <tt>:converters</tt> (the default) field converters
1734   # are set.  When +field_name+ is <tt>:header_converters</tt> header converters
1735   # are added instead.
1736   # 
1737   # The <tt>:unconverted_fields</tt> option is also actived for 
1738   # <tt>:converters</tt> calls, if requested.
1739   # 
1740   def init_converters(options, field_name = :converters)
1741     if field_name == :converters
1742       @unconverted_fields = options.delete(:unconverted_fields)
1743     end
1745     instance_variable_set("@#{field_name}", Array.new)
1746     
1747     # find the correct method to add the converters
1748     convert = method(field_name.to_s.sub(/ers\Z/, ""))
1749     
1750     # load converters
1751     unless options[field_name].nil?
1752       # allow a single converter not wrapped in an Array
1753       unless options[field_name].is_a? Array
1754         options[field_name] = [options[field_name]]
1755       end
1756       # load each converter...
1757       options[field_name].each do |converter|
1758         if converter.is_a? Proc  # custom code block
1759           convert.call(&converter)
1760         else                     # by name
1761           convert.call(converter)
1762         end
1763       end
1764     end
1765     
1766     options.delete(field_name)
1767   end
1768   
1769   # Stores header row settings and loads header converters, if needed.
1770   def init_headers(options)
1771     @use_headers    = options.delete(:headers)
1772     @return_headers = options.delete(:return_headers)
1774     # headers must be delayed until shift(), in case they need a row of content
1775     @headers = nil
1776     
1777     init_converters(options, :header_converters)
1778   end
1779   
1780   # 
1781   # The actual work method for adding converters, used by both CSV.convert() and
1782   # CSV.header_convert().
1783   # 
1784   # This method requires the +var_name+ of the instance variable to place the
1785   # converters in, the +const+ Hash to lookup named converters in, and the
1786   # normal parameters of the CSV.convert() and CSV.header_convert() methods.
1787   # 
1788   def add_converter(var_name, const, name = nil, &converter)
1789     if name.nil?  # custom converter
1790       instance_variable_get("@#{var_name}") << converter
1791     else          # named converter
1792       combo = const[name]
1793       case combo
1794       when Array  # combo converter
1795         combo.each do |converter_name|
1796           add_converter(var_name, const, converter_name)
1797         end
1798       else        # individual named converter
1799         instance_variable_get("@#{var_name}") << combo
1800       end
1801     end
1802   end
1803   
1804   # 
1805   # Processes +fields+ with <tt>@converters</tt>, or <tt>@header_converters</tt>
1806   # if +headers+ is passed as +true+, returning the converted field set.  Any
1807   # converter that changes the field into something other than a String halts
1808   # the pipeline of conversion for that field.  This is primarily an efficiency
1809   # shortcut.
1810   # 
1811   def convert_fields(fields, headers = false)
1812     # see if we are converting headers or fields
1813     converters = headers ? @header_converters : @converters
1814     
1815     fields.each_with_index.map do |field, index|  # map_with_index
1816       converters.each do |converter|
1817         field = if converter.arity == 1  # straight field converter
1818           converter[field]
1819         else                             # FieldInfo converter
1820           header = @use_headers && !headers ? @headers[index] : nil
1821           converter[field, FieldInfo.new(index, lineno, header)]
1822         end
1823         break unless field.is_a? String  # short-curcuit pipeline for speed
1824       end
1825       field  # final state of each field, converted or original
1826     end
1827   end
1828   
1829   # 
1830   # This methods is used to turn a finished +row+ into a CSV::Row.  Header rows
1831   # are also dealt with here, either by returning a CSV::Row with identical
1832   # headers and fields (save that the fields do not go through the converters)
1833   # or by reading past them to return a field row. Headers are also saved in
1834   # <tt>@headers</tt> for use in future rows.
1835   # 
1836   # When +nil+, +row+ is assumed to be a header row not based on an actual row
1837   # of the stream.
1838   # 
1839   def parse_headers(row = nil)
1840     if @headers.nil?                # header row
1841       @headers = case @use_headers  # save headers
1842       when Array  then @use_headers                         # Array of headers
1843       when String then self.class.parse_line(@use_headers)  # CSV header String
1844       else             row                                  # first row headers
1845       end
1846       
1847       # prepare converted and unconverted copies
1848       row      = @headers                       if row.nil?
1849       @headers = convert_fields(@headers, true)
1850       
1851       if @return_headers                                     # return headers
1852         return self.class::Row.new(@headers, row, true)
1853       elsif not [Array, String].include? @use_headers.class  # skip to field row
1854         return shift
1855       end
1856     end
1858     self.class::Row.new(@headers, convert_fields(row))  # field row
1859   end
1860   
1861   # 
1862   # Thiw methods injects an instance variable <tt>unconverted_fields</tt> into
1863   # +row+ and an accessor method for it called unconverted_fields().  The
1864   # variable is set to the contents of +fields+.
1865   # 
1866   def add_unconverted_fields(row, fields)
1867     class << row
1868       attr_reader :unconverted_fields
1869     end
1870     row.instance_eval { @unconverted_fields = fields }
1871     row
1872   end
1875 # Another name for CSV::instance().
1876 def CSV(*args, &block)
1877   CSV.instance(*args, &block)
1880 class Array
1881   # Equivalent to <tt>CSV::generate_line(self, options)</tt>.
1882   def to_csv(options = Hash.new)
1883     CSV.generate_line(self, options)
1884   end
1887 class String
1888   # Equivalent to <tt>CSV::parse_line(self, options)</tt>.
1889   def parse_csv(options = Hash.new)
1890     CSV.parse_line(self, options)
1891   end