(buffer: ArrayBuffer)
| 25 | * isolate. |
| 26 | */ |
| 27 | export function arrayBufferToBase64(buffer: ArrayBuffer): string { |
| 28 | const bytes = new Uint8Array(buffer) |
| 29 | |
| 30 | const fast = (bytes as Uint8ArrayInstanceWithBase64).toBase64 |
| 31 | if (typeof fast === 'function') { |
| 32 | return fast.call(bytes) |
| 33 | } |
| 34 | |
| 35 | if (typeof Buffer !== 'undefined' && typeof Buffer.from === 'function') { |
| 36 | return Buffer.from(buffer).toString('base64') |
| 37 | } |
| 38 | |
| 39 | if (typeof btoa === 'function') { |
| 40 | let binary = '' |
| 41 | // 32KB chunks keep us well under V8's argument-count limits for |
| 42 | // String.fromCharCode.apply on large buffers. |
| 43 | const chunkSize = 0x8000 |
| 44 | for (let i = 0; i < bytes.length; i += chunkSize) { |
| 45 | const chunk = bytes.subarray(i, i + chunkSize) |
| 46 | binary += String.fromCharCode.apply( |
| 47 | null, |
| 48 | // eslint-disable-next-line no-restricted-syntax -- TS lib types String.fromCharCode.apply as Array<number> but runtime accepts any ArrayLike |
| 49 | chunk as unknown as Array<number>, |
| 50 | ) |
| 51 | } |
| 52 | return btoa(binary) |
| 53 | } |
| 54 | |
| 55 | throw new Error('No base64 encoder available in this environment.') |
| 56 | } |
| 57 | |
| 58 | /** |
| 59 | * Decode a base64 string into an `ArrayBuffer`. |
no test coverage detected