EscapeSequenceEncoder.ts 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import { injectable } from 'inversify';
  2. import { IEscapeSequenceEncoder } from '../interfaces/utils/IEscapeSequenceEncoder';
  3. @injectable()
  4. export class EscapeSequenceEncoder implements IEscapeSequenceEncoder {
  5. /**
  6. * @type {Map<string, string>}
  7. */
  8. private readonly stringsCache: Map <string, string> = new Map();
  9. /**
  10. * @param {string} string
  11. * @param {boolean} encodeAllSymbols
  12. * @returns {string}
  13. */
  14. public encode (string: string, encodeAllSymbols: boolean): string {
  15. const cacheKey: string = `${string}-${String(encodeAllSymbols)}`;
  16. if (this.stringsCache.has(cacheKey)) {
  17. return <string>this.stringsCache.get(cacheKey);
  18. }
  19. const radix: number = 16;
  20. const replaceRegExp: RegExp = new RegExp('[\\s\\S]', 'g');
  21. const escapeSequenceRegExp: RegExp = new RegExp('[\'\"\\\\\\s]');
  22. const regExp: RegExp = new RegExp('[\\x00-\\x7F]');
  23. let prefix: string;
  24. let template: string;
  25. const result: string = string.replace(replaceRegExp, (character: string): string => {
  26. if (!encodeAllSymbols && !escapeSequenceRegExp.exec(character)) {
  27. return character;
  28. }
  29. if (regExp.exec(character)) {
  30. prefix = '\\x';
  31. template = '00';
  32. } else {
  33. prefix = '\\u';
  34. template = '0000';
  35. }
  36. return `${prefix}${(template + character.charCodeAt(0).toString(radix)).slice(-template.length)}`;
  37. });
  38. this.stringsCache.set(cacheKey, result);
  39. this.stringsCache.set(`${result}-${String(encodeAllSymbols)}`, result);
  40. return result;
  41. }
  42. }