simplecsv 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +1 -0
- data/History.txt +5 -0
- data/README.txt +1 -1
- data/TODO +0 -1
- data/ext/simplecsv/rb_simplecsv.c +92 -6
- data/lib/simplecsv/version.rb +2 -2
- data/test/simplecsv/simplecsv_test.rb +58 -1
- metadata +1 -1
data/CHANGELOG.txt
CHANGED
data/History.txt
CHANGED
data/README.txt
CHANGED
data/TODO
CHANGED
@@ -33,6 +33,7 @@ struct csv_parser_object {
|
|
33
33
|
}\
|
34
34
|
}
|
35
35
|
|
36
|
+
|
36
37
|
static void free_parser_object(struct csv_parser_object* parser_object)
|
37
38
|
{
|
38
39
|
if (parser_object){
|
@@ -44,7 +45,7 @@ static void free_parser_object(struct csv_parser_object* parser_object)
|
|
44
45
|
}
|
45
46
|
|
46
47
|
|
47
|
-
static void
|
48
|
+
static void default_field_callback(char* s, size_t i, void* obj)
|
48
49
|
{
|
49
50
|
VALUE row, str;
|
50
51
|
|
@@ -53,7 +54,8 @@ static void field_callback(char* s, size_t i, void* obj)
|
|
53
54
|
rb_ary_push(row, str);
|
54
55
|
}
|
55
56
|
|
56
|
-
|
57
|
+
|
58
|
+
static void default_row_callback(char c, void* obj)
|
57
59
|
{
|
58
60
|
VALUE row;
|
59
61
|
|
@@ -63,6 +65,32 @@ static void row_callback(char c, void* obj)
|
|
63
65
|
}
|
64
66
|
|
65
67
|
|
68
|
+
static void field_callback(char* s, size_t i, void* obj)
|
69
|
+
{
|
70
|
+
VALUE str, len, proc;
|
71
|
+
|
72
|
+
str = rb_str_new(s, i);
|
73
|
+
proc = rb_ivar_get((VALUE)obj, rb_intern("'proc'"));
|
74
|
+
|
75
|
+
rb_funcall((VALUE)obj, rb_intern("on_field"), 2, str, proc);
|
76
|
+
}
|
77
|
+
|
78
|
+
|
79
|
+
static void row_callback(char c, void* obj)
|
80
|
+
{
|
81
|
+
VALUE str, proc;
|
82
|
+
char row_delimiter[2];
|
83
|
+
|
84
|
+
row_delimiter[0] = c;
|
85
|
+
row_delimiter[1] = 0;
|
86
|
+
|
87
|
+
str = rb_str_new2(row_delimiter);
|
88
|
+
proc = rb_ivar_get((VALUE)obj, rb_intern("'proc'"));
|
89
|
+
|
90
|
+
rb_funcall((VALUE)obj, rb_intern("on_row"), 2, str, proc);
|
91
|
+
}
|
92
|
+
|
93
|
+
|
66
94
|
/*
|
67
95
|
* call-seq:
|
68
96
|
* parse(str, options = nil){|row| ...}
|
@@ -144,7 +172,7 @@ static VALUE simplecsv_s_parse(int argc, VALUE* argv, VALUE klass)
|
|
144
172
|
rb_ivar_set(klass, rb_intern("'row'"), rb_ary_new());
|
145
173
|
|
146
174
|
len = RSTRING(str)->len;
|
147
|
-
if (csv_parse(parser, StringValuePtr(str), len,
|
175
|
+
if (csv_parse(parser, StringValuePtr(str), len, default_field_callback, default_row_callback, (void*)klass) != len) {
|
148
176
|
switch (csv_error(parser)) {
|
149
177
|
case CSV_EPARSE:
|
150
178
|
rb_raise(eCSVParseError, "error while parsing by malformed data");
|
@@ -163,7 +191,7 @@ static VALUE simplecsv_s_parse(int argc, VALUE* argv, VALUE klass)
|
|
163
191
|
}
|
164
192
|
}
|
165
193
|
|
166
|
-
csv_fini(parser,
|
194
|
+
csv_fini(parser, default_field_callback, default_row_callback, (void*)klass);
|
167
195
|
csv_free(parser);
|
168
196
|
|
169
197
|
return Qnil;
|
@@ -343,14 +371,23 @@ static VALUE simplecsv_set_options(VALUE self, VALUE opts)
|
|
343
371
|
* [SimpleCSV::ParseError] failed to parse.
|
344
372
|
* [LocalJumpError] You must call this method with block.
|
345
373
|
*/
|
346
|
-
static VALUE simplecsv_parse(VALUE
|
374
|
+
static VALUE simplecsv_parse(int argc, VALUE* argv, VALUE self)
|
347
375
|
{
|
376
|
+
VALUE str, proc;
|
348
377
|
struct csv_parser_object* parser_object;
|
349
378
|
struct csv_parser* parser;
|
350
379
|
int len;
|
351
380
|
|
381
|
+
rb_scan_args(argc, argv, "1&", &str, &proc);
|
382
|
+
|
352
383
|
Check_Type(str, T_STRING);
|
353
384
|
|
385
|
+
if (CLASS_OF(self) == cSimpleCSV) {
|
386
|
+
rb_need_block();
|
387
|
+
}
|
388
|
+
|
389
|
+
rb_ivar_set(self, rb_intern("'proc'"), proc);
|
390
|
+
|
354
391
|
Get_Parser(self, parser_object, parser);
|
355
392
|
|
356
393
|
len = RSTRING(str)->len;
|
@@ -380,6 +417,53 @@ static VALUE simplecsv_parse(VALUE self, VALUE str)
|
|
380
417
|
|
381
418
|
|
382
419
|
|
420
|
+
/*
|
421
|
+
* call-seq:
|
422
|
+
* on_field(str, pr)
|
423
|
+
*
|
424
|
+
* This method is called when processing each field.
|
425
|
+
* You can write "pr.call(some_val)" for pass value to block of `parse' method.
|
426
|
+
*
|
427
|
+
* ==== Parameters
|
428
|
+
* [str] <code>String</code> : field text.
|
429
|
+
* [pr] <code>Proc</code> : a block, passing by `parse' method
|
430
|
+
*/
|
431
|
+
static VALUE simplecsv_on_field(VALUE self, VALUE str, VALUE proc)
|
432
|
+
{
|
433
|
+
VALUE row;
|
434
|
+
|
435
|
+
row = rb_ivar_get(self, rb_intern("'row'"));
|
436
|
+
rb_ary_push(row, str);
|
437
|
+
|
438
|
+
return Qnil;
|
439
|
+
}
|
440
|
+
|
441
|
+
|
442
|
+
|
443
|
+
/*
|
444
|
+
* call-seq:
|
445
|
+
* on_row(str, pr)
|
446
|
+
*
|
447
|
+
* This method is called when processing each row.
|
448
|
+
* You can write "pr.call(some_val)" for pass value to block of `parse' method.
|
449
|
+
*
|
450
|
+
* ==== Parameters
|
451
|
+
* [str] <code>String</code> : row delimitor (\n).
|
452
|
+
* [pr] <code>Proc</code> : a block, passing by `parse' method
|
453
|
+
*/
|
454
|
+
static VALUE simplecsv_on_row(VALUE self, VALUE str, VALUE proc)
|
455
|
+
{
|
456
|
+
VALUE row;
|
457
|
+
|
458
|
+
row = rb_ivar_get(self, rb_intern("'row'"));
|
459
|
+
rb_funcall(proc, rb_intern("call"), 1, row);
|
460
|
+
rb_ivar_set(self, rb_intern("'row'"), rb_ary_new());
|
461
|
+
|
462
|
+
return Qnil;
|
463
|
+
}
|
464
|
+
|
465
|
+
|
466
|
+
|
383
467
|
void Init_simplecsv(void)
|
384
468
|
{
|
385
469
|
cSimpleCSV = rb_define_class("SimpleCSV", rb_cObject);
|
@@ -399,6 +483,8 @@ void Init_simplecsv(void)
|
|
399
483
|
rb_define_method(cSimpleCSV, "initialize", simplecsv_initialize, -1);
|
400
484
|
rb_define_method(cSimpleCSV, "options", simplecsv_get_options, 0);
|
401
485
|
rb_define_method(cSimpleCSV, "options=", simplecsv_set_options, 1);
|
402
|
-
rb_define_method(cSimpleCSV, "parse", simplecsv_parse, 1);
|
486
|
+
rb_define_method(cSimpleCSV, "parse", simplecsv_parse, -1);
|
403
487
|
rb_define_method(cSimpleCSV, "write", simplecsv_s_write, 1);
|
488
|
+
rb_define_method(cSimpleCSV, "on_field", simplecsv_on_field, 2);
|
489
|
+
rb_define_method(cSimpleCSV, "on_row", simplecsv_on_row, 2);
|
404
490
|
}
|
data/lib/simplecsv/version.rb
CHANGED
@@ -194,7 +194,9 @@ _CSV_
|
|
194
194
|
simplecsv.parse(''){}
|
195
195
|
end
|
196
196
|
|
197
|
-
|
197
|
+
assert_raise(LocalJumpError) do
|
198
|
+
assert_nil simplecsv.parse('')
|
199
|
+
end
|
198
200
|
|
199
201
|
simplecsv.parse(<<_CSV_) do |row|
|
200
202
|
test
|
@@ -285,6 +287,16 @@ _CSV_
|
|
285
287
|
_CSV_
|
286
288
|
end
|
287
289
|
|
290
|
+
rows = 0
|
291
|
+
simplecsv = SimpleCSV.new(SimpleCSV::REPALL_NL)
|
292
|
+
simplecsv.parse(<<_CSV_) do |row|
|
293
|
+
|
294
|
+
|
295
|
+
|
296
|
+
_CSV_
|
297
|
+
rows += 1
|
298
|
+
end
|
299
|
+
assert_equal 3, rows
|
288
300
|
end
|
289
301
|
|
290
302
|
def test_write
|
@@ -311,4 +323,49 @@ _CSV_
|
|
311
323
|
simplecsv.write([1, 2, 3])
|
312
324
|
end
|
313
325
|
end
|
326
|
+
|
327
|
+
def test_options
|
328
|
+
simplecsv = SimpleCSV.new
|
329
|
+
assert_equal 0, simplecsv.options
|
330
|
+
|
331
|
+
simplecsv = SimpleCSV.new(SimpleCSV::STRICT)
|
332
|
+
assert_equal SimpleCSV::STRICT, simplecsv.options
|
333
|
+
|
334
|
+
simplecsv = SimpleCSV.new(SimpleCSV::REPALL_NL)
|
335
|
+
assert_equal SimpleCSV::REPALL_NL, simplecsv.options
|
336
|
+
|
337
|
+
simplecsv = SimpleCSV.new(SimpleCSV::STRICT | SimpleCSV::REPALL_NL)
|
338
|
+
assert_equal SimpleCSV::STRICT | SimpleCSV::REPALL_NL, simplecsv.options
|
339
|
+
|
340
|
+
simplecsv = SimpleCSV.new
|
341
|
+
simplecsv.options = SimpleCSV::STRICT
|
342
|
+
assert_equal SimpleCSV::STRICT, simplecsv.options
|
343
|
+
|
344
|
+
simplecsv = SimpleCSV.new(SimpleCSV::STRICT)
|
345
|
+
simplecsv.options = nil
|
346
|
+
assert_equal 0, simplecsv.options
|
347
|
+
end
|
348
|
+
|
349
|
+
class FirstLetter < SimpleCSV
|
350
|
+
def initialize
|
351
|
+
@ary = []
|
352
|
+
end
|
353
|
+
|
354
|
+
def on_field(str, pr)
|
355
|
+
@ary << str[0, 1]
|
356
|
+
end
|
357
|
+
|
358
|
+
def on_row(str, pr)
|
359
|
+
pr.call(@ary)
|
360
|
+
@ary = []
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
def test_subclass_customizing
|
365
|
+
FirstLetter.new.parse(<<_CSV_) do |row|
|
366
|
+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
|
367
|
+
_CSV_
|
368
|
+
assert_equal ["L", "c"], row
|
369
|
+
end
|
370
|
+
end
|
314
371
|
end
|
metadata
CHANGED