| 248 | } |
| 249 | |
| 250 | const protocol = function (self, message) { |
| 251 | let index = 0; |
| 252 | self.isCompressed = false; |
| 253 | // Get the size for the message |
| 254 | const size = |
| 255 | message[index++] | |
| 256 | (message[index++] << 8) | |
| 257 | (message[index++] << 16) | |
| 258 | (message[index++] << 24); |
| 259 | if (size !== message.length) throw new Error('corrupt wire protocol message'); |
| 260 | // Adjust to opcode |
| 261 | index = 12; |
| 262 | // Get the opCode for the message |
| 263 | let type = |
| 264 | message[index++] | |
| 265 | (message[index++] << 8) | |
| 266 | (message[index++] << 16) | |
| 267 | (message[index++] << 24); |
| 268 | |
| 269 | // Unpack and decompress if the message is OP_COMPRESSED |
| 270 | if (type === opcodes.OP_COMPRESSED) { |
| 271 | const requestID = message.readInt32LE(4); |
| 272 | const responseTo = message.readInt32LE(8); |
| 273 | const originalOpcode = message.readInt32LE(16); |
| 274 | const uncompressedSize = message.readInt32LE(20); |
| 275 | const compressorID = message.readUInt8(24); |
| 276 | |
| 277 | const compressedData = message.slice(25); |
| 278 | let uncompressedData; |
| 279 | switch (compressorID) { |
| 280 | case compressorIDs.snappy: |
| 281 | uncompressedData = snappy.uncompressSync(compressedData); |
| 282 | break; |
| 283 | case compressorIDs.zlib: |
| 284 | uncompressedData = zlib.inflateSync(compressedData); |
| 285 | break; |
| 286 | default: |
| 287 | uncompressedData = compressedData; |
| 288 | } |
| 289 | |
| 290 | if (uncompressedData.length !== uncompressedSize) { |
| 291 | throw new Error( |
| 292 | 'corrupt wire protocol message: uncompressed message is not the correct size' |
| 293 | ); |
| 294 | } |
| 295 | |
| 296 | // Reconstruct the msgHeader of the uncompressed opcode |
| 297 | const newMsgHeader = Buffer(MESSAGE_HEADER_SIZE); |
| 298 | newMsgHeader.writeInt32LE(MESSAGE_HEADER_SIZE + uncompressedData.length, 0); |
| 299 | newMsgHeader.writeInt32LE(requestID, 4); |
| 300 | newMsgHeader.writeInt32LE(responseTo, 8); |
| 301 | newMsgHeader.writeInt32LE(originalOpcode, 12); |
| 302 | |
| 303 | // Full uncompressed message |
| 304 | message = Buffer.concat([newMsgHeader, uncompressedData]); |
| 305 | type = originalOpcode; |
| 306 | |
| 307 | // Compressed flag |