From c375f7ee4d530087a0914fccf49f4416faf55067 Mon Sep 17 00:00:00 2001 From: Shawn Date: Mon, 7 Jan 2019 05:20:56 -0600 Subject: [PATCH] Fix corrupt outputs --- .../Assets/Editor/LBRY/lbry-format/index.js | 68 +++++++++++++----- .../Assets/Editor/LBRY/lbry-format~/index.js | 68 +++++++++++++----- lbry.unitypackage | Bin 7478 -> 7791 bytes 3 files changed, 104 insertions(+), 32 deletions(-) diff --git a/LBRY 3D Viewer/Assets/Editor/LBRY/lbry-format/index.js b/LBRY 3D Viewer/Assets/Editor/LBRY/lbry-format/index.js index dd49362..31878ae 100644 --- a/LBRY 3D Viewer/Assets/Editor/LBRY/lbry-format/index.js +++ b/LBRY 3D Viewer/Assets/Editor/LBRY/lbry-format/index.js @@ -64,29 +64,35 @@ async function walkAndRun(runCommand, dir, root) { const currentPath = path.join(dir, file); if (fs.statSync(currentPath).isDirectory()) { - walkAndRun(runCommand, currentPath); + await walkAndRun(runCommand, currentPath); } else { - runCommand(currentPath); + await runCommand(currentPath); } } }; +async function writeStream(stream, data) { + return new Promise((resolve) => { + stream.write(data); + stream.end(resolve) + }); +} + async function packDirectory(directory, options = {}) { + const zstd = await getZstd(); const packRoot = directory; const fileWriteStream = getFileWriteStream(options); - const zstd = await getZstd(); tarPack.pipe(fileWriteStream); writeFirstEntry(options, tarPack); - walkAndRun(async (file) => { - let contents = await readFile(file); - - contents = new Uint8Array(contents); + await walkAndRun(async (file) => { + try{ + contents = await readFile(path.normalize(file)); // Must be chunked to avoid issues with fixed memory limits. const chunkIterator = (() => { - const chunkSize = 4096; + const chunkSize = 2048; let position = 0; const iterator = { @@ -94,7 +100,7 @@ async function packDirectory(directory, options = {}) { const endIndex = position + chunkSize; const result = { value: contents.slice(position, endIndex), - done: endIndex >= contents.length, + done: position >= contents.length, }; position = endIndex; @@ -119,10 +125,34 @@ async function packDirectory(directory, options = {}) { } }); - entry.end(contents); + await writeStream(entry, contents); + //console.log(contents) + entry.end(); + }catch (e){console.log(e)} }, directory, packRoot); + tarPack.finalize(); }; + +function strToBuffer (string) { + let arrayBuffer = new ArrayBuffer(string.length * 1); + let newUint = new Uint8Array(arrayBuffer); + newUint.forEach((_, i) => { + newUint[i] = string.charCodeAt(i); + }); + return newUint; +} + +function streamToBuffer(stream) { + const chunks = [] + return new Promise((resolve, reject) => { + stream.on('data', chunk => chunks.push(chunk)) + stream.on('error', reject) + stream.on('end', () => resolve(Buffer.concat(chunks))) + }) +} + + async function unpackDirectory(directory, options = {}) { if(!fs.existsSync(directory)) { fs.mkdirSync(directory); @@ -134,18 +164,24 @@ async function unpackDirectory(directory, options = {}) { const extract = tar.extract(); extract.on('entry', async (header, fileStream, next) => { - fileStream.on('end', () => { - next(); - }) + let contents = await streamToBuffer(fileStream); + contents = new Uint8Array(contents); + + contents = zstd.decompress(contents); if(!/^\./.test(header.name)) { + if(header.name == 'index.html') { + console.log(String.fromCharCode.apply(null, contents)) + } const writePath = path.join(directory, header.name); - await fs.promises.mkdir(path.dirname(writePath), { recursive: true }); + fs.promises.mkdir(path.dirname(writePath), { recursive: true }); var fileWriteStream = fs.createWriteStream(writePath); - fileStream.pipe(fileWriteStream); + fileWriteStream.write(contents); + fileWriteStream.end(); + next(); } else { - // Just drain it fileStream.resume(); + next(); } }); diff --git a/LBRY 3D Viewer/Assets/Editor/LBRY/lbry-format~/index.js b/LBRY 3D Viewer/Assets/Editor/LBRY/lbry-format~/index.js index dd49362..31878ae 100644 --- a/LBRY 3D Viewer/Assets/Editor/LBRY/lbry-format~/index.js +++ b/LBRY 3D Viewer/Assets/Editor/LBRY/lbry-format~/index.js @@ -64,29 +64,35 @@ async function walkAndRun(runCommand, dir, root) { const currentPath = path.join(dir, file); if (fs.statSync(currentPath).isDirectory()) { - walkAndRun(runCommand, currentPath); + await walkAndRun(runCommand, currentPath); } else { - runCommand(currentPath); + await runCommand(currentPath); } } }; +async function writeStream(stream, data) { + return new Promise((resolve) => { + stream.write(data); + stream.end(resolve) + }); +} + async function packDirectory(directory, options = {}) { + const zstd = await getZstd(); const packRoot = directory; const fileWriteStream = getFileWriteStream(options); - const zstd = await getZstd(); tarPack.pipe(fileWriteStream); writeFirstEntry(options, tarPack); - walkAndRun(async (file) => { - let contents = await readFile(file); - - contents = new Uint8Array(contents); + await walkAndRun(async (file) => { + try{ + contents = await readFile(path.normalize(file)); // Must be chunked to avoid issues with fixed memory limits. const chunkIterator = (() => { - const chunkSize = 4096; + const chunkSize = 2048; let position = 0; const iterator = { @@ -94,7 +100,7 @@ async function packDirectory(directory, options = {}) { const endIndex = position + chunkSize; const result = { value: contents.slice(position, endIndex), - done: endIndex >= contents.length, + done: position >= contents.length, }; position = endIndex; @@ -119,10 +125,34 @@ async function packDirectory(directory, options = {}) { } }); - entry.end(contents); + await writeStream(entry, contents); + //console.log(contents) + entry.end(); + }catch (e){console.log(e)} }, directory, packRoot); + tarPack.finalize(); }; + +function strToBuffer (string) { + let arrayBuffer = new ArrayBuffer(string.length * 1); + let newUint = new Uint8Array(arrayBuffer); + newUint.forEach((_, i) => { + newUint[i] = string.charCodeAt(i); + }); + return newUint; +} + +function streamToBuffer(stream) { + const chunks = [] + return new Promise((resolve, reject) => { + stream.on('data', chunk => chunks.push(chunk)) + stream.on('error', reject) + stream.on('end', () => resolve(Buffer.concat(chunks))) + }) +} + + async function unpackDirectory(directory, options = {}) { if(!fs.existsSync(directory)) { fs.mkdirSync(directory); @@ -134,18 +164,24 @@ async function unpackDirectory(directory, options = {}) { const extract = tar.extract(); extract.on('entry', async (header, fileStream, next) => { - fileStream.on('end', () => { - next(); - }) + let contents = await streamToBuffer(fileStream); + contents = new Uint8Array(contents); + + contents = zstd.decompress(contents); if(!/^\./.test(header.name)) { + if(header.name == 'index.html') { + console.log(String.fromCharCode.apply(null, contents)) + } const writePath = path.join(directory, header.name); - await fs.promises.mkdir(path.dirname(writePath), { recursive: true }); + fs.promises.mkdir(path.dirname(writePath), { recursive: true }); var fileWriteStream = fs.createWriteStream(writePath); - fileStream.pipe(fileWriteStream); + fileWriteStream.write(contents); + fileWriteStream.end(); + next(); } else { - // Just drain it fileStream.resume(); + next(); } }); diff --git a/lbry.unitypackage b/lbry.unitypackage index 30f7c1425d828fe6f34938ba65a9bc0b335c411b..b946d38d3de508c9ebd6bff5789a553777fd9fb2 100644 GIT binary patch literal 7791 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 AZU6uP