polymech-astro/packages/node-murmurhash-native/stream.js
2025-08-25 08:22:26 +02:00

155 lines
4.0 KiB
JavaScript

"use strict";
var util = require('util');
var binding = require('./incremental');
var algorithms = {};
exports.getHashes = function() {
return Object.keys(binding)
.filter(function(name) {
return 'function' === typeof binding[name];
})
.map(function(name) { return name.toLowerCase(); });
};
Object.keys(binding).forEach(function(name) {
if (binding.hasOwnProperty(name) && 'function' === typeof binding[name]) {
algorithms[name.toLowerCase()] = binding[name];
}
});
algorithms.murmurhash3a = algorithms.murmurhash32 = algorithms.murmurhash32x86 = algorithms.murmurhash;
/* from nodejs lib/crypto.js */
var LazyTransform = require('./lazy_transform');
/**
* Creates and returns a MurmurHash object that can be used to generate murmurhash digests.
*
* Except murmur's `seed` and `endianness` options, the rest of the options are passed to
* stream.Transform constructor.
*
* @param {string|MurmurHash} algorithm|hasher - one of available algorithms
* or a murmur hasher instance
* @param {number|object} seed|options - hasher options
**/
exports.createHash = exports.MurmurHash = MurmurHash;
function MurmurHash(algorithm, options) {
var seed, endianness;
if (!(this instanceof MurmurHash))
return new MurmurHash(algorithm, options);
if (options && 'object' === typeof options) {
seed = options.seed;
endianness = options.endianness;
} else {
seed = options; options = undefined;
}
if (algorithm instanceof MurmurHash) {
this._handle = new algorithm._handle.constructor(algorithm._handle, endianness);
} else if (algorithm) {
// handle object from json
if ('object' === typeof algorithm) {
seed = algorithm.seed;
algorithm = algorithm.type;
}
var Handle = algorithms[algorithm.toLowerCase()];
if (Handle) {
this._handle = new Handle(seed, endianness);
} else {
throw new Error("Algorithm not supported");
}
} else {
throw new TypeError("Must give algorithm string, a serialized state or a MurmurHash instance");
}
LazyTransform.call(this, options);
}
util.inherits(MurmurHash, LazyTransform);
MurmurHash.prototype._transform = function(chunk, encoding, callback) {
if (chunk.length < 8192) { // this constant was chosen experimentally
this._handle.update(chunk, encoding);
callback();
} else {
this._handle.update(chunk, encoding, callback);
}
};
MurmurHash.prototype._flush = function(callback) {
this.push(this._handle.digest());
callback();
};
MurmurHash.prototype.update = function() {
var handle = this._handle;
return handle.update.apply(handle, arguments) && this;
};
MurmurHash.prototype.digest = function() {
var handle = this._handle;
return handle.digest.apply(handle, arguments);
};
MurmurHash.prototype.serialize = function(type, offset) {
return this._handle.serialize(type, offset);
};
MurmurHash.prototype.copy = function(target) {
this._handle.copy(target && target._handle);
return target;
};
MurmurHash.prototype.toJSON = function() {
var handle = this._handle;
return {
type: handle.constructor.name,
seed: handle.toJSON()
};
};
Object.defineProperty(MurmurHash.prototype, 'isBusy', {
get: function() {
return this._handle.isBusy;
},
enumerable: false,
configurable: false
});
Object.defineProperty(MurmurHash.prototype, 'total', {
get: function() {
return this._handle.total;
},
enumerable: true,
configurable: true
});
Object.defineProperty(MurmurHash.prototype, 'endianness', {
get: function() {
return this._handle.endianness;
},
set: function(value) {
this._handle.endianness = value;
},
enumerable: true,
configurable: false
});
Object.defineProperty(MurmurHash.prototype, 'SERIAL_BYTE_LENGTH', {
get: function() {
Object.defineProperty(this, 'SERIAL_BYTE_LENGTH', {
enumerable: true,
writable: true,
configurable: true,
value: this._handle.SERIAL_BYTE_LENGTH
});
return this.SERIAL_BYTE_LENGTH;
},
enumerable: true,
configurable: true,
});