Class: LibCsv

Inherits:
Object
  • Object
show all
Extended by:
FFI::Library
Defined in:
lib/lib_csv.rb

Defined Under Namespace

Classes: CsvParser

Class Method Summary collapse

Class Method Details

.parse(string, options = {}) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/lib_csv.rb', line 43

def self.parse(string, options = {})
  pointer = FFI::MemoryPointer.new :char, CsvParser.size, false
  parser = CsvParser.new pointer
  result = csv_init(parser, 0)

  if options[:col_sep]
    csv_set_delim(parser, options[:col_sep].ord)
  end

  if options[:quote_char]
    csv_set_quote(parser, options[:quote_char].ord)
  end

  fail "Couldn't initialize libcsv" if result == -1

  result = [[]]

  end_of_field_callback = Proc.new { |p_field, field_size, p_data|
    str = p_field.read_pointer.null? ? nil : p_field.read_string(field_size)
    result.last << str
  }

  end_of_record_callback = Proc.new { |last_char, p_data|
    result << [] unless last_char == -1
  }

  original_length = string.bytesize
  length = nil

  length = csv_parse(parser, string, original_length, end_of_field_callback, end_of_record_callback, nil)

  unless length == original_length
    case error = csv_error(parser)
      when CSV_EPARSE
        fail "Error when parsing malformed data"
      when CSV_ENOMEM
        fail "No memory"
      when CSV_ETOOBIG
        fail "Too large field data"
      when CSV_EINVALID
        fail csv_strerror(error)
      else
        fail "Failed due to unknown reason"
    end
  end

  csv_fini(parser, end_of_field_callback, end_of_record_callback, nil)
  csv_free(parser)
  result.pop if result.last == []

  return result
end