simplecsv 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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