// File: hey-yahei[P]ConvNet/src/TarFile.cpp
// Function: TarFile::IsValidTarFile()
bool TarFile::IsValidTarFile()
{
	if (!file) return false;

	const int block_size{ 512 };
	unsigned char buf[block_size];
	tar_posix_header* header = (tar_posix_header*)buf;
	memset(buf, 0, block_size);

	fseek(file, 0, SEEK_END);
	size = ftell(file);
	fseek(file, 0, SEEK_SET);
	if (size % block_size != 0) {
		fprintf(stderr, "tar file size should be a multiple of 512 bytes: %d\n", size);
		return false;
	}

	size_t pos{ 0 };

	while (1) {
		size_t read_size = fread(buf, block_size, 1, file);
		if (read_size != 1) break;
		if (strncmp(header->magic, TMAGIC, 5)) break;

		pos += block_size;
		size_t file_size{ 0 };
		sscanf(header->size, "%lo", &file_size);
		size_t file_block_count = (file_size + block_size - 1) / block_size;

		switch (header->typeflag) {
		case '0': // intentionally dropping through
		case '\0':
			// normal file
			file_sizes.push_back(file_size);
			file_names.push_back(std::string(header->name));
			file_data_start_addrs.push_back(pos);
			break;
		case '1':
			// hard link
			break;
		case '2':
			// symbolic link
			break;
		case '3':
			// device file/special file
			break;
		case '4':
			// block device
			break;
		case '5':
			// directory
			break;
		case '6':
			// named pipe
			break;
		default:
			break;
		}

		pos += file_block_count * block_size;
		fseek(file, pos, SEEK_SET);
	}

	fseek(file, 0, SEEK_SET);

	return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2b0, %rsp            # imm = 0x2B0
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x288(%rbp)
cmpq $0x0, (%rax)
jne 0x91a9
movb $0x0, -0x1(%rbp)
jmp 0x9498
movl $0x200, -0x14(%rbp)     # imm = 0x200
leaq -0x220(%rbp), %rax
movq %rax, -0x228(%rbp)
leaq -0x220(%rbp), %rdi
xorl %esi, %esi
movl $0x200, %edx            # imm = 0x200
callq 0x2110
movq -0x288(%rbp), %rax
movq (%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x2, %edx
callq 0x2260
movq -0x288(%rbp), %rax
movq (%rax), %rdi
callq 0x2030
movq %rax, %rcx
movq -0x288(%rbp), %rax
movq %rcx, 0x8(%rax)
movq (%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x2260
movq -0x288(%rbp), %rax
movq 0x8(%rax), %rax
andq $0x1ff, %rax            # imm = 0x1FF
cmpq $0x0, %rax
je 0x9257
movq -0x288(%rbp), %rax
movq 0x8d97(%rip), %rcx      # 0x11fd0
movq (%rcx), %rdi
movq 0x8(%rax), %rdx
leaq 0x32c8(%rip), %rsi      # 0xc50f
movb $0x0, %al
callq 0x2300
movb $0x0, -0x1(%rbp)
jmp 0x9498
movq $0x0, -0x230(%rbp)
movq -0x288(%rbp), %rax
leaq -0x220(%rbp), %rdi
movq (%rax), %rcx
movl $0x200, %esi            # imm = 0x200
movl $0x1, %edx
callq 0x2330
movq %rax, -0x238(%rbp)
cmpq $0x1, -0x238(%rbp)
je 0x9298
jmp 0x947f
movq -0x228(%rbp), %rdi
addq $0x101, %rdi            # imm = 0x101
leaq 0x3297(%rip), %rsi      # 0xc544
movl $0x5, %edx
callq 0x20f0
cmpl $0x0, %eax
je 0x92c1
jmp 0x947f
movq -0x230(%rbp), %rax
addq $0x200, %rax            # imm = 0x200
movq %rax, -0x230(%rbp)
movq $0x0, -0x240(%rbp)
movq -0x228(%rbp), %rdi
addq $0x7c, %rdi
leaq 0x3258(%rip), %rsi      # 0xc54a
xorl %eax, %eax
leaq -0x240(%rbp), %rdx
callq 0x21b0
movq -0x240(%rbp), %rax
addq $0x1ff, %rax            # imm = 0x1FF
shrq $0x9, %rax
movq %rax, -0x248(%rbp)
movq -0x228(%rbp), %rax
movsbl 0x9c(%rax), %eax
movl %eax, %ecx
movq %rcx, -0x290(%rbp)
subl $0x36, %eax
ja 0x9447
movq -0x290(%rbp), %rax
leaq 0x30ea(%rip), %rcx      # 0xc430
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x288(%rbp), %rdi
addq $0x28, %rdi
leaq -0x240(%rbp), %rsi
callq 0x9940
movq -0x288(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x2a8(%rbp)
movq -0x228(%rbp), %rax
movq %rax, -0x2a0(%rbp)
leaq -0x269(%rbp), %rdi
movq %rdi, -0x298(%rbp)
callq 0x2380
movq -0x2a0(%rbp), %rsi
movq -0x298(%rbp), %rdx
leaq -0x268(%rbp), %rdi
callq 0x99e0
jmp 0x93b5
movq -0x2a8(%rbp), %rdi
leaq -0x268(%rbp), %rsi
callq 0x99b0
jmp 0x93ca
leaq -0x268(%rbp), %rdi
callq 0x2130
leaq -0x269(%rbp), %rdi
callq 0x2220
movq -0x288(%rbp), %rdi
addq $0x40, %rdi
leaq -0x230(%rbp), %rsi
callq 0x9940
jmp 0x9449
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x278(%rbp)
movl %eax, -0x27c(%rbp)
jmp 0x942d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x278(%rbp)
movl %eax, -0x27c(%rbp)
leaq -0x268(%rbp), %rdi
callq 0x2130
leaq -0x269(%rbp), %rdi
callq 0x2220
jmp 0x94a6
jmp 0x9449
jmp 0x9449
jmp 0x9449
jmp 0x9449
jmp 0x9449
jmp 0x9449
jmp 0x9449
movq -0x288(%rbp), %rax
movq -0x248(%rbp), %rcx
shlq $0x9, %rcx
addq -0x230(%rbp), %rcx
movq %rcx, -0x230(%rbp)
movq (%rax), %rdi
movq -0x230(%rbp), %rsi
xorl %edx, %edx
callq 0x2260
jmp 0x9262
movq -0x288(%rbp), %rax
movq (%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x2260
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x2b0, %rsp            # imm = 0x2B0
popq %rbp
retq
movq -0x278(%rbp), %rdi
callq 0x2370
nopw %cs:(%rax,%rax)