class CA::CSVReader::Processor

Attributes

names[R]

Public Class Methods

new(io, sep:, rs:, &block) click to toggle source
# File lib/carray-io-csv/core.bak.rb, line 99
def initialize (io, sep:, rs:, &block)
  @io       = io
  @sep      = sep
  @rs       = rs
  @block    = block || proc { body }
  @namelist = nil
  @names    = nil
  @headerlist = []
  @header   = {}
  @note     = ""
  @table    = nil
  @regexp_simple1 = /#{@sep}/
  @regexp_simple2 = / *#{@sep} */
  @regexp_pat1    = /\A([^"#{@sep}][^#{@sep}]*) *#{@sep} */
  @regexp_pat2    = /\A"([^"]+)" *#{@sep} */
  @regexp_pat3    = /\A"((?:[^"]+|"")+)" *#{@sep} */
  @regexp_pat4    = /\A(?:""|) *#{@sep} */ 
  @sc       = StringScanner.new("")
end

Public Instance Methods

body(n=nil, cols=nil) click to toggle source
# File lib/carray-io-csv/core.bak.rb, line 197
    def body (n=nil, cols=nil)
      data = []
      count = 0
      if cols
        @cols = cols
      elsif @names
        @cols = @names.size
      else
        list = csv_feed()
        if list.nil?
          @rows  = 0
          @table = CArray.object(@rows, @cols)
          return
        end
        data.push(list)
        count += 1
        @cols = list.size
      end
      if n
        lsize = nil
        while count < n and list = csv_feed(@cols)
          lsize = list.size
          if lsize == @cols
            data.push(list)             
          elsif lsize <= @cols
            record = Array.new(@cols, nil)
            record[0,lsize] = list
            data.push(record)
          else
            extra = Array.new(lsize - @cols, nil)
            data.each do |row|
              row.push(*extra)
            end
            data.push(list)
            @cols = lsize
#            raise "csv parse error : too large column number at line #{@io.lineno}"
          end
          count += 1
        end
      else
        unless @io.eof?
          data += Rcsv.parse(@io, column_separator: @sep, header: :none)
        end
      end
      @rows  = data.size
      @table = CArray.object(@rows, @cols){ data }
      @table[:eq,""] = nil
    end
column_names(*namelist) click to toggle source
# File lib/carray-io-csv/core.bak.rb, line 159
def column_names (*namelist)
  if @header.has_key?("names")
    warn "override header['names']"
  end
  @names = namelist.map(&:to_s)
  @header["names"] = @names
  return namelist
end
Also aliased as: columns
columns(*namelist)
Alias for: column_names
convert(data_type, options={}, &block) click to toggle source
# File lib/carray-io-csv/core.bak.rb, line 306
def convert (data_type, options={}, &block)
  if block_given?
    if data_type.is_a?(Class) and data_type < CA::Struct
      @table = @table[:i, nil].convert(data_type, &block) 
    else
      @table = @table.convert(data_type, options, &block)
    end
  else
    if data_type.is_a?(Class) and data_type < CA::Struct
      @table = @table[:i,nil].convert(data_type) { |b|
        data_type.new(*b[0,nil])
      }
    else
      @table = @table.to_type(data_type, options)
    end
  end
end
downcase() click to toggle source
# File lib/carray-io-csv/core.bak.rb, line 253
def downcase
  @header["names"] = @header["names"].map(&:downcase)
  @names = @header["names"]
end
header(name = "names") click to toggle source
# File lib/carray-io-csv/core.bak.rb, line 170
def header (name = "names")
  name = name.to_s
  list = csv_feed()
  if name == "names"
    if @names 
      raise "already 'names' defined"
    end
    @names = list
  end
  @header[name] = list
  @headerlist.push(name)
  return list
end
note(n=1) click to toggle source
# File lib/carray-io-csv/core.bak.rb, line 186
def note (n=1)
  list = []
  n.times { list << @io.gets(@rs) }
  @note << (text = list.join)
  return text
end
process() { |name, table| ... } click to toggle source
# File lib/carray-io-csv/core.bak.rb, line 290
def process
  if @namelist
    @namelist.each_with_index do |name, i|
      yield(name, @table[nil, i])
    end
  elsif @names
    @names.each_with_index do |name, i|
      yield(name, @table[nil, i])
    end
  else
    @table.dim1.times do |i|
      yield(i, @table[nil,i])
    end
  end
