Skip to content

Commit

Permalink
Replace ugly data parsing with barse
Browse files Browse the repository at this point in the history
  • Loading branch information
MiniGod committed Dec 29, 2013
1 parent 2dab23b commit ba33e81
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 106 deletions.
142 changes: 36 additions & 106 deletions lib/client.js
@@ -1,4 +1,5 @@
var net = require('net')
, barse = require('barse')
, Serializer = require('./serializer')
, Deserializer = require('./deserializer')
;
Expand Down Expand Up @@ -112,110 +113,61 @@ Client.prototype.connect = function(callback, timeout) {
this.socket.on('close', function(had_error) {
self.emit('close', had_error);
});

var doHandshake = function(data) {
if (this.hsdata == null) {
this.hsdata = new Buffer(data.length);
data.copy(this.hsdata);
} else {
var tmp = new Buffer(this.hsdata.length + data.length);
this.hsdata.copy(tmp);
data.copy(tmp, this.hsdata.length);

this.hsdata = tmp;
}

// Need moar buffer
if (this.hsdata.length <= 4)
return;

var size = this.hsdata.readUInt32LE(0);
if (size > 64) {
var err = new Error('transport error - wrong lowlevel protocol header');
callback(err);
self.emit('error', err);
return false;
}

// Handshake
var handshake = this.hsdata.toString('utf8', 4, 4 + size);

if (handshake == 'GBXRemote 1') {
// We dont support v1
self.protocol = 1;
// TODO: Fix error?
var err = new Error('transport error - wrong lowlevel protocol version');
callback(err);
self.emit('error', err);
return false;
} else if (handshake == 'GBXRemote 2') {
self.protocol = 2;
} else {

var handshakeParser = barse()
.readUInt32LE('length')
.string('handshake', 'length')
;

var dataParser = barse()
.readUInt32LE('length')
.readUInt32LE('reqhandle')
.string('xml', 'length')
;

// Pipe data to handshakeParser
this.socket.pipe(handshakeParser);
// Then switch to dataParser once handshakeParser is done
handshakeParser.once('data', function() {
self.socket.unpipe(handshakeParser);
self.socket.pipe(dataParser);
})

// HANDSHAKE
handshakeParser.once('data', function(data) {
if (data.handshake != 'GBXRemote 2') {
var err = new Error('transport error - wrong lowlevel protocol version');
callback(err);
self.emit('error', err);
return false;
return;
}

// Handshake successfull


self.protocol = 2;
self.isReady = true;

callback();
self.emit('connect');
};

var onData = function(data) {
if (data == null)
data = new Buffer(0);

if (this.buff == null) {
this.buff = new Buffer(data.length);
data.copy(this.buff);
} else {
// TODO: Use Buffer.concat()? - requires node v0.8!
var tmp = new Buffer(this.buff.length + data.length);
this.buff.copy(tmp);
data.copy(tmp, this.buff.length);
this.buff = tmp;
}

// Need moar buffer to read size
if (this.buff.length < 4)
return;

var targetSize = this.buff.readUInt32LE(0);

// headerSize = targetSize + reqhandle = 8
var headerSize = 8;

// Need moar buffer to read data
if (this.buff.length < headerSize + targetSize)
return;

var response = this.buff.toString('utf8', headerSize, headerSize + targetSize);

var reqhandle = this.buff.readUInt32LE(4);

});

dataParser.on('data', function(data) {
var deserializer = new Deserializer();

// TODO: Use reqhandle to determine if its a response or callback
// Reponse
if (self.callbacks.hasOwnProperty(reqhandle)) {
deserializer.deserializeMethodResponse(response, function(a, b) {
self.callbacks[reqhandle].apply(this, arguments);
delete self.callbacks[reqhandle];
if (self.callbacks.hasOwnProperty(data.reqhandle)) {
deserializer.deserializeMethodResponse(data.xml, function(a, b) {
self.callbacks[data.reqhandle].apply(this, arguments);
delete self.callbacks[data.reqhandle];
});
}
// Callback
else {
deserializer.deserializeMethodCall(response, function(err, method, res) {
deserializer.deserializeMethodCall(data.xml, function(err, method, res) {
if (err) {
// This should never happen....
// There is nothing we can do about this one.
// Its not a response to a request, and its not a valid callback (MethodCall)
//console.log(err);
console.warn('Not a response, nor a callback! (reqhandle: 0x%s)', reqhandle.toString(16));
console.warn('Not a response, nor a callback! (reqhandle: 0x%s)', data.reqhandle.toString(16));
return;
} else {
// its a callback from the server
Expand All @@ -224,28 +176,6 @@ Client.prototype.connect = function(callback, timeout) {
}
});
}

// Cut away this message...
var tmp = new Buffer(this.buff.length - headerSize - targetSize);
this.buff.copy(tmp, 0, headerSize + targetSize);
this.buff = tmp;

// ... and fake an onData call if more data left
if (this.buff.length) {
process.nextTick(function(){
onData()
});
}
};

// TODO: Fix the ondata callback, and its functions (kinda messy)
this.socket.on('data', function(data) {
// TODO: Do buffering here

if (!self.isReady)
doHandshake(data);
else
onData(data);
});
};

Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -19,6 +19,7 @@
, "dependencies" : {
"sax" : "0.4.x"
, "xmlbuilder" : "0.3.1"
, "barse" : "~0.4.1"
}
, "devDependencies" : {
"vows" : "0.6.x"
Expand Down

0 comments on commit ba33e81

Please sign in to comment.