Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | 33x 33x 6x 6x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 6x 6x 6x 6x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 5120x 10x 10x 6x | import { PassThrough } from 'stream' export class TarStream { output = new PassThrough() currentFileSize = 0 beginFile(path: string, size: number) { Iif (path.length > 100) { throw new Error(`File name too long: ${path}`) } const header = createHeader(path, size) this.output.write(header) this.currentFileSize = 0 } async appendFile(data: Uint8Array) { return new Promise<void>(resolve => { Iif (!this.output.write(data)) { this.output.once('drain', () => { resolve() }) } else { resolve() } this.currentFileSize += data.length }) } async endFile() { const padding = this.currentFileSize % 512 === 0 ? 0 : 512 - (this.currentFileSize % 512) if (padding > 0) { this.output.write(Buffer.alloc(padding, 0)) } } async end() { return new Promise<void>(resolve => { this.output.write(createEndOfArchive()) this.output.end(() => { resolve() }) }) } } function createHeader(path: string, size: number): Uint8Array { // Initialize header with zeros const header = Buffer.alloc(512, 0) // File name, truncated to 100 characters if necessary header.write(path.slice(0, 100).padEnd(100, '\0'), 0, 100) // File mode (octal) and null-terminated header.write('0000777\0', 100, 8) // UID and GID (octal) and null-terminated header.write('0001750\0', 108, 8) // UID header.write('0001750\0', 116, 8) // GID // File size in octal (11 chars) and null-terminated header.write(size.toString(8).padStart(11, '0') + '\0', 124, 12) // Modification time in octal and null-terminated const modTime = Math.floor(new Date().getTime() / 1000) header.write(modTime.toString(8).padStart(11, '0') + '\0', 136, 12) // Checksum placeholder (8 spaces) header.write(' ', 148, 8) // Typeflag (normal file) header.write('0', 156, 1) // USTAR magic and version header.write('ustar\0\0', 257, 8) // Calculate checksum let checksum = 0 for (let i = 0; i < 512; i++) { checksum += header[i] } header.write(checksum.toString(8).padStart(6, '0') + '\0 ', 148, 8) return header } function createEndOfArchive(): Uint8Array { return Buffer.alloc(1024, 0) } |