mirror of
https://github.com/jwetzell/osc-js.git
synced 2026-08-13 03:03:41 +00:00
Merge pull request #14 from jwetzell/bundle-multiple-content-chunks
fix osc bundles not parsing multiple content chunks correctly
This commit is contained in:
+41
-31
@@ -22,42 +22,52 @@ export function bundleFromBuffer(bytes: Uint8Array): [OSCBundle | undefined, Uin
|
||||
|
||||
let endOfBundle = false;
|
||||
|
||||
let [contentSize, remainingBytes] = oscTypeConverterMap.i.fromBuffer(bytesAfterTimeTag);
|
||||
if (typeof contentSize === 'number') {
|
||||
while (!endOfBundle) {
|
||||
if (remainingBytes.length < contentSize) {
|
||||
throw new Error('bundle does not contain enough data');
|
||||
}
|
||||
// let [contentSize, remainingBytes] = oscTypeConverterMap.i.fromBuffer(bytesAfterTimeTag);
|
||||
let remainingBytes = bytesAfterTimeTag;
|
||||
|
||||
const bundleContentBytes = remainingBytes.subarray(0, contentSize);
|
||||
while (!endOfBundle) {
|
||||
let [contentSize, bytesAfterContentSize] = oscTypeConverterMap.i.fromBuffer(remainingBytes);
|
||||
|
||||
if (bundleContentBytes[0] === 35) {
|
||||
// # character indicating contents is a bundle
|
||||
const [content, bytesAfterContent] = bundleFromBuffer(bundleContentBytes);
|
||||
if (content) {
|
||||
bundleContents.push(content);
|
||||
}
|
||||
} else if (bundleContentBytes[0] === 47) {
|
||||
const [content, bytesAfterContent] = messageFromBuffer(bundleContentBytes);
|
||||
if (content && content !== undefined) {
|
||||
bundleContents.push(content);
|
||||
}
|
||||
} else {
|
||||
throw new Error('bundle contents does not look like a OSC message or bundle');
|
||||
}
|
||||
|
||||
remainingBytes = remainingBytes.subarray(contentSize);
|
||||
if (remainingBytes.length === 0) {
|
||||
endOfBundle = true;
|
||||
}
|
||||
if (typeof contentSize !== 'number') {
|
||||
throw new Error('problem decoding content size');
|
||||
}
|
||||
|
||||
remainingBytes = bytesAfterContentSize;
|
||||
|
||||
if (remainingBytes.length < contentSize) {
|
||||
throw new Error('bundle does not contain enough data');
|
||||
}
|
||||
|
||||
const bundleContentBytes = bytesAfterContentSize.subarray(0, contentSize);
|
||||
|
||||
if (bundleContentBytes[0] === 35) {
|
||||
// # character indicating contents is a bundle
|
||||
const [content, bytesAfterContent] = bundleFromBuffer(bundleContentBytes);
|
||||
if (content) {
|
||||
bundleContents.push(content);
|
||||
}
|
||||
} else if (bundleContentBytes[0] === 47) {
|
||||
const [content, bytesAfterContent] = messageFromBuffer(bundleContentBytes);
|
||||
if (content && content !== undefined) {
|
||||
bundleContents.push(content);
|
||||
}
|
||||
} else {
|
||||
throw new Error('bundle contents does not look like a OSC message or bundle');
|
||||
}
|
||||
|
||||
remainingBytes = bytesAfterContentSize.subarray(contentSize);
|
||||
if (remainingBytes.length === 0) {
|
||||
endOfBundle = true;
|
||||
}
|
||||
return [{
|
||||
timeTag,
|
||||
contents: bundleContents,
|
||||
},remainingBytes];
|
||||
}
|
||||
|
||||
return [undefined, undefined]
|
||||
return [
|
||||
{
|
||||
timeTag,
|
||||
contents: bundleContents,
|
||||
},
|
||||
remainingBytes,
|
||||
];
|
||||
}
|
||||
|
||||
export function bundleToBuffer(bundle: OSCBundle): Uint8Array {
|
||||
|
||||
@@ -20,13 +20,79 @@ const tests = [
|
||||
contents: [{ address: '/oscillator/4/frequency', args: [{ type: 'f', value: 440 }] }],
|
||||
},
|
||||
},
|
||||
{
|
||||
decription: 'resolume bundle example',
|
||||
bytes: new Uint8Array([
|
||||
0x23, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x28, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6c, 0x61, 0x79, 0x65, 0x72,
|
||||
0x73, 0x2f, 0x31, 0x2f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x2c, 0x66, 0x00, 0x00, 0x3d,
|
||||
0x6d, 0x9c, 0x9c, 0x00, 0x00, 0x00, 0x2c, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x2f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x2f, 0x70, 0x6f, 0x73, 0x69,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x00, 0x2c, 0x66, 0x00, 0x00, 0x3d, 0x6d, 0x9c, 0x9c, 0x00, 0x00, 0x00, 0x3c, 0x2f, 0x63,
|
||||
0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x2f, 0x31,
|
||||
0x2f, 0x63, 0x6c, 0x69, 0x70, 0x73, 0x2f, 0x34, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f,
|
||||
0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x66, 0x00, 0x00, 0x3d, 0x6d, 0x9c,
|
||||
0x9c, 0x00, 0x00, 0x00, 0x38, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x73,
|
||||
0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x63, 0x6c, 0x69, 0x70, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f,
|
||||
0x72, 0x74, 0x2f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x66, 0x00, 0x00,
|
||||
0x3d, 0x6d, 0x9c, 0x9c, 0x00, 0x00, 0x00, 0x28, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x2f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x2f, 0x31, 0x2f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x00, 0x00, 0x2c, 0x66, 0x00, 0x00, 0x3d, 0x6d, 0x9c, 0x9c, 0x00, 0x00, 0x00, 0x2c, 0x2f, 0x63, 0x6f, 0x6d, 0x70,
|
||||
0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x6c, 0x61, 0x79,
|
||||
0x65, 0x72, 0x2f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x2c, 0x66, 0x00, 0x00, 0x3d, 0x6d, 0x9c,
|
||||
0x9c, 0x00, 0x00, 0x00, 0x3c, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6c,
|
||||
0x61, 0x79, 0x65, 0x72, 0x73, 0x2f, 0x31, 0x2f, 0x63, 0x6c, 0x69, 0x70, 0x73, 0x2f, 0x34, 0x2f, 0x74, 0x72, 0x61,
|
||||
0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x2c, 0x66, 0x00, 0x00, 0x3d, 0x6d, 0x9c, 0x9c, 0x00, 0x00, 0x00, 0x38, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73,
|
||||
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x63, 0x6c, 0x69, 0x70, 0x2f,
|
||||
0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00,
|
||||
0x00, 0x00, 0x00, 0x2c, 0x66, 0x00, 0x00, 0x3d, 0x6d, 0x9c, 0x9c,
|
||||
]),
|
||||
expected: {
|
||||
timeTag: [0, 1],
|
||||
contents: [
|
||||
{
|
||||
address: '/composition/layers/1/position',
|
||||
args: [{ type: 'f', value: 0.05801068246364593505859375 }],
|
||||
},
|
||||
{
|
||||
address: '/composition/selectedlayer/position',
|
||||
args: [{ type: 'f', value: 0.05801068246364593505859375 }],
|
||||
},
|
||||
{
|
||||
address: '/composition/layers/1/clips/4/transport/position',
|
||||
args: [{ type: 'f', value: 0.05801068246364593505859375 }],
|
||||
},
|
||||
{
|
||||
address: '/composition/selectedclip/transport/position',
|
||||
args: [{ type: 'f', value: 0.05801068246364593505859375 }],
|
||||
},
|
||||
{
|
||||
address: '/composition/layers/1/position',
|
||||
args: [{ type: 'f', value: 0.05801068246364593505859375 }],
|
||||
},
|
||||
{
|
||||
address: '/composition/selectedlayer/position',
|
||||
args: [{ type: 'f', value: 0.05801068246364593505859375 }],
|
||||
},
|
||||
{
|
||||
address: '/composition/layers/1/clips/4/transport/position',
|
||||
args: [{ type: 'f', value: 0.05801068246364593505859375 }],
|
||||
},
|
||||
{
|
||||
address: '/composition/selectedclip/transport/position',
|
||||
args: [{ type: 'f', value: 0.05801068246364593505859375 }],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
describe('OSC Bundle Decoding', () => {
|
||||
tests.forEach((bundleTest) => {
|
||||
it(bundleTest.description, () => {
|
||||
const [encoded, remainingBytes] = osc.bundleFromBuffer(bundleTest.bytes);
|
||||
equal(remainingBytes.length, 0)
|
||||
equal(remainingBytes.length, 0);
|
||||
deepEqual(encoded, bundleTest.expected);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user