| 36 | } |
| 37 | |
| 38 | function encodeUTF16(str: string, littleEndian: boolean, addBOM = false) { |
| 39 | // count code units |
| 40 | const codepoints = Array.from(str); |
| 41 | // worst case 2 units per code point |
| 42 | const buf = new ArrayBuffer((codepoints.length * 2 + (addBOM ? 2 : 0))); |
| 43 | const dv = new DataView(buf); |
| 44 | let offset = 0; |
| 45 | if (addBOM) { |
| 46 | dv.setUint16(0, littleEndian ? 0xFF_FE : 0xFE_FF, false); |
| 47 | offset += 2; |
| 48 | } |
| 49 | for (const ch of codepoints) { |
| 50 | const cp = ch.codePointAt(0) || 0; |
| 51 | if (cp <= 0xffff) { |
| 52 | dv.setUint16(offset, cp, littleEndian); |
| 53 | offset += 2; |
| 54 | } else { |
| 55 | const v = cp - 0x10000; |
| 56 | const hi = 0xd800 + (v >> 10); |
| 57 | const lo = 0xdc00 + (v & 0x3ff); |
| 58 | dv.setUint16(offset, hi, littleEndian); |
| 59 | dv.setUint16(offset + 2, lo, littleEndian); |
| 60 | offset += 4; |
| 61 | } |
| 62 | } |
| 63 | return new Uint8Array(buf, 0, offset); |
| 64 | } |
| 65 | |
| 66 | function encodeUTF32(str: string, littleEndian: boolean, addBOM = false) { |
| 67 | const codepoints = Array.from(str, (ch) => ch.codePointAt(0) || 0); |