From 5ef294e74682d9d524315248e62536c58b00f8db Mon Sep 17 00:00:00 2001 From: Aleks Selivanov Date: Tue, 28 Apr 2015 01:04:43 +0500 Subject: [PATCH 1/4] Add support for multi-reply handlers --- lib/xcore.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/xcore.js b/lib/xcore.js index f4744a7..baf6075 100644 --- a/lib/xcore.js +++ b/lib/xcore.js @@ -510,9 +510,11 @@ XClient.prototype.expectReplyHeader = function() var result = unpack.call(client, data, opt_data); var callback = handler[1]; - callback(null, result); - // TODO: add multiple replies flag and delete handler only after last reply (eg ListFontsWithInfo) - delete client.replies[seq_num]; + var multiReply = handler[2]; + var handled = callback(null, result); + if (!multiReply || handled) { + delete client.replies[seq_num]; + } } // wait for new packet from server client.expectReplyHeader(); From 0c127d5003c823a4814c41aa5172873fd73495a1 Mon Sep 17 00:00:00 2001 From: Aleks Selivanov Date: Wed, 29 Apr 2015 10:53:36 +0500 Subject: [PATCH 2/4] Move check for end of reply sequence from callback to handler --- lib/xcore.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/xcore.js b/lib/xcore.js index baf6075..faad715 100644 --- a/lib/xcore.js +++ b/lib/xcore.js @@ -511,8 +511,8 @@ XClient.prototype.expectReplyHeader = function() var result = unpack.call(client, data, opt_data); var callback = handler[1]; var multiReply = handler[2]; - var handled = callback(null, result); - if (!multiReply || handled) { + callback(null, result); + if (!multiReply || result === undefined) { delete client.replies[seq_num]; } } From 62286ed71b51d34dd54e95e2fefc3641576f99f0 Mon Sep 17 00:00:00 2001 From: Aleks Selivanov Date: Wed, 29 Apr 2015 13:32:48 +0500 Subject: [PATCH 3/4] Delegate check for end of reply sequence to unpacker --- lib/xcore.js | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/lib/xcore.js b/lib/xcore.js index faad715..f309dcb 100644 --- a/lib/xcore.js +++ b/lib/xcore.js @@ -197,7 +197,7 @@ XClient.prototype.importRequestsFromTemplates = function(target, reqs) var requestArguments = reqPack[1]; if (callback) - this.replies[this.seq_num] = [reqReplTemplate[1], callback]; + this.replies[this.seq_num] = [reqReplTemplate[1], callback, reqReplTemplate[2]]; client.pack_stream.pack(format, requestArguments); var b = client.pack_stream.write_queue[0]; @@ -225,7 +225,7 @@ XClient.prototype.importRequestsFromTemplates = function(target, reqs) requestArguments.push(args[a]); if (callback) - this.replies[this.seq_num] = [reqReplTemplate[1], callback]; + this.replies[this.seq_num] = [reqReplTemplate[1], callback, reqReplTemplate[2]]; client.pack_stream.pack(format, requestArguments); client.pack_stream.flush(); @@ -427,6 +427,10 @@ XClient.prototype.expectReplyHeader = function() var seq_num = res[2]; var bad_value = res[3]; + function unsubscribe() { + delete client.replies[seq_num]; + } + if (type == 0) { var error_code = res[1]; @@ -459,9 +463,9 @@ XClient.prototype.expectReplyHeader = function() if (!handled) client.emit('error', error); // TODO: should we delete seq2stack and reply even if there is no handler? - if (client.options.debug) - delete client.seq2stack[seq_num]; - delete client.replies[seq_num]; + if (client.options.debug) + delete client.seq2stack[seq_num]; + unsubscribe(); } else client.emit('error', error); client.expectReplyHeader(); @@ -504,17 +508,19 @@ XClient.prototype.expectReplyHeader = function() var handler = client.replies[seq_num]; if (handler) { var unpack = handler[0]; + var callback = handler[1]; + var multiReply = handler[2]; if (client.pending_atoms[seq_num]) { opt_data = seq_num; } - - var result = unpack.call(client, data, opt_data); - var callback = handler[1]; - var multiReply = handler[2]; - callback(null, result); - if (!multiReply || result === undefined) { - delete client.replies[seq_num]; + var args = [data, opt_data]; + if (multiReply) { + args.push(unsubscribe); + } else { + unsubscribe(); } + var result = unpack.apply(client, args); + callback(null, result); } // wait for new packet from server client.expectReplyHeader(); From 25ad8445688fd5f6a254a16ae156c3526c4b12a8 Mon Sep 17 00:00:00 2001 From: Aleks Selivanov Date: Fri, 6 May 2016 17:14:30 +0300 Subject: [PATCH 4/4] Improve code formatting --- lib/xcore.js | 189 +++++++++++++++++++++++++-------------------------- 1 file changed, 94 insertions(+), 95 deletions(-) diff --git a/lib/xcore.js b/lib/xcore.js index f309dcb..715edf2 100644 --- a/lib/xcore.js +++ b/lib/xcore.js @@ -422,119 +422,118 @@ XClient.prototype.expectReplyHeader = function() var client = this; client.pack_stream.get( 8, function(headerBuf) { - var res = headerBuf.unpack('CCSL'); - var type = res[0]; - var seq_num = res[2]; - var bad_value = res[3]; + var res = headerBuf.unpack('CCSL'); + var type = res[0]; + var seq_num = res[2]; + var bad_value = res[3]; - function unsubscribe() { - delete client.replies[seq_num]; - } - - if (type == 0) - { - var error_code = res[1]; - var error = new Error(); - error.error = error_code; - error.seq = seq_num; - if (client.options.debug) { - error.longstack = client.seq2stack[error.seq] - console.log(client.seq2stack[error.seq].stack); - } - - // unpack error packet (32 bytes for all error types, 8 of them in CCSL header) - client.pack_stream.get(24, function(buf) { - - var res = buf.unpack('SC'); - error.message = xerrors.errorText[error_code]; - error.badParam = bad_value; - error.minorOpcode = res[0]; - error.majorOpcode = res[1]; - - var extUnpacker = client.errorParsers[error_code]; - if (extUnpacker) { - extUnpacker(error, error_code, seq_num, bad_value, buf); - } + function unsubscribe() { + delete client.replies[seq_num]; + } - var handler = client.replies[seq_num]; - if (handler) { - var callback = handler[1]; - var handled = callback(error); - if (!handled) - client.emit('error', error); - // TODO: should we delete seq2stack and reply even if there is no handler? - if (client.options.debug) - delete client.seq2stack[seq_num]; - unsubscribe(); - } else - client.emit('error', error); - client.expectReplyHeader(); - } ); - return; - } else if (type > 1) - { - client.pack_stream.get(24, function(buf) { - var extra = res[3]; - var code = res[1]; - var ev = client.unpackEvent(type, seq_num, extra, code, buf, headerBuf); - - // raw event 32-bytes packet (primarily for use in SendEvent); - // TODO: Event::pack based on event parameters, inverse to unpackEvent - ev.rawData = new Buffer(32); - headerBuf.copy(ev.rawData); - buf.copy(ev.rawData, 8); - - client.emit('event', ev); - var ee = client.event_consumers[ev.wid]; - if (ee) { - ee.emit('event', ev); - } - if (ev.parent) { - ee = client.event_consumers[ev.parent]; - if (ee) - ee.emit('child-event', ev); - } - client.expectReplyHeader(); - } ); - return; + if (type == 0) { + var error_code = res[1]; + var error = new Error(); + error.error = error_code; + error.seq = seq_num; + if (client.options.debug) { + error.longstack = client.seq2stack[error.seq] + console.log(client.seq2stack[error.seq].stack); } - var opt_data = res[1]; - var length_total = res[3]; // in 4-bytes units, _including_ this header - var bodylength = 24 + length_total*4; // 24 is rest if 32-bytes header - - client.pack_stream.get( bodylength, function( data ) { + // unpack error packet (32 bytes for all error types, 8 of them in CCSL header) + client.pack_stream.get(24, function(buf) { + var res = buf.unpack('SC'); + error.message = xerrors.errorText[error_code]; + error.badParam = bad_value; + error.minorOpcode = res[0]; + error.majorOpcode = res[1]; + + var extUnpacker = client.errorParsers[error_code]; + if (extUnpacker) { + extUnpacker(error, error_code, seq_num, bad_value, buf); + } var handler = client.replies[seq_num]; if (handler) { - var unpack = handler[0]; var callback = handler[1]; - var multiReply = handler[2]; - if (client.pending_atoms[seq_num]) { - opt_data = seq_num; + var handled = callback(error); + if (!handled) { + client.emit('error', error); } - var args = [data, opt_data]; - if (multiReply) { - args.push(unsubscribe); - } else { - unsubscribe(); + // TODO: should we delete seq2stack and reply even if there is no handler? + if (client.options.debug) { + delete client.seq2stack[seq_num]; + } + unsubscribe(); + } else { + client.emit('error', error); + } + client.expectReplyHeader(); + } ); + return; + } else if (type > 1) { + client.pack_stream.get(24, function(buf) { + var extra = res[3]; + var code = res[1]; + var ev = client.unpackEvent(type, seq_num, extra, code, buf, headerBuf); + + // raw event 32-bytes packet (primarily for use in SendEvent); + // TODO: Event::pack based on event parameters, inverse to unpackEvent + ev.rawData = new Buffer(32); + headerBuf.copy(ev.rawData); + buf.copy(ev.rawData, 8); + + client.emit('event', ev); + var ee = client.event_consumers[ev.wid]; + if (ee) { + ee.emit('event', ev); + } + if (ev.parent) { + ee = client.event_consumers[ev.parent]; + if (ee) { + ee.emit('child-event', ev); } - var result = unpack.apply(client, args); - callback(null, result); } - // wait for new packet from server client.expectReplyHeader(); }); + return; } - ); + + var opt_data = res[1]; + var length_total = res[3]; // in 4-bytes units, _including_ this header + var bodylength = 24 + length_total*4; // 24 is rest if 32-bytes header + + client.pack_stream.get( bodylength, function( data ) { + + var handler = client.replies[seq_num]; + if (handler) { + var unpack = handler[0]; + var callback = handler[1]; + var multiReply = handler[2]; + if (client.pending_atoms[seq_num]) { + opt_data = seq_num; + } + var args = [data, opt_data]; + if (multiReply) { + args.push(unsubscribe); + } else { + unsubscribe(); + } + var result = unpack.apply(client, args); + callback(null, result); + } + // wait for new packet from server + client.expectReplyHeader(); + }); + }); } -XClient.prototype.startHandshake = function() { +XClient.prototype.startHandshake = function() +{ var client = this; - handshake.writeClientHello(this.pack_stream, this.displayNum, this.authHost); - handshake.readServerHello(this.pack_stream, function(display) - { + handshake.readServerHello(this.pack_stream, function(display) { // TODO: readServerHello can set error state in display // emit error in that case client.expectReplyHeader();