Class: CcsvExt

Inherits:
Object
  • Object
show all
Defined in:
lib/ccsv_ext/version.rb,
ext/ccsv_ext/ccsv_ext.c

Constant Summary collapse

VERSION =
"0.1.3"

Class Method Summary collapse

Class Method Details

.parse_line(str, delimiter) ⇒ Object

Ccsv.parse_line(string ,delimiter)



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'ext/ccsv_ext/ccsv_ext.c', line 8

static VALUE parse_line(VALUE self, VALUE str, VALUE delimiter) {
  char *line = RSTRING_PTR(str);
  char *delim = RSTRING_PTR(delimiter);
  int len = RSTRING_LEN(str);
  char *token = (char *) malloc(len + 1);
  VALUE ary = rb_ary_new();

  /* if token == NULL - exit */
  if (token == NULL)
    return ary;

  /* chomp! */
  if(line[len] == EOL){
    if(line[len-1] == CR)
      len -= 1;
    line[len] = '\0';
  }

  /* skip empty line */
  if (len < 2) {
    free(token);
    return ary;
  }

  int i = 0;
  long pos = 0;
  int has_quote = 0;

  do {
    token[pos++] = line[i];
    if (!has_quote && (line[i] == delim[0] || line[i] == EOL)) {
      token[pos - 1] = 0;
      rb_ary_push(ary, rb_enc_str_new(&token[0], strlen(&token[0]), rb_utf8_encoding()));
      pos = 0;
      memset(token, 0, strlen(token));
    }
    if (line[i] == QUOTE && line[i + 1] != QUOTE) {
      pos--;
      has_quote = !has_quote;
    }
    if (line[i] == QUOTE && line[i + 1] == QUOTE) {
      if (!has_quote && line[i + 2] == delim[0])
        token[pos - 1] = 0;
      i++;
    }
  } while (line[++i]);

  if (line[i - 1] == delim[0])
    rb_ary_push(ary, rb_str_new2(""));
  else if (line[i - 1] == QUOTE) {
    token[pos] = 0;
    rb_ary_push(ary, rb_enc_str_new(&token[0], strlen(&token[0]), rb_utf8_encoding()));
  }
  else if (line[i - 1] != EOL)
    rb_ary_push(ary, rb_enc_str_new(&token[0], strlen(&token[0]), rb_utf8_encoding()));

  free(token);
  rb_ary_dup(ary);
}