Source: util/string.ts

  1. /**
  2. * @author Michael Hasenstein <hasenstein@yahoo.com>
  3. * @copyright REFINIO GmbH 2020
  4. * @license CC-BY-NC-SA-2.5; portions MIT License
  5. * @version 0.0.1
  6. */
  7. /**
  8. * Helper function(s) for strings.
  9. * @module
  10. */
  11. import {createError} from '../errors';
  12. import {isInteger} from './type-checks-basic';
  13. /**
  14. * **JS RUNTIME OPTIMIZATION PREVENTION HACK**
  15. *
  16. * Workaround for {@link https://bugs.chromium.org/p/v8/issues/detail?id=2869}
  17. *
  18. * This is the same as the standard string function `substr`, but it forces the JS runtime to
  19. * allocate new memory.
  20. *
  21. * Modern runtimes internally don't always allocate new memory, instead they keep a reference to
  22. * the original string as well as start and end within that string if the runtime sees a
  23. * read-only use of the sub string.
  24. * @static
  25. * @param {string} s - A string
  26. * @param {number} start - A non-negative integer start position
  27. * @param {number} [length=s.length-start] - A non-negative length. If omitted, it is calculated
  28. * as `s.length - start`
  29. * @returns {string}
  30. */
  31. export function substrForceMemCopy(
  32. s: string,
  33. start: number,
  34. length: number = s.length - start
  35. ): string {
  36. // Because of the charAt() this case would not work and needs to be handled separately now.
  37. // This must happen BEFORE the error-throwing parameter checks in order to work like the
  38. // original substr() for these cases!
  39. if (start > s.length || length === 0) {
  40. return '';
  41. }
  42. // We don't recreate the exact same behavior of the original substr() function, so we must
  43. // exclude negative values
  44. if (!isInteger(start) || !isInteger(length) || start < 0 || length < 0) {
  45. throw createError('US-SSFMC1', {s, start, length});
  46. }
  47. // Adding the last character in a string concatenation operation *should* work around any
  48. // current string operation optimizations and force the runtime to allocate new memory for the
  49. // resulting string.
  50. return s.substr(start, length - 1) + s.charAt(start + length - 1);
  51. }