end
rename(name, newname) click to toggle source
# File lib/carray-io-csv/core.bak.rb, line 246
def rename (name, newname)
  names = @header["names"]
  i = names.index(name)
  names[i] = newname
  @names = @header["names"]
end
run() click to toggle source
# File lib/carray-io-csv/core.bak.rb, line 119
def run
  case @block.arity
  when 1
    @block.call(self)
  when -1, 0
    instance_exec(&@block)
  else
    raise "invalid block paramter"
  end
  if @header.has_key?("names")          
    @header["names"].each_with_index do |name, k|
      if name.nil? or name.empty?
        @header["names"][k] = "c#{k}"
      end
    end
  else
    @header["names"] = (0...@cols).map{|k| "c#{k}"}
  end
  header = @header
  note  = @note
  @table.instance_exec{ 
    @names  = header["names"]
    @header = header
    @note  = note
  }
  @table.extend(CArray::TableMethods)
  @table.column_names = header["names"]
  class << @table
    attr_reader :note
    def header (name=nil)
      if name
        return @header[name.to_s]
      else
        return @header
      end
    end
  end
  return @table
end
select(*namelist) click to toggle source
# File lib/carray-io-csv/core.bak.rb, line 258
def select (*namelist)
  @namelist = namelist.empty? ? nil : namelist
  case @namelist
  when nil
  when Array
    index = (0...@cols).map.to_a
    index_list = @namelist.map{ |x|
      case x
      when Integer
        x
      when Range
        index[x]
      when String, Symbol
        if @names and i = @names.index(x.to_s) 
          i
        else
          raise "invalid argument #{x}"
        end
      else
        raise "invalid argument"
      end
    }.flatten
    @table = @table[nil, CA_INT(index_list)].to_ca
    @header.keys.each do |k|
      @header[k] = @header[k].values_at(*index_list)
    end
    @names = @header["names"]
  else
    raise
  end
end
skip(n=1) click to toggle source
# File lib/carray-io-csv/core.bak.rb, line 193
def skip (n=1)
  n.times { @io.gets(@rs) }
end

Private Instance Methods

csv_feed(cols=nil) click to toggle source
# File lib/carray-io-csv/core.bak.rb, line 326
def csv_feed (cols=nil)
  if @io.eof?
    return nil
  end
  line = nil
  loop do
    if newline = @io.gets(@rs)
      if line
        line << newline
      else
        line = newline
      end
      count_quote = line.count('"')
    else
      line = ""
      count_quote = 0
    end
    if count_quote == 0
      line.chomp!
      if line.count(' ') == 0
        return line.split(@sep, -1) ### /#{@sep}/
      else
        return line.split(@regexp_simple2, -1) ### / *#{@sep} */
      end
    end
    if count_quote % 2 == 0 
      line.chomp!
      return csv_split(line, cols)
    else
      if newline
        next
      else
        raise "csv parse error"
      end
    end
  end
end
csv_split(text, cols=nil) click to toggle source
# File lib/carray-io-csv/core.bak.rb, line 364
def csv_split (text, cols=nil)
  if cols
    csv = Array.new(cols)
  else
    csv = []
  end
  text << @sep
  @sc.string = text
  i = 0
  begin
    case
    when @sc.scan(@regexp_pat1)
              ### /\A([^"#{@sep}][^#{@sep}]*) *#{@sep} */
      csv[i] = @sc[1]
    when @sc.scan(@regexp_pat2)
              ### /\A"([^"]+)" *#{@sep} */
      csv[i] = @sc[1]
    when @sc.scan(@regexp_pat3)
              ### /\A"((?:[^"]+|"")+)" *#{@sep} */
      s = @sc[1]
      if s =~ /"/
        csv[i] = s.gsub(/""/, '"') 
      else
        csv[i] = s
      end
    when @sc.scan(@regexp_pat4)
              ### /\A(?:""|) *#{@sep} */
      csv[i] = nil
    else
      raise "csv parse error"
    end
    i += 1
  end until @sc.eos?
  return csv
end