Skip to content

Instantly share code, notes, and snippets.

@amsul
Created March 14, 2019 02:51
Show Gist options
  • Save amsul/101a9c1c00597ab96e0b23cf649d50cb to your computer and use it in GitHub Desktop.
Save amsul/101a9c1c00597ab96e0b23cf649d50cb to your computer and use it in GitHub Desktop.
Convert a string to an array buffer with JavaScript
// Modified from https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder#Polyfill
function stringToBuffer(str) {
'use strict'
let Len = str.length,
resPos = -1
// The Uint8Array's length must be at least 3x the length of the string because an invalid UTF-16
// takes up the equivalent space of 3 UTF-8 characters to encode it properly.
let resArr = new Uint8Array(Len * 3)
for (let point = 0, nextcode = 0, i = 0; i !== Len; ) {
point = str.charCodeAt(i)
i += 1
if (point >= 0xd800 && point <= 0xdbff) {
if (i === Len) {
resArr[(resPos += 1)] = 0xef /*0b11101111*/
resArr[(resPos += 1)] = 0xbf /*0b10111111*/
resArr[(resPos += 1)] = 0xbd /*0b10111101*/
break
}
// https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
nextcode = str.charCodeAt(i)
if (nextcode >= 0xdc00 && nextcode <= 0xdfff) {
point = (point - 0xd800) * 0x400 + nextcode - 0xdc00 + 0x10000
i += 1
if (point > 0xffff) {
resArr[(resPos += 1)] = (0x1e /*0b11110*/ << 3) | (point >>> 18)
resArr[(resPos += 1)] =
(0x2 /*0b10*/ << 6) | ((point >>> 12) & 0x3f) /*0b00111111*/
resArr[(resPos += 1)] =
(0x2 /*0b10*/ << 6) | ((point >>> 6) & 0x3f) /*0b00111111*/
resArr[(resPos += 1)] =
(0x2 /*0b10*/ << 6) | (point & 0x3f) /*0b00111111*/
continue
}
} else {
resArr[(resPos += 1)] = 0xef /*0b11101111*/
resArr[(resPos += 1)] = 0xbf /*0b10111111*/
resArr[(resPos += 1)] = 0xbd /*0b10111101*/
continue
}
}
if (point <= 0x007f) {
resArr[(resPos += 1)] = (0x0 /*0b0*/ << 7) | point
} else if (point <= 0x07ff) {
resArr[(resPos += 1)] = (0x6 /*0b110*/ << 5) | (point >>> 6)
resArr[(resPos += 1)] =
(0x2 /*0b10*/ << 6) | (point & 0x3f) /*0b00111111*/
} else {
resArr[(resPos += 1)] = (0xe /*0b1110*/ << 4) | (point >>> 12)
resArr[(resPos += 1)] =
(0x2 /*0b10*/ << 6) | ((point >>> 6) & 0x3f) /*0b00111111*/
resArr[(resPos += 1)] =
(0x2 /*0b10*/ << 6) | (point & 0x3f) /*0b00111111*/
}
}
return resArr.subarray(0, resPos + 1)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment