Skip to content

Commit

Permalink
fix(io-utils): added ensureString, updated io deserializers in order …
Browse files Browse the repository at this point in the history
…to accept buffers

core: corrected registerDeserializer to read files as binary (buffers)
  • Loading branch information
z3dev authored Nov 9, 2024
2 parents 15a50a0 + ce2bfe9 commit 36b339f
Show file tree
Hide file tree
Showing 18 changed files with 143 additions and 23 deletions.
85 changes: 78 additions & 7 deletions packages/cli/cli.conversions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,23 @@ test.afterEach.always((t) => {
// remove files
try {
if (t.context.file1Path) fs.unlinkSync(t.context.file1Path)
} catch (err) {}
} catch (err) { }

try {
if (t.context.file2Path) fs.unlinkSync(t.context.file2Path)
} catch (err) {}
} catch (err) { }

try {
if (t.context.file3Path) fs.unlinkSync(t.context.file3Path)
} catch (err) {}
} catch (err) { }

try {
if (t.context.file4Path) fs.unlinkSync(t.context.file4Path)
} catch (err) {}
} catch (err) { }

try {
if (t.context.file5Path) fs.unlinkSync(t.context.file5Path)
} catch (err) { }
})

test.beforeEach((t) => {
Expand Down Expand Up @@ -68,6 +72,57 @@ module.exports = { main, getParameterDefinitions }
return filePath
}

const createImportJscad = (id, extension) => {
const jscadScript = `// test script ${id} -- import
const main = () => {
return require('./test${id}.${extension}')
}
module.exports = { main }
`

const fileName = `./test${id}-import.jscad`;
const filePath = path.resolve(__dirname, fileName);
fs.writeFileSync(filePath, jscadScript);
return filePath;
}

const testBackImport = (t, testID, extension) => {
const cliPath = t.context.cliPath;

const file4Path = createImportJscad(testID, extension);
t.context.file4Path = file4Path;
t.true(fs.existsSync(file4Path));

const file5Name = `./test${testID}-import.stl`;
const file5Path = path.resolve(__dirname, file5Name);
t.context.file5Path = file5Path;
t.false(fs.existsSync(file5Path));

cmd = `node ${cliPath} ${file4Path}`
execSync(cmd, { stdio: [0, 1, 2] })
t.true(fs.existsSync(file5Path));
}

const runOnFixture = (t, fixtureName) => {
const inputFile = path.resolve(
__dirname,
path.join('test_fixtures', fixtureName, 'index.js'));

const outputFile = inputFile.replace('.js', '.stl');
t.context.file1Path = outputFile;

t.false(fs.existsSync(outputFile));

const cmd = `node ${t.context.cliPath} ${inputFile}`
execSync(cmd, { stdio: [0, 1, 2] });
t.true(fs.existsSync(outputFile))

return outputFile;
}


test('cli (conversions STL)', (t) => {
const testID = 11

Expand All @@ -87,18 +142,20 @@ test('cli (conversions STL)', (t) => {

let cmd = `node ${cliPath} ${file1Path}`
execSync(cmd, { stdio: [0, 1, 2] })
t.true(fs.existsSync(file2Path))
t.true(fs.existsSync(file2Path));

// convert from STL to JSCAD script
const file3Name = `./test${testID}.js`
const file3Path = path.resolve(__dirname, file3Name)
t.false(fs.existsSync(file3Path))
t.false(fs.existsSync(file3Path));

t.context.file3Path = file3Path

cmd = `node ${cliPath} ${file2Path} -o ${file3Path} -v -add-metadata false`
execSync(cmd, { stdio: [0, 1, 2] })
t.true(fs.existsSync(file3Path))
t.true(fs.existsSync(file3Path));

testBackImport(t, testID, 'stl');
})

test('cli (conversions DXF)', (t) => {
Expand Down Expand Up @@ -132,6 +189,8 @@ test('cli (conversions DXF)', (t) => {
cmd = `node ${cliPath} ${file2Path} -of js`
execSync(cmd, { stdio: [0, 1, 2] })
t.true(fs.existsSync(file3Path))

testBackImport(t, testID, 'dxf');
})

test('cli (conversions AMF)', (t) => {
Expand Down Expand Up @@ -165,6 +224,8 @@ test('cli (conversions AMF)', (t) => {
cmd = `node ${cliPath} ${file2Path} -of js`
execSync(cmd, { stdio: [0, 1, 2] })
t.true(fs.existsSync(file3Path))

testBackImport(t, testID, 'amf');
})

test('cli (conversions JSON)', (t) => {
Expand Down Expand Up @@ -198,6 +259,8 @@ test('cli (conversions JSON)', (t) => {
cmd = `node ${cliPath} ${file2Path} -of js`
execSync(cmd, { stdio: [0, 1, 2] })
t.true(fs.existsSync(file3Path))

testBackImport(t, testID, 'json');
})

test('cli (conversions SVG)', (t) => {
Expand Down Expand Up @@ -264,4 +327,12 @@ test('cli (conversions X3D)', (t) => {
cmd = `node ${cliPath} ${file2Path} -of js`
execSync(cmd, { stdio: [0, 1, 2] })
t.true(fs.existsSync(file3Path))

testBackImport(t, testID, 'x3d');
})

test('cli (import STL)', (t) => {
const testID = 17

runOnFixture(t, 'stl_import')
})
Binary file not shown.
6 changes: 6 additions & 0 deletions packages/cli/test_fixtures/stl_import/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

function main() {
return require('./binary_stl.stl');
}

module.exports = { main }
13 changes: 11 additions & 2 deletions packages/core/src/io/registerExtensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,17 @@ const registerDeserializer = (extension, fs, _require) => {
const deserializer = deserializers[extension]
const fileExtension = '.' + extension
_require.extensions[fileExtension] = (module, filename) => {
const content = fs.readFileSync(filename, 'utf8')
const parsed = deserializer({ filename, output: 'geometry' }, content)
const fileReadResult = fs.readFileSync(filename);

// https://nodejs.org/api/buffer.html#bufbuffer: Buffer.buffer is not
// guaranteed to correspond exactly to the original Buffer.
const fileContent = fileReadResult.buffer
? fileReadResult.buffer.slice(
fileReadResult.byteOffset,
fileReadResult.byteOffset + fileReadResult.length)
: fileReadResult;

const parsed = deserializer({ filename, output: 'geometry' }, fileContent)
module.exports = parsed
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/io/amf-deserializer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"license": "MIT",
"dependencies": {
"@jscad/modeling": "2.12.3",
"@jscad/io-utils": "2.0.28",
"saxes": "5.0.1"
},
"devDependencies": {
Expand Down
3 changes: 3 additions & 0 deletions packages/io/amf-deserializer/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ All code released under MIT license
* const { deserializer, extension } = require('@jscad/amf-serializer')
*/

const { ensureString } = require('@jscad/io-utils')

const version = require('../package.json').version
const translate = require('./translate')
const instantiate = require('./deserialize')
Expand All @@ -48,6 +50,7 @@ const deserialize = (options, input) => {
}
options = Object.assign({}, defaults, options)

input = ensureString(input);
return options.output === 'script' ? translate(options, input) : instantiate(options, input)
}

Expand Down
17 changes: 11 additions & 6 deletions packages/io/dxf-deserializer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ All code released under MIT license
*/

const { ensureString } = require('@jscad/io-utils')

const version = require('./package.json').version

const { BYLAYER, getTLA } = require('./autocad')
const colorIndex = require('./colorindex2017')
const dxf = require('./DxfReader')
Expand Down Expand Up @@ -275,7 +278,7 @@ const handleXcoord = (reader, group, value) => {
const obj = reader.objstack.pop()
if ('type' in obj) {
if (obj.type === 'lwpolyline') {
// special handling to build a list of vertices
// special handling to build a list of vertices
if (obj.pptxs === undefined) {
obj.pptxs = []
obj.bulgs = []
Expand All @@ -284,7 +287,7 @@ const handleXcoord = (reader, group, value) => {
obj.bulgs.push(0)
} else {
if (obj.type === 'mesh') {
// special handling to build a list of vertices
// special handling to build a list of vertices
if (obj.pptxs === undefined) {
obj.pptxs = []
}
Expand All @@ -307,7 +310,7 @@ const handleYcoord = (reader, group, value) => {
const obj = reader.objstack.pop()
if ('type' in obj) {
if (obj.type === 'lwpolyline' || obj.type === 'mesh') {
// special handling to build a list of vertices
// special handling to build a list of vertices
if (obj.pptys === undefined) {
obj.pptys = []
}
Expand All @@ -329,7 +332,7 @@ const handleZcoord = (reader, group, value) => {
const obj = reader.objstack.pop()
if ('type' in obj) {
if (obj.type === 'mesh') {
// special handling to build a list of vertices
// special handling to build a list of vertices
if (obj.pptzs === undefined) {
obj.pptzs = []
}
Expand All @@ -351,7 +354,7 @@ const handleBulge = (reader, group, value) => {
const obj = reader.objstack.pop()
if ('type' in obj) {
if (obj.type === 'lwpolyline') {
// special handling to build a list of vertices
// special handling to build a list of vertices
const bulgs = obj.bulgs
if (bulgs !== undefined) {
const pptxs = obj.pptxs
Expand All @@ -376,7 +379,7 @@ const handleLen = (reader, group, value) => {
const obj = reader.objstack.pop()
if ('type' in obj) {
if (obj.type === 'mesh') {
// mesh has an order of lengths
// mesh has an order of lengths
const state = obj.state
// console.log('mesh len: '+group+','+value+','+state)
switch (group) {
Expand Down Expand Up @@ -600,6 +603,8 @@ const deserialize = (options, src) => {
}
}
options = Object.assign({}, defaults, options)

src = ensureString(src);
return options.output === 'script' ? translate(src, options) : instantiate(src, options)
}

Expand Down
3 changes: 2 additions & 1 deletion packages/io/dxf-deserializer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
],
"license": "MIT",
"dependencies": {
"@jscad/modeling": "2.12.3"
"@jscad/modeling": "2.12.3",
"@jscad/io-utils": "2.0.28"
},
"devDependencies": {
"ava": "3.15.0",
Expand Down
9 changes: 9 additions & 0 deletions packages/io/io-utils/ensureString.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const ensureString = (stringOrArrayBuffer, defaultBinaryEncoding = 'utf-8') => {
if (typeof (stringOrArrayBuffer) === 'string') {
return stringOrArrayBuffer;
}

return new TextDecoder(defaultBinaryEncoding).decode(new Uint8Array(stringOrArrayBuffer));
}

module.exports = ensureString;
3 changes: 2 additions & 1 deletion packages/io/io-utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ module.exports = {
convertToBlob: require('./convertToBlob'),
makeBlob: require('./makeBlob'),
BinaryReader: require('./BinaryReader'),
Blob: require('./Blob')
Blob: require('./Blob'),
ensureString: require('./ensureString')
}
4 changes: 3 additions & 1 deletion packages/io/json-deserializer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ All code released under MIT license
*/

const { flatten, toArray } = require('@jscad/array-utils')
const { ensureString } = require('@jscad/io-utils')

const version = require('./package.json').version

Expand All @@ -45,6 +46,7 @@ const deserialize = (options, input) => {
options = Object.assign({}, defaults, options)

// convert the JSON notation into anonymous object(s)
input = ensureString(input);
let objects = JSON.parse(input)

// cleanup the objects
Expand All @@ -69,7 +71,7 @@ const translate = (options, objects) => {
: ''

script +=
`
`
const { geometries } = require('@jscad/modeling')
const main = () => {
Expand Down
3 changes: 2 additions & 1 deletion packages/io/json-deserializer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
],
"license": "MIT",
"dependencies": {
"@jscad/array-utils": "2.1.4"
"@jscad/array-utils": "2.1.4",
"@jscad/io-utils": "2.0.28"
},
"devDependencies": {
"@jscad/modeling": "2.12.3",
Expand Down
3 changes: 3 additions & 0 deletions packages/io/obj-deserializer/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const { colors, primitives } = require('@jscad/modeling')
const { ensureString } = require('@jscad/io-utils')

const version = require('./package.json').version

Expand Down Expand Up @@ -32,6 +33,8 @@ const deserialize = (options, input) => {
options = Object.assign({}, defaults, options)
const { output } = options

input = ensureString(input);

options && options.statusCallback && options.statusCallback({ progress: 0 })

const { positions, groups } = getGroups(input, options)
Expand Down
3 changes: 2 additions & 1 deletion packages/io/obj-deserializer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
],
"license": "MIT",
"dependencies": {
"@jscad/modeling": "2.12.3"
"@jscad/modeling": "2.12.3",
"@jscad/io-utils": "2.0.28"
},
"devDependencies": {
"ava": "3.15.0",
Expand Down
1 change: 1 addition & 0 deletions packages/io/svg-deserializer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"dependencies": {
"@jscad/array-utils": "2.1.4",
"@jscad/modeling": "2.12.3",
"@jscad/io-utils": "2.0.28",
"saxes": "5.0.1"
},
"devDependencies": {
Expand Down
Loading

0 comments on commit 36b339f

Please sign in to comment.