Browse Source

querystring: improve unescapeBuffer() performance

Refactored the `unescapeBuffer` function in order to simplify it,
and also to improve the performance.

PR-URL: https://github.com/nodejs/node/pull/12525
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Brian White <mscdex@mscdex.net>
v6
Jesus Seijas 8 years ago
committed by Luigi Pinca
parent
commit
19685eac65
  1. 91
      lib/querystring.js

91
lib/querystring.js

@ -64,67 +64,44 @@ const unhexTable = [
// a safe fast alternative to decodeURIComponent // a safe fast alternative to decodeURIComponent
function unescapeBuffer(s, decodeSpaces) { function unescapeBuffer(s, decodeSpaces) {
var out = Buffer.allocUnsafe(s.length); var out = Buffer.allocUnsafe(s.length);
var state = 0; var index = 0;
var n, m, hexchar, c; var outIndex = 0;
var currentChar;
for (var inIndex = 0, outIndex = 0; ; inIndex++) { var nextChar;
if (inIndex < s.length) { var hexHigh;
c = s.charCodeAt(inIndex); var hexLow;
} else { var maxLength = s.length - 2;
if (state > 0) { // Flag to know if some hex chars have been decoded
out[outIndex++] = 37/*%*/; var hasHex = false;
if (state === 2) while (index < s.length) {
out[outIndex++] = hexchar; currentChar = s.charCodeAt(index);
} if (currentChar === 43 /*'+'*/ && decodeSpaces) {
break; out[outIndex++] = 32; // ' '
index++;
continue;
} }
switch (state) { if (currentChar === 37 /*'%'*/ && index < maxLength) {
case 0: // Any character currentChar = s.charCodeAt(++index);
switch (c) { hexHigh = unhexTable[currentChar];
case 37: // '%' if (!(hexHigh >= 0)) {
n = 0; out[outIndex++] = 37; // '%'
m = 0; } else {
state = 1; nextChar = s.charCodeAt(++index);
break; hexLow = unhexTable[nextChar];
case 43: // '+' if (!(hexLow >= 0)) {
if (decodeSpaces) out[outIndex++] = 37; // '%'
c = 32; // ' ' out[outIndex++] = currentChar;
// falls through currentChar = nextChar;
default: } else {
out[outIndex++] = c; hasHex = true;
break; currentChar = hexHigh * 16 + hexLow;
}
break;
case 1: // First hex digit
hexchar = c;
n = unhexTable[c];
if (!(n >= 0)) {
out[outIndex++] = 37/*%*/;
out[outIndex++] = c;
state = 0;
break;
}
state = 2;
break;
case 2: // Second hex digit
state = 0;
m = unhexTable[c];
if (!(m >= 0)) {
out[outIndex++] = 37/*%*/;
out[outIndex++] = hexchar;
out[outIndex++] = c;
break;
} }
out[outIndex++] = 16 * n + m; }
break;
} }
out[outIndex++] = currentChar;
index++;
} }
return hasHex ? out.slice(0, outIndex) : out;
// TODO support returning arbitrary buffers.
return out.slice(0, outIndex);
} }

Loading…
Cancel
Save