annotate node_modules/socket.io/lib/parser.js @ 70:753414e075a0

danger stash pop
author tzara <rc-web@kiben.net>
date Sat, 26 Oct 2013 13:43:08 +0000
parents 333afcfd3f3a
children
rev   line source
rc-web@69 1
rc-web@69 2 /*!
rc-web@69 3 * socket.io-node
rc-web@69 4 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
rc-web@69 5 * MIT Licensed
rc-web@69 6 */
rc-web@69 7
rc-web@69 8 /**
rc-web@69 9 * Module dependencies.
rc-web@69 10 */
rc-web@69 11
rc-web@69 12 /**
rc-web@69 13 * Packet types.
rc-web@69 14 */
rc-web@69 15
rc-web@69 16 var packets = exports.packets = {
rc-web@69 17 'disconnect': 0
rc-web@69 18 , 'connect': 1
rc-web@69 19 , 'heartbeat': 2
rc-web@69 20 , 'message': 3
rc-web@69 21 , 'json': 4
rc-web@69 22 , 'event': 5
rc-web@69 23 , 'ack': 6
rc-web@69 24 , 'error': 7
rc-web@69 25 , 'noop': 8
rc-web@69 26 }
rc-web@69 27 , packetslist = Object.keys(packets);
rc-web@69 28
rc-web@69 29 /**
rc-web@69 30 * Errors reasons.
rc-web@69 31 */
rc-web@69 32
rc-web@69 33 var reasons = exports.reasons = {
rc-web@69 34 'transport not supported': 0
rc-web@69 35 , 'client not handshaken': 1
rc-web@69 36 , 'unauthorized': 2
rc-web@69 37 }
rc-web@69 38 , reasonslist = Object.keys(reasons);
rc-web@69 39
rc-web@69 40 /**
rc-web@69 41 * Errors advice.
rc-web@69 42 */
rc-web@69 43
rc-web@69 44 var advice = exports.advice = {
rc-web@69 45 'reconnect': 0
rc-web@69 46 }
rc-web@69 47 , advicelist = Object.keys(advice);
rc-web@69 48
rc-web@69 49 /**
rc-web@69 50 * Encodes a packet.
rc-web@69 51 *
rc-web@69 52 * @api private
rc-web@69 53 */
rc-web@69 54
rc-web@69 55 exports.encodePacket = function (packet) {
rc-web@69 56 var type = packets[packet.type]
rc-web@69 57 , id = packet.id || ''
rc-web@69 58 , endpoint = packet.endpoint || ''
rc-web@69 59 , ack = packet.ack
rc-web@69 60 , data = null;
rc-web@69 61
rc-web@69 62 switch (packet.type) {
rc-web@69 63 case 'message':
rc-web@69 64 if (packet.data !== '')
rc-web@69 65 data = packet.data;
rc-web@69 66 break;
rc-web@69 67
rc-web@69 68 case 'event':
rc-web@69 69 var ev = { name: packet.name };
rc-web@69 70
rc-web@69 71 if (packet.args && packet.args.length) {
rc-web@69 72 ev.args = packet.args;
rc-web@69 73 }
rc-web@69 74
rc-web@69 75 data = JSON.stringify(ev);
rc-web@69 76 break;
rc-web@69 77
rc-web@69 78 case 'json':
rc-web@69 79 data = JSON.stringify(packet.data);
rc-web@69 80 break;
rc-web@69 81
rc-web@69 82 case 'ack':
rc-web@69 83 data = packet.ackId
rc-web@69 84 + (packet.args && packet.args.length
rc-web@69 85 ? '+' + JSON.stringify(packet.args) : '');
rc-web@69 86 break;
rc-web@69 87
rc-web@69 88 case 'connect':
rc-web@69 89 if (packet.qs)
rc-web@69 90 data = packet.qs;
rc-web@69 91 break;
rc-web@69 92
rc-web@69 93 case 'error':
rc-web@69 94 var reason = packet.reason ? reasons[packet.reason] : ''
rc-web@69 95 , adv = packet.advice ? advice[packet.advice] : ''
rc-web@69 96
rc-web@69 97 if (reason !== '' || adv !== '')
rc-web@69 98 data = reason + (adv !== '' ? ('+' + adv) : '')
rc-web@69 99
rc-web@69 100 break;
rc-web@69 101 }
rc-web@69 102
rc-web@69 103 // construct packet with required fragments
rc-web@69 104 var encoded = type + ':' + id + (ack == 'data' ? '+' : '') + ':' + endpoint;
rc-web@69 105
rc-web@69 106 // data fragment is optional
rc-web@69 107 if (data !== null && data !== undefined)
rc-web@69 108 encoded += ':' + data;
rc-web@69 109
rc-web@69 110 return encoded;
rc-web@69 111 };
rc-web@69 112
rc-web@69 113 /**
rc-web@69 114 * Encodes multiple messages (payload).
rc-web@69 115 *
rc-web@69 116 * @param {Array} messages
rc-web@69 117 * @api private
rc-web@69 118 */
rc-web@69 119
rc-web@69 120 exports.encodePayload = function (packets) {
rc-web@69 121 var decoded = '';
rc-web@69 122
rc-web@69 123 if (packets.length == 1)
rc-web@69 124 return packets[0];
rc-web@69 125
rc-web@69 126 for (var i = 0, l = packets.length; i < l; i++) {
rc-web@69 127 var packet = packets[i];
rc-web@69 128 decoded += '\ufffd' + packet.length + '\ufffd' + packets[i]
rc-web@69 129 }
rc-web@69 130
rc-web@69 131 return decoded;
rc-web@69 132 };
rc-web@69 133
rc-web@69 134 /**
rc-web@69 135 * Decodes a packet
rc-web@69 136 *
rc-web@69 137 * @api private
rc-web@69 138 */
rc-web@69 139
rc-web@69 140 var regexp = /([^:]+):([0-9]+)?(\+)?:([^:]+)?:?([\s\S]*)?/;
rc-web@69 141
rc-web@69 142 /**
rc-web@69 143 * Wrap the JSON.parse in a seperate function the crankshaft optimizer will
rc-web@69 144 * only punish this function for the usage for try catch
rc-web@69 145 *
rc-web@69 146 * @api private
rc-web@69 147 */
rc-web@69 148
rc-web@69 149 function parse (data) {
rc-web@69 150 try { return JSON.parse(data) }
rc-web@69 151 catch (e) { return false }
rc-web@69 152 }
rc-web@69 153
rc-web@69 154 exports.decodePacket = function (data) {
rc-web@69 155 var pieces = data.match(regexp);
rc-web@69 156
rc-web@69 157 if (!pieces) return {};
rc-web@69 158
rc-web@69 159 var id = pieces[2] || ''
rc-web@69 160 , data = pieces[5] || ''
rc-web@69 161 , packet = {
rc-web@69 162 type: packetslist[pieces[1]]
rc-web@69 163 , endpoint: pieces[4] || ''
rc-web@69 164 };
rc-web@69 165
rc-web@69 166 // whether we need to acknowledge the packet
rc-web@69 167 if (id) {
rc-web@69 168 packet.id = id;
rc-web@69 169 if (pieces[3])
rc-web@69 170 packet.ack = 'data';
rc-web@69 171 else
rc-web@69 172 packet.ack = true;
rc-web@69 173 }
rc-web@69 174
rc-web@69 175 // handle different packet types
rc-web@69 176 switch (packet.type) {
rc-web@69 177 case 'message':
rc-web@69 178 packet.data = data || '';
rc-web@69 179 break;
rc-web@69 180
rc-web@69 181 case 'event':
rc-web@69 182 pieces = parse(data);
rc-web@69 183 if (pieces) {
rc-web@69 184 packet.name = pieces.name;
rc-web@69 185 packet.args = pieces.args;
rc-web@69 186 }
rc-web@69 187
rc-web@69 188 packet.args = packet.args || [];
rc-web@69 189 break;
rc-web@69 190
rc-web@69 191 case 'json':
rc-web@69 192 packet.data = parse(data);
rc-web@69 193 break;
rc-web@69 194
rc-web@69 195 case 'connect':
rc-web@69 196 packet.qs = data || '';
rc-web@69 197 break;
rc-web@69 198
rc-web@69 199 case 'ack':
rc-web@69 200 pieces = data.match(/^([0-9]+)(\+)?(.*)/);
rc-web@69 201 if (pieces) {
rc-web@69 202 packet.ackId = pieces[1];
rc-web@69 203 packet.args = [];
rc-web@69 204
rc-web@69 205 if (pieces[3]) {
rc-web@69 206 packet.args = parse(pieces[3]) || [];
rc-web@69 207 }
rc-web@69 208 }
rc-web@69 209 break;
rc-web@69 210
rc-web@69 211 case 'error':
rc-web@69 212 pieces = data.split('+');
rc-web@69 213 packet.reason = reasonslist[pieces[0]] || '';
rc-web@69 214 packet.advice = advicelist[pieces[1]] || '';
rc-web@69 215 }
rc-web@69 216
rc-web@69 217 return packet;
rc-web@69 218 };
rc-web@69 219
rc-web@69 220 /**
rc-web@69 221 * Decodes data payload. Detects multiple messages
rc-web@69 222 *
rc-web@69 223 * @return {Array} messages
rc-web@69 224 * @api public
rc-web@69 225 */
rc-web@69 226
rc-web@69 227 exports.decodePayload = function (data) {
rc-web@69 228 if (undefined == data || null == data) {
rc-web@69 229 return [];
rc-web@69 230 }
rc-web@69 231
rc-web@69 232 if (data[0] == '\ufffd') {
rc-web@69 233 var ret = [];
rc-web@69 234
rc-web@69 235 for (var i = 1, length = ''; i < data.length; i++) {
rc-web@69 236 if (data[i] == '\ufffd') {
rc-web@69 237 ret.push(exports.decodePacket(data.substr(i + 1, length)));
rc-web@69 238 i += Number(length) + 1;
rc-web@69 239 length = '';
rc-web@69 240 } else {
rc-web@69 241 length += data[i];
rc-web@69 242 }
rc-web@69 243 }
rc-web@69 244
rc-web@69 245 return ret;
rc-web@69 246 } else {
rc-web@69 247 return [exports.decodePacket(data)];
rc-web@69 248 }
rc-web@69 249 };