| 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 | |
| } | |