node-a2r-slip
Version:
RFC 1055 compliant SLIP decoder and encoder stram classes
200 lines (172 loc) • 5.5 kB
JavaScript
// Generated by CoffeeScript 1.4.0
(function() {
var END, ESC, ESC_END, ESC_ESC, SlipDecoder, SlipEncoder, stream,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
stream = require("stream");
END = 0xc0;
ESC = 0xdb;
ESC_END = 0xdc;
ESC_ESC = 0xde;
SlipEncoder = (function(_super) {
__extends(SlipEncoder, _super);
function SlipEncoder(bufsize) {
if (bufsize == null) {
bufsize = 65536;
}
this.buffer = new Buffer(bufsize);
this.pos = 0;
this.writable = true;
this.readable = true;
}
SlipEncoder.prototype.write = function(buffer, encoding) {
var byte, i, len;
try {
if (Buffer.isBuffer(buffer)) {
this.buffer[this.pos++] = END;
i = 0;
len = buffer.length;
while (i < len) {
if (this.pos >= this.buffer.length) {
this.pos = 0;
this.emit("error", new Error("Buffer is to small"));
return false;
}
byte = buffer[i++];
switch (byte) {
case END:
this.buffer[this.pos++] = ESC;
this.buffer[this.pos++] = ESC_END;
break;
case ESC:
this.buffer[this.pos++] = ESC;
this.buffer[this.pos++] = ESC_ESC;
break;
default:
this.buffer[this.pos++] = byte;
}
}
this.buffer[this.pos++] = END;
buffer = new Buffer(this.pos);
this.buffer.copy(buffer, 0, 0, this.pos);
this.pos = 0;
this.emit("data", buffer);
} else {
this.write(new Buffer(buffer, encoding));
}
} catch (e) {
this.emit("error", e);
}
return true;
};
SlipEncoder.prototype.end = function(buffer, encoding) {
if (buffer) {
this.write(buffer, encoding);
}
return this.emit("end");
};
return SlipEncoder;
})(stream.Stream);
SlipDecoder = (function(_super) {
__extends(SlipDecoder, _super);
function SlipDecoder(bufsize) {
if (bufsize == null) {
bufsize = 65536;
}
this.buffer = new Buffer(bufsize);
this.pos = 0;
this.writable = true;
this.readable = true;
}
SlipDecoder.prototype.protocolViolation = function() {
var buf;
if (this.pos > 0) {
buf = new Buffer(this.pos);
this.buffer.copy(buf, 0, 0, this.pos);
}
this.lastWasEsc = false;
this.pos = 0;
return this.emit("error", new Error("Invalid data"), buf);
};
SlipDecoder.prototype.write = function(buffer, encoding) {
var buf, byte, i, len;
try {
if (Buffer.isBuffer(buffer)) {
i = 0;
len = buffer.length;
while (i < len) {
byte = buffer[i++];
if (this.pos >= this.buffer.length) {
this.emit("error", new Error("Buffer is to small"));
this.pos = 0;
return false;
}
if (this.lastWasEsc) {
switch (byte) {
case ESC_END:
this.buffer[this.pos++] = END;
break;
case ESC_ESC:
this.buffer[this.pos++] = ESC;
break;
default:
this.protocolViolation();
return true;
}
this.lastWasEsc = false;
} else {
switch (byte) {
case END:
if (this.pos > 0) {
buf = new Buffer(this.pos);
this.buffer.copy(buf, 0, 0, this.pos);
this.emit("data", buf);
this.pos = 0;
}
break;
case ESC:
if ((i + 1) <= len) {
byte = buffer[i++];
switch (byte) {
case ESC_END:
this.buffer[this.pos++] = END;
break;
case ESC_ESC:
this.buffer[this.pos++] = ESC;
break;
default:
this.protocolViolation();
return true;
}
} else {
this.lastWasEsc = true;
}
break;
default:
this.buffer[this.pos++] = byte;
}
}
}
} else {
this.write(new Buffer(buffer, encoding));
}
} catch (e) {
this.emit("error", e);
}
return true;
};
SlipDecoder.prototype.end = function(buffer, encoding) {
if (buffer) {
this.write(buffer, encoding);
}
return this.emit("end");
};
return SlipDecoder;
})(stream.Stream);
module.exports.SlipDecoder = SlipDecoder;
module.exports.SlipEncoder = SlipEncoder;
module.exports.END = END;
module.exports.ESC = ESC;
module.exports.ESC_END = ESC_END;
module.exports.ESC_ESC = ESC_ESC;
}).call(this);