blob: 9fcdb9fac0762d6f0f563b5efa635c8068699b9b [file] [log] [blame]
// Generated by CoffeeScript 1.9.3
var Parser, StringDecoder, stream, util;
stream = require('stream');
util = require('util');
StringDecoder = require('string_decoder').StringDecoder;
module.exports = function() {
var callback, called, chunks, data, options, parser;
if (arguments.length === 3) {
data = arguments[0];
options = arguments[1];
callback = arguments[2];
if (typeof callback !== 'function') {
throw Error("Invalid callback argument: " + (JSON.stringify(callback)));
}
if (typeof data !== 'string') {
return callback(Error("Invalid data argument: " + (JSON.stringify(data))));
}
} else if (arguments.length === 2) {
if (typeof arguments[0] === 'string' || Buffer.isBuffer(arguments[0])) {
data = arguments[0];
} else {
options = arguments[0];
}
if (typeof arguments[1] === 'function') {
callback = arguments[1];
} else {
options = arguments[1];
}
} else if (arguments.length === 1) {
if (typeof arguments[0] === 'function') {
callback = arguments[0];
} else {
options = arguments[0];
}
}
if (options == null) {
options = {};
}
parser = new Parser(options);
if (data != null) {
process.nextTick(function() {
parser.write(data);
return parser.end();
});
}
if (callback) {
called = false;
chunks = options.objname ? {} : [];
parser.on('readable', function() {
var chunk, results;
results = [];
while (chunk = parser.read()) {
if (options.objname) {
results.push(chunks[chunk[0]] = chunk[1]);
} else {
results.push(chunks.push(chunk));
}
}
return results;
});
parser.on('error', function(err) {
called = true;
return callback(err);
});
parser.on('end', function() {
if (!called) {
return callback(null, chunks);
}
});
}
return parser;
};
Parser = function(options) {
var base, base1, base10, base11, base12, base2, base3, base4, base5, base6, base7, base8, base9, k, v;
if (options == null) {
options = {};
}
options.objectMode = true;
this.options = {};
for (k in options) {
v = options[k];
this.options[k] = v;
}
stream.Transform.call(this, this.options);
if ((base = this.options).rowDelimiter == null) {
base.rowDelimiter = null;
}
if ((base1 = this.options).delimiter == null) {
base1.delimiter = ',';
}
if ((base2 = this.options).quote == null) {
base2.quote = '"';
}
if ((base3 = this.options).escape == null) {
base3.escape = '"';
}
if ((base4 = this.options).columns == null) {
base4.columns = null;
}
if ((base5 = this.options).comment == null) {
base5.comment = '';
}
if ((base6 = this.options).objname == null) {
base6.objname = false;
}
if ((base7 = this.options).trim == null) {
base7.trim = false;
}
if ((base8 = this.options).ltrim == null) {
base8.ltrim = false;
}
if ((base9 = this.options).rtrim == null) {
base9.rtrim = false;
}
if ((base10 = this.options).auto_parse == null) {
base10.auto_parse = false;
}
if ((base11 = this.options).auto_parse_date == null) {
base11.auto_parse_date = false;
}
if ((base12 = this.options).skip_empty_lines == null) {
base12.skip_empty_lines = false;
}
this.lines = 0;
this.count = 0;
this.is_int = /^(\-|\+)?([1-9]+[0-9]*)$/;
this.is_float = function(value) {
return (value - parseFloat(value) + 1) >= 0;
};
this.decoder = new StringDecoder();
this.buf = '';
this.quoting = false;
this.commenting = false;
this.field = '';
this.nextChar = null;
this.closingQuote = 0;
this.line = [];
this.chunks = [];
return this;
};
util.inherits(Parser, stream.Transform);
module.exports.Parser = Parser;
Parser.prototype._transform = function(chunk, encoding, callback) {
var err;
if (chunk instanceof Buffer) {
chunk = this.decoder.write(chunk);
}
try {
this.__write(chunk, false);
return callback();
} catch (_error) {
err = _error;
return this.emit('error', err);
}
};
Parser.prototype._flush = function(callback) {
var err;
try {
this.__write(this.decoder.end(), true);
if (this.quoting) {
this.emit('error', new Error("Quoted field not terminated at line " + (this.lines + 1)));
return;
}
if (this.line.length > 0) {
this.__push(this.line);
}
return callback();
} catch (_error) {
err = _error;
return this.emit('error', err);
}
};
Parser.prototype.__push = function(line) {
var field, i, j, len, lineAsColumns;
if (this.options.columns === true) {
this.options.columns = line;
return;
} else if (typeof this.options.columns === 'function') {
this.options.columns = this.options.columns(line);
return;
}
this.count++;
if (this.options.columns != null) {
lineAsColumns = {};
for (i = j = 0, len = line.length; j < len; i = ++j) {
field = line[i];
lineAsColumns[this.options.columns[i]] = field;
}
if (this.options.objname) {
return this.push([lineAsColumns[this.options.objname], lineAsColumns]);
} else {
return this.push(lineAsColumns);
}
} else {
return this.push(line);
}
};
Parser.prototype.__write = function(chars, end, callback) {
var acceptedLength, areNextCharsDelimiter, areNextCharsRowDelimiters, auto_parse, char, escapeIsQuote, i, isDelimiter, isEscape, isNextCharAComment, isQuote, isRowDelimiter, is_float, is_int, l, ltrim, nextCharPos, ref, results, rowDelimiter, rowDelimiterLength, rtrim, wasCommenting;
is_int = (function(_this) {
return function(value) {
if (typeof _this.is_int === 'function') {
return _this.is_int(value);
} else {
return _this.is_int.test(value);
}
};
})(this);
is_float = (function(_this) {
return function(value) {
if (typeof _this.is_float === 'function') {
return _this.is_float(value);
} else {
return _this.is_float.test(value);
}
};
})(this);
auto_parse = (function(_this) {
return function(value) {
var m;
if (_this.options.auto_parse && is_int(_this.field)) {
_this.field = parseInt(_this.field);
} else if (_this.options.auto_parse && is_float(_this.field)) {
_this.field = parseFloat(_this.field);
} else if (_this.options.auto_parse && _this.options.auto_parse_date) {
m = Date.parse(_this.field);
if (!isNaN(m)) {
_this.field = new Date(m);
}
}
return _this.field;
};
})(this);
ltrim = this.options.trim || this.options.ltrim;
rtrim = this.options.trim || this.options.rtrim;
chars = this.buf + chars;
l = chars.length;
rowDelimiterLength = this.options.rowDelimiter ? this.options.rowDelimiter.length : 0;
i = 0;
if (this.lines === 0 && 0xFEFF === chars.charCodeAt(0)) {
i++;
}
while (i < l) {
acceptedLength = rowDelimiterLength + this.options.comment.length + this.options.escape.length + this.options.delimiter.length;
if (this.quoting) {
acceptedLength += this.options.quote.length;
}
if (!end && (i + acceptedLength >= l)) {
break;
}
char = this.nextChar ? this.nextChar : chars.charAt(i);
this.nextChar = chars.charAt(i + 1);
if (this.options.rowDelimiter == null) {
if ((this.field === '') && (char === '\n' || char === '\r')) {
rowDelimiter = char;
nextCharPos = i + 1;
} else if (this.nextChar === '\n' || this.nextChar === '\r') {
rowDelimiter = this.nextChar;
nextCharPos = i + 2;
}
if (rowDelimiter) {
if (rowDelimiter === '\r' && chars.charAt(nextCharPos) === '\n') {
rowDelimiter += '\n';
}
this.options.rowDelimiter = rowDelimiter;
rowDelimiterLength = this.options.rowDelimiter.length;
}
}
if (!this.commenting && char === this.options.escape) {
escapeIsQuote = this.options.escape === this.options.quote;
isEscape = this.nextChar === this.options.escape;
isQuote = this.nextChar === this.options.quote;
if (!(escapeIsQuote && !this.field && !this.quoting) && (isEscape || isQuote)) {
i++;
char = this.nextChar;
this.nextChar = chars.charAt(i + 1);
this.field += char;
i++;
continue;
}
}
if (!this.commenting && char === this.options.quote) {
if (this.quoting) {
areNextCharsRowDelimiters = this.options.rowDelimiter && chars.substr(i + 1, this.options.rowDelimiter.length) === this.options.rowDelimiter;
areNextCharsDelimiter = chars.substr(i + 1, this.options.delimiter.length) === this.options.delimiter;
isNextCharAComment = this.nextChar === this.options.comment;
if (this.nextChar && !areNextCharsRowDelimiters && !areNextCharsDelimiter && !isNextCharAComment) {
if (this.options.relax) {
this.quoting = false;
this.field = "" + this.options.quote + this.field;
} else {
throw Error("Invalid closing quote at line " + (this.lines + 1) + "; found " + (JSON.stringify(this.nextChar)) + " instead of delimiter " + (JSON.stringify(this.options.delimiter)));
}
} else {
this.quoting = false;
this.closingQuote = this.options.quote.length;
i++;
if (end && i === l) {
this.line.push(auto_parse(this.field));
}
continue;
}
} else if (!this.field) {
this.quoting = true;
i++;
continue;
} else if (this.field && !this.options.relax) {
throw Error("Invalid opening quote at line " + (this.lines + 1));
}
}
isRowDelimiter = this.options.rowDelimiter && chars.substr(i, this.options.rowDelimiter.length) === this.options.rowDelimiter;
if (isRowDelimiter) {
this.lines++;
}
wasCommenting = false;
if (!this.commenting && !this.quoting && this.options.comment && chars.substr(i, this.options.comment.length) === this.options.comment) {
this.commenting = true;
} else if (this.commenting && isRowDelimiter) {
wasCommenting = true;
this.commenting = false;
}
isDelimiter = chars.substr(i, this.options.delimiter.length) === this.options.delimiter;
if (!this.commenting && !this.quoting && (isDelimiter || isRowDelimiter)) {
if (isRowDelimiter && this.line.length === 0 && this.field === '') {
if (wasCommenting || this.options.skip_empty_lines) {
i += this.options.rowDelimiter.length;
this.nextChar = chars.charAt(i);
continue;
}
}
if (rtrim) {
if (!this.closingQuote) {
this.field = this.field.trimRight();
}
}
this.line.push(auto_parse(this.field));
this.closingQuote = 0;
this.field = '';
if (isDelimiter) {
i += this.options.delimiter.length;
this.nextChar = chars.charAt(i);
if (end && !this.nextChar) {
isRowDelimiter = true;
this.line.push('');
}
}
if (isRowDelimiter) {
this.__push(this.line);
this.line = [];
i += (ref = this.options.rowDelimiter) != null ? ref.length : void 0;
this.nextChar = chars.charAt(i);
continue;
}
} else if (!this.commenting && !this.quoting && (char === ' ' || char === '\t')) {
if (!(ltrim && !this.field)) {
this.field += char;
}
if (end && i + 1 === l) {
if (this.options.trim || this.options.rtrim) {
this.field = this.field.trimRight();
}
this.line.push(auto_parse(this.field));
}
i++;
} else if (!this.commenting) {
this.field += char;
i++;
if (end && i === l) {
this.line.push(auto_parse(this.field));
}
} else {
i++;
}
}
this.buf = '';
results = [];
while (i < l) {
this.buf += chars.charAt(i);
results.push(i++);
}
return results;
};