Skip to content
This repository was archived by the owner on Jun 28, 2021. It is now read-only.

Commit fb3cc3c

Browse files
authored
Merge pull request #291 from Fateslayer/multiple-column-delimiters
add multiple column delimiter support
2 parents a48be3c + 233a3b0 commit fb3cc3c

File tree

2 files changed

+80
-19
lines changed

2 files changed

+80
-19
lines changed

lib/index.js

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -95,21 +95,27 @@ class Parser extends Transform {
9595
}
9696
}
9797
// Normalize option `delimiter`
98-
if(options.delimiter === undefined || options.delimiter === null || options.delimiter === false){
99-
options.delimiter = Buffer.from(',')
100-
}else if(typeof options.delimiter === 'string' && options.delimiter.length !== 0){
101-
options.delimiter = Buffer.from(options.delimiter)
102-
}else if(
103-
(Buffer.isBuffer(options.delimiter) && options.delimiter.length === 0) ||
104-
(typeof options.delimiter === 'string' && options.delimiter.length === 0) ||
105-
(!Buffer.isBuffer(options.delimiter) && typeof options.delimiter !== 'string')
106-
){
98+
const delimiter_json = JSON.stringify(options.delimiter)
99+
if(!Array.isArray(options.delimiter)) options.delimiter = [options.delimiter]
100+
if(options.delimiter.length === 0){
107101
throw new CsvError('CSV_INVALID_OPTION_DELIMITER', [
108102
'Invalid option delimiter:',
109-
'delimiter must be a non empty string or buffer,',
110-
`got ${JSON.stringify(options.delimiter)}`
103+
'delimiter must be a non empty string or buffer or array of string|buffer,',
104+
`got ${delimiter_json}`
111105
])
112106
}
107+
options.delimiter = options.delimiter.map(function(del){
108+
if(del === undefined || del === null || del === false){
109+
return Buffer.from(',')
110+
}else if((typeof del === 'string' || Buffer.isBuffer(del)) && del.length !== 0){
111+
return Buffer.from(del)
112+
}
113+
throw new CsvError('CSV_INVALID_OPTION_DELIMITER', [
114+
'Invalid option delimiter:',
115+
'delimiter must be a non empty string or buffer or array of string|buffer,',
116+
`got ${delimiter_json}`
117+
])
118+
})
113119
// Normalize option `escape`
114120
if(options.escape === undefined || options.escape === null){
115121
options.escape = Buffer.from('"')
@@ -923,12 +929,16 @@ class Parser extends Transform {
923929
}
924930
__isDelimiter(chr, buf, pos){
925931
const {delimiter} = this.options
926-
const delLength = delimiter.length
927-
if(delimiter[0] !== chr) return 0
928-
for(let i = 1; i < delLength; i++){
929-
if(delimiter[i] !== buf[pos+i]) return 0
932+
loop1: for(let i = 0; i < delimiter.length; i++){
933+
const del = delimiter[i]
934+
if(del[0] === chr){
935+
for(let j = 1; j < del.length; j++){
936+
if(del[j] !== buf[pos+j]) continue loop1
937+
}
938+
return del.length
939+
}
930940
}
931-
return delimiter.length
941+
return 0
932942
}
933943
__isRecordDelimiter(chr, buf, pos){
934944
const {record_delimiter} = this.options

test/option.delimiter.coffee

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,32 @@ describe 'Option `delimiter`', ->
99
(->
1010
parse '', delimiter: '', (->)
1111
).should.throw
12-
message: 'Invalid option delimiter: delimiter must be a non empty string or buffer, got ""'
12+
message: 'Invalid option delimiter: delimiter must be a non empty string or buffer or array of string|buffer, got ""'
1313
code: 'CSV_INVALID_OPTION_DELIMITER'
1414
(->
1515
parse '', delimiter: Buffer.from(''), (->)
1616
).should.throw
17-
message: 'Invalid option delimiter: delimiter must be a non empty string or buffer, got {"type":"Buffer","data":[]}'
17+
message: 'Invalid option delimiter: delimiter must be a non empty string or buffer or array of string|buffer, got {"type":"Buffer","data":[]}'
1818
code: 'CSV_INVALID_OPTION_DELIMITER'
1919
(->
2020
parse '', delimiter: true, (->)
2121
).should.throw
22-
message: 'Invalid option delimiter: delimiter must be a non empty string or buffer, got true'
22+
message: 'Invalid option delimiter: delimiter must be a non empty string or buffer or array of string|buffer, got true'
23+
code: 'CSV_INVALID_OPTION_DELIMITER'
24+
(->
25+
parse '', delimiter: [], (->)
26+
).should.throw
27+
message: 'Invalid option delimiter: delimiter must be a non empty string or buffer or array of string|buffer, got []'
28+
code: 'CSV_INVALID_OPTION_DELIMITER'
29+
(->
30+
parse '', delimiter: [''], (->)
31+
).should.throw
32+
message: 'Invalid option delimiter: delimiter must be a non empty string or buffer or array of string|buffer, got [""]'
33+
code: 'CSV_INVALID_OPTION_DELIMITER'
34+
(->
35+
parse '', delimiter: [',',''], (->)
36+
).should.throw
37+
message: 'Invalid option delimiter: delimiter must be a non empty string or buffer or array of string|buffer, got [",",""]'
2338
code: 'CSV_INVALID_OPTION_DELIMITER'
2439

2540
it 'using default comma', (next) ->
@@ -69,3 +84,39 @@ describe 'Option `delimiter`', ->
6984
[ '','1974','8.8392926E7','','']
7085
]
7186
next()
87+
88+
it 'using array of a single delimiter', (next) ->
89+
parse """
90+
abc,,123,
91+
,def,,
92+
""", delimiter: [','], (err, data) ->
93+
return next err if err
94+
data.should.eql [
95+
[ 'abc','','123','']
96+
[ '','def','','']
97+
]
98+
next()
99+
100+
it 'using array of a single delimiter of multiple characters', (next) ->
101+
parse """
102+
!#
103+
!#
104+
""", delimiter: ['!#'], (err, data) ->
105+
return next err if err
106+
data.should.eql [
107+
[ '', '']
108+
[ '', '']
109+
]
110+
next()
111+
112+
it 'using array of a multiple delimiters of variable length', (next) ->
113+
parse """
114+
abc,;;123;;
115+
;;def;;,
116+
""", delimiter: [',', ';;'], (err, data) ->
117+
return next err if err
118+
data.should.eql [
119+
[ 'abc','','123','']
120+
[ '','def','','']
121+
]
122+
next()

0 commit comments

Comments
 (0)