bamfcsv 0.3.1 → 0.3.2
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/README +8 -0
- data/ext/bamfcsv/bamfcsv_ext.c +4 -3
- data/lib/bamfcsv.rb +5 -1
- data/lib/bamfcsv/version.rb +1 -1
- data/spec/fixtures/pipe-delimited.csv +2 -0
- data/spec/lib/bamfcsv_spec.rb +46 -0
- metadata +10 -8
data/README
CHANGED
@@ -23,5 +23,13 @@ irb(1.9.2): table.first["foo"]
|
|
23
23
|
irb(1.9.2): table[1]["bar"]
|
24
24
|
==========> "4"
|
25
25
|
|
26
|
+
DOUBLE-AND/ALSO it supports custom field separators!!
|
27
|
+
|
28
|
+
irb(1.9.2): BAMFCSV.parse(<<EOF, separator: '|')
|
29
|
+
?> foo|bar
|
30
|
+
?> baz|quux
|
31
|
+
?> EOF
|
32
|
+
==========> [["foo", "bar"], ["baz", "quux"]]
|
33
|
+
|
26
34
|
|
27
35
|
(*) Results may vary.
|
data/ext/bamfcsv/bamfcsv_ext.c
CHANGED
@@ -28,10 +28,11 @@ bool quotes_end_line(char* cur) {
|
|
28
28
|
return *(cur-1) == '"' || (*(cur-1) == '\r' && *(cur-2) == '"');
|
29
29
|
}
|
30
30
|
|
31
|
-
VALUE bamfcsv_parse_string(VALUE self, VALUE string) {
|
31
|
+
VALUE bamfcsv_parse_string(VALUE self, VALUE string, VALUE rstr_sep) {
|
32
32
|
char *buf = RSTRING_PTR(string);
|
33
33
|
long bufsize = RSTRING_LEN(string);
|
34
34
|
rb_encoding *enc = rb_enc_from_index(ENCODING_GET(string));
|
35
|
+
char separator = *RSTRING_PTR(rstr_sep);
|
35
36
|
|
36
37
|
unsigned long num_rows = 1, cell_count = 1;
|
37
38
|
int quote_count = 0, quotes_matched = 1;
|
@@ -62,7 +63,7 @@ VALUE bamfcsv_parse_string(VALUE self, VALUE string) {
|
|
62
63
|
|
63
64
|
if (quotes_matched) {
|
64
65
|
|
65
|
-
if (*cur ==
|
66
|
+
if (*cur == separator) {
|
66
67
|
|
67
68
|
if (quote_count && *(cur-1) != '"')
|
68
69
|
rb_raise(BAMFCSV_MalformedCSVError_class, "Unclosed quoted field on line %lu, cell %lu.", num_rows, cell_count);
|
@@ -124,7 +125,7 @@ void Init_bamfcsv() {
|
|
124
125
|
|
125
126
|
BAMFCSV_module = rb_define_module("BAMFCSV");
|
126
127
|
VALUE bamfcsv_singleton_class = rb_singleton_class(BAMFCSV_module);
|
127
|
-
rb_define_private_method(bamfcsv_singleton_class, "__parse_string", bamfcsv_parse_string,
|
128
|
+
rb_define_private_method(bamfcsv_singleton_class, "__parse_string", bamfcsv_parse_string, 2);
|
128
129
|
|
129
130
|
BAMFCSV_MalformedCSVError_class = rb_define_class_under(BAMFCSV_module, "MalformedCSVError", rb_eRuntimeError);
|
130
131
|
}
|
data/lib/bamfcsv.rb
CHANGED
@@ -14,7 +14,10 @@ module BAMFCSV
|
|
14
14
|
# copy the pointer, not the contents. So we make a copy, parse
|
15
15
|
# that, and throw away the copy.
|
16
16
|
copy = "" + csv_str
|
17
|
-
|
17
|
+
separator = opts.fetch(:separator, ',')
|
18
|
+
raise InvalidSeparator, "Separator must be exactly one character long" if separator.size != 1
|
19
|
+
raise InvalidSeparator, "Separator cannot be '\"'" if separator == '"'
|
20
|
+
matrix = __parse_string(copy, separator)
|
18
21
|
if opts[:headers]
|
19
22
|
Table.new(matrix)
|
20
23
|
else
|
@@ -22,4 +25,5 @@ module BAMFCSV
|
|
22
25
|
end
|
23
26
|
end
|
24
27
|
|
28
|
+
class InvalidSeparator < StandardError; end
|
25
29
|
end
|
data/lib/bamfcsv/version.rb
CHANGED
data/spec/lib/bamfcsv_spec.rb
CHANGED
@@ -38,6 +38,28 @@ describe BAMFCSV do
|
|
38
38
|
BAMFCSV.read("spec/fixtures/terminated-with-cr.csv").should == [["a"],["b"]]
|
39
39
|
end
|
40
40
|
|
41
|
+
describe "Alternate separators" do
|
42
|
+
it "raises BAMFCSV::InvalidSeparator if :separator is not exactly one character long" do
|
43
|
+
expect { BAMFCSV.read("spec/fixtures/pipe-delimited.csv", :separator => '') }.should raise_error(BAMFCSV::InvalidSeparator)
|
44
|
+
expect { BAMFCSV.read("spec/fixtures/pipe-delimited.csv", :separator => 'as') }.should raise_error(BAMFCSV::InvalidSeparator)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "raises BAMFCSV::InvalidSeparator if :separator is a double-quote" do
|
48
|
+
expect { BAMFCSV.read("spec/fixtures/pipe-delimited.csv", :separator => '"') }.should raise_error(BAMFCSV::InvalidSeparator)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "accepts a single character, non-quote :separator option" do
|
52
|
+
parsed = BAMFCSV.read("spec/fixtures/pipe-delimited.csv", :separator => '|')
|
53
|
+
parsed.should == [["foo", "bar"], ["pipe", "delimited"]]
|
54
|
+
end
|
55
|
+
|
56
|
+
it "works with tables too" do
|
57
|
+
table = BAMFCSV.read("spec/fixtures/pipe-delimited.csv", :headers => true, :separator => '|')
|
58
|
+
table.first["foo"].should == "pipe"
|
59
|
+
table.first["bar"].should == "delimited"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
41
63
|
it "raises Errno::ENOENT when the file does not exist" do
|
42
64
|
expect do
|
43
65
|
BAMFCSV.read("spec/fixtures/this-file-does-not-not-exist.csv")
|
@@ -250,5 +272,29 @@ CSV
|
|
250
272
|
BAMFCSV.parse(csv, :headers => true).first.inspect.should == inspected
|
251
273
|
end
|
252
274
|
end
|
275
|
+
describe "Alternate separators" do
|
276
|
+
it "raises BAMFCSV::InvalidSeparator if :separator is not exactly one character long" do
|
277
|
+
expect { BAMFCSV.parse("1,2", :separator => '') }.should raise_error(BAMFCSV::InvalidSeparator)
|
278
|
+
expect { BAMFCSV.parse("1,2", :separator => 'as') }.should raise_error(BAMFCSV::InvalidSeparator)
|
279
|
+
end
|
280
|
+
|
281
|
+
it "raises BAMFCSV::InvalidSeparator if :separator is a double-quote" do
|
282
|
+
expect { BAMFCSV.parse("1,2", :separator => '"') }.should raise_error(BAMFCSV::InvalidSeparator)
|
283
|
+
end
|
284
|
+
|
285
|
+
it "accepts a single character, non-quote :separator option" do
|
286
|
+
semicolon = BAMFCSV.parse("foo;bar\n1;2", :separator => ';')
|
287
|
+
semicolon.should == [["foo", "bar"], ["1", "2"]]
|
288
|
+
pipe = BAMFCSV.parse("foo|bar\n1|2", :separator => '|')
|
289
|
+
pipe.should == [["foo", "bar"], ["1", "2"]]
|
290
|
+
end
|
291
|
+
|
292
|
+
it "works with tables too" do
|
293
|
+
table = BAMFCSV.parse("foo;bar\nbaz;qux", :headers => true, :separator => ';')
|
294
|
+
table.first["foo"].should == "baz"
|
295
|
+
table.first["bar"].should == "qux"
|
296
|
+
end
|
297
|
+
end
|
253
298
|
end
|
299
|
+
|
254
300
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bamfcsv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2011-08-
|
13
|
+
date: 2011-08-27 00:00:00.000000000Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|
17
|
-
requirement: &
|
17
|
+
requirement: &2156352680 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ~>
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: 2.5.0
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *2156352680
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: fuubar
|
28
|
-
requirement: &
|
28
|
+
requirement: &2156352180 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: 0.0.2
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *2156352180
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: rake-compiler
|
39
|
-
requirement: &
|
39
|
+
requirement: &2156351720 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ~>
|
@@ -44,7 +44,7 @@ dependencies:
|
|
44
44
|
version: 0.7.1
|
45
45
|
type: :development
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *2156351720
|
48
48
|
description: BAMFCSV parses csv like a BAMF. BAMF!!
|
49
49
|
email:
|
50
50
|
- jon@thinkrelevance.com
|
@@ -71,6 +71,7 @@ files:
|
|
71
71
|
- spec/fixtures/empty.csv
|
72
72
|
- spec/fixtures/escapes.csv
|
73
73
|
- spec/fixtures/one-column.csv
|
74
|
+
- spec/fixtures/pipe-delimited.csv
|
74
75
|
- spec/fixtures/terminated-with-cr.csv
|
75
76
|
- spec/fixtures/test.csv
|
76
77
|
- spec/lib/bamfcsv_spec.rb
|
@@ -108,6 +109,7 @@ test_files:
|
|
108
109
|
- spec/fixtures/empty.csv
|
109
110
|
- spec/fixtures/escapes.csv
|
110
111
|
- spec/fixtures/one-column.csv
|
112
|
+
- spec/fixtures/pipe-delimited.csv
|
111
113
|
- spec/fixtures/terminated-with-cr.csv
|
112
114
|
- spec/fixtures/test.csv
|
113
115
|
- spec/lib/bamfcsv_spec.rb
|