Bug fixing. First functional version
This commit is contained in:
29
bin/test-server.js
Normal file
29
bin/test-server.js
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
var EventEmitter = require("EventEmitter");
|
var EventEmitter = require("events").EventEmitter;
|
||||||
var Types = require("types");
|
var Types = require("./types.js");
|
||||||
|
|
||||||
//A controler owned buffer representation
|
//A controler owned buffer representation
|
||||||
function Buffer (client, buffId) {
|
function Buffer (client, buffId) {
|
||||||
@@ -177,6 +177,6 @@ function Buffer (client, buffId) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer.prototype = EventEmitter;
|
Buffer.prototype = EventEmitter.prototype;
|
||||||
|
|
||||||
module.exports = Buffer;
|
module.exports = Buffer;
|
||||||
|
|||||||
160
lib/controler.js
160
lib/controler.js
@@ -1,8 +1,9 @@
|
|||||||
var Transform = require("stream").Transform;
|
var Transform = require("stream").Transform;
|
||||||
var EventEmitter = require("events").EventEmitter;
|
var EventEmitter = require("events").EventEmitter;
|
||||||
var Types = require("types");
|
var Types = require("./types.js");
|
||||||
var Buffer = require("buffer");
|
var Buffer = require("./buffer.js");
|
||||||
var events = require("events");
|
var events = require("./event.js");
|
||||||
|
|
||||||
|
|
||||||
//A stream Transform implementation returning full netbeans messages
|
//A stream Transform implementation returning full netbeans messages
|
||||||
function MessageTransform(opts) {
|
function MessageTransform(opts) {
|
||||||
@@ -12,26 +13,24 @@ function MessageTransform(opts) {
|
|||||||
var buffer;
|
var buffer;
|
||||||
|
|
||||||
this._transform = function(data, encoding, callback) {
|
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) {
|
this.push(data.slice(offstart, i));
|
||||||
if (buffer !== undefined) {
|
offstart = i + 1;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
buffer = buffer.concat(data);
|
if (offstart < i) {
|
||||||
|
buffer = data.slice(offstart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
callback();
|
||||||
};
|
};
|
||||||
|
|
||||||
this._flush = function (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
|
//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
|
//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";
|
"use strict";
|
||||||
|
|
||||||
EventEmitter.call(this);
|
EventEmitter.call(this);
|
||||||
@@ -56,14 +57,18 @@ function NetbeansClient(socket, authentication) {
|
|||||||
|
|
||||||
var messageTransform = new MessageTransform();
|
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 */
|
/* 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;
|
connected = true;
|
||||||
|
|
||||||
messageTransform.removeAllListeners("data");
|
messageTransform.removeAllListeners("data");
|
||||||
messageTransform.on("data", function(message) {
|
messageTransform.on("data", function(data) {
|
||||||
|
var message = data.toString();
|
||||||
|
console.log(message);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var iName = 0; /*Index of the name separator in case of an Event */
|
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) {
|
if (iName > 0 && iSeqno > 0) {
|
||||||
isEvent = true;
|
isEvent = true;
|
||||||
args.push("event");
|
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(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) {
|
else if (iName === 0 && iSeqno === 0) {
|
||||||
seqno = Number.parseInt(message.substr(0, i), 10);
|
seqno = parseInt(message.substr(0, i), 10);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw "Unknown message type";
|
throw "Unknown message type";
|
||||||
@@ -156,7 +161,7 @@ function NetbeansClient(socket, authentication) {
|
|||||||
else {
|
else {
|
||||||
var argument = message.substr(argStartOffset, i);
|
var argument = message.substr(argStartOffset, i);
|
||||||
|
|
||||||
if (Number.NaN(argument)) {
|
if (Number.isNaN(argument)) {
|
||||||
if (argument.contains("/")) {
|
if (argument.contains("/")) {
|
||||||
args.push(argument.split("/"));
|
args.push(argument.split("/"));
|
||||||
}
|
}
|
||||||
@@ -165,14 +170,14 @@ function NetbeansClient(socket, authentication) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
args.push(Number.parseInt(argument));
|
args.push(parseInt(argument));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEvent) {
|
if (isEvent) {
|
||||||
self.emit.apply(self, args);
|
onEvent.apply(null, args);
|
||||||
}
|
}
|
||||||
else if (callbacks.hasOwnProperty(seqno)) {
|
else if (callbacks.hasOwnProperty(seqno)) {
|
||||||
callbacks[seqno].apply(null, args);
|
callbacks[seqno].apply(null, args);
|
||||||
@@ -183,36 +188,36 @@ function NetbeansClient(socket, authentication) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ex) {
|
catch (ex) {
|
||||||
self.emit("error", ex.message);
|
onError.call(null, ex.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//TODO send a message to client ?
|
//TODO send a message to client ?
|
||||||
socket.end();
|
socket.destroy();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
messageTransform.on("error", function (error) {
|
messageTransform.on("error", function (error) {
|
||||||
self.emit("error", error);
|
onError.call(null, error);
|
||||||
});
|
});
|
||||||
|
|
||||||
messageTransform.on("end",function () {
|
messageTransform.on("end",function () {
|
||||||
self.emit("disconnect");
|
onDisconnected.call(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
messageTransform.on("close", function () {
|
messageTransform.on("close", function () {
|
||||||
self.emit("disconnect");
|
onDisconnected.call(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
//Send a command message.
|
//Send a command message.
|
||||||
//Needs the name of the buffer, the buffer id and the parameters of the command
|
//Needs the name of the buffer, the buffer id and the parameters of the command
|
||||||
this.sendCommand = function(name, buffer) {
|
this.sendCommand = function(name, buffer) {
|
||||||
let seqno = currentSeqno;
|
var seqno = currentSeqno;
|
||||||
currentSeqno += 1;
|
currentSeqno += 1;
|
||||||
|
|
||||||
var data = buffer + ":" + name + ":" + seqno;
|
var data = buffer + ":" + name + "!" + seqno;
|
||||||
|
|
||||||
for (var i = 2 ; i < arguments.length ; ++i) {
|
for (var i = 2 ; i < arguments.length ; ++i) {
|
||||||
data += " " + arguments[i];
|
data += " " + arguments[i];
|
||||||
@@ -226,13 +231,13 @@ function NetbeansClient(socket, authentication) {
|
|||||||
//Call a function.
|
//Call a function.
|
||||||
//Needs the name of the function, the bufferid, the parametres of the command and the callback to retreive the reply
|
//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) {
|
this.callFunction = function(name, buffer) {
|
||||||
let seqno = currentSeqno;
|
var seqno = currentSeqno;
|
||||||
currentSeqno += 1;
|
currentSeqno += 1;
|
||||||
|
|
||||||
var lastArg = arguments.length - 1;
|
var lastArg = arguments.length - 1;
|
||||||
|
|
||||||
if (typeof(arguments[lastArg]) === "function") {
|
if (typeof(arguments[lastArg]) === "function") {
|
||||||
callbacks.defineProperty(currentSeqno,arguments[lastArg]);
|
Object.defineProperty(callbacks, currentSeqno, {value: arguments[lastArg]});
|
||||||
lastArg -= 1;
|
lastArg -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,7 +256,7 @@ function NetbeansClient(socket, authentication) {
|
|||||||
socket.pipe(messageTransform);
|
socket.pipe(messageTransform);
|
||||||
}
|
}
|
||||||
|
|
||||||
NetbeansClient.prototype = EventEmitter;
|
NetbeansClient.prototype = EventEmitter.prototype;
|
||||||
|
|
||||||
//Wrapper around the controler exposing functions and commands as methods
|
//Wrapper around the controler exposing functions and commands as methods
|
||||||
//Takes an incomming connexion (socket:Socket), an authentication callback (authentication:function(string))
|
//Takes an incomming connexion (socket:Socket), an authentication callback (authentication:function(string))
|
||||||
@@ -259,37 +264,52 @@ NetbeansClient.prototype = EventEmitter;
|
|||||||
function Controler(socket, authentication) {
|
function Controler(socket, authentication) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
EventEmitter.call(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 buffId = 0;
|
||||||
var buffers = new {};
|
var buffers = {};
|
||||||
|
|
||||||
function getBuffer() {
|
function getBuffer() {
|
||||||
buffId += 1;
|
buffId += 1;
|
||||||
var buffer = new Buffer(client, buffId);
|
var buffer = new Buffer(client, buffId);
|
||||||
buffers.defineProperty(buffId, buffer);
|
Object.defineProperty(buffers, buffId, {value: buffer});
|
||||||
return 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 */
|
/* GLOBAL COMMANDS */
|
||||||
|
|
||||||
@@ -307,7 +327,7 @@ function Controler(socket, authentication) {
|
|||||||
this.specialKeys = function (keys) {
|
this.specialKeys = function (keys) {
|
||||||
client.sendCommand("specialKeys", 0,Types.string(keys));
|
client.sendCommand("specialKeys", 0,Types.string(keys));
|
||||||
};
|
};
|
||||||
|
|
||||||
//Create a new buffer. Return the buffer created
|
//Create a new buffer. Return the buffer created
|
||||||
this.create = function() {
|
this.create = function() {
|
||||||
var buffer = getBuffer();
|
var buffer = getBuffer();
|
||||||
@@ -342,9 +362,23 @@ function Controler(socket, authentication) {
|
|||||||
this.getModified = function (callback) {
|
this.getModified = function (callback) {
|
||||||
client.callFunction("getModified", 0, 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;
|
module.exports.Controler = Controler;
|
||||||
|
|||||||
@@ -1,19 +1,24 @@
|
|||||||
var net = require("net");
|
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";
|
"use strict";
|
||||||
|
|
||||||
var server = net.createServer(function (connexion) {
|
var server = net.createServer(function (connexion) {
|
||||||
|
console.log("Incomming connexion");
|
||||||
|
|
||||||
var ctrl = new Controler(connexion, function(pwd) {
|
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;
|
||||||
|
|||||||
@@ -61,6 +61,6 @@ function string (value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports.string = string;
|
module.exports.string = string;
|
||||||
module.esports.color = color;
|
module.exports.color = color;
|
||||||
module.exports.position = position;
|
module.exports.position = position;
|
||||||
module.exports.bool = bool;
|
module.exports.bool = bool;
|
||||||
|
|||||||
Reference in New Issue
Block a user