Skip to content

Commit

Permalink
fix: fixes issue #18 (performance issue with escapeContent)
Browse files Browse the repository at this point in the history
  • Loading branch information
nbouvrette committed Oct 5, 2023
1 parent 9653f5e commit 0796ea0
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 33 deletions.
50 changes: 17 additions & 33 deletions src/escape/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,66 +35,50 @@ const escapeContent = (
unescapedContent: string,
escapeSpace: boolean,
escapeUnicode: boolean
): string => {
let escapedContent = ''
for (
let character = unescapedContent[0], position = 0;
position < unescapedContent.length;
position++, character = unescapedContent[position]
) {
): string =>
// By using a regular expression we avoid iterating through all characters and improve performance.
unescapedContent.replace(/[\s!#:=\\]|[^\u0020-\u007E]/g, (character) => {
switch (character) {
case ' ': {
// Escape space if required, or if it is first character.
escapedContent += escapeSpace || position === 0 ? '\\ ' : ' '
break
// Escape space if required, or if it's the first character.
return escapeSpace || character === unescapedContent[0] ? '\\ ' : ' '
}
// Backslash.
case '\\': {
escapedContent += '\\\\'
break
// Backslash.
return '\\\\'
}
case '\f': {
// Formfeed.
escapedContent += '\\f'
break
return '\\f'
}
case '\n': {
// Newline.
escapedContent += '\\n'
break
return '\\n'
}
case '\r': {
// Carriage return.
escapedContent += '\\r'
break
return '\\r'
}
case '\t': {
// Tab.
escapedContent += '\\t'
break
return '\\t'
}
case '=':
case ':':
case '#':
case '!': {
// Escapes =, :, # and !.
escapedContent += `\\${character}`
break
// =, :, # and !.
return `\\${character}`
}
default: {
if (escapeUnicode) {
const codePoint: number = character.codePointAt(0) as number // Can never be `undefined`.
if (codePoint < 0x0020 || codePoint > 0x007e) {
escapedContent += `\\u${codePoint.toString(16).padStart(4, '0')}`
break
// Any character that is not in the range of ASCII printable characters.
return `\\u${codePoint.toString(16).padStart(4, '0')}`
}
}
// Non-escapable characters.
escapedContent += character
break
return character
}
}
}

return escapedContent
}
})
1 change: 1 addition & 0 deletions src/unescape/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* This exception is thrown if malformed escaped unicode characters are present.
*/
export const unescapeContent = (escapedContent: string): string =>
// By using a regular expression we avoid iterating through all characters and improve performance.
escapedContent.replace(/\\[^u]|\\u.{4}/g, (escapeSequence: string): string => {
const nextCharacter = escapeSequence.charAt(1)
switch (nextCharacter) {
Expand Down

0 comments on commit 0796ea0

Please sign in to comment.