Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
fs: refactor fs module
PR-URL: #20764 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
- Loading branch information
Showing
with
1,164 additions
and 1,002 deletions.
- +430 −952 lib/fs.js
- +108 −0 lib/internal/fs/read_file_context.js
- +383 −0 lib/internal/fs/streams.js
- +45 −0 lib/internal/fs/sync_write_stream.js
- +0 −42 lib/internal/fs/utils.js
- +168 −0 lib/internal/fs/watchers.js
- +2 −2 lib/internal/process/stdio.js
- +4 −0 node.gyp
- +21 −3 src/node_constants.cc
- +1 −1 test/parallel/test-internal-fs-syncwritestream.js
- +1 −1 test/parallel/test-repl-underscore.js
- +1 −1 test/parallel/test-sync-io-option.js
@@ -0,0 +1,108 @@ | ||
'use strict'; | ||
|
||
const { Buffer } = require('buffer'); | ||
const { FSReqWrap, close, read } = process.binding('fs'); | ||
|
||
const kReadFileBufferLength = 8 * 1024; | ||
|
||
function readFileAfterRead(err, bytesRead) { | ||
const context = this.context; | ||
|
||
if (err) | ||
return context.close(err); | ||
|
||
if (bytesRead === 0) | ||
return context.close(); | ||
|
||
context.pos += bytesRead; | ||
|
||
if (context.size !== 0) { | ||
if (context.pos === context.size) | ||
context.close(); | ||
else | ||
context.read(); | ||
} else { | ||
// unknown size, just read until we don't get bytes. | ||
context.buffers.push(context.buffer.slice(0, bytesRead)); | ||
context.read(); | ||
} | ||
} | ||
|
||
function readFileAfterClose(err) { | ||
const context = this.context; | ||
const callback = context.callback; | ||
let buffer = null; | ||
|
||
if (context.err || err) | ||
return callback(context.err || err); | ||
|
||
try { | ||
if (context.size === 0) | ||
buffer = Buffer.concat(context.buffers, context.pos); | ||
else if (context.pos < context.size) | ||
buffer = context.buffer.slice(0, context.pos); | ||
else | ||
buffer = context.buffer; | ||
|
||
if (context.encoding) | ||
buffer = buffer.toString(context.encoding); | ||
} catch (err) { | ||
return callback(err); | ||
} | ||
|
||
callback(null, buffer); | ||
} | ||
|
||
class ReadFileContext { | ||
constructor(callback, encoding) { | ||
this.fd = undefined; | ||
this.isUserFd = undefined; | ||
this.size = undefined; | ||
this.callback = callback; | ||
this.buffers = null; | ||
this.buffer = null; | ||
this.pos = 0; | ||
this.encoding = encoding; | ||
this.err = null; | ||
} | ||
|
||
read() { | ||
let buffer; | ||
let offset; | ||
let length; | ||
|
||
if (this.size === 0) { | ||
buffer = this.buffer = Buffer.allocUnsafeSlow(kReadFileBufferLength); | ||
offset = 0; | ||
length = kReadFileBufferLength; | ||
} else { | ||
buffer = this.buffer; | ||
offset = this.pos; | ||
length = Math.min(kReadFileBufferLength, this.size - this.pos); | ||
} | ||
|
||
const req = new FSReqWrap(); | ||
req.oncomplete = readFileAfterRead; | ||
req.context = this; | ||
|
||
read(this.fd, buffer, offset, length, -1, req); | ||
} | ||
|
||
close(err) { | ||
const req = new FSReqWrap(); | ||
req.oncomplete = readFileAfterClose; | ||
req.context = this; | ||
this.err = err; | ||
|
||
if (this.isUserFd) { | ||
process.nextTick(function tick() { | ||
req.oncomplete(null); | ||
}); | ||
return; | ||
} | ||
|
||
close(this.fd, req); | ||
} | ||
} | ||
|
||
module.exports = ReadFileContext; |
Oops, something went wrong.