From d73050abc267082b41b7380d7b7083cab273e96b Mon Sep 17 00:00:00 2001 From: Mita Lapo Date: Tue, 18 May 2021 13:14:40 +0300 Subject: [PATCH 1/3] support reading from a pipe, such as stdin --- example.js | 11 ++++++++--- readlines.js | 19 +++++++++++++++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/example.js b/example.js index 8df4045..2c38624 100644 --- a/example.js +++ b/example.js @@ -1,14 +1,19 @@ 'use strict'; const lineByLine = require('./readlines.js'); -const liner = new lineByLine('./test/fixtures/normalFile.txt'); + +const fname = process.argv.length > 2 ? process.argv[2] : './test/fixtures/normalFile.txt'; +const enc = process.argv.length > 3 ? process.argv[3] : 'ascii'; +console.log('Reading', enc, 'encoded file', fname); + +const liner = new lineByLine(fname === '-' ? 0 : fname); let line; let lineNumber = 0; while (line = liner.next()) { - console.log('Line ' + lineNumber + ': ' + line.toString('ascii')); + console.log('Line ' + lineNumber + ': ' + line.toString(enc)); lineNumber++; } -console.log('end of line reached'); +console.log('end of file reached'); diff --git a/readlines.js b/readlines.js index 6b8bdc1..1b420f5 100644 --- a/readlines.js +++ b/readlines.js @@ -47,6 +47,7 @@ class LineByLine { reset() { this.eofReached = false; this.linesCache = []; + this.seekable = true; this.fdPosition = 0; } @@ -87,9 +88,18 @@ class LineByLine { let bytesRead; const buffers = []; do { - const readBuffer = new Buffer(this.options.readChunk); + const readBuffer = Buffer.alloc(this.options.readChunk); - bytesRead = fs.readSync(this.fd, readBuffer, 0, this.options.readChunk, this.fdPosition); + if (this.seekable) { + try { + bytesRead = fs.readSync(this.fd, readBuffer, 0, this.options.readChunk, this.fdPosition); + } catch { + this.seekable = false; + } + } + if (!this.seekable) { + bytesRead = fs.readSync(this.fd, readBuffer, 0, this.options.readChunk); + } totalBytesRead = totalBytesRead + bytesRead; this.fdPosition = this.fdPosition + bytesRead; @@ -100,10 +110,11 @@ class LineByLine { let bufferData = Buffer.concat(buffers); if (bytesRead < this.options.readChunk) { - this.eofReached = true; bufferData = bufferData.slice(0, totalBytesRead); } + this.eofReached = bytesRead === 0; + if (totalBytesRead) { this.linesCache = this._extractLines(bufferData); @@ -116,7 +127,7 @@ class LineByLine { } next() { - if (!this.fd) return false; + if (this.fd === null) return false; let line = false; From ad336305872da1fbefec98b5251808a9094ab266 Mon Sep 17 00:00:00 2001 From: Mita Lapo Date: Tue, 18 May 2021 13:39:58 +0300 Subject: [PATCH 2/3] fix catch --- readlines.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readlines.js b/readlines.js index 1b420f5..58fa2a5 100644 --- a/readlines.js +++ b/readlines.js @@ -93,7 +93,7 @@ class LineByLine { if (this.seekable) { try { bytesRead = fs.readSync(this.fd, readBuffer, 0, this.options.readChunk, this.fdPosition); - } catch { + } catch (e) { this.seekable = false; } } From d43732dde0e3c0d9662fd87be8ecb8d611de189b Mon Sep 17 00:00:00 2001 From: Mita Lapo Date: Fri, 21 May 2021 18:50:53 +0300 Subject: [PATCH 3/3] fix eof and test conditions --- readlines.js | 1 + test/readlines.test.js | 1 + 2 files changed, 2 insertions(+) diff --git a/readlines.js b/readlines.js index 58fa2a5..893eb0c 100644 --- a/readlines.js +++ b/readlines.js @@ -132,6 +132,7 @@ class LineByLine { let line = false; if (this.eofReached && this.linesCache.length === 0) { + this.close(); return line; } diff --git a/test/readlines.test.js b/test/readlines.test.js index 970836f..2a1b499 100644 --- a/test/readlines.test.js +++ b/test/readlines.test.js @@ -127,6 +127,7 @@ test('should correctly processes NULL character in lines', (t) => { t.equals(liner.next().toString(), 'line wi'+String.fromCharCode(0)+'th null', 'line 1: line with null'); t.equals(liner.next().toString(), 'another line without null', 'line 2: another line without null'); + t.equals(liner.next(), false, 'line 3: false'); t.equals(liner.fd, null, 'fd is null'); t.end(); })