BatchedHash.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const Hash = require("../Hash");
  7. const { digest, update } = require("./hash-digest");
  8. /** @type {number} */
  9. const MAX_SHORT_STRING = require("./wasm-hash").MAX_SHORT_STRING;
  10. /** @typedef {import("../../../declarations/WebpackOptions").HashDigest} Encoding */
  11. class BatchedHash extends Hash {
  12. /**
  13. * @param {Hash} hash hash
  14. */
  15. constructor(hash) {
  16. super();
  17. /** @type {undefined | string} */
  18. this.string = undefined;
  19. /** @type {undefined | Encoding} */
  20. this.encoding = undefined;
  21. /** @type {Hash} */
  22. this.hash = hash;
  23. }
  24. /**
  25. * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
  26. * @overload
  27. * @param {string | Buffer} data data
  28. * @returns {Hash} updated hash
  29. */
  30. /**
  31. * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
  32. * @overload
  33. * @param {string} data data
  34. * @param {Encoding} inputEncoding data encoding
  35. * @returns {Hash} updated hash
  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 {Encoding=} inputEncoding data encoding
  41. * @returns {Hash} updated hash
  42. */
  43. update(data, inputEncoding) {
  44. if (this.string !== undefined) {
  45. if (
  46. typeof data === "string" &&
  47. inputEncoding === this.encoding &&
  48. this.string.length + data.length < MAX_SHORT_STRING
  49. ) {
  50. this.string += data;
  51. return this;
  52. }
  53. if (this.encoding) {
  54. update(this.hash, this.string, this.encoding);
  55. } else {
  56. update(this.hash, this.string);
  57. }
  58. this.string = undefined;
  59. }
  60. if (typeof data === "string") {
  61. if (
  62. data.length < MAX_SHORT_STRING &&
  63. // base64 encoding is not valid since it may contain padding chars
  64. (!inputEncoding || !inputEncoding.startsWith("ba"))
  65. ) {
  66. this.string = data;
  67. this.encoding = inputEncoding;
  68. } else if (inputEncoding) {
  69. update(this.hash, data, inputEncoding);
  70. } else {
  71. update(this.hash, data);
  72. }
  73. } else {
  74. update(this.hash, data);
  75. }
  76. return this;
  77. }
  78. /**
  79. * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
  80. * @overload
  81. * @returns {Buffer} digest
  82. */
  83. /**
  84. * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
  85. * @overload
  86. * @param {Encoding} encoding encoding of the return value
  87. * @returns {string} digest
  88. */
  89. /**
  90. * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
  91. * @param {Encoding=} encoding encoding of the return value
  92. * @returns {string | Buffer} digest
  93. */
  94. digest(encoding) {
  95. if (this.string !== undefined) {
  96. if (this.encoding) {
  97. update(this.hash, this.string, this.encoding);
  98. } else {
  99. update(this.hash, this.string);
  100. }
  101. }
  102. if (!encoding) {
  103. return digest(this.hash);
  104. }
  105. return digest(this.hash, encoding);
  106. }
  107. }
  108. module.exports = BatchedHash;