diff --git a/benchmark/buffers/buffer-is-encoding.js b/benchmark/buffers/buffer-is-encoding.js new file mode 100644 index 00000000000000..8e3824fed46625 --- /dev/null +++ b/benchmark/buffers/buffer-is-encoding.js @@ -0,0 +1,43 @@ +'use strict'; + +const common = require('../common.js'); + +const bench = common.createBenchmark(main, { + encoding: [ 'hex', + 'utf8', + 'utf-8', + 'ascii', + 'binary', + 'base64', + 'ucs2', + 'ucs-2', + 'utf16le', + 'utf-16le', + 'HEX', + 'UTF8', + 'UTF-8', + 'ASCII', + 'BINARY', + 'BASE64', + 'UCS2', + 'UCS-2', + 'UTF16LE', + 'UTF-16LE', + 'utf9', + 'utf-7', + 'utf17le', + 'utf-17le', + 'Unicode-FTW', + 'new gnu gun' + ] +}); + +function main(conf) { + var encoding = conf.encoding; + bench.start(); + var n = 1024 * 1024; + for (let i = 0; i < n; i++) { + Buffer.isEncoding(encoding); + } + bench.end(n); +} diff --git a/lib/buffer.js b/lib/buffer.js index 766a82c2f21f0e..50aadbd5c76a91 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -185,30 +185,133 @@ Buffer.compare = function compare(a, b) { Buffer.isEncoding = function(encoding) { - var loweredCase = false; - for (;;) { - switch (encoding) { - case 'hex': - case 'utf8': - case 'utf-8': - case 'ascii': - case 'binary': - case 'base64': - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': + if (typeof encoding !== 'string') + encoding = '' + encoding; + + // only allow: + // 'hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', + // 'ucs2', 'ucs-2', 'utf16le', 'utf-16le' + + switch (encoding.length) { + case 3: // hex + var code0 = encoding.charCodeAt(0); + var code1 = encoding.charCodeAt(1); + var code2 = encoding.charCodeAt(2); + if ((code0 === 72 || code0 === 104) && // h, H + (code1 === 69 || code1 === 101) && // e, E + (code2 === 88 || code2 === 120)) { // x, X return true; - - default: - if (loweredCase) - return false; - encoding = ('' + encoding).toLowerCase(); - loweredCase = true; - } + } + + break; + case 4: // utf8/ucs2 + var code0 = encoding.charCodeAt(0); + var code1 = encoding.charCodeAt(1); + var code2 = encoding.charCodeAt(2); + var code3 = encoding.charCodeAt(3); + if ((code0 === 85 || code0 === 117)) { // u, U + if ((code1 === 84 || code1 === 116) && // t, T + (code2 === 70 || code2 === 102) && // f, F + code3 === 56) { // 8 + return true; + } else if ((code1 === 67 || code1 === 99) && // c, C + (code2 === 83 || code2 === 115) && // s, S + code3 === 50) { // 2 + return true; + } + } + break; + case 5: // utf-8/ucs-2/ascii + var code0 = encoding.charCodeAt(0); + var code1 = encoding.charCodeAt(1); + var code2 = encoding.charCodeAt(2); + var code3 = encoding.charCodeAt(3); + var code4 = encoding.charCodeAt(4); + if ((code0 === 85 || code0 === 117)) { // u, U + if ((code1 === 84 || code1 === 116) && // t, T + (code2 === 70 || code2 === 102) && // f, F + code3 === 45 && // - + code4 === 56) { // 8 + return true; + } else if ((code1 === 67 || code1 === 99) && // c, C + (code2 === 83 || code2 === 115) && // s, S + code3 === 45 && // - + code4 === 50) { // 2 + return true; + } + } else if ((code0 === 65 || code0 === 97) && // a, A + (code1 === 83 || code1 === 115) && // s, S + (code2 === 67 || code2 === 99) && // c, C + (code3 === 73 || code3 === 105) && // i, I + (code4 === 73 || code4 === 105)) { // i, I + return true; + } + break; + case 6: // binary/base64 + var code0 = encoding.charCodeAt(0); + var code1 = encoding.charCodeAt(1); + var code2 = encoding.charCodeAt(2); + var code3 = encoding.charCodeAt(3); + var code4 = encoding.charCodeAt(4); + var code5 = encoding.charCodeAt(5); + if ((code0 === 66 || code0 === 98)) { // b, B + if ((code1 === 73 || code1 === 105) && // i, I + (code2 === 78 || code2 === 110) && // n, N + (code3 === 65 || code3 === 97) && // a, A + (code4 === 82 || code4 === 114) && // r, R + (code5 === 89 || code5 === 121)) { // y, Y + return true; + } else if ((code1 === 65 || code1 === 97) && // a, A + (code2 === 83 || code2 === 115) && // s, S + (code3 === 69 || code3 === 101) && // e, E + code4 === 54 && // 6 + code5 === 52) { // 4 + return true; + } + } + break; + case 7: // utf16le + var code0 = encoding.charCodeAt(0); + var code1 = encoding.charCodeAt(1); + var code2 = encoding.charCodeAt(2); + var code3 = encoding.charCodeAt(3); + var code4 = encoding.charCodeAt(4); + var code5 = encoding.charCodeAt(5); + var code6 = encoding.charCodeAt(6); + if ((code0 === 85 || code0 === 117) && // u, U + (code1 === 84 || code1 === 116) && // t, T + (code2 === 70 || code2 === 102) && // f, F + code3 === 49 && // 1 + code4 === 54 && // 6 + (code5 === 76 || code5 === 108) && // l, L + (code6 === 69 || code6 === 101)) { // e, E + return true; + } + break; + case 8: // utf-16le + var code0 = encoding.charCodeAt(0); + var code1 = encoding.charCodeAt(1); + var code2 = encoding.charCodeAt(2); + var code3 = encoding.charCodeAt(3); + var code4 = encoding.charCodeAt(4); + var code5 = encoding.charCodeAt(5); + var code6 = encoding.charCodeAt(6); + var code7 = encoding.charCodeAt(7); + if ((code0 === 85 || code0 === 117) && // u, U + (code1 === 84 || code1 === 116) && // t, T + (code2 === 70 || code2 === 102) && // f, F + code3 === 45 && // - + code4 === 49 && // 1 + code5 === 54 && // 6 + (code6 === 76 || code6 === 108) && // l, L + (code7 === 69 || code7 === 101)) { // e, E + return true; + } + break; } -}; + return false; +}; Buffer.concat = function(list, length) { if (!Array.isArray(list)) diff --git a/test/parallel/test-buffer.js b/test/parallel/test-buffer.js index 8d42bea82d5e8c..eb40ecb9d70698 100644 --- a/test/parallel/test-buffer.js +++ b/test/parallel/test-buffer.js @@ -998,14 +998,17 @@ Buffer(Buffer(0), 0, 0); 'ucs-2', 'utf16le', 'utf-16le' ].forEach(function(enc) { - assert.equal(Buffer.isEncoding(enc), true); + assert.equal(Buffer.isEncoding(enc), true, `${enc} should be an encoding`); }); [ 'utf9', 'utf-7', + 'utf17le', + 'utf-17le', 'Unicode-FTW', 'new gnu gun' ].forEach(function(enc) { - assert.equal(Buffer.isEncoding(enc), false); + assert.equal(Buffer.isEncoding(enc), false, + `${enc} should not an encoding`); });