| /* |
| MIT License http://www.opensource.org/licenses/mit-license.php |
| Author Tobias Koppers @sokra |
| */ |
| "use strict"; |
| |
| /** @typedef {{new(): Hash}} HashConstructor */ |
| /** |
| * @typedef {Object} Hash |
| * @property {function(string|Buffer, string=): Hash} update |
| * @property {function(string): string} digest |
| */ |
| |
| const BULK_SIZE = 1000; |
| |
| /** |
| * @implements {Hash} |
| */ |
| class BulkUpdateDecorator { |
| constructor(hash) { |
| this.hash = hash; |
| this.buffer = ""; |
| } |
| |
| update(data, inputEncoding) { |
| if ( |
| inputEncoding !== undefined || |
| typeof data !== "string" || |
| data.length > BULK_SIZE |
| ) { |
| if (this.buffer.length > 0) { |
| this.hash.update(this.buffer); |
| this.buffer = ""; |
| } |
| this.hash.update(data, inputEncoding); |
| } else { |
| this.buffer += data; |
| if (this.buffer.length > BULK_SIZE) { |
| this.hash.update(this.buffer); |
| this.buffer = ""; |
| } |
| } |
| return this; |
| } |
| |
| digest(encoding) { |
| if (this.buffer.length > 0) { |
| this.hash.update(this.buffer); |
| } |
| var digestResult = this.hash.digest(encoding); |
| return typeof digestResult === "string" |
| ? digestResult |
| : digestResult.toString(); |
| } |
| } |
| |
| /* istanbul ignore next */ |
| class DebugHash { |
| constructor() { |
| this.string = ""; |
| } |
| |
| update(data, inputEncoding) { |
| if (typeof data !== "string") data = data.toString("utf-8"); |
| this.string += data; |
| return this; |
| } |
| |
| digest(encoding) { |
| return this.string.replace(/[^a-z0-9]+/gi, m => |
| Buffer.from(m).toString("hex") |
| ); |
| } |
| } |
| |
| /** |
| * Creates a hash by name or function |
| * @param {string | HashConstructor} algorithm the algorithm name or a constructor creating a hash |
| * @returns {Hash} the hash |
| */ |
| module.exports = algorithm => { |
| if (typeof algorithm === "function") { |
| return new BulkUpdateDecorator(new algorithm()); |
| } |
| switch (algorithm) { |
| // TODO add non-cryptographic algorithm here |
| case "debug": |
| return new DebugHash(); |
| default: |
| return new BulkUpdateDecorator(require("crypto").createHash(algorithm)); |
| } |
| }; |