add DCS interface, payload limits for DCS/OSC

This commit is contained in:
Jörg Breitbart
2019-07-26 15:59:24 +02:00
parent 82aaef29f1
commit a9b2728c07
9 changed files with 105 additions and 19 deletions
+4 -4
View File
@@ -138,7 +138,7 @@ describe('DcsParser', () => {
});
describe('DcsHandlerFactory', () => {
it('should be called once on end(true)', () => {
parser.setDcsHandler('+p', new DcsHandlerFactory((params, data) => reports.push([params, data])));
parser.setDcsHandler('+p', new DcsHandlerFactory((params, data) => reports.push([params.toArray(), data])));
parser.hook('+', Params.fromArray([1, 2, 3]), 'p'.charCodeAt(0));
let data = toUtf32('Here comes');
parser.put(data, 0, data.length);
@@ -148,7 +148,7 @@ describe('DcsParser', () => {
assert.deepEqual(reports, [[[1, 2, 3], 'Here comes the mouse!']]);
});
it('should not be called on end(false)', () => {
parser.setDcsHandler('+p', new DcsHandlerFactory((params, data) => reports.push([params, data])));
parser.setDcsHandler('+p', new DcsHandlerFactory((params, data) => reports.push([params.toArray(), data])));
parser.hook('+', Params.fromArray([1, 2, 3]), 'p'.charCodeAt(0));
let data = toUtf32('Here comes');
parser.put(data, 0, data.length);
@@ -158,8 +158,8 @@ describe('DcsParser', () => {
assert.deepEqual(reports, []);
});
it('should be disposable', () => {
parser.setDcsHandler('+p', new DcsHandlerFactory((params, data) => reports.push(['one', params, data])));
const dispo = parser.addDcsHandler('+p', new DcsHandlerFactory((params, data) => reports.push(['two', params, data])));
parser.setDcsHandler('+p', new DcsHandlerFactory((params, data) => reports.push(['one', params.toArray(), data])));
const dispo = parser.addDcsHandler('+p', new DcsHandlerFactory((params, data) => reports.push(['two', params.toArray(), data])));
parser.hook('+', Params.fromArray([1, 2, 3]), 'p'.charCodeAt(0));
let data = toUtf32('Here comes');
parser.put(data, 0, data.length);
+27 -3
View File
@@ -6,6 +6,7 @@
import { IDisposable } from 'common/Types';
import { IDcsHandler, IParams, ParamsArray, IHandlerCollection, IDcsParser, DcsFallbackHandler } from 'common/parser/Types';
import { utf32ToString } from 'common/input/TextDecoder';
import { Params } from './Params';
export class DcsParser implements IDcsParser {
@@ -98,24 +99,47 @@ export class DcsParser implements IDcsParser {
}
}
// limit allowed payload for DcsHandlerFactory
const PAYLOAD_LIMIT = 50000000;
/**
* Convenient class to create a DCS handler from a single callback function.
* Note: The payload is currently limited to 50 MB (hardcoded).
*/
export class DcsHandlerFactory implements IDcsHandler {
private _data = '';
private _params: IParams | undefined;
constructor(private _handler: (params: ParamsArray, data: string) => any) {}
private _hitLimit: boolean = false;
constructor(private _handler: (params: IParams, data: string) => any) {}
public hook(collect: string, params: IParams, flag: number): void {
this._params = params.clone();
this._data = '';
this._hitLimit = false;
}
public put(data: Uint32Array, start: number, end: number): void {
if (this._hitLimit) {
return;
}
this._data += utf32ToString(data, start, end);
if (this._data.length > PAYLOAD_LIMIT) {
this._data = '';
this._hitLimit = true;
}
}
public unhook(success: boolean): any {
let ret;
if (success) {
ret = this._handler(this._params ? this._params.toArray() : [], this._data);
if (this._hitLimit) {
ret = false;
} else if (success) {
ret = this._handler(this._params ? this._params : new Params(), this._data);
}
this._params = undefined;
this._data = '';
this._hitLimit = false;
return ret;
}
}
+20 -1
View File
@@ -163,25 +163,44 @@ export class OscParser extends Disposable {
}
// limit allowed payload for OscHandlerFactory
const PAYLOAD_LIMIT = 50000000;
/**
* Convenient class to allow attaching string based handler functions
* as OSC handlers.
*/
export class OscHandlerFactory implements IOscHandler {
private _data = '';
private _hitLimit: boolean = false;
constructor(private _handler: (data: string) => any) {}
public start(): void {
this._data = '';
this._hitLimit = false;
}
public put(data: Uint32Array, start: number, end: number): void {
if (this._hitLimit) {
return;
}
this._data += utf32ToString(data, start, end);
if (this._data.length > PAYLOAD_LIMIT) {
this._data = '';
this._hitLimit = true;
}
}
public end(success: boolean): any {
let ret;
if (success) {
if (this._hitLimit) {
ret = false;
} else if (success) {
ret = this._handler(this._data);
}
this._data = '';
this._hitLimit = false;
return ret;
}
}