// File: /workspace/github_cpp_makefile_star2_O3/lianxings[P]ftp_benchmark/ftp_benchmark.cc
// Function: null2ftp_worker_core(recvParam*, ftplib*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int, ftpInfo*)
static void null2ftp_worker_core(recvParam * pRecv, ftplib * ftpClient, string ftpPath, int deep, ftpInfo * pFtp) 
{
    int ret = 0;
    int retry = 0;
    char nameBuf[512];
    int ioUnit = 256 << 10;
    char printBuf[1024];
    char sizeStrBuf[128];
    ftplib::accesstype type = ftplib::filewrite;
    ftplib::transfermode mode = ftplib::image;
    ftphandle *nData = NULL;
    char ac[3] = "rb";

    // normalize directory path format
    string nullStr("");
    normalize_dir_format(nullStr, ftpPath);

    // check if ftp directory exists
    if (!ftpClient->Chdir(ftpPath.c_str())) {
        fprintf(stderr, "change to directory %s failed: %s.\n", ftpPath.c_str(), ftpClient->mp_ftphandle->response);
        return;
    }

    if (deep <= pRecv->layer) {
        for (int i = 0; i < pRecv->width; i++) {
            sprintf(nameBuf, "%s_dir_%d/", pRecv->testName.c_str(), i);
		    string dirPath = ftpPath + nameBuf;
            retry = 0;
            if (!ftpClient->Chdir(dirPath.c_str())) {
                if (!ftpClient->Mkdir(dirPath.c_str())) {
                    fprintf(stderr, "make directory %s failed: %s.\n", dirPath.c_str(), ftpClient->mp_ftphandle->response);
                        continue;
                }
            }
			null2ftp_worker_core(pRecv, ftpClient, dirPath, deep + 1, pFtp);
		}
	} else {        
        char * dataBuf = (char *)malloc(ioUnit);
		if (dataBuf == NULL) {
            fprintf(stderr, "allocate %d memory failed.\n", ioUnit);
			return;
		}
        
        srand(time(NULL));
        for (int i = 0; i < pRecv->fileNum; i++) {
            int64_t osize;
            if (pRecv->maxSize == pRecv->fileSize) {
				osize = rand();
				osize = (osize << 24) + osize;
                osize = (osize%(pRecv->maxSize - pRecv->minSize + 1)) + pRecv->minSize;
            } else {
                osize = pRecv->fileSize;
			}
            //++fileNum;
            totalFileSize += osize;
            size_to_string(osize, sizeStrBuf);
            sprintf(nameBuf, "%s_file_%d", pRecv->testName.c_str(), i);
			string filePath = ftpPath + nameBuf;
            ret = build_ftp_data_connection(filePath, type, mode, ftpClient, pFtp, &nData);
            if (ret < 0) {
                ++failed;
                errorSize += osize;
                if (ret == -1)
                    sprintf(printBuf, "\nget ftp data connection failed: source: null, destination: %s, size: %s\n",\
                                                                                      filePath.c_str(), sizeStrBuf);
                else
                    sprintf(printBuf, "\nre-login ftp server %s failed: source: null, destination: %s, size: %s\n",\
                                                                   pFtp->ftpServer , filePath.c_str(), sizeStrBuf);
                fwrite(printBuf, 1, strlen(printBuf), errorFd);
                write(2, printBuf, strlen(printBuf));
                continue;
            }

            Md5Context md5Context;
            if (pRecv->verify){
                Md5Initialise( &md5Context );
            }

            int upload = 0;
            int ioUnitTmp = ioUnit;
            while (upload < osize) {
                if (ioUnitTmp > osize - upload)
                    ioUnitTmp = osize - upload;
                memset(dataBuf, rand()%94+33, ioUnitTmp);
                if (ftpClient->FtpWrite(dataBuf, ioUnitTmp, nData) < ioUnitTmp) {
                    ++failed;
                    errorSize += osize;
                    sprintf(printBuf, "\nftp write failed: source: null, destination: %s, size: %s\n", filePath.c_str(), sizeStrBuf);
                    fwrite(printBuf, 1, strlen(printBuf), errorFd);
                    write(2, printBuf, strlen(printBuf));
                    break;
                }
                if (pRecv->verify) {
                    Md5Update( &md5Context, (const void*)dataBuf, ioUnitTmp);
                }
                finishSize += ioUnitTmp;
                upload += ioUnitTmp;
            }
            
            char md5str[33] = {'\0'};
            if (upload == osize) {
                ++finished;
                if(pRecv->verify) {
                    MD5_HASH md5;
                    char tmp[3] = {'\0'};
                    Md5Finalise( &md5Context, &md5);
                    memset(md5str, 0, sizeof(md5str));
                    for(int j = 0; j < sizeof(md5); j++ ) {
                        sprintf( tmp,"%2.2x", md5.bytes[j]);
                        strcat(md5str, tmp);
                    }
                }
            }
            
            ftpClient->FtpClose(nData);

            if (pRecv->verify) {   // if need to verify
                string newFilePath = filePath + ".md5";
                ret = build_ftp_data_connection(newFilePath, type, mode, ftpClient, pFtp, &nData);
                if (ret < 0) {
                    ++md5Failed;
                    if (ret == -1)
                        sprintf(printBuf, "\nget ftp data connection failed: source: null, destination: %s\n",\
                                                                                         newFilePath.c_str());
                    else
                        sprintf(printBuf, "\nre-login ftp server %s failed: source: null, destination: %s\n",\
                                                                      pFtp->ftpServer , newFilePath.c_str());
                    fwrite(printBuf, 1, strlen(printBuf), errorFd);
                    write(2, printBuf, strlen(printBuf));
                    continue;
                }
                
                if (ftpClient->FtpWrite(md5str, strlen(md5str), nData) < strlen(md5str)) {
                    ++md5Failed;
                    sprintf(printBuf, "\nftp write failed: source: null, destination: %s\n", newFilePath.c_str());
                    fwrite(printBuf, 1, strlen(printBuf), errorFd);
                    write(2, printBuf, strlen(printBuf));
                    break;
                }
                ftpClient->FtpClose(nData);
            }
            
        }
		free(dataBuf);
    }
	return;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x858, %rsp            # imm = 0x858
movq %r8, 0x20(%rsp)
movl %ecx, 0x8(%rsp)
movq %rdx, %rbx
movq %rsi, %r12
movq %rdi, %r13
movq $0x0, 0x18(%rsp)
leaq 0xd0(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x8bf1(%rip), %rdx      # 0x12902
leaq 0xc0(%rsp), %r14
movq %r14, %rdi
movq %rdx, %rsi
callq 0xd43e
movq %r14, %rdi
movq %rbx, %rsi
callq 0xdddf
movq (%rbx), %rsi
movq %r12, %rdi
callq 0xfd48
testl %eax, %eax
je 0xa531
movl 0x8(%rsp), %eax
cmpl %eax, 0x24(%r13)
movq %r13, 0x28(%rsp)
jge 0xa3c8
movl $0x40000, %edi          # imm = 0x40000
callq 0x4500
movq %rax, 0x8(%rsp)
testq %rax, %rax
je 0xa557
movq %rbx, 0x130(%rsp)
xorl %edi, %edi
callq 0x4360
movl %eax, %edi
callq 0x43a0
cmpl $0x0, 0x28(%r13)
jle 0xa3b9
xorl %r15d, %r15d
movq %r12, 0x78(%rsp)
movq 0x30(%r13), %r14
cmpq %r14, 0x38(%r13)
jne 0x9dcb
callq 0x40d0
movslq %eax, %rcx
movq %rcx, %rax
shlq $0x18, %rax
addq %rcx, %rax
movq 0x38(%r13), %rcx
movq 0x40(%r13), %rsi
subq %rsi, %rcx
incq %rcx
cqto
idivq %rcx
movq %rdx, %r14
addq %rsi, %r14
addq %r14, 0xe75e(%rip)      # 0x18530
movq %r14, %rdi
leaq 0x1d0(%rsp), %rsi
callq 0xdc66
movq 0x130(%rsp), %rbx
movq (%r13), %rdx
leaq 0x650(%rsp), %rbp
movq %rbp, %rdi
leaq 0x9070(%rip), %rsi      # 0x12e70
movl %r15d, %ecx
xorl %eax, %eax
callq 0x40a0
leaq 0x60(%rsp), %rax
movq %rax, 0x50(%rsp)
movq (%rbx), %rsi
movq 0x8(%rbx), %rdx
addq %rsi, %rdx
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
callq 0xd3a8
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x4740
leaq 0xb0(%rsp), %rax
movq %rax, 0xa0(%rsp)
movq 0x50(%rsp), %rsi
movq 0x58(%rsp), %rdx
addq %rsi, %rdx
leaq 0xa0(%rsp), %rdi
callq 0xd3a8
leaq 0xa0(%rsp), %rdi
movl $0x4, %esi
movl $0x49, %edx
movq %r12, %rcx
movq 0x20(%rsp), %r8
leaq 0x18(%rsp), %r9
callq 0x5e39
movl %eax, %ebp
movq 0xa0(%rsp), %rdi
leaq 0xb0(%rsp), %rax
cmpq %rax, %rdi
leaq 0x250(%rsp), %rbx
je 0x9eb3
movq 0xb0(%rsp), %rsi
incq %rsi
callq 0x4400
testl %ebp, %ebp
js 0x9f8c
cmpb $0x1, 0x4c(%r13)
jne 0x9ecf
leaq 0x138(%rsp), %rdi
callq 0x10a64
movl %r15d, 0x74(%rsp)
xorl %ebx, %ebx
testq %r14, %r14
jle 0xa03d
movl $0x40000, %r15d         # imm = 0x40000
xorl %r12d, %r12d
movslq %r15d, %r15
movq %r14, %rax
subq %rbx, %rax
cmpq %r15, %rax
cmovll %eax, %r15d
callq 0x40d0
cltq
imulq $-0x51b3bea3, %rax, %rcx # imm = 0xAE4C415D
shrq $0x20, %rcx
addl %eax, %ecx
movl %ecx, %edx
shrl $0x1f, %edx
shrl $0x6, %ecx
addl %edx, %ecx
imull $0x5e, %ecx, %ecx
subl %ecx, %eax
addb $0x21, %al
movslq %r15d, %rbp
movzbl %al, %esi
movq 0x8(%rsp), %r13
movq %r13, %rdi
movq %rbp, %rdx
callq 0x4210
movq 0x18(%rsp), %rcx
movq 0x78(%rsp), %rdi
movq %r13, %rsi
movl %ebp, %edx
callq 0xfb38
cmpl %r15d, %eax
jl 0x9fd0
movq 0x28(%rsp), %rax
cmpb $0x1, 0x4c(%rax)
jne 0x9f70
leaq 0x138(%rsp), %rdi
movq 0x8(%rsp), %rsi
movl %r15d, %edx
callq 0x10a7d
lock
addq %rbp, 0xe5a8(%rip)      # 0x18520
addl %r15d, %r12d
movslq %r12d, %rbx
cmpq %rbx, %r14
jg 0x9ee8
jmp 0xa03d
lock
incq 0xe574(%rip)            # 0x18508
lock
addq %r14, 0xe58c(%rip)      # 0x18528
cmpl $-0x1, %ebp
je 0xa260
movq 0x20(%rsp), %rax
movq (%rax), %rdx
movq 0x50(%rsp), %rcx
movq %rbx, %rdi
leaq 0x8f09(%rip), %rsi      # 0x12ec5
leaq 0x1d0(%rsp), %r8
xorl %eax, %eax
callq 0x40a0
jmp 0xa27e
lock
incq 0xe530(%rip)            # 0x18508
lock
addq %r14, 0xe548(%rip)      # 0x18528
movq 0x50(%rsp), %rdx
leaq 0x250(%rsp), %r15
movq %r15, %rdi
leaq 0x8f17(%rip), %rsi      # 0x12f0e
leaq 0x1d0(%rsp), %rcx
xorl %eax, %eax
callq 0x40a0
movq %r15, %rdi
callq 0x4180
movq 0xe4cb(%rip), %rcx      # 0x184e0
movl $0x1, %esi
movq %r15, %rdi
movq %rax, %rdx
callq 0x4750
movq %r15, %rdi
callq 0x4180
movl $0x2, %edi
movq %r15, %rsi
movq %rax, %rdx
callq 0x4140
xorps %xmm0, %xmm0
movaps %xmm0, 0x110(%rsp)
movaps %xmm0, 0x100(%rsp)
movb $0x0, 0x120(%rsp)
cmpq %rbx, %r14
movq 0x78(%rsp), %r12
movq 0x28(%rsp), %r13
jne 0xa0ef
lock
incq 0xe48d(%rip)            # 0x18500
cmpb $0x1, 0x4c(%r13)
jne 0xa0ef
movb $0x0, 0x16(%rsp)
movw $0x0, 0x14(%rsp)
leaq 0x138(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x1143a
xorps %xmm0, %xmm0
movaps %xmm0, 0x110(%rsp)
movaps %xmm0, 0x100(%rsp)
movb $0x0, 0x120(%rsp)
xorl %ebx, %ebx
leaq 0x8244(%rip), %r14      # 0x12300
leaq 0x14(%rsp), %rbp
leaq 0x100(%rsp), %r15
movzbl 0x30(%rsp,%rbx), %edx
movq %rbp, %rdi
movq %r14, %rsi
xorl %eax, %eax
callq 0x40a0
movq %r15, %rdi
movq %rbp, %rsi
callq 0x46f0
incq %rbx
cmpq $0x10, %rbx
jne 0xa0c9
movq 0x18(%rsp), %rsi
movq %r12, %rdi
callq 0xf9cc
movl 0x74(%rsp), %r15d
cmpb $0x1, 0x4c(%r13)
jne 0xa385
leaq 0x40(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x50(%rsp), %rsi
movq 0x58(%rsp), %rdx
addq %rsi, %rdx
leaq 0x30(%rsp), %rbx
movq %rbx, %rdi
callq 0xd3a8
movq %rbx, %rdi
leaq 0x81cc(%rip), %rsi      # 0x12306
callq 0x4740
leaq 0x90(%rsp), %rax
movq %rax, 0x80(%rsp)
movq 0x30(%rsp), %rsi
movq 0x38(%rsp), %rdx
addq %rsi, %rdx
leaq 0x80(%rsp), %rdi
callq 0xd3a8
leaq 0x80(%rsp), %rdi
movl $0x4, %esi
movl $0x49, %edx
movq %r12, %rcx
movq 0x20(%rsp), %r8
leaq 0x18(%rsp), %r9
callq 0x5e39
movl %eax, %ebp
movq 0x80(%rsp), %rdi
leaq 0x90(%rsp), %rax
cmpq %rax, %rdi
je 0xa1b4
movq 0x90(%rsp), %rsi
incq %rsi
callq 0x4400
testl %ebp, %ebp
js 0xa2bf
leaq 0x100(%rsp), %rbx
movq %rbx, %rdi
callq 0x4180
movq 0x18(%rsp), %rcx
movq %r12, %rdi
movq %rbx, %rsi
movl %eax, %edx
callq 0xfb38
movslq %eax, %rbx
leaq 0x100(%rsp), %rdi
callq 0x4180
cmpq %rbx, %rax
jbe 0xa2f4
lock
incq 0xe311(%rip)            # 0x18510
movq 0x30(%rsp), %rdx
xorl %ebp, %ebp
leaq 0x250(%rsp), %r14
movq %r14, %rdi
leaq 0x8db1(%rip), %rsi      # 0x12fc9
xorl %eax, %eax
callq 0x40a0
movq %r14, %rdi
callq 0x4180
movq 0xe2b2(%rip), %rcx      # 0x184e0
movl $0x1, %esi
movq %r14, %rdi
movq %rax, %rdx
callq 0x4750
movq %r14, %rdi
callq 0x4180
movl $0x5, %ebx
movl $0x2, %edi
movq %r14, %rsi
movq %rax, %rdx
callq 0x4140
jmp 0xa364
movq 0x50(%rsp), %rdx
movq %rbx, %rdi
leaq 0x8c0c(%rip), %rsi      # 0x12e7b
leaq 0x1d0(%rsp), %rcx
xorl %eax, %eax
callq 0x40a0
movq %rbx, %rdi
callq 0x4180
movq 0xe253(%rip), %rcx      # 0x184e0
movl $0x1, %esi
movq %rbx, %rdi
movq %rax, %rdx
callq 0x4750
movq %rbx, %rdi
callq 0x4180
movq %rbx, %rsi
movl $0x7, %ebx
movl $0x2, %edi
movq %rax, %rdx
callq 0x4140
jmp 0xa387
lock
incq 0xe249(%rip)            # 0x18510
cmpl $-0x1, %ebp
je 0xa308
movq 0x20(%rsp), %rax
movq (%rax), %rdx
movq 0x30(%rsp), %rcx
leaq 0x250(%rsp), %rbx
movq %rbx, %rdi
leaq 0x8c9f(%rip), %rsi      # 0x12f8a
xorl %eax, %eax
callq 0x40a0
jmp 0xa326
movq 0x18(%rsp), %rsi
movq %r12, %rdi
callq 0xf9cc
xorl %ebx, %ebx
movb $0x1, %bpl
jmp 0xa364
movq 0x30(%rsp), %rdx
leaq 0x250(%rsp), %rbx
movq %rbx, %rdi
leaq 0x8c2b(%rip), %rsi      # 0x12f4a
xorl %eax, %eax
callq 0x40a0
movq %rbx, %rdi
callq 0x4180
movq 0xe1ab(%rip), %rcx      # 0x184e0
movl $0x1, %esi
movq %rbx, %rdi
movq %rax, %rdx
callq 0x4750
movq %rbx, %rdi
callq 0x4180
movl $0x2, %edi
movq %rbx, %rsi
movq %rax, %rdx
callq 0x4140
movl $0x7, %ebx
xorl %ebp, %ebp
movq 0x30(%rsp), %rdi
leaq 0x40(%rsp), %rax
cmpq %rax, %rdi
je 0xa380
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x4400
testb %bpl, %bpl
je 0xa387
xorl %ebx, %ebx
movq 0x50(%rsp), %rdi
leaq 0x60(%rsp), %rax
cmpq %rax, %rdi
je 0xa3a3
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x4400
cmpl $0x7, %ebx
je 0xa3ac
testl %ebx, %ebx
jne 0xa3b9
incl %r15d
cmpl 0x28(%r13), %r15d
jl 0x9d96
movq 0x8(%rsp), %rdi
callq 0x44a0
jmp 0xa55c
cmpl $0x0, 0x20(%r13)
jle 0xa55c
movq %r13, %rax
incl 0x8(%rsp)
leaq 0x650(%rsp), %r15
leaq 0x138(%rsp), %r13
leaq 0xe0(%rsp), %r14
xorl %ebp, %ebp
movq (%rax), %rdx
movq %r15, %rdi
leaq 0x8a29(%rip), %rsi      # 0x12e2a
movl %ebp, %ecx
xorl %eax, %eax
callq 0x40a0
leaq 0x148(%rsp), %rax
movq %rax, 0x138(%rsp)
movq (%rbx), %rsi
movq 0x8(%rbx), %rdx
addq %rsi, %rdx
movq %r13, %rdi
callq 0xd3a8
movq %r13, %rdi
movq %r15, %rsi
callq 0x4740
movq 0x138(%rsp), %rsi
movq %r12, %rdi
callq 0xfd48
testl %eax, %eax
jne 0xa463
movq 0x138(%rsp), %rsi
movq %r12, %rdi
callq 0xfce2
testl %eax, %eax
je 0xa503
leaq 0xf0(%rsp), %rax
movq %rax, 0xe0(%rsp)
movq 0x138(%rsp), %rsi
movq 0x140(%rsp), %rdx
addq %rsi, %rdx
movq %r14, %rdi
callq 0xd3a8
movq 0x28(%rsp), %rdi
movq %r12, %rsi
movq %r14, %rdx
movl 0x8(%rsp), %ecx
movq 0x20(%rsp), %r8
callq 0x9cd2
movq 0xe0(%rsp), %rdi
leaq 0xf0(%rsp), %rax
cmpq %rax, %rdi
je 0xa4cc
movq 0xf0(%rsp), %rsi
incq %rsi
callq 0x4400
movq 0x138(%rsp), %rdi
leaq 0x148(%rsp), %rax
cmpq %rax, %rdi
je 0xa4f1
movq 0x148(%rsp), %rsi
incq %rsi
callq 0x4400
incl %ebp
movq 0x28(%rsp), %rax
cmpl 0x20(%rax), %ebp
jl 0xa3f4
jmp 0xa55c
movq 0xdabe(%rip), %rax      # 0x17fc8
movq (%rax), %rdi
movq 0x138(%rsp), %rdx
movq (%r12), %rcx
movl $0x88, %eax
addq %rax, %rcx
leaq 0x890d(%rip), %rsi      # 0x12e35
xorl %eax, %eax
callq 0x4530
jmp 0xa4cc
movq 0xda90(%rip), %rax      # 0x17fc8
movq (%rax), %rdi
movq (%rbx), %rdx
movl $0x88, %ecx
addq (%r12), %rcx
leaq 0x88b8(%rip), %rsi      # 0x12e06
xorl %eax, %eax
callq 0x4530
jmp 0xa55c
callq 0x4991
movq 0xc0(%rsp), %rdi
leaq 0xd0(%rsp), %rax
cmpq %rax, %rdi
je 0xa581
movq 0xd0(%rsp), %rsi
incq %rsi
callq 0x4400
addq $0x858, %rsp            # imm = 0x858
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xa682
jmp 0xa682
movq %rax, %rbx
movq 0x80(%rsp), %rdi
leaq 0x90(%rsp), %rax
cmpq %rax, %rdi
je 0xa5e3
movq 0x90(%rsp), %rsi
incq %rsi
callq 0x4400
jmp 0xa5e3
jmp 0xa5e0
jmp 0xa682
jmp 0xa682
movq %rax, %rbx
jmp 0xa6a9
jmp 0xa682
movq %rax, %rbx
movq 0x30(%rsp), %rdi
leaq 0x40(%rsp), %rax
cmpq %rax, %rdi
je 0xa685
movq 0x40(%rsp), %rsi
jmp 0xa61d
movq %rax, %rbx
movq 0xa0(%rsp), %rdi
leaq 0xb0(%rsp), %rax
cmpq %rax, %rdi
je 0xa685
movq 0xb0(%rsp), %rsi
incq %rsi
callq 0x4400
jmp 0xa685
jmp 0xa659
jmp 0xa659
jmp 0xa682
jmp 0xa682
movq %rax, %rbx
movq 0xe0(%rsp), %rdi
leaq 0xf0(%rsp), %rax
cmpq %rax, %rdi
je 0xa663
movq 0xf0(%rsp), %rsi
incq %rsi
callq 0x4400
jmp 0xa663
movq %rax, %rbx
jmp 0xa6a1
jmp 0xa660
movq %rax, %rbx
movq 0x138(%rsp), %rdi
leaq 0x148(%rsp), %rax
cmpq %rax, %rdi
je 0xa6a1
movq 0x148(%rsp), %rsi
jmp 0xa699
movq %rax, %rbx
movq 0x50(%rsp), %rdi
leaq 0x60(%rsp), %rax
cmpq %rax, %rdi
je 0xa6a1
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x4400
leaq 0xd0(%rsp), %r15
movq 0xc0(%rsp), %rdi
cmpq %r15, %rdi
je 0xa6c6
movq 0xd0(%rsp), %rsi
incq %rsi
callq 0x4400
movq %rbx, %rdi
callq 0x46e0