Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- var Parser = (function() {
- var QUOTE = '"';
- var NEW_LINE = '\n';
- var DELIMITER = ',';
- var newLineLength = NEW_LINE.length;
- var delimiterLength = DELIMITER.length;
- function parse(input) {
- var index = 0,
- EOFIndex = input.length,
- beginCaptureIndex = -1,
- endCaptureIndex = -1,
- delimiterIndex = -1,
- newLineIndex = -1,
- rows = [],
- row = [];
- for (; EOFIndex ;) {
- // quoted field
- if (charAt(index) === QUOTE) {
- // field start index without opening quote
- beginCaptureIndex = index + 1;
- // consume string until we find a quote or reach the EOF
- while (isEOF(index) ? false : charAt(++index) === QUOTE ?
- // true (continue) : next char is a quote, this is an escaped quote / part of the data
- // false (stop) : next char is not a quote, we found the fields terminating quote
- charAt(++index) === QUOTE :
- // was not a quote, keep going
- true
- ){}
- // field end index without closing quote
- endCaptureIndex = index - 1;
- push(
- // unescape quotes within a quoted field
- unescape(
- input.substring(beginCaptureIndex, endCaptureIndex)
- ));
- } else {
- // this is not a quoted field which makes finding
- // the next delimiter pretty straight forward.
- // -1 is an acceptable value
- delimiterIndex = findNextDelimiter();
- // small optimization.. we don't need to find the next newline
- // if it is already placed after the delimiter index.
- // -1 is an acceptable value
- newLineIndex = ~delimiterIndex && ~newLineIndex && delimiterIndex < newLineIndex ?
- newLineIndex : findNextNewLine();
- // the next delimiter comes before the next newline,
- // or this is the last line. we've reached the end of a field
- if (~delimiterIndex && (delimiterIndex < newLineIndex || !~newLineIndex)) {
- endCaptureIndex = delimiterIndex;
- } else {
- // no delimiter was found or the delimier was found after the
- // next newline. this is the last field in the row (and possibly the input)
- endCaptureIndex = ~newLineIndex ? newLineIndex : EOFIndex;
- }
- push(input.substring(index, index = endCaptureIndex));
- }
- if (isEOF(index)) { // end of file
- // save the current row
- commitRow();
- // bail out
- break;
- } else if (chars(newLineLength) === NEW_LINE) { // end of a row
- // save the current row
- commitRow();
- // advance index past the newline and continue processing
- index += newLineLength;
- } else if (chars(delimiterLength) === DELIMITER) { // end of field
- // advance index past the delimiter and continue processing
- index += delimiterLength;
- }
- }
- return rows;
- ///////////
- ///////////
- function isEOF(i) {
- return i >= EOFIndex;
- }
- function charAt(i) {
- return input.charAt(i);
- }
- function chars(i) {
- return input.substr(index, i);
- }
- function findNextDelimiter() {
- return input.indexOf(DELIMITER, index);
- }
- function findNextNewLine() {
- return input.indexOf(NEW_LINE, index);
- }
- function push(val) {
- return row.push(val);
- }
- function commitRow() {
- rows.push(row.splice(0, row.length));
- }
- function unescape(val) {
- return val.replace(/""/g, '"');
- }
- }
- return {
- parse: parse
- };
- })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement