function byteLength (string) { let length = 0 for (let i = 0, n = string.length; i < n; i++) { const code = string.charCodeAt(i) if (code >= 0xd800 && code <= 0xdbff && i + 1 < n) { const code = string.charCodeAt(i + 1) if (code >= 0xdc00 && code <= 0xdfff) { length += 4 i++ continue } } if (code <= 0x7f) length += 1 else if (code <= 0x7ff) length += 2 else length += 3 } return length } let toString if (typeof TextDecoder !== 'undefined') { const decoder = new TextDecoder() toString = function toString (buffer) { return decoder.decode(buffer) } } else { toString = function toString (buffer) { const len = buffer.byteLength let output = '' let i = 0 while (i < len) { let byte = buffer[i] if (byte <= 0x7f) { output += String.fromCharCode(byte) i++ continue } let bytesNeeded = 0 let codePoint = 0 if (byte <= 0xdf) { bytesNeeded = 1 codePoint = byte & 0x1f } else if (byte <= 0xef) { bytesNeeded = 2 codePoint = byte & 0x0f } else if (byte <= 0xf4) { bytesNeeded = 3 codePoint = byte & 0x07 } if (len - i - bytesNeeded > 0) { let k = 0 while (k < bytesNeeded) { byte = buffer[i + k + 1] codePoint = (codePoint << 6) | (byte & 0x3f) k += 1 } } else { codePoint = 0xfffd bytesNeeded = len - i } output += String.fromCodePoint(codePoint) i += bytesNeeded + 1 } return output } } let write if (typeof TextEncoder !== 'undefined') { const encoder = new TextEncoder() write = function write (buffer, string, offset = 0, length = byteLength(string)) { const len = Math.min(length, buffer.byteLength - offset) encoder.encodeInto(string, buffer.subarray(offset, offset + len)) return len } } else { write = function write (buffer, string, offset = 0, length = byteLength(string)) { const len = Math.min(length, buffer.byteLength - offset) buffer = buffer.subarray(offset, offset + len) let i = 0 let j = 0 while (i < string.length) { const code = string.codePointAt(i) if (code <= 0x7f) { buffer[j++] = code i++ continue } let count = 0 let bits = 0 if (code <= 0x7ff) { count = 6 bits = 0xc0 } else if (code <= 0xffff) { count = 12 bits = 0xe0 } else if (code <= 0x1fffff) { count = 18 bits = 0xf0 } buffer[j++] = bits | (code >> count) count -= 6 while (count >= 0) { buffer[j++] = 0x80 | ((code >> count) & 0x3f) count -= 6 } i += code >= 0x10000 ? 2 : 1 } return len } } module.exports = { byteLength, toString, write }