| 1586 | // Partially decompress a gzip-encoded Uint8Array, returning a Uint8Array of |
| 1587 | // the specified numBytes from the start of the file. |
| 1588 | export function decompressPartialGzip( |
| 1589 | fileBytes: Uint8Array, |
| 1590 | numBytes: number, |
| 1591 | ): Uint8Array { |
| 1592 | const chunks: Uint8Array[] = []; |
| 1593 | let totalBytes = 0; |
| 1594 | let result: Uint8Array | null = null; |
| 1595 | |
| 1596 | const gunzip = new Gunzip((data, final) => { |
| 1597 | chunks.push(data); |
| 1598 | totalBytes += data.length; |
| 1599 | if (final || totalBytes >= numBytes) { |
| 1600 | const allBytes = new Uint8Array(totalBytes); |
| 1601 | let offset = 0; |
| 1602 | for (const chunk of chunks) { |
| 1603 | allBytes.set(chunk, offset); |
| 1604 | offset += chunk.length; |
| 1605 | } |
| 1606 | result = allBytes.slice(0, numBytes); |
| 1607 | } |
| 1608 | }); |
| 1609 | |
| 1610 | const CHUNK_SIZE = 1024; |
| 1611 | let offset = 0; |
| 1612 | while (result == null && offset < fileBytes.length) { |
| 1613 | const chunk = fileBytes.slice(offset, offset + CHUNK_SIZE); |
| 1614 | gunzip.push(chunk, false); |
| 1615 | offset += CHUNK_SIZE; |
| 1616 | } |
| 1617 | |
| 1618 | if (result == null) { |
| 1619 | gunzip.push(new Uint8Array(), true); |
| 1620 | if (result == null) { |
| 1621 | throw new Error("Failed to decompress partial gzip"); |
| 1622 | } |
| 1623 | } |
| 1624 | return result; |
| 1625 | } |
| 1626 | |
| 1627 | export class GunzipReader { |
| 1628 | fileBytes: Uint8Array; |