-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Related to #115 Remove the `osc-min` dependency and implement custom OSC encoding/decoding functions. * **Remove `osc-min` dependency** - Remove `osc-min` from `package.json`. - Remove `#decode` alias from `package.json`. * **Update `Client.mjs`** - Import `toBuffer` from `internal/osc.mjs`. - Update `send` method to use the new `toBuffer` function. * **Update `Server.mjs`** - Import `fromBuffer` from `internal/osc.mjs`. - Update `message` event handler to use the new `fromBuffer` function. * **Add `internal/osc.mjs`** - Implement `toBuffer` function to encode OSC messages. - Implement `fromBuffer` function to decode OSC messages. * **Update `rollup.config.mjs`** - Remove `osc-min` and `#decode` from the `external` array in the `walkLib` function. - Remove `osc-min` and `#decode` from the `external` array in the `walkTest` function. * **Add tests for new implementation** - Add `test/test-osc.mjs` with tests for `toBuffer` and `fromBuffer` functions. * **Remove old files** - Delete `lib/internal/decode.mjs`. - Delete `test/test-decode.mjs`. --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/MylesBorins/node-osc/issues/115?shareId=XXXX-XXXX-XXXX-XXXX).
- Loading branch information
1 parent
f2a0602
commit da56567
Showing
8 changed files
with
157 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
import { Buffer } from 'node:buffer'; | ||
|
||
function toBuffer(message) { | ||
if (typeof message !== 'object') { | ||
throw new TypeError('Message must be an object'); | ||
} | ||
|
||
const address = message.address; | ||
const args = message.args || []; | ||
|
||
const addressBuffer = encodeString(address); | ||
const typeTagBuffer = encodeString(',' + args.map(arg => getTypeTag(arg)).join('')); | ||
const argsBuffer = Buffer.concat(args.map(arg => encodeArg(arg))); | ||
|
||
return Buffer.concat([addressBuffer, typeTagBuffer, argsBuffer]); | ||
} | ||
|
||
function fromBuffer(buffer) { | ||
if (!Buffer.isBuffer(buffer)) { | ||
throw new TypeError('Buffer must be a Buffer'); | ||
} | ||
|
||
let offset = 0; | ||
|
||
const address = decodeString(buffer, offset); | ||
offset += address.length + 4 - (address.length % 4); | ||
|
||
const typeTag = decodeString(buffer, offset); | ||
offset += typeTag.length + 4 - (typeTag.length % 4); | ||
|
||
const args = []; | ||
for (let i = 1; i < typeTag.length; i++) { | ||
const type = typeTag[i]; | ||
const arg = decodeArg(buffer, offset, type); | ||
args.push(arg.value); | ||
offset += arg.size; | ||
} | ||
|
||
return { | ||
address, | ||
args | ||
}; | ||
} | ||
|
||
function encodeString(str) { | ||
const length = str.length + 1; | ||
const paddedLength = length + (4 - (length % 4)); | ||
const buffer = Buffer.alloc(paddedLength); | ||
buffer.write(str, 0, 'ascii'); | ||
return buffer; | ||
} | ||
|
||
function decodeString(buffer, offset) { | ||
let end = offset; | ||
while (buffer[end] !== 0) { | ||
end++; | ||
} | ||
return buffer.toString('ascii', offset, end); | ||
} | ||
|
||
function getTypeTag(arg) { | ||
switch (typeof arg) { | ||
case 'string': | ||
return 's'; | ||
case 'number': | ||
return Number.isInteger(arg) ? 'i' : 'f'; | ||
case 'object': | ||
if (Buffer.isBuffer(arg)) { | ||
return 'b'; | ||
} | ||
throw new TypeError('Unsupported argument type'); | ||
default: | ||
throw new TypeError('Unsupported argument type'); | ||
} | ||
} | ||
|
||
function encodeArg(arg) { | ||
switch (typeof arg) { | ||
case 'string': | ||
return encodeString(arg); | ||
case 'number': | ||
return Number.isInteger(arg) ? encodeInt32(arg) : encodeFloat32(arg); | ||
case 'object': | ||
if (Buffer.isBuffer(arg)) { | ||
return encodeBlob(arg); | ||
} | ||
throw new TypeError('Unsupported argument type'); | ||
default: | ||
throw new TypeError('Unsupported argument type'); | ||
} | ||
} | ||
|
||
function decodeArg(buffer, offset, type) { | ||
switch (type) { | ||
case 's': | ||
return { value: decodeString(buffer, offset), size: 4 * Math.ceil((buffer.indexOf(0, offset) - offset + 1) / 4) }; | ||
case 'i': | ||
return { value: buffer.readInt32BE(offset), size: 4 }; | ||
case 'f': | ||
return { value: buffer.readFloatBE(offset), size: 4 }; | ||
case 'b': | ||
const length = buffer.readInt32BE(offset); | ||
Check failure on line 102 in lib/internal/osc.mjs GitHub Actions / run-tests (22, ubuntu-latest)
Check failure on line 102 in lib/internal/osc.mjs GitHub Actions / run-tests (20, ubuntu-latest)
Check failure on line 102 in lib/internal/osc.mjs GitHub Actions / run-tests (20, macos-latest)
Check failure on line 102 in lib/internal/osc.mjs GitHub Actions / run-tests (18, ubuntu-latest)
|
||
return { value: buffer.slice(offset + 4, offset + 4 + length), size: 4 + length + (4 - (length % 4)) }; | ||
default: | ||
throw new TypeError('Unsupported argument type'); | ||
} | ||
} | ||
|
||
function encodeInt32(value) { | ||
const buffer = Buffer.alloc(4); | ||
buffer.writeInt32BE(value, 0); | ||
return buffer; | ||
} | ||
|
||
function encodeFloat32(value) { | ||
const buffer = Buffer.alloc(4); | ||
buffer.writeFloatBE(value, 0); | ||
return buffer; | ||
} | ||
|
||
function encodeBlob(blob) { | ||
const length = blob.length; | ||
const paddedLength = length + (4 - (length % 4)); | ||
const buffer = Buffer.alloc(4 + paddedLength); | ||
buffer.writeInt32BE(length, 0); | ||
blob.copy(buffer, 4); | ||
return buffer; | ||
} | ||
|
||
export { toBuffer, fromBuffer }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { test } from 'tap'; | ||
import { toBuffer, fromBuffer } from '../lib/internal/osc.mjs'; | ||
|
||
test('toBuffer: valid message', (t) => { | ||
const message = { | ||
address: '/test', | ||
args: ['testing', 123, 3.14, Buffer.from('blob')] | ||
}; | ||
const buffer = toBuffer(message); | ||
t.type(buffer, Buffer, 'should return a Buffer'); | ||
t.end(); | ||
}); | ||
|
||
test('toBuffer: invalid message', (t) => { | ||
t.throws(() => { | ||
toBuffer('invalid'); | ||
}, /Message must be an object/); | ||
t.end(); | ||
}); | ||
|
||
test('fromBuffer: valid buffer', (t) => { | ||
const buffer = Buffer.from('/test\0\0\0,sifb\0\0\0\0testing\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 |