source: imaps-frontend/node_modules/webpack/lib/util/createHash.js@ 79a0317

main
Last change on this file since 79a0317 was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 3 days ago

F4 Finalna Verzija

  • Property mode set to 100644
File size: 5.5 KB
RevLine 
[79a0317]1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const Hash = require("./Hash");
9
10const BULK_SIZE = 2000;
11
12// We are using an object instead of a Map as this will stay static during the runtime
13// so access to it can be optimized by v8
14/** @type {{[key: string]: Map<string, string>}} */
15const digestCaches = {};
16
17/** @typedef {function(): Hash} HashFactory */
18
19class BulkUpdateDecorator extends Hash {
20 /**
21 * @param {Hash | HashFactory} hashOrFactory function to create a hash
22 * @param {string=} hashKey key for caching
23 */
24 constructor(hashOrFactory, hashKey) {
25 super();
26 this.hashKey = hashKey;
27 if (typeof hashOrFactory === "function") {
28 this.hashFactory = hashOrFactory;
29 this.hash = undefined;
30 } else {
31 this.hashFactory = undefined;
32 this.hash = hashOrFactory;
33 }
34 this.buffer = "";
35 }
36
37 /**
38 * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
39 * @param {string|Buffer} data data
40 * @param {string=} inputEncoding data encoding
41 * @returns {this} updated hash
42 */
43 update(data, inputEncoding) {
44 if (
45 inputEncoding !== undefined ||
46 typeof data !== "string" ||
47 data.length > BULK_SIZE
48 ) {
49 if (this.hash === undefined)
50 this.hash = /** @type {HashFactory} */ (this.hashFactory)();
51 if (this.buffer.length > 0) {
52 this.hash.update(this.buffer);
53 this.buffer = "";
54 }
55 this.hash.update(data, inputEncoding);
56 } else {
57 this.buffer += data;
58 if (this.buffer.length > BULK_SIZE) {
59 if (this.hash === undefined)
60 this.hash = /** @type {HashFactory} */ (this.hashFactory)();
61 this.hash.update(this.buffer);
62 this.buffer = "";
63 }
64 }
65 return this;
66 }
67
68 /**
69 * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
70 * @param {string=} encoding encoding of the return value
71 * @returns {string|Buffer} digest
72 */
73 digest(encoding) {
74 let digestCache;
75 const buffer = this.buffer;
76 if (this.hash === undefined) {
77 // short data for hash, we can use caching
78 const cacheKey = `${this.hashKey}-${encoding}`;
79 digestCache = digestCaches[cacheKey];
80 if (digestCache === undefined) {
81 digestCache = digestCaches[cacheKey] = new Map();
82 }
83 const cacheEntry = digestCache.get(buffer);
84 if (cacheEntry !== undefined) return cacheEntry;
85 this.hash = /** @type {HashFactory} */ (this.hashFactory)();
86 }
87 if (buffer.length > 0) {
88 this.hash.update(buffer);
89 }
90 const digestResult = this.hash.digest(encoding);
91 const result =
92 typeof digestResult === "string" ? digestResult : digestResult.toString();
93 if (digestCache !== undefined) {
94 digestCache.set(buffer, result);
95 }
96 return result;
97 }
98}
99
100/* istanbul ignore next */
101class DebugHash extends Hash {
102 constructor() {
103 super();
104 this.string = "";
105 }
106
107 /**
108 * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
109 * @param {string|Buffer} data data
110 * @param {string=} inputEncoding data encoding
111 * @returns {this} updated hash
112 */
113 update(data, inputEncoding) {
114 if (typeof data !== "string") data = data.toString("utf-8");
115 const prefix = Buffer.from("@webpack-debug-digest@").toString("hex");
116 if (data.startsWith(prefix)) {
117 data = Buffer.from(data.slice(prefix.length), "hex").toString();
118 }
119 this.string += `[${data}](${
120 /** @type {string} */ (new Error().stack).split("\n", 3)[2]
121 })\n`;
122 return this;
123 }
124
125 /**
126 * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
127 * @param {string=} encoding encoding of the return value
128 * @returns {string|Buffer} digest
129 */
130 digest(encoding) {
131 return Buffer.from(`@webpack-debug-digest@${this.string}`).toString("hex");
132 }
133}
134
135/** @type {typeof import("crypto") | undefined} */
136let crypto;
137/** @type {typeof import("./hash/xxhash64") | undefined} */
138let createXXHash64;
139/** @type {typeof import("./hash/md4") | undefined} */
140let createMd4;
141/** @type {typeof import("./hash/BatchedHash") | undefined} */
142let BatchedHash;
143
144/** @typedef {string | typeof Hash} Algorithm */
145
146/**
147 * Creates a hash by name or function
148 * @param {Algorithm} algorithm the algorithm name or a constructor creating a hash
149 * @returns {Hash} the hash
150 */
151module.exports = algorithm => {
152 if (typeof algorithm === "function") {
153 // eslint-disable-next-line new-cap
154 return new BulkUpdateDecorator(() => new algorithm());
155 }
156 switch (algorithm) {
157 // TODO add non-cryptographic algorithm here
158 case "debug":
159 return new DebugHash();
160 case "xxhash64":
161 if (createXXHash64 === undefined) {
162 createXXHash64 = require("./hash/xxhash64");
163 if (BatchedHash === undefined) {
164 BatchedHash = require("./hash/BatchedHash");
165 }
166 }
167 return new /** @type {typeof import("./hash/BatchedHash")} */ (
168 BatchedHash
169 )(createXXHash64());
170 case "md4":
171 if (createMd4 === undefined) {
172 createMd4 = require("./hash/md4");
173 if (BatchedHash === undefined) {
174 BatchedHash = require("./hash/BatchedHash");
175 }
176 }
177 return new /** @type {typeof import("./hash/BatchedHash")} */ (
178 BatchedHash
179 )(createMd4());
180 case "native-md4":
181 if (crypto === undefined) crypto = require("crypto");
182 return new BulkUpdateDecorator(
183 () => /** @type {typeof import("crypto")} */ (crypto).createHash("md4"),
184 "md4"
185 );
186 default:
187 if (crypto === undefined) crypto = require("crypto");
188 return new BulkUpdateDecorator(
189 () =>
190 /** @type {typeof import("crypto")} */ (crypto).createHash(algorithm),
191 algorithm
192 );
193 }
194};
Note: See TracBrowser for help on using the repository browser.