read-lines-riched
Advanced tools
Comparing version 0.1.3 to 0.2.3
@@ -19,3 +19,3 @@ { | ||
"args": [ | ||
"${workspaceFolder}\\test\\read_lines.spec.js" | ||
"${workspaceFolder}/test/main.spec.js" | ||
] | ||
@@ -22,0 +22,0 @@ } |
141
main.js
@@ -5,23 +5,45 @@ "use strict" | ||
const fs = require("fs-extra"); | ||
var TESTABLE = false; | ||
const NEW_LINE_CHARACTERS = ["\n", "\r"]; | ||
var eDir = Object.freeze({ | ||
"StartToEnd": 1, | ||
"EndToStart": -1 | ||
StartToEnd: 1, | ||
EndToStart: -1 | ||
}); | ||
function readLines(file_path, options) { | ||
function readLines(file_path, options = {bChunk :1024, dir:eDir.StartToEnd}) { | ||
let dir = options.dir; | ||
let bChunk = options.bChunk; | ||
async function readNextChar(fd, stat, readedCharCount) { | ||
var originPos = dir === eDir.EndToStart ? stat.size - 1 : 0; | ||
const carriage = platformValue('\r\n', '\n', '\r'); | ||
const carriageReg = platformValue(/\r\n/, /\n/, /\r/); | ||
var offsetToRead = (originPos + dir * readedCharCount); | ||
if (stat.size <= offsetToRead || offsetToRead < 0) | ||
async function readNextChar(fd, stat, readedCharCount, bytesChunk = bChunk) { | ||
if (readedCharCount == stat.size) | ||
return ''; | ||
var { readBytes, buffer} = await fs.read(fd, Buffer.alloc(1), 0, 1, offsetToRead); | ||
var originPos = dir === eDir.EndToStart ? stat.size : 0; | ||
return String.fromCharCode(buffer[0]); | ||
var readSize = bytesChunk; | ||
var relativePosition = (originPos + dir * readedCharCount); | ||
var readPosition = dir === eDir.EndToStart ? relativePosition - readSize : relativePosition; | ||
if (readPosition < 0) //If end to start read the characters left | ||
{ | ||
readPosition = 0; | ||
readSize = relativePosition; | ||
} else if (readPosition + readSize > stat.size) //If start to end read the characters left | ||
{ | ||
readPosition = relativePosition | ||
readSize = stat.size - relativePosition; | ||
} | ||
var { | ||
readBytes, | ||
buffer | ||
} = await fs.read(fd, Buffer.alloc(readSize), 0, readSize, readPosition); | ||
return buffer.toString('utf8'); | ||
}; | ||
@@ -38,5 +60,6 @@ | ||
]); | ||
let readedCharCount = 0; | ||
var linesCache = []; | ||
@@ -46,54 +69,80 @@ async function readNextLine() { | ||
await cleanForNextRead(); | ||
if (linesCache.length > 0) | ||
return linesCache.pop(); | ||
let line = await readLine(); | ||
var line = await readLinesCache(); | ||
return line; | ||
} | ||
async function readLine() | ||
{ | ||
let line = ""; | ||
async function readLinesCache() { | ||
let lines = ''; | ||
var char = await readNextChar(self.fd, self.stat, readedCharCount); | ||
var charsChunk; | ||
var carriageCount = 0; | ||
while(char && !isNewLineOrUnknown(char)){ | ||
line += char; | ||
var newLinePattern = dir === eDir.StartToEnd ? /.\r|.\n/ : /\r.|\n./; | ||
readedCharCount += 1; | ||
char = await readNextChar(self.fd, self.stat, readedCharCount); | ||
while ((charsChunk = await readNextChar(self.fd, self.stat, readedCharCount))) { | ||
readedCharCount += charsChunk.length; | ||
lines = dir === eDir.StartToEnd ? lines + charsChunk : charsChunk + lines; | ||
if (newLinePattern.test(lines)) | ||
break; | ||
} | ||
return dir === eDir.StartToEnd ? line: line.split('').reverse().join(''); | ||
linesCache = updateCache(lines); | ||
return linesCache.length > 0 ? linesCache.pop() : ''; | ||
} | ||
async function cleanForNextRead() | ||
{ | ||
var char = await readNextChar(self.fd, self.stat, readedCharCount); | ||
function updateCache(newLines) { | ||
var linesArr = newLines.split(/\r|\n/); | ||
var lastCharIsNewLine = dir === eDir.StartToEnd ? linesArr[linesArr.length - 1] : linesArr[0]; | ||
linesArr = linesArr.filter(x => x); | ||
if (linesArr.length > 1 && lastCharIsNewLine) //last item depending direction is dirty if is not new line | ||
readedCharCount -= dir === eDir.StartToEnd ? linesArr.pop().length : linesArr.shift().length; | ||
while(char && isNewLineOrUnknown(char))//Cleaning \\n \\r or unknown characters | ||
{ | ||
readedCharCount += char.length; | ||
char = await readNextChar(self.fd, self.stat, readedCharCount); | ||
if (dir === eDir.StartToEnd) { | ||
linesArr = linesArr.reverse(); | ||
} | ||
return linesArr.concat(linesCache); | ||
} | ||
function isNewLineOrUnknown(char) | ||
{ | ||
return NEW_LINE_CHARACTERS.includes(char) || char.length > 1; | ||
function platformValue(windows, macos, linux = macos) { //If not windows platform carriage return takes only one character | ||
if (process.platform === 'win32') | ||
return windows; | ||
else if (process.platform === 'darwin') | ||
return macos; | ||
else | ||
return linux | ||
} | ||
async function closeReader(){ | ||
async function closeReader() { | ||
await fs.close(self.fd); | ||
} | ||
return { | ||
readNextChar: readNextChar, | ||
readNextLine: readNextLine, | ||
closeReader: closeReader | ||
}; | ||
function getCache() | ||
{ | ||
return linesCache; | ||
} | ||
if (TESTABLE) | ||
return { | ||
readNextChar: readNextChar, | ||
readNextLine: readNextLine, | ||
closeReader: closeReader, | ||
updateCache: updateCache, | ||
getCache: getCache | ||
}; | ||
else | ||
return { | ||
readNextChar: readNextChar, | ||
readNextLine: readNextLine, | ||
closeReader: closeReader, | ||
}; | ||
} | ||
function readLinesStartToEnd(file_path, options = {}){ | ||
function readLinesStartToEnd(file_path, bChunk = 1024) { | ||
var options = {}; | ||
options.bChunk = bChunk; | ||
options.dir = eDir.StartToEnd; | ||
@@ -103,3 +152,5 @@ return readLines(file_path, options); | ||
function readLinesEndToStart(file_path, options = {}){ | ||
function readLinesEndToStart(file_path, bChunk = 1024) { | ||
var options = {}; | ||
options.bChunk = bChunk; | ||
options.dir = eDir.EndToStart; | ||
@@ -109,5 +160,11 @@ return readLines(file_path, options); | ||
function makeTestable(){ | ||
TESTABLE = true; | ||
} | ||
module.exports = { | ||
readLinesStartToEnd: readLinesStartToEnd, | ||
readLinesEndToStart: readLinesEndToStart, | ||
readLines : readLines, | ||
makeTestable: makeTestable | ||
}; |
{ | ||
"name": "read-lines-riched", | ||
"version": "0.1.3", | ||
"version": "0.2.3", | ||
"description": "Easy way to read file lines on two directions: from the beginning to the end and from the end to the beginning.", | ||
"main": "main.js", | ||
"scripts": { | ||
"test": "mocha ./test/read_lines.spec.js" | ||
"test": "mocha ./test/main.spec.js" | ||
}, | ||
@@ -9,0 +9,0 @@ "repository": { |
@@ -1,6 +0,6 @@ | ||
# Read Lines Riched | ||
# What is this? | ||
Easy way to read file lines on two directions: from the beginning to the end and from the end to the beginning. | ||
Easy way to read file lines async and efficiently on two directions: from the beginning to the end and from the end to the beginning. | ||
## Installing | ||
# Installing | ||
@@ -11,3 +11,3 @@ ``` | ||
## Running the tests | ||
# Run tests | ||
@@ -18,46 +18,64 @@ ``` | ||
## Usage with Promise | ||
# Highlights of functionality | ||
* `readLines(file_path[,options])` - Return instance of `readLineRiched` configured with options to read file lines. | ||
* `options` Object (Optional) | ||
* `bChunk` Integer - Size in bytes of how many bytes are readed from file at the same time. Default is 1024. | ||
* `dir` Integer - 1 read lines from beginning to the end. -1 read lines from the end to the beginning. Default is 1. | ||
Reading lines example from the end of the file to the beginning. | ||
* `readLinesStartToEnd(file_path)` - Return instance of `readLineRiched` that read from the beginning of the file to the end reading chunks of 1kb. | ||
* `readLinesEndToStart(file_path)` - Return instance of `readLineRiched` that read from the end of the file to the beginning reading chunks of 1kb. | ||
* `readLineRiched.readNextLine()` - Read next line of file based on given configuration. | ||
# Usage | ||
## Reading from beginning to end using Promise | ||
``` | ||
const {readLinesEndToStart} = require("read-lines-riched"); | ||
const readLinesEndToStart = require("read-lines-riched").readLinesEndToStart(file_path); | ||
let endToStartRL = readLinesEndToStart("./testing_file"); | ||
var func = function () { | ||
endToStartRL.readNextLine().then(line => { | ||
readLinesEndToStart.readNextLine().then(line => { | ||
if (line) { | ||
console.log(line); | ||
func() | ||
} | ||
else | ||
endToStartRL.closeReader(); | ||
} else | ||
readLinesEndToStart.closeReader(); | ||
}); | ||
}; | ||
func(); | ||
``` | ||
## Usage with Async Await | ||
## Reading from end to beginning using Async | ||
``` | ||
const readLinesStartToEnd = require("read-lines-riched").readLinesStartToEnd(file_path); | ||
Reading lines example from the beginning of the file to the end. | ||
(async function () { | ||
var line; | ||
while (line = await readLinesStartToEnd.readNextLine()) { | ||
console.log(line); | ||
} | ||
readLinesStartToEnd.closeReader(); | ||
})(); | ||
``` | ||
const { readLinesStartToEnd} = require("read-lines-riched"); | ||
## Reading from end to beginning on chunks of 4kb. | ||
``` | ||
const readLinesRiched = require("read-lines-riched").readLines(file_path, { | ||
bChunk: 1024 * 4, | ||
dir: -1 | ||
}); | ||
const startToEndRL = readLinesStartToEnd("./testing_file"); | ||
(async function(){ | ||
var line = await startToEndRL.readNextLine(); | ||
while(line) | ||
{ | ||
(async function () { | ||
var line; | ||
while (line = await readLinesRiched.readNextLine()) { | ||
console.log(line); | ||
line = await startToEndRL.readNextLine(); | ||
} | ||
startToEndRL.closeReader(); | ||
readLinesRiched.closeReader(); | ||
})(); | ||
``` | ||
## Contributing | ||
# Changelog | ||
All notable changes to this project can be seen [here](https://github.com/Puzzle9900/read-lines-riched/blob/master/CHANGELOG.md). | ||
# Contributing | ||
1. Fork it on Github [https://github.com/Puzzle9900/read-lines-riched](https://github.com/Puzzle9900/read-lines-riched) | ||
@@ -70,3 +88,3 @@ 2. Create your feature branch: `git checkout -b my-new-feature` | ||
## License | ||
# License | ||
@@ -73,0 +91,0 @@ This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
91
1
10543
7
151
1