PageRenderTime 47ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/csv.rb

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