ToBinaryRuntimeModule.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Alexander Akait @alexander-akait
  4. */
  5. "use strict";
  6. const RuntimeGlobals = require("../RuntimeGlobals");
  7. const RuntimeModule = require("../RuntimeModule");
  8. const Template = require("../Template");
  9. /** @typedef {import("../Compilation")} Compilation */
  10. class ToBinaryRuntimeModule extends RuntimeModule {
  11. constructor() {
  12. super("to binary");
  13. }
  14. /**
  15. * @returns {string | null} runtime code
  16. */
  17. generate() {
  18. const compilation = /** @type {Compilation} */ (this.compilation);
  19. const fn = RuntimeGlobals.toBinary;
  20. const { runtimeTemplate } = compilation;
  21. // Inspired by esbuild
  22. const isNodePlatform = compilation.compiler.platform.node;
  23. const isWebPlatform = compilation.compiler.platform.web;
  24. const isNeutralPlatform = runtimeTemplate.isNeutralPlatform();
  25. const toImmutableBytes = runtimeTemplate.basicFunction("value", [
  26. runtimeTemplate.destructureObject(["buffer"], "value"),
  27. `${runtimeTemplate.renderConst()} throwErr = ${runtimeTemplate.basicFunction("", ["throw new TypeError('ArrayBuffer is immutable');"])};`,
  28. "Object.defineProperties(buffer, { immutable: { value: true }, resize: { value: throwErr }, transfer: { value: throwErr }, transferToFixedLength: { value: throwErr } });",
  29. "Object.freeze(buffer);",
  30. "return value;"
  31. ]);
  32. return Template.asString([
  33. "// define to binary helper",
  34. `${runtimeTemplate.renderConst()} toImmutableBytes = ${toImmutableBytes}`,
  35. `${fn} = ${isNeutralPlatform ? "typeof Buffer !== 'undefined' ? " : ""}${
  36. isNodePlatform || isNeutralPlatform
  37. ? `${runtimeTemplate.returningFunction("toImmutableBytes(new Uint8Array(Buffer.from(base64, 'base64')))", "base64")}`
  38. : ""
  39. } ${isNeutralPlatform ? ": " : ""}${
  40. isWebPlatform || isNeutralPlatform
  41. ? `(${runtimeTemplate.basicFunction("", [
  42. `${runtimeTemplate.renderConst()} table = new Uint8Array(128);`,
  43. "for (var i = 0; i < 64; i++) table[i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i * 4 - 205] = i;",
  44. `return ${runtimeTemplate.basicFunction("base64", [
  45. `${runtimeTemplate.renderConst()} n = base64.length, bytes = new Uint8Array((n - (base64[n - 1] == '=') - (base64[n - 2] == '=')) * 3 / 4 | 0);`,
  46. "for (var i = 0, j = 0; i < n;) {",
  47. Template.indent([
  48. `${runtimeTemplate.renderConst()} c0 = table[base64.charCodeAt(i++)], c1 = table[base64.charCodeAt(i++)];`,
  49. `${runtimeTemplate.renderConst()} c2 = table[base64.charCodeAt(i++)], c3 = table[base64.charCodeAt(i++)];`,
  50. "bytes[j++] = (c0 << 2) | (c1 >> 4);",
  51. "bytes[j++] = (c1 << 4) | (c2 >> 2);",
  52. "bytes[j++] = (c2 << 6) | c3;"
  53. ]),
  54. "}",
  55. "return toImmutableBytes(bytes)"
  56. ])}`
  57. ])})();`
  58. : ""
  59. }`
  60. ]);
  61. }
  62. }
  63. module.exports = ToBinaryRuntimeModule;