TextEncoder/TextDecoder polyfills for utf-8
// TextEncoder/TextDecoder polyfills for utf-8 - an implementation of TextEncoder/TextDecoder APIs
// To the extent possible under law, the author(s) have dedicated all copyright and related and neigring rights to this software to the public domain worldwide. This software is distributed without any warranty.
// You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
// Some important notes about the polyfill below:
// Native TextEncoder/TextDecoder implementation is overwritten
// String..codePointAt polyfill not included, as well as String.fromCodePoint
// TextEncoder..encode returns a regular array instead of Uint8Array
// No options (fatal of the TextDecoder constructor and stream of the TextDecoder..decode method) are supported.
// TextDecoder..decode does not valid byte sequences
// This is a demonstrative implementation not intended to have the best performance
// http://encoding.spec.whatwg.org/#textencoder
// http://encoding.spec.whatwg.org/#textencoder
function TextEncoder() {
}
TextEncoder..encode = function (string) {
var octets = [];
var length = string.length;
var i = 0;
while (i < length) {
var codePoint = string.codePointAt(i);
var c = 0;
var bits = 0;
if (codePoint <= 0x0000007F) {
c = 0;
bits = 0x00;
} else if (codePoint <= 0x000007FF) {
c = 6;
bits = 0xC0;
} else if (codePoint <= 0x0000FFFF) {
c = 12;
bits = 0xE0;
} else if (codePoint <= 0x001FFFFF) {
c = 18;
bits = 0xF0;
}
octets.push(bits | (codePoint >> c));
c -= 6;
while (c >= 0) {
octets.push(0x80 | ((codePoint >> c) & 0x3F));
c -= 6;
}
i += codePoint >= 0x10000 ? 2 : 1;
}
return octets;
};
function TextDecoder() {
}
TextDecoder..decode = function (octets) {
var string = "";
var i = 0;
while (i < octets.length) {
var octet = octets[i];
var bytesNeeded = 0;
var codePoint = 0;
if (octet <= 0x7F) {
bytesNeeded = 0;
codePoint = octet & 0xFF;
} else if (octet <= 0xDF) {
bytesNeeded = 1;
codePoint = octet & 0x1F;
} else if (octet <= 0xEF) {
bytesNeeded = 2;
codePoint = octet & 0x0F;
} else if (octet <= 0xF4) {
bytesNeeded = 3;
codePoint = octet & 0x07;
}
if (octets.length - i - bytesNeeded > 0) {
var k = 0;
while (k < bytesNeeded) {
octet = octets[i + k + 1];
codePoint = (codePoint << 6) | (octet & 0x3F);
k += 1;
}
} else {
codePoint = 0xFFFD;
bytesNeeded = octets.length - i;
}
string += String.fromCodePoint(codePoint);
i += bytesNeeded + 1;
}
return string
};
@agnivade

Hi, can you please attach a license to this code ? We would like to use it in the Go project here - https://go-review.googlesource.com/c/go/+/131718.

@anonyco

These are not polyfills. They do not provide standards-compliant behavior and overwrite the native implementation when TextEncoder/TextDecoder are natively supported.

@Yaffle

@anonyco, The work to not overwrite the native is "left to the readers as an exercise".
The behavior is almost standard-compliant. The decoding/encoding is good enough, the options are not supported (but old Firefox does not support them as well), the result is an array, not typed array/view.

@anonyco

Please at least include the following disclaimer in a comment at the top of the code:

  • Native TextEncoder/TextDecoder implementation is overwritten
  • String..codePointAt polyfill not included
  • TextEncoder..encode returns a regular array instead of Uint8Array
  • This is a demonstrative implementation not intended to have the best performance

Nobody likes disclaimers about their code, but disclaimers help prevent code from being misused and people from being misled.

Please also switch from the Unlicense to CC0: https://creativecommons.org/2011/04/15/plaintext-versions-of-creative-commons-licenses-and-cc0/. Both licenses have the same intentions, but there is a big difference: CC0 is battle-tested, thorough, and recognized everywhere, whereas the Unlicense is rather vague, untested, and not universally recognized.

Thank you.

@Yaffle

@anonyco, OK, thanks

@anonyco

Thank you so much. You are doing a great service for people inexperienced with JavaScript who are trying to feel their way around. I just want to suggest not calling them "issues." That word has negative connotations. One man's "issue" can be another man's treasure, so please do something like

    // Some important notes about the polyfill below:
    // N.B. that
    // Ponies to watch out for:

Thank you.

@Yaffle

@anonyco, thank you

@prldm

huge thanks

Sign up for free to join this conversation on . Already have an account? Sign in to comment