method

parse_body

Importance_0
v1_8_7_330 - Show latest stable - 0 notes - Class: CSV
parse_body(src, idx, fs, rs) private

No documentation

This method has no description. You can help the Ruby community by adding new notes.

Hide source
# File lib/csv.rb, line 343
    def parse_body(src, idx, fs, rs)
      fs_str = fs
      fs_size = fs_str.size
      rs_str = rs || "\n"
      rs_size = rs_str.size
      fs_idx = rs_idx = 0
      cell = Cell.new
      state = :ST_START
      quoted = cr = false
      c = nil
      last_idx = idx
      while c = src[idx]
        unless quoted
          fschar = (c == fs_str[fs_idx])
          rschar = (c == rs_str[rs_idx])
          # simple 1 char backtrack
          if !fschar and c == fs_str[0]
            fs_idx = 0
            fschar = true
            if state == :ST_START
              state = :ST_DATA
            elsif state == :ST_QUOTE
              raise IllegalFormatError
            end
          end
          if !rschar and c == rs_str[0]
            rs_idx = 0
            rschar = true
            if state == :ST_START
              state = :ST_DATA
            elsif state == :ST_QUOTE
              raise IllegalFormatError
            end
          end
        end
        if c == ?"
          fs_idx = rs_idx = 0
          if cr
            raise IllegalFormatError
          end
          cell << src[last_idx, (idx - last_idx)]
          last_idx = idx
          if state == :ST_DATA
            if quoted
              last_idx += 1
              quoted = false
              state = :ST_QUOTE
            else
              raise IllegalFormatError
            end
          elsif state == :ST_QUOTE
            cell << c.chr
            last_idx += 1
            quoted = true
            state = :ST_DATA
          else  # :ST_START
            quoted = true
            last_idx += 1
            state = :ST_DATA
          end
        elsif fschar or rschar
          if fschar
            fs_idx += 1
          end
          if rschar
            rs_idx += 1
          end
          sep = nil
          if fs_idx == fs_size
            if state == :ST_START and rs_idx > 0 and fs_idx < rs_idx
              state = :ST_DATA
            end
            cell << src[last_idx, (idx - last_idx - (fs_size - 1))]
            last_idx = idx
            fs_idx = rs_idx = 0
            if cr
              raise IllegalFormatError
            end
            sep = :DT_COLSEP
          elsif rs_idx == rs_size
            if state == :ST_START and fs_idx > 0 and rs_idx < fs_idx
              state = :ST_DATA
            end
            if !(rs.nil? and cr)
              cell << src[last_idx, (idx - last_idx - (rs_size - 1))]
              last_idx = idx
            end
            fs_idx = rs_idx = 0
            sep = :DT_ROWSEP
          end
          if sep
            if state == :ST_DATA
              return sep, idx + 1, cell;
            elsif state == :ST_QUOTE
              return sep, idx + 1, cell;
            else  # :ST_START
              return sep, idx + 1, nil
            end
          end
        elsif rs.nil? and c == ?\r
          # special \r treatment for backward compatibility
          fs_idx = rs_idx = 0
          if cr
            raise IllegalFormatError
          end
          cell << src[last_idx, (idx - last_idx)]
          last_idx = idx
          if quoted
            state = :ST_DATA
          else
            cr = true
          end
        else
          fs_idx = rs_idx = 0
          if state == :ST_DATA or state == :ST_START
            if cr
              raise IllegalFormatError
            end
            state = :ST_DATA
          else  # :ST_QUOTE
            raise IllegalFormatError
          end
        end
        idx += 1
      end
      if state == :ST_START
        if fs_idx > 0 or rs_idx > 0
          state = :ST_DATA
        else
          return :DT_EOS, idx, nil
        end
      elsif quoted
        raise IllegalFormatError
      elsif cr
        raise IllegalFormatError
      end
      cell << src[last_idx, (idx - last_idx)]
      last_idx = idx
      return :DT_EOS, idx, cell
    end
Register or log in to add new notes.