fast-text-encoding
Advanced tools
Comparing version 1.0.0 to 1.0.1
{ | ||
"name": "fast-text-encoding", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "Fast polyfill for TextEncoder and TextDecoder, only supports utf-8", | ||
@@ -8,3 +8,7 @@ "main": "text.min.js", | ||
"author": "Sam Thorogood <sam.thorogood@gmail.com>", | ||
"license": "Apache-2" | ||
"license": "Apache-2", | ||
"devDependencies": { | ||
"chai": "^4.2.0", | ||
"mocha": "^7.1.0" | ||
} | ||
} |
@@ -35,2 +35,5 @@ This is a fast polyfill for [`TextEncoder`][1] and [`TextDecoder`][2], which let you encode and decode JavaScript strings into UTF-8 bytes. | ||
However, note that `Buffer.from('Turn me into UTF-8!')` is Node's native version of the text encoding functionality. | ||
You can probably massage [`Buffer`](https://nodejs.org/api/buffer.html) into acting like `TextEncoder` and `TextDecoder`. | ||
# Supports | ||
@@ -52,2 +55,2 @@ | ||
// code here | ||
``` | ||
``` |
71
text.js
@@ -31,11 +31,11 @@ /* | ||
// used for FastTextDecoder | ||
const validUtfLabels = ['utf-8', 'utf8', 'unicode-1-1-utf-8']; | ||
/** | ||
* @constructor | ||
* @param {string=} utfLabel | ||
*/ | ||
function FastTextEncoder(utfLabel='utf-8') { | ||
if (utfLabel !== 'utf-8') { | ||
throw new RangeError( | ||
`Failed to construct 'TextEncoder': The encoding label provided ('${utfLabel}') is invalid.`); | ||
} | ||
function FastTextEncoder() { | ||
// This does not accept an encoding, and always uses UTF-8: | ||
// https://www.w3.org/TR/encoding/#dom-textencoder | ||
} | ||
@@ -57,3 +57,2 @@ | ||
const len = string.length; | ||
const out = []; | ||
@@ -111,3 +110,5 @@ let at = 0; // output position | ||
return target.slice(0, at); | ||
// Use subarray if slice isn't supported (IE11). This will use more memory | ||
// because the original array still exists. | ||
return target.slice ? target.slice(0, at) : target.subarray(0, at); | ||
} | ||
@@ -121,3 +122,3 @@ | ||
function FastTextDecoder(utfLabel='utf-8', options={fatal: false}) { | ||
if (utfLabel !== 'utf-8') { | ||
if (validUtfLabels.indexOf(utfLabel.toLowerCase()) == -1) { | ||
throw new RangeError( | ||
@@ -140,2 +141,3 @@ `Failed to construct 'TextDecoder': The encoding label provided ('${utfLabel}') is invalid.`); | ||
* @param {{stream: boolean}=} options | ||
* @return {string} | ||
*/ | ||
@@ -147,22 +149,45 @@ FastTextDecoder.prototype.decode = function(buffer, options={stream: false}) { | ||
const bytes = new Uint8Array(buffer); | ||
// Look for ArrayBufferView, which isn't a real type, but basically represents | ||
// all the valid TypedArray types plus DataView. They all have ".buffer" as | ||
// an instance of ArrayBuffer. | ||
if (buffer.buffer instanceof ArrayBuffer) { | ||
buffer = buffer.buffer; | ||
} | ||
let bytes = new Uint8Array(buffer); | ||
let pos = 0; | ||
const len = bytes.length; | ||
const out = []; | ||
let pending = []; | ||
const chunks = []; | ||
while (pos < len) { | ||
for (;;) { | ||
const more = pos < bytes.length; | ||
// If there's no more data or we're >65k bytes, create a chunk. | ||
// This isn't done at the end by simply slicing the data into equal sized | ||
// chunks as we might hit a surrogate pair. | ||
if (!more || (pos & 0x10000)) { | ||
chunks.push(String.fromCharCode.apply(null, pending)); | ||
if (!more) { | ||
return chunks.join(''); | ||
} | ||
// Move the buffer forward and create another chunk. | ||
pending = []; | ||
bytes = bytes.subarray(pos); | ||
pos = 0; | ||
} | ||
const byte1 = bytes[pos++]; | ||
if (byte1 === 0) { | ||
break; // NULL | ||
} | ||
if ((byte1 & 0x80) === 0) { // 1-byte | ||
out.push(byte1); | ||
pending.push(0); | ||
} else if ((byte1 & 0x80) === 0) { // 1-byte | ||
pending.push(byte1); | ||
} else if ((byte1 & 0xe0) === 0xc0) { // 2-byte | ||
const byte2 = bytes[pos++] & 0x3f; | ||
out.push(((byte1 & 0x1f) << 6) | byte2); | ||
pending.push(((byte1 & 0x1f) << 6) | byte2); | ||
} else if ((byte1 & 0xf0) === 0xe0) { | ||
const byte2 = bytes[pos++] & 0x3f; | ||
const byte3 = bytes[pos++] & 0x3f; | ||
out.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3); | ||
pending.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3); | ||
} else if ((byte1 & 0xf8) === 0xf0) { | ||
@@ -178,6 +203,6 @@ const byte2 = bytes[pos++] & 0x3f; | ||
codepoint -= 0x10000; | ||
out.push((codepoint >>> 10) & 0x3ff | 0xd800) | ||
pending.push((codepoint >>> 10) & 0x3ff | 0xd800); | ||
codepoint = 0xdc00 | codepoint & 0x3ff; | ||
} | ||
out.push(codepoint); | ||
pending.push(codepoint); | ||
} else { | ||
@@ -187,4 +212,2 @@ // FIXME: we're ignoring this | ||
} | ||
return String.fromCharCode.apply(null, out); | ||
} | ||
@@ -191,0 +214,0 @@ |
@@ -1,5 +0,5 @@ | ||
(function(l){function m(b){b=void 0===b?"utf-8":b;if("utf-8"!==b)throw new RangeError("Failed to construct 'TextEncoder': The encoding label provided ('"+b+"') is invalid.");}function k(b,a){b=void 0===b?"utf-8":b;a=void 0===a?{fatal:!1}:a;if("utf-8"!==b)throw new RangeError("Failed to construct 'TextDecoder': The encoding label provided ('"+b+"') is invalid.");if(a.fatal)throw Error("Failed to construct 'TextDecoder': the 'fatal' option is unsupported.");}if(l.TextEncoder&&l.TextDecoder)return!1; | ||
Object.defineProperty(m.prototype,"encoding",{value:"utf-8"});m.prototype.encode=function(b,a){a=void 0===a?{stream:!1}:a;if(a.stream)throw Error("Failed to encode: the 'stream' option is unsupported.");a=0;for(var h=b.length,f=0,c=Math.max(32,h+(h>>1)+7),e=new Uint8Array(c>>3<<3);a<h;){var d=b.charCodeAt(a++);if(55296<=d&&56319>=d){if(a<h){var g=b.charCodeAt(a);56320===(g&64512)&&(++a,d=((d&1023)<<10)+(g&1023)+65536)}if(55296<=d&&56319>=d)continue}f+4>e.length&&(c+=8,c*=1+a/b.length*2,c=c>>3<<3, | ||
g=new Uint8Array(c),g.set(e),e=g);if(0===(d&4294967168))e[f++]=d;else{if(0===(d&4294965248))e[f++]=d>>6&31|192;else if(0===(d&4294901760))e[f++]=d>>12&15|224,e[f++]=d>>6&63|128;else if(0===(d&4292870144))e[f++]=d>>18&7|240,e[f++]=d>>12&63|128,e[f++]=d>>6&63|128;else continue;e[f++]=d&63|128}}return e.slice(0,f)};Object.defineProperty(k.prototype,"encoding",{value:"utf-8"});Object.defineProperty(k.prototype,"fatal",{value:!1});Object.defineProperty(k.prototype,"ignoreBOM",{value:!1});k.prototype.decode= | ||
function(b,a){a=void 0===a?{stream:!1}:a;if(a.stream)throw Error("Failed to decode: the 'stream' option is unsupported.");b=new Uint8Array(b);a=0;for(var h=b.length,f=[];a<h;){var c=b[a++];if(0===c)break;if(0===(c&128))f.push(c);else if(192===(c&224)){var e=b[a++]&63;f.push((c&31)<<6|e)}else if(224===(c&240)){e=b[a++]&63;var d=b[a++]&63;f.push((c&31)<<12|e<<6|d)}else if(240===(c&248)){e=b[a++]&63;d=b[a++]&63;var g=b[a++]&63;c=(c&7)<<18|e<<12|d<<6|g;65535<c&&(c-=65536,f.push(c>>>10&1023|55296),c=56320| | ||
c&1023);f.push(c)}}return String.fromCharCode.apply(null,f)};l.TextEncoder=m;l.TextDecoder=k})("undefined"!==typeof window?window:"undefined"!==typeof global?global:this); | ||
(function(l){function m(){}function k(b,a){b=void 0===b?"utf-8":b;a=void 0===a?{fatal:!1}:a;if(-1==n.indexOf(b.toLowerCase()))throw new RangeError("Failed to construct 'TextDecoder': The encoding label provided ('"+b+"') is invalid.");if(a.fatal)throw Error("Failed to construct 'TextDecoder': the 'fatal' option is unsupported.");}if(l.TextEncoder&&l.TextDecoder)return!1;var n=["utf-8","utf8","unicode-1-1-utf-8"];Object.defineProperty(m.prototype,"encoding",{value:"utf-8"});m.prototype.encode=function(b, | ||
a){a=void 0===a?{stream:!1}:a;if(a.stream)throw Error("Failed to encode: the 'stream' option is unsupported.");a=0;for(var g=b.length,f=0,c=Math.max(32,g+(g>>1)+7),e=new Uint8Array(c>>3<<3);a<g;){var d=b.charCodeAt(a++);if(55296<=d&&56319>=d){if(a<g){var h=b.charCodeAt(a);56320===(h&64512)&&(++a,d=((d&1023)<<10)+(h&1023)+65536)}if(55296<=d&&56319>=d)continue}f+4>e.length&&(c+=8,c*=1+a/b.length*2,c=c>>3<<3,h=new Uint8Array(c),h.set(e),e=h);if(0===(d&4294967168))e[f++]=d;else{if(0===(d&4294965248))e[f++]= | ||
d>>6&31|192;else if(0===(d&4294901760))e[f++]=d>>12&15|224,e[f++]=d>>6&63|128;else if(0===(d&4292870144))e[f++]=d>>18&7|240,e[f++]=d>>12&63|128,e[f++]=d>>6&63|128;else continue;e[f++]=d&63|128}}return e.slice?e.slice(0,f):e.subarray(0,f)};Object.defineProperty(k.prototype,"encoding",{value:"utf-8"});Object.defineProperty(k.prototype,"fatal",{value:!1});Object.defineProperty(k.prototype,"ignoreBOM",{value:!1});k.prototype.decode=function(b,a){a=void 0===a?{stream:!1}:a;if(a.stream)throw Error("Failed to decode: the 'stream' option is unsupported."); | ||
b.buffer instanceof ArrayBuffer&&(b=b.buffer);b=new Uint8Array(b);a=0;for(var g=[],f=[];;){var c=a<b.length;if(!c||a&65536){f.push(String.fromCharCode.apply(null,g));if(!c)return f.join("");g=[];b=b.subarray(a);a=0}c=b[a++];if(0===c)g.push(0);else if(0===(c&128))g.push(c);else if(192===(c&224)){var e=b[a++]&63;g.push((c&31)<<6|e)}else if(224===(c&240)){e=b[a++]&63;var d=b[a++]&63;g.push((c&31)<<12|e<<6|d)}else if(240===(c&248)){e=b[a++]&63;d=b[a++]&63;var h=b[a++]&63;c=(c&7)<<18|e<<12|d<<6|h;65535< | ||
c&&(c-=65536,g.push(c>>>10&1023|55296),c=56320|c&1023);g.push(c)}}};l.TextEncoder=m;l.TextDecoder=k})("undefined"!==typeof window?window:"undefined"!==typeof global?global:this); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
28406
273
55
2
7