PageRenderTime 70ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/Languages/Ruby/StdLib/ruby/1.9.1/csv.rb

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