BatchedHash.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. /**
  11. * @import {
  12. * HashDigest as Encoding
  13. * } from "../../../declarations/WebpackOptions"
  14. */
  15. class BatchedHash extends Hash {
  16. /**
  17. * Creates an instance of BatchedHash.
  18. * @param {Hash} hash hash
  19. */
  20. constructor(hash) {
  21. super();
  22. /** @type {undefined | string} */
  23. this.string = undefined;
  24. /** @type {undefined | Encoding} */
  25. this.encoding = undefined;
  26. /** @type {Hash} */
  27. this.hash = hash;
  28. }
  29. /**
  30. * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
  31. * @overload
  32. * @param {string | Buffer} data data
  33. * @returns {Hash} updated hash
  34. */
  35. /**
  36. * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
  37. * @overload
  38. * @param {string} data data
  39. * @param {Encoding} inputEncoding data encoding
  40. * @returns {Hash} updated hash
  41. */
  42. /**
  43. * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
  44. * @param {string | Buffer} data data
  45. * @param {Encoding=} inputEncoding data encoding
  46. * @returns {Hash} updated hash
  47. */
  48. update(data, inputEncoding) {
  49. if (this.string !== undefined) {
  50. if (
  51. typeof data === "string" &&
  52. inputEncoding === this.encoding &&
  53. this.string.length + data.length < MAX_SHORT_STRING
  54. ) {
  55. this.string += data;
  56. return this;
  57. }
  58. if (this.encoding) {
  59. update(this.hash, this.string, this.encoding);
  60. } else {
  61. update(this.hash, this.string);
  62. }
  63. this.string = undefined;
  64. }
  65. if (typeof data === "string") {
  66. if (
  67. data.length < MAX_SHORT_STRING &&
  68. // base64 encoding is not valid since it may contain padding chars
  69. (!inputEncoding || !inputEncoding.startsWith("ba"))
  70. ) {
  71. this.string = data;
  72. this.encoding = inputEncoding;
  73. } else if (inputEncoding) {
  74. update(this.hash, data, inputEncoding);
  75. } else {
  76. update(this.hash, data);
  77. }
  78. } else {
  79. update(this.hash, data);
  80. }
  81. return this;
  82. }
  83. /**
  84. * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
  85. * @overload
  86. * @returns {Buffer} digest
  87. */
  88. /**
  89. * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
  90. * @overload
  91. * @param {Encoding} encoding encoding of the return value
  92. * @returns {string} digest
  93. */
  94. /**
  95. * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
  96. * @param {Encoding=} encoding encoding of the return value
  97. * @returns {string | Buffer} digest
  98. */
  99. digest(encoding) {
  100. if (this.string !== undefined) {
  101. if (this.encoding) {
  102. update(this.hash, this.string, this.encoding);
  103. } else {
  104. update(this.hash, this.string);
  105. }
  106. }
  107. if (!encoding) {
  108. return digest(this.hash);
  109. }
  110. return digest(this.hash, encoding);
  111. }
  112. }
  113. module.exports = BatchedHash;