From 703e03aba33f234712206769f57717ba7d92d23d Mon Sep 17 00:00:00 2001 From: LinuxWizard42 Date: Wed, 12 Oct 2022 22:54:37 +0300 Subject: Added export_allowed file to make repository visible in cgit --- .../src/fileCompareHandler/closeFile.js | 28 +++ .../src/fileCompareHandler/defaultFileCompare.js | 113 ++++++++++++ .../src/fileCompareHandler/lineBasedFileCompare.js | 196 +++++++++++++++++++++ 3 files changed, 337 insertions(+) create mode 100644 node_modules/dir-compare/src/fileCompareHandler/closeFile.js create mode 100644 node_modules/dir-compare/src/fileCompareHandler/defaultFileCompare.js create mode 100644 node_modules/dir-compare/src/fileCompareHandler/lineBasedFileCompare.js (limited to 'node_modules/dir-compare/src/fileCompareHandler') diff --git a/node_modules/dir-compare/src/fileCompareHandler/closeFile.js b/node_modules/dir-compare/src/fileCompareHandler/closeFile.js new file mode 100644 index 0000000..10118e1 --- /dev/null +++ b/node_modules/dir-compare/src/fileCompareHandler/closeFile.js @@ -0,0 +1,28 @@ +var fs = require('fs') + +var closeFilesSync = function (fd1, fd2) { + if (fd1) { + fs.closeSync(fd1) + } + if (fd2) { + fs.closeSync(fd2) + } +} + +var closeFilesAsync = function (fd1, fd2, fdQueue) { + if (fd1 && fd2) { + return fdQueue.promises.close(fd1).then(() => fdQueue.promises.close(fd2)) + } + if (fd1) { + return fdQueue.promises.close(fd1) + } + if (fd2) { + return fdQueue.promises.close(fd2) + } +} + + +module.exports = { + closeFilesSync: closeFilesSync, + closeFilesAsync: closeFilesAsync +} diff --git a/node_modules/dir-compare/src/fileCompareHandler/defaultFileCompare.js b/node_modules/dir-compare/src/fileCompareHandler/defaultFileCompare.js new file mode 100644 index 0000000..26188ca --- /dev/null +++ b/node_modules/dir-compare/src/fileCompareHandler/defaultFileCompare.js @@ -0,0 +1,113 @@ +var fs = require('fs') +var bufferEqual = require('buffer-equal') +var FileDescriptorQueue = require('../fs/FileDescriptorQueue') +var closeFilesSync = require('./closeFile').closeFilesSync +var closeFilesAsync = require('./closeFile').closeFilesAsync +var fsPromise = require('../fs/fsPromise') +var BufferPool = require('../fs/BufferPool') + +var MAX_CONCURRENT_FILE_COMPARE = 8 +var BUF_SIZE = 100000 +var fdQueue = new FileDescriptorQueue(MAX_CONCURRENT_FILE_COMPARE * 2) +var bufferPool = new BufferPool(BUF_SIZE, MAX_CONCURRENT_FILE_COMPARE); // fdQueue guarantees there will be no more than MAX_CONCURRENT_FILE_COMPARE async processes accessing the buffers concurrently + + +/** + * Compares two partial buffers. + */ +var compareBuffers = function (buf1, buf2, contentSize) { + return bufferEqual(buf1.slice(0, contentSize), buf2.slice(0, contentSize)) +} + +/** + * Compares two files by content. + */ +var compareSync = function (path1, stat1, path2, stat2, options) { + var fd1, fd2 + if (stat1.size !== stat2.size) { + return false + } + var bufferPair = bufferPool.allocateBuffers() + try { + fd1 = fs.openSync(path1, 'r') + fd2 = fs.openSync(path2, 'r') + var buf1 = bufferPair.buf1 + var buf2 = bufferPair.buf2 + var progress = 0 + while (true) { + var size1 = fs.readSync(fd1, buf1, 0, BUF_SIZE, null) + var size2 = fs.readSync(fd2, buf2, 0, BUF_SIZE, null) + if (size1 !== size2) { + return false + } else if (size1 === 0) { + // End of file reached + return true + } else if (!compareBuffers(buf1, buf2, size1)) { + return false + } + } + } finally { + closeFilesSync(fd1, fd2) + bufferPool.freeBuffers(bufferPair) + } +} + + +/** + * Compares two files by content + */ +var compareAsync = function (path1, stat1, path2, stat2, options) { + var fd1, fd2 + var bufferPair + if (stat1.size !== stat2.size) { + return Promise.resolve(false) + } + return Promise.all([fdQueue.promises.open(path1, 'r'), fdQueue.promises.open(path2, 'r')]) + .then(function (fds) { + bufferPair = bufferPool.allocateBuffers() + fd1 = fds[0] + fd2 = fds[1] + var buf1 = bufferPair.buf1 + var buf2 = bufferPair.buf2 + var progress = 0 + var compareAsyncInternal = function () { + return Promise.all([ + fsPromise.read(fd1, buf1, 0, BUF_SIZE, null), + fsPromise.read(fd2, buf2, 0, BUF_SIZE, null) + ]).then(function (bufferSizes) { + var size1 = bufferSizes[0] + var size2 = bufferSizes[1] + if (size1 !== size2) { + return false + } else if (size1 === 0) { + // End of file reached + return true + } else if (!compareBuffers(buf1, buf2, size1)) { + return false + } else { + return compareAsyncInternal() + } + }) + } + return compareAsyncInternal() + }) + .then( + // 'finally' polyfill for node 8 and below + function (res) { + return finalizeAsync(fd1, fd2, bufferPair).then(() => res) + }, + function (err) { + return finalizeAsync(fd1, fd2, bufferPair).then(() => { throw err; }) + } + ) +} + +function finalizeAsync(fd1, fd2, bufferPair) { + bufferPool.freeBuffers(bufferPair) + return closeFilesAsync(fd1, fd2, fdQueue) +} + +module.exports = { + compareSync: compareSync, + compareAsync: compareAsync +} diff --git a/node_modules/dir-compare/src/fileCompareHandler/lineBasedFileCompare.js b/node_modules/dir-compare/src/fileCompareHandler/lineBasedFileCompare.js new file mode 100644 index 0000000..c2de4b2 --- /dev/null +++ b/node_modules/dir-compare/src/fileCompareHandler/lineBasedFileCompare.js @@ -0,0 +1,196 @@ +/** + * Compare files line by line with options to ignore + * line endings and white space differencies. + */ +var fs = require('fs') +var FileDescriptorQueue = require('../fs/FileDescriptorQueue') +var closeFilesSync = require('./closeFile').closeFilesSync +var closeFilesAsync = require('./closeFile').closeFilesAsync +var fsPromise = require('../fs/fsPromise') +var BufferPool = require('../fs/BufferPool') + +const LINE_TOKENIZER_REGEXP = /[^\n]+\n?|\n/g +const TRIM_LINE_ENDING_REGEXP = /\r\n$/g +const SPLIT_CONTENT_AND_LINE_ENDING_REGEXP = /([^\r\n]*)([\r\n]*)/ +const TRIM_WHITE_SPACES_REGEXP = /^[ \f\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+|[ \f\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+$/g + +var MAX_CONCURRENT_FILE_COMPARE = 8 +var BUF_SIZE = 100000 +var fdQueue = new FileDescriptorQueue(MAX_CONCURRENT_FILE_COMPARE * 2) +var bufferPool = new BufferPool(BUF_SIZE, MAX_CONCURRENT_FILE_COMPARE); // fdQueue guarantees there will be no more than MAX_CONCURRENT_FILE_COMPARE async processes accessing the buffers concurrently + +function compareSync(path1, stat1, path2, stat2, options) { + var fd1, fd2 + var bufferPair = bufferPool.allocateBuffers() + var bufferSize = options.lineBasedHandlerBufferSize || BUF_SIZE + try { + fd1 = fs.openSync(path1, 'r') + fd2 = fs.openSync(path2, 'r') + var buf1 = bufferPair.buf1 + var buf2 = bufferPair.buf2 + var nextPosition1 = 0, nextPosition2 = 0 + while (true) { + var lines1 = readLinesSync(fd1, buf1, bufferSize, nextPosition1) + var lines2 = readLinesSync(fd2, buf2, bufferSize, nextPosition2) + if (lines1.length === 0 && lines2.length === 0) { + // End of file reached + return true + } + var equalLines = compareLines(lines1, lines2, options) + if (equalLines === 0) { + return false + } + nextPosition1 += calculateSize(lines1, equalLines) + nextPosition2 += calculateSize(lines2, equalLines) + } + } finally { + closeFilesSync(fd1, fd2) + bufferPool.freeBuffers(bufferPair) + } +} + +async function compareAsync(path1, stat1, path2, stat2, options) { + var fd1, fd2 + var bufferSize = options.lineBasedHandlerBufferSize || BUF_SIZE + var bufferPair + try { + var fds = await Promise.all([fdQueue.promises.open(path1, 'r'), fdQueue.promises.open(path2, 'r')]) + bufferPair = bufferPool.allocateBuffers() + fd1 = fds[0] + fd2 = fds[1] + var buf1 = bufferPair.buf1 + var buf2 = bufferPair.buf2 + var nextPosition1 = 0, nextPosition2 = 0 + while (true) { + var lines1 = await readLinesAsync(fd1, buf1, bufferSize, nextPosition1) + var lines2 = await readLinesAsync(fd2, buf2, bufferSize, nextPosition2) + if (lines1.length === 0 && lines2.length === 0) { + // End of file reached + return true + } + var equalLines = compareLines(lines1, lines2, options) + if (equalLines === 0) { + return false + } + nextPosition1 += calculateSize(lines1, equalLines) + nextPosition2 += calculateSize(lines2, equalLines) + } + } finally { + bufferPool.freeBuffers(bufferPair) + await closeFilesAsync(fd1, fd2, fdQueue) + } +} + +/** + * Read lines from file starting with nextPosition. + * Returns 0 lines if eof is reached, otherwise returns at least one complete line. + */ +function readLinesSync(fd, buf, bufferSize, nextPosition) { + var lines = [] + var chunk = "" + while (true) { + var size = fs.readSync(fd, buf, 0, bufferSize, nextPosition) + if (size === 0) { + // end of file + normalizeLastFileLine(lines) + return lines + } + chunk += buf.toString('utf8', 0, size) + lines = chunk.match(LINE_TOKENIZER_REGEXP) + if (lines.length > 1) { + return removeLastIncompleteLine(lines) + } + nextPosition += size + } +} + +/** + * Read lines from file starting with nextPosition. + * Returns 0 lines if eof is reached, otherwise returns at least one complete line. + */ +async function readLinesAsync(fd, buf, bufferSize, nextPosition) { + var lines = [] + var chunk = "" + while (true) { + var size = await fsPromise.read(fd, buf, 0, bufferSize, nextPosition) + if (size === 0) { + // end of file + normalizeLastFileLine(lines) + return lines + } + chunk += buf.toString('utf8', 0, size) + lines = chunk.match(LINE_TOKENIZER_REGEXP) + if (lines.length > 1) { + return removeLastIncompleteLine(lines) + } + nextPosition += size + } +} + +function removeLastIncompleteLine(lines) { + const lastLine = lines[lines.length - 1] + if (!lastLine.endsWith('\n')) { + return lines.slice(0, lines.length - 1) + } + return lines +} + +function normalizeLastFileLine(lines) { + if (lines.length === 0) { + return + } + const lastLine = lines[lines.length - 1] + if (!lastLine.endsWith('\n')) { + lines[lines.length - 1] = lastLine + '\n' + } +} + +function calculateSize(lines, numberOfLines) { + var size = 0 + for (var i = 0; i < numberOfLines; i++) { + var line = lines[i] + size += line.length + } + return size +} + +function compareLines(lines1, lines2, options) { + var equalLines = 0 + var len = lines1.length < lines2.length ? lines1.length : lines2.length + for (var i = 0; i < len; i++) { + var line1 = lines1[i] + var line2 = lines2[i] + if (options.ignoreLineEnding) { + line1 = trimLineEnding(line1) + line2 = trimLineEnding(line2) + } + if (options.ignoreWhiteSpaces) { + line1 = trimSpaces(line1) + line2 = trimSpaces(line2) + } + if (line1 !== line2) { + return equalLines + } + equalLines++ + } + return equalLines +} + +// Trims string like ' abc \n' into 'abc\n' +function trimSpaces(s) { + var matchResult = s.match(SPLIT_CONTENT_AND_LINE_ENDING_REGEXP); + var content = matchResult[1] + var lineEnding = matchResult[2] + var trimmed = content.replace(TRIM_WHITE_SPACES_REGEXP, '') + return trimmed + lineEnding +} + +// Trims string like 'abc\r\n' into 'abc\n' +function trimLineEnding(s) { + return s.replace(TRIM_LINE_ENDING_REGEXP, '\n') +} + +module.exports = { + compareSync: compareSync, + compareAsync: compareAsync +} -- cgit v1.2.3-86-g962b