// File: /workspace/github_cpp_makefile_star2_O2/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 $0x848, %rsp            # imm = 0x848
movq %r8, 0x18(%rsp)
movl %ecx, %ebp
movq %rdx, %rbx
movq %rsi, %r12
movq %rdi, 0x20(%rsp)
andq $0x0, 0x10(%rsp)
leaq 0x87f7(%rip), %rsi      # 0x108f2
leaq 0xc8(%rsp), %r14
leaq 0x128(%rsp), %rdx
movq %r14, %rdi
callq 0x9dca
movq %r14, %rdi
movq %rbx, %rsi
callq 0xbe13
movq (%rbx), %rsi
movq %r12, %rdi
callq 0xdace
testl %eax, %eax
je 0x8793
movq 0x20(%rsp), %r14
cmpl %ebp, 0x24(%r14)
jge 0x86b4
movl $0x40000, %edi          # imm = 0x40000
callq 0x44f0
movq %rax, 0x28(%rsp)
testq %rax, %rax
je 0x87bc
xorl %edi, %edi
callq 0x4350
movl %eax, %edi
callq 0x43a0
xorl %eax, %eax
movq %rbx, 0x30(%rsp)
movq %r12, 0x38(%rsp)
cmpl 0x28(%r14), %eax
jge 0x868b
movl %eax, 0x8(%rsp)
movq 0x30(%r14), %r15
cmpq %r15, 0x38(%r14)
jne 0x81b1
callq 0x40c0
cltq
imulq $0x1000001, %rax, %rax  # imm = 0x1000001
movq 0x38(%r14), %rcx
movq 0x40(%r14), %rsi
subq %rsi, %rcx
incq %rcx
cqto
idivq %rcx
movq %rdx, %r15
addq %rsi, %r15
addq %r15, 0xf368(%rip)      # 0x17520
movq %r15, %rdi
leaq 0x1c0(%rsp), %rsi
callq 0xbcb2
movq (%r14), %rdx
leaq 0x640(%rsp), %r13
movq %r13, %rdi
leaq 0x8c83(%rip), %rsi      # 0x10e60
movl 0x8(%rsp), %ecx
xorl %eax, %eax
callq 0x4090
leaq 0x88(%rsp), %rbp
movq %rbp, %rdi
movq %rbx, %rsi
movq %r13, %rdx
callq 0x9d7c
leaq 0xe8(%rsp), %r13
movq %r13, %rdi
movq %rbp, %rsi
callq 0x4510
movq %r13, %rdi
pushq $0x4
popq %rsi
pushq $0x49
popq %rdx
movq %r12, %rcx
movq 0x18(%rsp), %r8
leaq 0x10(%rsp), %r9
callq 0x55ec
movl %eax, %ebp
movq %r13, %rdi
callq 0x4170
testl %ebp, %ebp
js 0x82e1
cmpb $0x0, 0x4c(%r14)
je 0x8252
leaq 0x128(%rsp), %rdi
callq 0xe704
movl $0x40000, %r14d         # imm = 0x40000
xorl %r12d, %r12d
movslq %r12d, %rbx
movq %r15, %rax
subq %rbx, %rax
jle 0x839c
movslq %r14d, %r14
cmpq %r14, %rax
cmovll %eax, %r14d
callq 0x40c0
cltd
pushq $0x5e
popq %rcx
idivl %ecx
addb $0x21, %dl
movslq %r14d, %rbp
movzbl %dl, %esi
movq 0x28(%rsp), %r13
movq %r13, %rdi
movq %rbp, %rdx
callq 0x4210
movq 0x10(%rsp), %rcx
movq 0x38(%rsp), %rdi
movq %r13, %rsi
movl %ebp, %edx
callq 0xd8cc
cmpl %r14d, %eax
jl 0x8330
movq 0x20(%rsp), %rax
cmpb $0x1, 0x4c(%rax)
jne 0x82d1
leaq 0x128(%rsp), %rdi
movq 0x28(%rsp), %rsi
movl %r14d, %edx
callq 0xe71d
lock
addq %rbp, 0xf237(%rip)      # 0x17510
addl %r14d, %r12d
jmp 0x825b
lock
incq 0xf20f(%rip)            # 0x174f8
lock
addq %r15, 0xf227(%rip)      # 0x17518
cmpl $-0x1, %ebp
je 0x8549
movq 0x18(%rsp), %rax
movq (%rax), %rdx
movq 0x88(%rsp), %rcx
leaq 0x240(%rsp), %r15
movq %r15, %rdi
leaq 0x8b99(%rip), %rsi      # 0x10eb5
leaq 0x1c0(%rsp), %r8
xorl %eax, %eax
callq 0x4090
jmp 0x8572
lock
incq 0xf1c0(%rip)            # 0x174f8
lock
addq %r15, 0xf1d8(%rip)      # 0x17518
movq 0x88(%rsp), %rdx
leaq 0x240(%rsp), %r14
movq %r14, %rdi
leaq 0x8ba4(%rip), %rsi      # 0x10efe
leaq 0x1c0(%rsp), %rcx
xorl %eax, %eax
callq 0x4090
movq %r14, %rdi
callq 0x4160
movq 0xf158(%rip), %rcx      # 0x174d0
movq %r14, %rdi
pushq $0x1
popq %rsi
movq %rax, %rdx
callq 0x4720
movq %r14, %rdi
callq 0x4160
pushq $0x2
popq %rdi
movq %r14, %rsi
movq %rax, %rdx
callq 0x4120
xorps %xmm0, %xmm0
movaps %xmm0, 0x50(%rsp)
movaps %xmm0, 0x40(%rsp)
movb $0x0, 0x60(%rsp)
cmpq %rbx, %r15
movq 0x38(%rsp), %r12
movq 0x20(%rsp), %r14
leaq 0x88(%rsp), %r15
jne 0x8438
lock
incq 0xf123(%rip)            # 0x174f0
cmpb $0x1, 0x4c(%r14)
jne 0x8438
movb $0x0, 0xe(%rsp)
andw $0x0, 0xc(%rsp)
leaq 0x128(%rsp), %rdi
leaq 0x68(%rsp), %rsi
callq 0xf0d6
xorps %xmm0, %xmm0
movaps %xmm0, 0x50(%rsp)
movaps %xmm0, 0x40(%rsp)
movb $0x0, 0x60(%rsp)
xorl %ebx, %ebx
cmpq $0x10, %rbx
je 0x8438
movzbl 0x68(%rsp,%rbx), %edx
leaq 0xc(%rsp), %r13
movq %r13, %rdi
leaq 0x7ed1(%rip), %rsi      # 0x102f0
xorl %eax, %eax
callq 0x4090
leaq 0x40(%rsp), %rdi
movq %r13, %rsi
callq 0x46b0
incq %rbx
jmp 0x8405
movq 0x10(%rsp), %rsi
movq %r12, %rdi
callq 0xd740
cmpb $0x1, 0x4c(%r14)
movq 0x30(%rsp), %rbx
jne 0x8663
leaq 0x68(%rsp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
leaq 0x7e8f(%rip), %rdx      # 0x102f6
callq 0x9d7c
leaq 0xa8(%rsp), %rdi
movq %rbx, %rsi
callq 0x4510
leaq 0xa8(%rsp), %rbx
movq %rbx, %rdi
pushq $0x4
popq %rsi
pushq $0x49
popq %rdx
movq %r12, %rcx
movq 0x18(%rsp), %r8
leaq 0x10(%rsp), %r9
callq 0x55ec
movl %eax, %ebp
movq %rbx, %rdi
callq 0x4170
testl %ebp, %ebp
js 0x85b2
leaq 0x40(%rsp), %rbx
movq %rbx, %rdi
callq 0x4160
movq 0x10(%rsp), %rcx
movq %r12, %rdi
movq %rbx, %rsi
movl %eax, %edx
callq 0xd8cc
movslq %eax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x4160
cmpq %rbx, %rax
jbe 0x85e7
lock
incq 0xf012(%rip)            # 0x17500
movq 0x68(%rsp), %rdx
xorl %ebx, %ebx
leaq 0x240(%rsp), %r13
movq %r13, %rdi
leaq 0x8ab2(%rip), %rsi      # 0x10fb9
xorl %eax, %eax
callq 0x4090
movq %r13, %rdi
callq 0x4160
movq 0xefb3(%rip), %rcx      # 0x174d0
movq %r13, %rdi
pushq $0x1
popq %rsi
movq %rax, %rdx
callq 0x4720
movq %r13, %rdi
callq 0x4160
pushq $0x2
popq %rdi
movq %r13, %rsi
movq %rax, %rdx
callq 0x4120
pushq $0x5
popq %rbp
jmp 0x8650
movq 0x88(%rsp), %rdx
leaq 0x240(%rsp), %r15
movq %r15, %rdi
leaq 0x8908(%rip), %rsi      # 0x10e6b
leaq 0x1c0(%rsp), %rcx
xorl %eax, %eax
callq 0x4090
movq %r15, %rdi
callq 0x4160
movq 0xef4f(%rip), %rcx      # 0x174d0
movq %r15, %rdi
pushq $0x1
popq %rsi
movq %rax, %rdx
callq 0x4720
movq %r15, %rdi
callq 0x4160
pushq $0x2
popq %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x4120
leaq 0x88(%rsp), %rdi
jmp 0x8666
lock
incq 0xef46(%rip)            # 0x17500
cmpl $-0x1, %ebp
je 0x85fa
movq 0x18(%rsp), %rax
movq (%rax), %rdx
movq 0x68(%rsp), %rcx
leaq 0x240(%rsp), %rbx
movq %rbx, %rdi
leaq 0x899c(%rip), %rsi      # 0x10f7a
xorl %eax, %eax
callq 0x4090
jmp 0x8618
movq 0x10(%rsp), %rsi
movq %r12, %rdi
callq 0xd740
xorl %ebp, %ebp
movb $0x1, %bl
jmp 0x8650
movq 0x68(%rsp), %rdx
leaq 0x240(%rsp), %rbx
movq %rbx, %rdi
leaq 0x8929(%rip), %rsi      # 0x10f3a
xorl %eax, %eax
callq 0x4090
movq %rbx, %rdi
callq 0x4160
movq 0xeea9(%rip), %rcx      # 0x174d0
movq %rbx, %rdi
pushq $0x1
popq %rsi
movq %rax, %rdx
callq 0x4720
movq %rbx, %rdi
callq 0x4160
pushq $0x2
popq %rdi
movq %rbx, %rsi
movq %rax, %rdx
callq 0x4120
xorl %ebx, %ebx
pushq $0x7
popq %rbp
leaq 0x68(%rsp), %rdi
callq 0x4170
testb %bl, %bl
movq 0x30(%rsp), %rbx
je 0x8676
movq %r15, %rdi
callq 0x4170
movl 0x8(%rsp), %eax
incl %eax
jmp 0x8172
movq %r15, %rdi
callq 0x4170
cmpl $0x7, %ebp
movl 0x8(%rsp), %eax
je 0x866f
testl %ebp, %ebp
je 0x866f
movq 0x28(%rsp), %rdi
callq 0x4480
leaq 0xc8(%rsp), %rdi
callq 0x4170
addq $0x848, %rsp            # imm = 0x848
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
incl %ebp
movl %ebp, 0x28(%rsp)
leaq 0x640(%rsp), %r15
leaq 0x128(%rsp), %r13
leaq 0x108(%rsp), %r14
xorl %ebp, %ebp
movq 0x20(%rsp), %rax
cmpl 0x20(%rax), %ebp
jge 0x8695
movq (%rax), %rdx
movq %r15, %rdi
leaq 0x872f(%rip), %rsi      # 0x10e1a
movl %ebp, %ecx
xorl %eax, %eax
callq 0x4090
movq %r13, %rdi
movq %rbx, %rsi
movq %r15, %rdx
callq 0x9d7c
movq 0x128(%rsp), %rsi
movq %r12, %rdi
callq 0xdace
testl %eax, %eax
jne 0x872a
movq 0x128(%rsp), %rsi
movq %r12, %rdi
callq 0xda6a
testl %eax, %eax
je 0x8765
movq %r14, %rdi
movq %r13, %rsi
callq 0x4510
movq 0x20(%rsp), %rdi
movq %r12, %rsi
movq %r14, %rdx
movl 0x28(%rsp), %ecx
movq 0x18(%rsp), %r8
callq 0x80cb
movq %r14, %rdi
callq 0x4170
movq %r13, %rdi
callq 0x4170
incl %ebp
jmp 0x86d4
movq 0xe85c(%rip), %rax      # 0x16fc8
movq (%rax), %rdi
movq 0x128(%rsp), %rdx
movq (%r12), %rcx
movl $0x88, %eax
addq %rax, %rcx
leaq 0x869b(%rip), %rsi      # 0x10e25
xorl %eax, %eax
callq 0x4530
jmp 0x8756
movq 0xe82e(%rip), %rax      # 0x16fc8
movq (%rax), %rdi
movq (%rbx), %rdx
movl $0x88, %ecx
addq (%r12), %rcx
leaq 0x8646(%rip), %rsi      # 0x10df6
xorl %eax, %eax
callq 0x4530
jmp 0x8695
movq 0xe805(%rip), %rax      # 0x16fc8
movq (%rax), %rdi
leaq 0x8677(%rip), %rsi      # 0x10e44
movl $0x40000, %edx          # imm = 0x40000
xorl %eax, %eax
callq 0x4530
jmp 0x8695
jmp 0x8842
jmp 0x882e
jmp 0x8842
movq %rax, %rbx
leaq 0xa8(%rsp), %rdi
callq 0x4170
jmp 0x87ff
jmp 0x8842
jmp 0x8842
jmp 0x8842
movq %rax, %rbx
leaq 0x68(%rsp), %rdi
jmp 0x8811
movq %rax, %rbx
leaq 0xe8(%rsp), %rdi
callq 0x4170
jmp 0x8845
jmp 0x882e
jmp 0x882e
movq %rax, %rbx
leaq 0x108(%rsp), %rdi
callq 0x4170
jmp 0x8838
movq %rax, %rbx
jmp 0x8852
jmp 0x8842
movq %rax, %rbx
leaq 0x128(%rsp), %rdi
jmp 0x884d
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x4170
leaq 0xc8(%rsp), %rdi
callq 0x4170
movq %rbx, %rdi
callq 0x46a0