UNPKG

memjs

Version:

A memcache client for node using the binary protocol and SASL authentication

129 lines (111 loc) 3.36 kB
// # MemJS utility functions var header = require('./header'); var bufferify = function(val) { return Buffer.isBuffer(val) ? val : Buffer.from(val); }; exports.makeRequestBuffer = function(opcode, key, extras, value, opaque) { key = bufferify(key); extras = bufferify(extras); value = bufferify(value); var buf = Buffer.alloc(24 + key.length + extras.length + value.length); buf.fill(); var requestHeader = { magic: 0x80, opcode: opcode, keyLength: key.length, extrasLength: extras.length, totalBodyLength: key.length + value.length + extras.length, opaque: opaque }; header.toBuffer(requestHeader).copy(buf); extras.copy(buf, 24); key.copy(buf, 24 + extras.length); value.copy(buf, 24 + extras.length + key.length); return buf; }; exports.makeAmountInitialAndExpiration = function(amount, amountIfEmpty, expiration) { var buf = Buffer.alloc(20); buf.writeUInt32BE(0, 0); buf.writeUInt32BE(amount, 4); buf.writeUInt32BE(0, 8); buf.writeUInt32BE(amountIfEmpty, 12); buf.writeUInt32BE(expiration, 16); return buf; }; exports.makeExpiration = function(expiration) { var buf = Buffer.alloc(4); buf.writeUInt32BE(expiration, 0); return buf; }; exports.hashCode = function(str) { var ret, i, len; for(ret = 0, i = 0, len = str.length; i < len; i++) { ret = (31 * ret + str.charCodeAt(i)) << 0; } return Math.abs(ret); }; exports.parseMessage = function(dataBuf) { if (dataBuf.length < 24) { return false; } var responseHeader = header.fromBuffer(dataBuf); if (dataBuf.length < responseHeader.totalBodyLength + 24 || responseHeader.totalBodyLength < responseHeader.keyLength + responseHeader.extrasLength) { return false; } var pointer = 24; var extras = dataBuf.slice(pointer, pointer + responseHeader.extrasLength); pointer += responseHeader.extrasLength; var key = dataBuf.slice(pointer, pointer + responseHeader.keyLength); pointer += responseHeader.keyLength; var val = dataBuf.slice(pointer, 24 + responseHeader.totalBodyLength); return {header: responseHeader, key: key, extras: extras, val: val}; }; exports.merge = function(original, deflt) { var attr, originalValue; for (attr in deflt) { if (deflt.hasOwnProperty(attr)) { originalValue = original[attr]; if (originalValue === undefined || originalValue === null) { original[attr] = deflt[attr]; } } } return original; }; // timestamp provides a monotonic timestamp with millisecond accuracy, useful // for timers. exports.timestamp = function() { var times = process.hrtime(); return (times[0] * 1000) + Math.round((times[1] / 1000000)); }; if(!Buffer.concat) { Buffer.concat = function(list, length) { if (!Array.isArray(list)) { throw new Error('Usage: Buffer.concat(list, [length])'); } if (list.length === 0) { return Buffer.alloc(0); } if (list.length === 1) { return list[0]; } var i, buf; if (typeof length !== 'number') { length = 0; for (i = 0; i < list.length; i++) { buf = list[i]; length += buf.length; } } var buffer = Buffer.alloc(length); var pos = 0; for (i = 0; i < list.length; i++) { buf = list[i]; buf.copy(buffer, pos); pos += buf.length; } return buffer; }; }