Skip to content

Commit

Permalink
Remove osc-min dependency
Browse files Browse the repository at this point in the history
Related to #115

---

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
MylesBorins committed Nov 15, 2024
1 parent 5e6d356 commit a087a51
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 41 deletions.
4 changes: 1 addition & 3 deletions lib/Client.mjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { createSocket } from 'node:dgram';
import oscMin from 'osc-min';
import { toBuffer } from '#osc';
import Message from './Message.mjs';

const { toBuffer } = oscMin;

class Client {
constructor(host, port) {
this.host = host;
Expand Down
4 changes: 2 additions & 2 deletions lib/Server.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createSocket } from 'node:dgram';
import { EventEmitter } from 'node:events';

import decode from '#decode';
import { fromBuffer } from '#osc';

class Server extends EventEmitter {
constructor(port, host='127.0.0.1', cb) {
Expand All @@ -25,7 +25,7 @@ class Server extends EventEmitter {
});
this._sock.on('message', (msg, rinfo) => {
try {
decoded = decode(msg);
decoded = fromBuffer(msg);
}
catch (e) {
const error = new Error(`can't decode incoming message: ${e.message}`);
Expand Down
33 changes: 0 additions & 33 deletions lib/internal/decode.mjs

This file was deleted.

99 changes: 99 additions & 0 deletions lib/internal/osc.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { Buffer } from 'node:buffer';

function toBuffer(message) {
if (typeof message !== 'object' || !message.address) {
throw new Error('Invalid OSC message');
}

const addressBuffer = toOSCString(message.address);
const typeTagBuffer = toOSCString(',' + message.args.map(arg => getTypeTag(arg)).join(''));
const argsBuffer = Buffer.concat(message.args.map(arg => toOSCArgument(arg)));

return Buffer.concat([addressBuffer, typeTagBuffer, argsBuffer]);
}

function fromBuffer(buffer) {
let offset = 0;

const address = readOSCString(buffer, offset);
offset += address.length + 4 - (address.length % 4);

const typeTag = readOSCString(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 = readOSCArgument(buffer, offset, type);
args.push(arg.value);
offset += arg.size;
}

return { address, args };
}

function toOSCString(str) {
const buffer = Buffer.from(str + '\0');
const padding = 4 - (buffer.length % 4);
return Buffer.concat([buffer, Buffer.alloc(padding)]);
}

function readOSCString(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': return 'b';
default: throw new Error('Unsupported argument type');
}
}

function toOSCArgument(arg) {
switch (typeof arg) {
case 'string': return toOSCString(arg);
case 'number': return Number.isInteger(arg) ? toOSCInt32(arg) : toOSCFloat32(arg);
case 'object': return toOSCBlob(arg);
default: throw new Error('Unsupported argument type');
}
}

function readOSCArgument(buffer, offset, type) {
switch (type) {
case 's': return { value: readOSCString(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': return readOSCBlob(buffer, offset);
default: throw new Error('Unsupported argument type');
}
}

function toOSCInt32(num) {
const buffer = Buffer.alloc(4);
buffer.writeInt32BE(num);
return buffer;
}

function toOSCFloat32(num) {
const buffer = Buffer.alloc(4);
buffer.writeFloatBE(num);
return buffer;
}

function toOSCBlob(blob) {
const sizeBuffer = toOSCInt32(blob.length);
const padding = 4 - (blob.length % 4);
return Buffer.concat([sizeBuffer, blob, Buffer.alloc(padding)]);
}

function readOSCBlob(buffer, offset) {
const size = buffer.readInt32BE(offset);
const value = buffer.slice(offset + 4, offset + 4 + size);
return { value, size: 4 + size + (4 - (size % 4)) };
}

export { toBuffer, fromBuffer };
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
"#decode": {
"require": "./dist/lib/internal/decode.js",
"default": "./lib/internal/decode.mjs"
},
"#osc": {
"require": "./dist/lib/internal/osc.js",
"default": "./lib/internal/osc.mjs"
}
},
"author": {
Expand Down Expand Up @@ -42,9 +46,6 @@
"type": "git",
"url": "git+https://github.com/MylesBorins/node-osc.git"
},
"dependencies": {
"osc-min": "^1.1.1"
},
"devDependencies": {
"@eslint/js": "^9.4.0",
"eslint": "^9.4.0",
Expand Down

0 comments on commit a087a51

Please sign in to comment.