(zeroBasedStartLine: number)
| 71 | return this.#cursor >= this.#input.length; |
| 72 | } |
| 73 | #parseRecord(zeroBasedStartLine: number): string[] | null { |
| 74 | let fullLine = this.#readLine(); |
| 75 | if (fullLine === null) return null; |
| 76 | if (fullLine.length === 0) { |
| 77 | return []; |
| 78 | } |
| 79 | |
| 80 | let zeroBasedLine = zeroBasedStartLine; |
| 81 | |
| 82 | // line starting with comment character is ignored |
| 83 | if (this.#options.comment && fullLine[0] === this.#options.comment) { |
| 84 | return []; |
| 85 | } |
| 86 | |
| 87 | let line = fullLine; |
| 88 | const quote = '"'; |
| 89 | const quoteLen = quote.length; |
| 90 | const separatorLen = this.#options.separator.length; |
| 91 | let recordBuffer = ""; |
| 92 | const fieldIndexes = [] as number[]; |
| 93 | parseField: while (true) { |
| 94 | if (this.#options.trimLeadingSpace) { |
| 95 | line = line.trimStart(); |
| 96 | } |
| 97 | |
| 98 | if (line.length === 0 || !line.startsWith(quote)) { |
| 99 | // Non-quoted string field |
| 100 | const i = line.indexOf(this.#options.separator); |
| 101 | let field = line; |
| 102 | if (i >= 0) { |
| 103 | field = field.substring(0, i); |
| 104 | } |
| 105 | // Check to make sure a quote does not appear in field. |
| 106 | if (!this.#options.lazyQuotes) { |
| 107 | const j = field.indexOf(quote); |
| 108 | if (j >= 0) { |
| 109 | const col = codePointLength( |
| 110 | fullLine.slice(0, fullLine.length - line.slice(j).length), |
| 111 | ); |
| 112 | throw new SyntaxError( |
| 113 | createBareQuoteErrorMessage( |
| 114 | zeroBasedStartLine, |
| 115 | zeroBasedLine, |
| 116 | col, |
| 117 | ), |
| 118 | ); |
| 119 | } |
| 120 | } |
| 121 | recordBuffer += field; |
| 122 | fieldIndexes.push(recordBuffer.length); |
| 123 | if (i >= 0) { |
| 124 | line = line.substring(i + separatorLen); |
| 125 | continue parseField; |
| 126 | } |
| 127 | break parseField; |
| 128 | } else { |
| 129 | // Quoted string field |
| 130 | line = line.substring(quoteLen); |
no test coverage detected