| 77793 | } |
| 77794 | |
| 77795 | function parseRows(text, f) { |
| 77796 | var rows = [], |
| 77797 | // output rows |
| 77798 | N = text.length, |
| 77799 | I = 0, |
| 77800 | // current character index |
| 77801 | n = 0, |
| 77802 | // current line number |
| 77803 | t, |
| 77804 | // current token |
| 77805 | eof = N <= 0, |
| 77806 | // current token followed by EOF? |
| 77807 | eol = false; // current token followed by EOL? |
| 77808 | // Strip the trailing newline. |
| 77809 | |
| 77810 | if (text.charCodeAt(N - 1) === NEWLINE) --N; |
| 77811 | if (text.charCodeAt(N - 1) === RETURN) --N; |
| 77812 | |
| 77813 | function token() { |
| 77814 | if (eof) return EOF; |
| 77815 | if (eol) return eol = false, EOL; // Unescape quotes. |
| 77816 | |
| 77817 | var i, |
| 77818 | j = I, |
| 77819 | c; |
| 77820 | |
| 77821 | if (text.charCodeAt(j) === QUOTE) { |
| 77822 | while (I++ < N && text.charCodeAt(I) !== QUOTE || text.charCodeAt(++I) === QUOTE); |
| 77823 | |
| 77824 | if ((i = I) >= N) eof = true;else if ((c = text.charCodeAt(I++)) === NEWLINE) eol = true;else if (c === RETURN) { |
| 77825 | eol = true; |
| 77826 | if (text.charCodeAt(I) === NEWLINE) ++I; |
| 77827 | } |
| 77828 | return text.slice(j + 1, i - 1).replace(/""/g, "\""); |
| 77829 | } // Find next delimiter or newline. |
| 77830 | |
| 77831 | |
| 77832 | while (I < N) { |
| 77833 | if ((c = text.charCodeAt(i = I++)) === NEWLINE) eol = true;else if (c === RETURN) { |
| 77834 | eol = true; |
| 77835 | if (text.charCodeAt(I) === NEWLINE) ++I; |
| 77836 | } else if (c !== DELIMITER) continue; |
| 77837 | return text.slice(j, i); |
| 77838 | } // Return last token before EOF. |
| 77839 | |
| 77840 | |
| 77841 | return eof = true, text.slice(j, N); |
| 77842 | } |
| 77843 | |
| 77844 | while ((t = token()) !== EOF) { |
| 77845 | var row = []; |
| 77846 | |
| 77847 | while (t !== EOL && t !== EOF) row.push(t), t = token(); |
| 77848 | |
| 77849 | if (f && (row = f(row, n++)) == null) continue; |
| 77850 | rows.push(row); |
| 77851 | } |
| 77852 | |