diff --git a/bin/test-server.js b/bin/test-server.js new file mode 100644 index 0000000..08265ab --- /dev/null +++ b/bin/test-server.js @@ -0,0 +1,29 @@ +var server = require("../lib/server.js"); +var event = require("../lib/event.js"); + +server.createServer(3219, "127.0.0.1", function (password) { + "use strict"; + + return true; +}, function (controler) { + "use strict"; + + console.log("Connected"); + + console.log("Ready to serve"); + + process.stdin.on("data", function(data) { + if (data.toString() !== "exit"){ + eval(data.toString()); + } + else { + + controler.detach(); + } + }); + +}); + + + + diff --git a/lib/buffer.js b/lib/buffer.js index 16e6ed8..78c892c 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -1,5 +1,5 @@ -var EventEmitter = require("EventEmitter"); -var Types = require("types"); +var EventEmitter = require("events").EventEmitter; +var Types = require("./types.js"); //A controler owned buffer representation function Buffer (client, buffId) { @@ -177,6 +177,6 @@ function Buffer (client, buffId) { }; } -Buffer.prototype = EventEmitter; +Buffer.prototype = EventEmitter.prototype; module.exports = Buffer; diff --git a/lib/controler.js b/lib/controler.js index 772313a..b6c89c0 100644 --- a/lib/controler.js +++ b/lib/controler.js @@ -1,8 +1,9 @@ var Transform = require("stream").Transform; var EventEmitter = require("events").EventEmitter; -var Types = require("types"); -var Buffer = require("buffer"); -var events = require("events"); +var Types = require("./types.js"); +var Buffer = require("./buffer.js"); +var events = require("./event.js"); + //A stream Transform implementation returning full netbeans messages function MessageTransform(opts) { @@ -12,26 +13,24 @@ function MessageTransform(opts) { var buffer; this._transform = function(data, encoding, callback) { - var endpos = data.indexOf("\n"); + var offstart = 0; + for (var i = 0 ; i < data.length ; ++i) { + if (data[i] === 10) { + if (buffer !== undefined) { + this.push(buffer); + buffer = undefined; + } - if (endpos > -1) { - if (buffer !== undefined) { - this.push(buffer); - buffer = undefined; - } - - if (endpos > 0) { - this.push(data.substr(0, endpos)); - } - callback(); - - if (endpos < data.length - 1) { - buffer = data.substr(endpos + 1); + this.push(data.slice(offstart, i)); + offstart = i + 1; } } - else { - buffer = buffer.concat(data); + + if (offstart < i) { + buffer = data.slice(offstart); } + + callback(); }; this._flush = function (callback) { @@ -40,9 +39,11 @@ function MessageTransform(opts) { }; } +MessageTransform.prototype = Transform.prototype; + //Main netbeans object. Needs the socket of the incomming connexion and an authentication callback //This callback just get the password sent by Vim. It must return true to allow connexion -function NetbeansClient(socket, authentication) { +function NetbeansClient(socket, authentication, onEvent, onError, onDisconnected) { "use strict"; EventEmitter.call(this); @@ -56,14 +57,18 @@ function NetbeansClient(socket, authentication) { var messageTransform = new MessageTransform(); - messageTransform.on("data",function (message) { + messageTransform.on("data",function (data) { + var message = data.toString(); + console.log(message); /* The first message must be an authentication one */ - if (message.startsWith("AUTH ") && authentication(message.substring(message.indexOf(" ") + 1))) { + if (message.indexOf("AUTH ") === 0 && authentication(message.substring(message.indexOf(" ") + 1))) { connected = true; messageTransform.removeAllListeners("data"); - messageTransform.on("data", function(message) { + messageTransform.on("data", function(data) { + var message = data.toString(); + console.log(message); try { var iName = 0; /*Index of the name separator in case of an Event */ @@ -86,12 +91,12 @@ function NetbeansClient(socket, authentication) { if (iName > 0 && iSeqno > 0) { isEvent = true; args.push("event"); - args.push(Number.parseInt(message.substr(0, iName), 10)); + args.push(parseInt(message.substr(0, iName), 10)); args.push(message.substring(iName + 1, iSeqno)); - args.push(Number.parseInt(message.substring(iSeqno + 1, i), 10)); + args.push(parseInt(message.substring(iSeqno + 1, i), 10)); } else if (iName === 0 && iSeqno === 0) { - seqno = Number.parseInt(message.substr(0, i), 10); + seqno = parseInt(message.substr(0, i), 10); } else { throw "Unknown message type"; @@ -156,7 +161,7 @@ function NetbeansClient(socket, authentication) { else { var argument = message.substr(argStartOffset, i); - if (Number.NaN(argument)) { + if (Number.isNaN(argument)) { if (argument.contains("/")) { args.push(argument.split("/")); } @@ -165,14 +170,14 @@ function NetbeansClient(socket, authentication) { } } else { - args.push(Number.parseInt(argument)); + args.push(parseInt(argument)); } } } } if (isEvent) { - self.emit.apply(self, args); + onEvent.apply(null, args); } else if (callbacks.hasOwnProperty(seqno)) { callbacks[seqno].apply(null, args); @@ -183,36 +188,36 @@ function NetbeansClient(socket, authentication) { } } catch (ex) { - self.emit("error", ex.message); + onError.call(null, ex.message); } }); } else { //TODO send a message to client ? - socket.end(); + socket.destroy(); } }); messageTransform.on("error", function (error) { - self.emit("error", error); + onError.call(null, error); }); messageTransform.on("end",function () { - self.emit("disconnect"); + onDisconnected.call(null); }); messageTransform.on("close", function () { - self.emit("disconnect"); + onDisconnected.call(null); }); //Send a command message. //Needs the name of the buffer, the buffer id and the parameters of the command this.sendCommand = function(name, buffer) { - let seqno = currentSeqno; + var seqno = currentSeqno; currentSeqno += 1; - var data = buffer + ":" + name + ":" + seqno; + var data = buffer + ":" + name + "!" + seqno; for (var i = 2 ; i < arguments.length ; ++i) { data += " " + arguments[i]; @@ -226,13 +231,13 @@ function NetbeansClient(socket, authentication) { //Call a function. //Needs the name of the function, the bufferid, the parametres of the command and the callback to retreive the reply this.callFunction = function(name, buffer) { - let seqno = currentSeqno; + var seqno = currentSeqno; currentSeqno += 1; var lastArg = arguments.length - 1; if (typeof(arguments[lastArg]) === "function") { - callbacks.defineProperty(currentSeqno,arguments[lastArg]); + Object.defineProperty(callbacks, currentSeqno, {value: arguments[lastArg]}); lastArg -= 1; } @@ -251,7 +256,7 @@ function NetbeansClient(socket, authentication) { socket.pipe(messageTransform); } -NetbeansClient.prototype = EventEmitter; +NetbeansClient.prototype = EventEmitter.prototype; //Wrapper around the controler exposing functions and commands as methods //Takes an incomming connexion (socket:Socket), an authentication callback (authentication:function(string)) @@ -259,37 +264,52 @@ NetbeansClient.prototype = EventEmitter; function Controler(socket, authentication) { "use strict"; + var self = this; + EventEmitter.call(this); - var client = new NetbeansClient(socket, authentication); + var client = new NetbeansClient(socket, authentication, function(name, buffId) { + switch (name) { + case events.disconnect : + socket.destroy(); + self.emit("disconnected"); + break; + case events.killed : + if (buffers.hasOwnProperty(buffId)) { + buffers[buffId].emit.apply(buffers[buffId], Array.prototype.slice(arguments, 1)); + delete buffers[buffId]; + } + break; + default : + var target = self; + + if (buffId > 0 && buffers.hasOwnProperty(buffId)) { + target = buffers[buffId]; + } + + target.emit.apply(target, Array.prototype.slice(arguments, 1)); + break; + } + }, + function (error) { + console.log("ERROR : "+error); + self.emit("error",error); + }, + function () { + console.log("DISCONNECTED"); + self.emit("disconnected"); + }); + var buffId = 0; - var buffers = new {}; + var buffers = {}; function getBuffer() { buffId += 1; var buffer = new Buffer(client, buffId); - buffers.defineProperty(buffId, buffer); + Object.defineProperty(buffers, buffId, {value: buffer}); return buffer; } - - client.on("event", function (buffId, name, seqno) { - var target = this; - - if (buffId > 0 && buffers.hasOwnProperty(buffId)) { - target = buffers[buffId]; - } - - target.emit.apply(target, Array.prototype.slice(arguments, 1)); - }); - - client.on("error", function (error) { - console.errort("Error : "+error); - }); - - client.on("disconnected", function () { - - }); /* GLOBAL COMMANDS */ @@ -307,7 +327,7 @@ function Controler(socket, authentication) { this.specialKeys = function (keys) { client.sendCommand("specialKeys", 0,Types.string(keys)); }; - + //Create a new buffer. Return the buffer created this.create = function() { var buffer = getBuffer(); @@ -342,9 +362,23 @@ function Controler(socket, authentication) { this.getModified = function (callback) { client.callFunction("getModified", 0, callback); }; + + + /* CONNEXION CONTROL */ + + //Close the underlying connexion with Vim, but not Vim + this.detach = function () { + socket.end("DETACH\n"); + self.emit("disconnected"); + }; + + //Close the underlying connexion with Vim and Vim. Ensure that data has been saved before + this.close = function () { + socket.end("DISCONNECT\n"); + self.emit("disconnected"); + }; } -Controler.prototype = EventEmitter; +Controler.prototype = EventEmitter.prototype; -module.exports.events = events; module.exports.Controler = Controler; diff --git a/lib/events.js b/lib/event.js similarity index 100% rename from lib/events.js rename to lib/event.js diff --git a/lib/server.js b/lib/server.js index 3f9f7a2..e9263f5 100644 --- a/lib/server.js +++ b/lib/server.js @@ -1,19 +1,24 @@ var net = require("net"); -var Controler = require("controler"); +var Controler = require("./controler.js").Controler; -function createServer(host, port, callback) { +function createServer(port, host, authentication, connected) { "use strict"; var server = net.createServer(function (connexion) { + console.log("Incomming connexion"); + var ctrl = new Controler(connexion, function(pwd) { - return callback(ctrl, pwd); + return authentication.call(null, pwd); }); + connected.call(null, ctrl); }); - server.listen(host,port, function () { - - - }); + host = host || "127.0.0.1"; + port = port || 3219; + + server.listen(port, host); } + +module.exports.createServer = createServer; diff --git a/lib/types.js b/lib/types.js index a761c2f..12cc8f9 100644 --- a/lib/types.js +++ b/lib/types.js @@ -61,6 +61,6 @@ function string (value) { } module.exports.string = string; -module.esports.color = color; +module.exports.color = color; module.exports.position = position; module.exports.bool = bool;