ws2mpd/commands.js

70 lines
1.4 KiB
JavaScript

const EventEmitter = require("events");
function log(...args) {
console.log(Date.now(), ...args);
}
class Command extends EventEmitter {
constructor(mpd) {
super();
this._mpd = mpd;
this._buffer = Buffer.alloc(0);
this._dataListener = data => this._onData(data);
mpd.on("data", this._dataListener);
}
_onData(data) {
log("<-- mpd", data);
this._buffer = Buffer.concat([this._buffer, data]);
this._processBuffer();
}
_processBuffer() {} // abstract
_done(data) {
this._mpd.off("data", this._dataListener);
this.emit("done", data);
}
_getLine() {
let index = this._buffer.indexOf(0x0a);
if (index == -1) { return null; }
let str = this._buffer.slice(0, index).toString("utf8");
this._buffer = this._buffer.slice(index+1);
return str;
}
}
class Normal extends Command {
constructor(mpd, command) {
super(mpd);
this._lines = [];
log("--> mpd", command);
mpd.write(command + "\n");
}
_processBuffer() {
while (1) {
let line = this._getLine();
if (!line) { break; }
this._lines.push(line);
if (line.startsWith("OK") || line.startsWith("ACK")) { return this._done(this._lines); }
}
}
}
class Welcome extends Command {
_processBuffer() {
let line = this._getLine();
if (line) { this._done(line); }
}
}
exports.create = function(mpd, command) {
return new Normal(mpd, command);
}
exports.welcome = function(mpd) {
return new Welcome(mpd);
}