// File: lrq3000[P]rfrb/./src/fileHandler.cpp
// Function: FileHandler::FileHandler(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
FileHandler::FileHandler(std::string inputFolder, std::string outputFolder)
{
	inFolder = inputFolder;
	outFolder = outputFolder;
	std::vector<std::string> imgs;

	//Get all files in the input folder for windows and unix
#ifdef WINDOWS
	HANDLE dir;
	WIN32_FIND_DATA file_data;

	if ((dir = FindFirstFile((directory + "/*").c_str(), &file_data)) == INVALID_HANDLE_VALUE)
	{
		std::cerr << "Couldn't find any files in directory " << inputFolder << std::endl;
		exit(EXIT_FAILURE);
	}
	do {
		const string file_name = file_data.cFileName;
		const string full_file_name = directory + "/" + file_name;
		const bool is_directory = (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;

		if (file_name[0] == '.')
			continue;
		if (is_directory)
			continue;
		imgs.push_back(full_file_name);
	} while (FindNextFile(dir, &file_data));

	FindClose(dir);
#else
	DIR *dpdf;
	struct dirent *epdf;
	dpdf = opendir(inputFolder.c_str());
	if (dpdf != NULL)
	{
		while ((epdf=readdir(dpdf))!=NULL)
		{
			if (epdf->d_name[0] == '.')
				continue;
			if (epdf->d_type == DT_REG)
			{
				std::string tmp = inputFolder+epdf->d_name;
				std::cout << tmp << std::endl;
				imgs.push_back(tmp);
			}
		}
	}
#endif

	//Error
	if (imgs.empty())
	{
		std::cerr << "No valid directory or no valid datas in directory." << std::endl;
		exit(EXIT_FAILURE);
	}

	//Initial values are set
	maxBufferSize = (BUFLENGTH/(imgs.size()+0))/2*2;
	size_t realLength=0;
	size_t counter=0;
	while (maxBufferSize != 0)
	{
		maxBufferSize = maxBufferSize >> 1;
		++counter;
	}
	counter-=1;
	realLength = std::pow(2,counter);
	maxBufferSize = std::min(realLength, 16lu*1024lu*1024lu);
	std::cout << "Image-Buffers:\t" << maxBufferSize/1024/1024 << "MB" << std::endl;

	//Calculate MD5Sum, if it is not windows, and initialize the fileReaders and the fileWriter
	for (unsigned int i = 0; i < imgs.size(); ++i)
	{
#ifndef WINDOWS
		std::string sys = "md5sum ";
		sys += imgs.at(i);
		std::cout << std::endl;
		std::cout << "Hash5 for " << imgs.at(i) << ":" << std::endl;
		if (system(sys.c_str()))
		{}
		std::cout << std::endl;
#endif
		FileReader *a = new FileReader(imgs.at(i),maxBufferSize);
		inFiles.push_back(a);
	}
	writer = new FileWriter(outFolder+"recoveredImage.dd",maxBufferSize);
}

// Assembly:
subq $0x1e8, %rsp            # imm = 0x1E8
movq %rsi, 0xd0(%rsp)
movq %rdx, 0xa8(%rsp)
movq %rdi, 0x1e0(%rsp)
movq %rsi, 0x1d8(%rsp)
movq %rdx, 0x1d0(%rsp)
movq 0x1e0(%rsp), %rdi
movq %rdi, 0xc8(%rsp)
movq %rdi, %rax
movq %rax, 0xb0(%rsp)
callq 0x65c0
movq 0xc8(%rsp), %rdi
addq $0x20, %rdi
movq %rdi, 0xb8(%rsp)
callq 0x65c0
movq 0xc8(%rsp), %rdi
addq $0x40, %rdi
movq %rdi, 0xc0(%rsp)
callq 0x18e50
movq 0xc8(%rsp), %rdi
movq 0xd0(%rsp), %rsi
callq 0x6050
jmp 0xc498
movq 0xa8(%rsp), %rsi
movq 0xb0(%rsp), %rdi
addq $0x20, %rdi
callq 0x6050
jmp 0xc4b3
leaq 0x1a8(%rsp), %rdi
callq 0x18ef0
movq 0xd0(%rsp), %rdi
callq 0x6180
movq %rax, %rdi
callq 0x6630
movq %rax, 0xa0(%rsp)
jmp 0xc4df
movq 0xa0(%rsp), %rax
movq %rax, 0x1a0(%rsp)
cmpq $0x0, 0x1a0(%rsp)
je 0xc635
jmp 0xc500
movq 0x1a0(%rsp), %rdi
callq 0x6650
movq %rax, 0x98(%rsp)
jmp 0xc517
movq 0x98(%rsp), %rax
movq %rax, 0x198(%rsp)
cmpq $0x0, %rax
je 0xc633
movq 0x198(%rsp), %rax
movsbl 0x13(%rax), %eax
cmpl $0x2e, %eax
jne 0xc576
jmp 0xc500
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1c8(%rsp)
movl %eax, 0x1c4(%rsp)
jmp 0xcbc4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1c8(%rsp)
movl %eax, 0x1c4(%rsp)
jmp 0xcbb7
movq 0x198(%rsp), %rax
movzbl 0x12(%rax), %eax
cmpl $0x8, %eax
jne 0xc62e
movq 0xd0(%rsp), %rsi
movq 0x198(%rsp), %rdx
addq $0x13, %rdx
leaq 0x178(%rsp), %rdi
callq 0x18e60
jmp 0xc5ae
movq 0x479fb(%rip), %rdi     # 0x53fb0
leaq 0x178(%rsp), %rsi
callq 0x6390
movq %rax, 0x90(%rsp)
jmp 0xc5cc
movq 0x90(%rsp), %rdi
movq 0x47995(%rip), %rsi     # 0x53f70
callq 0x6470
jmp 0xc5e2
leaq 0x1a8(%rsp), %rdi
leaq 0x178(%rsp), %rsi
callq 0x18f00
jmp 0xc5f9
leaq 0x178(%rsp), %rdi
callq 0x6260
jmp 0xc62e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1c8(%rsp)
movl %eax, 0x1c4(%rsp)
leaq 0x178(%rsp), %rdi
callq 0x6260
jmp 0xcbb7
jmp 0xc500
jmp 0xc635
leaq 0x1a8(%rsp), %rdi
callq 0x18f70
testb $0x1, %al
jne 0xc648
jmp 0xc685
movq 0x479a1(%rip), %rdi     # 0x53ff0
leaq 0x2ec65(%rip), %rsi     # 0x3b2bb
callq 0x6420
movq %rax, 0x88(%rsp)
jmp 0xc665
movq 0x88(%rsp), %rdi
movq 0x478fc(%rip), %rsi     # 0x53f70
callq 0x6470
jmp 0xc67b
movl $0x1, %edi
callq 0x6500
leaq 0x1a8(%rsp), %rdi
callq 0x18fc0
movq %rax, %rcx
addq $0x0, %rcx
movl $0x40000000, %eax       # imm = 0x40000000
xorl %edx, %edx
divq %rcx
shrq %rax
shlq %rax
movl %eax, 0x47dd9(%rip)     # 0x54488
movq $0x0, 0x170(%rsp)
movq $0x0, 0x168(%rsp)
cmpl $0x0, 0x47dba(%rip)     # 0x54488
je 0xc6f4
movl 0x47db2(%rip), %eax     # 0x54488
sarl %eax
movl %eax, 0x47daa(%rip)     # 0x54488
movq 0x168(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x168(%rsp)
jmp 0xc6c7
movq 0x168(%rsp), %rax
decq %rax
movq %rax, 0x168(%rsp)
movq 0x168(%rsp), %rsi
movl $0x2, %edi
callq 0x18fe0
movsd %xmm0, 0x80(%rsp)
jmp 0xc724
movsd 0x80(%rsp), %xmm0
movsd 0x2e23b(%rip), %xmm2    # 0x3a970
movaps %xmm0, %xmm1
subsd %xmm2, %xmm1
cvttsd2si %xmm1, %rcx
cvttsd2si %xmm0, %rax
movq %rax, %rdx
sarq $0x3f, %rdx
andq %rdx, %rcx
orq %rcx, %rax
movq %rax, 0x170(%rsp)
movq $0x1000000, 0x160(%rsp) # imm = 0x1000000
leaq 0x170(%rsp), %rdi
leaq 0x160(%rsp), %rsi
callq 0xbe00
movq %rax, 0x78(%rsp)
jmp 0xc783
movq 0x78(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x47cf8(%rip)     # 0x54488
movq 0x47819(%rip), %rdi     # 0x53fb0
leaq 0x2eb50(%rip), %rsi     # 0x3b2ee
callq 0x6420
movq %rax, 0x70(%rsp)
jmp 0xc7aa
movq 0x70(%rsp), %rdi
movl 0x47cd3(%rip), %esi     # 0x54488
movl %esi, %eax
addl $0x3ff, %eax            # imm = 0x3FF
testl %esi, %esi
cmovsl %eax, %esi
sarl $0xa, %esi
movl %esi, %eax
addl $0x3ff, %eax            # imm = 0x3FF
testl %esi, %esi
cmovsl %eax, %esi
sarl $0xa, %esi
callq 0x6720
movq %rax, 0x68(%rsp)
jmp 0xc7df
movq 0x68(%rsp), %rdi
leaq 0x2eb13(%rip), %rsi     # 0x3b2fe
callq 0x6420
movq %rax, 0x60(%rsp)
jmp 0xc7f7
movq 0x60(%rsp), %rdi
movq 0x4776d(%rip), %rsi     # 0x53f70
callq 0x6470
jmp 0xc80a
movl $0x0, 0x15c(%rsp)
movl 0x15c(%rsp), %eax
movq %rax, 0x58(%rsp)
leaq 0x1a8(%rsp), %rdi
callq 0x18fc0
movq %rax, %rcx
movq 0x58(%rsp), %rax
cmpq %rcx, %rax
jae 0xcad7
leaq 0x137(%rsp), %rdi
movq %rdi, 0x50(%rsp)
callq 0x6760
movq 0x50(%rsp), %rdx
leaq 0x2eaa4(%rip), %rsi     # 0x3b301
leaq 0x138(%rsp), %rdi
callq 0x65b0
jmp 0xc86c
leaq 0x137(%rsp), %rdi
callq 0x6490
movl 0x15c(%rsp), %eax
movl %eax, %esi
leaq 0x1a8(%rsp), %rdi
callq 0x19030
movq %rax, 0x48(%rsp)
jmp 0xc896
movq 0x48(%rsp), %rsi
leaq 0x138(%rsp), %rdi
callq 0x6530
jmp 0xc8aa
movq 0x476ff(%rip), %rdi     # 0x53fb0
movq 0x476b8(%rip), %rsi     # 0x53f70
callq 0x6470
jmp 0xc8bf
movq 0x476ea(%rip), %rdi     # 0x53fb0
leaq 0x2ea3c(%rip), %rsi     # 0x3b309
callq 0x6420
movq %rax, 0x40(%rsp)
jmp 0xc8d9
movl 0x15c(%rsp), %eax
movl %eax, %esi
leaq 0x1a8(%rsp), %rdi
callq 0x19030
movq %rax, 0x38(%rsp)
jmp 0xc8f6
movq 0x38(%rsp), %rsi
movq 0x40(%rsp), %rdi
callq 0x6390
movq %rax, 0x30(%rsp)
jmp 0xc90c
movq 0x30(%rsp), %rdi
leaq 0x2dbf1(%rip), %rsi     # 0x3a509
callq 0x6420
movq %rax, 0x28(%rsp)
jmp 0xc924
movq 0x28(%rsp), %rdi
movq 0x47640(%rip), %rsi     # 0x53f70
callq 0x6470
jmp 0xc937
leaq 0x138(%rsp), %rdi
callq 0x6180
movq %rax, %rdi
callq 0x6360
movl %eax, 0x24(%rsp)
jmp 0xc952
movl 0x24(%rsp), %eax
cmpl $0x0, %eax
je 0xc99c
jmp 0xc99c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1c8(%rsp)
movl %eax, 0x1c4(%rsp)
leaq 0x137(%rsp), %rdi
callq 0x6490
jmp 0xcbb7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1c8(%rsp)
movl %eax, 0x1c4(%rsp)
jmp 0xcac5
movq 0x4760d(%rip), %rdi     # 0x53fb0
movq 0x475c6(%rip), %rsi     # 0x53f70
callq 0x6470
jmp 0xc9b1
movl $0x2b8, %edi            # imm = 0x2B8
callq 0x6430
movq %rax, 0x18(%rsp)
jmp 0xc9c2
movb $0x1, 0x107(%rsp)
movl 0x15c(%rsp), %eax
movl %eax, %esi
leaq 0x1a8(%rsp), %rdi
callq 0x19030
movq %rax, 0x10(%rsp)
jmp 0xc9e7
movq 0x10(%rsp), %rsi
leaq 0x108(%rsp), %rdi
callq 0x6190
jmp 0xc9fb
movq 0x18(%rsp), %rdi
movslq 0x47a81(%rip), %rdx     # 0x54488
leaq 0x108(%rsp), %rsi
callq 0x2fbb0
jmp 0xca16
movb $0x0, 0x107(%rsp)
leaq 0x108(%rsp), %rdi
callq 0x6260
movq 0x18(%rsp), %rax
movq 0xb0(%rsp), %rdi
movq %rax, 0x128(%rsp)
addq $0x40, %rdi
leaq 0x128(%rsp), %rsi
callq 0x19070
jmp 0xca53
leaq 0x138(%rsp), %rdi
callq 0x6260
movl 0x15c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x15c(%rsp)
jmp 0xc815
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1c8(%rsp)
movl %eax, 0x1c4(%rsp)
jmp 0xcaad
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1c8(%rsp)
movl %eax, 0x1c4(%rsp)
leaq 0x108(%rsp), %rdi
callq 0x6260
testb $0x1, 0x107(%rsp)
jne 0xcab9
jmp 0xcac3
movq 0x18(%rsp), %rdi
callq 0x63f0
jmp 0xcac5
leaq 0x138(%rsp), %rdi
callq 0x6260
jmp 0xcbb7
movl $0x2a0, %edi            # imm = 0x2A0
callq 0x6430
movq %rax, 0x8(%rsp)
jmp 0xcae8
movq 0xb0(%rsp), %rsi
movb $0x1, 0xdf(%rsp)
addq $0x20, %rsi
leaq 0x2e7a6(%rip), %rdx     # 0x3b2a9
leaq 0xe0(%rsp), %rdi
callq 0x18e60
jmp 0xcb12
movq 0x8(%rsp), %rdi
movslq 0x4796a(%rip), %rdx     # 0x54488
leaq 0xe0(%rsp), %rsi
callq 0x34590
jmp 0xcb2d
movq 0xb0(%rsp), %rax
movq 0x8(%rsp), %rcx
movb $0x0, 0xdf(%rsp)
movq %rcx, 0x58(%rax)
leaq 0xe0(%rsp), %rdi
callq 0x6260
leaq 0x1a8(%rsp), %rdi
callq 0x190e0
addq $0x1e8, %rsp            # imm = 0x1E8
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1c8(%rsp)
movl %eax, 0x1c4(%rsp)
jmp 0xcb9f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1c8(%rsp)
movl %eax, 0x1c4(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0x6260
testb $0x1, 0xdf(%rsp)
jne 0xcbab
jmp 0xcbb5
movq 0x8(%rsp), %rdi
callq 0x63f0
jmp 0xcbb7
leaq 0x1a8(%rsp), %rdi
callq 0x190e0
movq 0xc0(%rsp), %rdi
callq 0x9db0
movq 0xb8(%rsp), %rdi
callq 0x6260
movq 0xc8(%rsp), %rdi
callq 0x6260
movq 0x1c8(%rsp), %rdi
callq 0x6750
nopl (%rax,%rax)