// File: /workspace/github_cpp_makefile_star2_O2/sisong[P]ApkDiffPatch/src/normalized/normalized.cpp
// Function: ZipNormalized(char const*, char const*, int, int, bool, unsigned long, bool, int*)
bool ZipNormalized(const char* srcApk,const char* dstApk,int ZipAlignSize,int compressLevel,
                   bool isNotCompressEmptyFile,size_t pageAlignSoFile,bool pageAlignCompatible,int* out_apkFilesRemoved){
    bool result=true;
    bool _isInClear=false;
    int  fileCount=0;
    bool isHaveApkV2Sign=false;
    bool isHaveApkV3Sign=false;
    int  jarSignFileCount=0;
    std::vector<int>   fileIndexs;
    std::vector<std::string>  removedFiles;
    std::vector<std::string> _compressedEmptyFiles; //only for WARNING
    UnZipper unzipper;
    Zipper   zipper;
    UnZipper_init(&unzipper);
    Zipper_init(&zipper);
    
    check(UnZipper_openFile(&unzipper,srcApk));
    fileCount=UnZipper_fileCount(&unzipper);
    check(Zipper_openFile(&zipper,dstApk,fileCount,ZipAlignSize,compressLevel,kDefaultZlibCompressMemLevel,
                          pageAlignSoFile,pageAlignCompatible,kPageAlign_inNormalize));
    isHaveApkV2Sign=UnZipper_isHaveApkV2Sign(&unzipper);
    isHaveApkV3Sign=UnZipper_isHaveApkV3Sign(&unzipper);
    {
        int apkFilesRemoved=0;
        std::vector<TFileValue> files;
        getAllFiles(&unzipper,files);
        apkFilesRemoved=removeNonEmptyDirs(&unzipper,files);
        fileCount=(int)files.size();
        std::sort(files.begin(),files.end(),TFileValue::TCmp(UnZipper_fileCount(&unzipper)));
        for (int i=0; i<fileCount; ++i) {
            int fileIndex=files[i].fileIndex;
            if (UnZipper_file_isApkV1Sign(&unzipper,fileIndex)){
                ++jarSignFileCount;
                if (isHaveApkV2Sign){
                    ++apkFilesRemoved;
                    removedFiles.push_back(files[i].fileName);
                    continue; //remove JarSign(ApkV1Sign) when found ApkV2Sign
                }
            }
            if (UnZipper_file_isStampCertFile(&unzipper,fileIndex)){
                ++apkFilesRemoved;
                removedFiles.push_back(files[i].fileName);
                continue; //remove stamp cert file
            }

            fileIndexs.push_back(fileIndex);
        }
        if (out_apkFilesRemoved)
            *out_apkFilesRemoved=apkFilesRemoved;
    }
    
    printf("\n");
    for (int i=0; i<(int)fileIndexs.size(); ++i) {
        int fileIndex=fileIndexs[i];
        std::string fileName=zipFile_name(&unzipper,fileIndex);
        if (g_isPrintNormalizingFileName)
            hpatch_printPath_utf8(("\""+fileName+"\"\n").c_str());
        if (compressLevel==0){
            check(Zipper_file_append_set_new_isCompress(&zipper,false));
        } else if (isCompressedEmptyFile(&unzipper,fileIndex)){
            if (isNotCompressEmptyFile){
                check(Zipper_file_append_set_new_isCompress(&zipper,false));
                hpatch_printPath_utf8(("NOTE: \""+fileName+"\"").c_str());
                printf(" is a compressed empty file, change to uncompressed!\n");
            }else{
                _compressedEmptyFiles.push_back(fileName);
             }
        }
        bool isAlwaysReCompress=true;
        check(Zipper_file_append_copy(&zipper,&unzipper,fileIndex,isAlwaysReCompress));
    }
    printf("\n");

    //no run: check(Zipper_copyExtra_before_fileHeader(&zipper,&unzipper));
    for (int i=0; i<(int)fileIndexs.size(); ++i) {
        int fileIndex=fileIndexs[i];
        if (compressLevel==0){
            check(Zipper_file_append_set_new_isCompress(&zipper,false));
        } else if (isNotCompressEmptyFile&&isCompressedEmptyFile(&unzipper,fileIndex)){
            check(Zipper_fileHeader_append_set_new_isCompress(&zipper,false));
        }
        check(Zipper_fileHeader_append(&zipper,&unzipper,fileIndex));
    }
    check(Zipper_endCentralDirectory_append(&zipper,&unzipper));
    
    for (int i=0;i<(int)_compressedEmptyFiles.size();++i){
        hpatch_printPath_utf8(("WARNING: \""+_compressedEmptyFiles[i]).c_str());
        printf(" is a compressed empty file, can't patch by old(version<v1.3.5) ZipPatch!)\n");
    }
    if (jarSignFileCount>0){
        if (isHaveApkV2Sign){
            printf("WARNING: src removed JarSign(ApkV1Sign) (%d file, need re-sign)\n",jarSignFileCount);
        }else{
            printf("WARNING: src JarSign(ApkV1Sign) (%d file) has been Normalized, Don't re-sign!\n",jarSignFileCount);
        }
    }
    for (size_t i=0;i<removedFiles.size();++i)
        hpatch_printPath_utf8((std::string("WARNING:   removed file: \"")+removedFiles[i]+"\"\n").c_str());
    if (isHaveApkV2Sign){
        printf(isHaveApkV3Sign?
                "WARNING: src removed ApkV2Sign & ApkV3Sign  data (%d Byte, need re-sign)\n"
               :"WARNING: src removed ApkV2Sign data (%d Byte, need re-sign)\n",
                (int)UnZipper_ApkV2SignSize(&unzipper));
    }
    printf("src fileCount: %d  (filseSize: %" PRIu64 ")\n"
            "out fileCount: %d  (filseSize: %" PRIu64 ")\n\n",
            fileCount,unzipper._fileStream.base.streamSize,
            (int)fileIndexs.size(),zipper._fileStream.out_length);

clear:
    _isInClear=true;
    check(UnZipper_close(&unzipper));
    check(Zipper_close(&zipper));
    return result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x308, %rsp            # imm = 0x308
movq %r9, %rbx
movl %r8d, 0x1c(%rsp)
movl %ecx, 0x14(%rsp)
movl %edx, %ebp
movq %rsi, %r14
movq %rdi, %r15
xorps %xmm0, %xmm0
movaps %xmm0, 0x80(%rsp)
andq $0x0, 0x90(%rsp)
movaps %xmm0, 0xa0(%rsp)
andq $0x0, 0xb0(%rsp)
movaps %xmm0, 0xc0(%rsp)
andq $0x0, 0xd0(%rsp)
leaq 0xf8(%rsp), %rdi
callq 0xacb1
leaq 0x1a8(%rsp), %rdi
callq 0xbbbe
leaq 0xf8(%rsp), %rdi
movq %r15, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0xb549
testb %al, %al
je 0x40ba
leaq 0xf8(%rsp), %rdi
callq 0xa7a9
subq $0x8, %rsp
movzbl 0x348(%rsp), %r10d
leaq 0x1b0(%rsp), %rdi
pushq $0x8
popq %r9
movq %r14, %rsi
movl %eax, %edx
movl %ebp, %ecx
movl 0x1c(%rsp), %r8d
pushq $0x1
pushq %r10
pushq %rbx
callq 0xc0b7
addq $0x20, %rsp
testb %al, %al
je 0x40c3
leaq 0xf8(%rsp), %rdi
movq 0x50(%rdi), %rax
movq %rax, 0x78(%rsp)
movq 0x98(%rdi), %rax
movq %rax, 0x70(%rsp)
callq 0xac9a
movb %al, 0x7(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
andq $0x0, 0x30(%rsp)
leaq 0xf8(%rsp), %rdi
callq 0xa7a9
movl %eax, %ebx
movslq %eax, %rsi
leaq 0x20(%rsp), %rdi
callq 0x4a80
xorl %r12d, %r12d
testl %ebx, %ebx
cmovlel %r12d, %ebx
imulq $0x28, %rbx, %r13
leaq 0x50(%rsp), %rbx
leaq 0xf8(%rsp), %r14
xorl %ebp, %ebp
cmpq %r12, %r13
je 0x4157
movq 0x20(%rsp), %r15
movl %ebp, 0x20(%r15,%r12)
movq %rbx, %rdi
movq %r14, %rsi
movl %ebp, %edx
callq 0x48e5
addq %r12, %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0x3360
movq %rbx, %rdi
callq 0x3160
incl %ebp
addq $0x28, %r12
jmp 0x407c
leaq 0x19f96(%rip), %rdi     # 0x1e057
jmp 0x40ca
leaq 0x19fb8(%rip), %rdi     # 0x1e082
callq 0x3440
movl $0x0, 0x8(%rsp)
leaq 0xf8(%rsp), %rdi
callq 0xacbd
movl 0x8(%rsp), %ebx
testb %al, %al
jne 0x40fa
leaq 0x1a1af(%rip), %rdi     # 0x1e2a2
callq 0x3440
xorl %ebx, %ebx
leaq 0x1a8(%rsp), %rdi
callq 0xbbca
testb %al, %al
jne 0x4119
leaq 0x1a1b1(%rip), %rdi     # 0x1e2c3
callq 0x3440
xorl %ebx, %ebx
leaq 0xc0(%rsp), %rdi
callq 0x4a5e
leaq 0xa0(%rsp), %rdi
callq 0x4a5e
leaq 0x80(%rsp), %rdi
callq 0x5458
andb $0x1, %bl
movl %ebx, %eax
addq $0x308, %rsp            # imm = 0x308
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xf8(%rsp), %rdi
callq 0xa7a9
movl %eax, %ebx
movslq %eax, %rsi
leaq 0x50(%rsp), %rdi
leaq 0xd8(%rsp), %rdx
callq 0x4d5c
xorl %eax, %eax
testl %ebx, %ebx
movl $0x0, %ebp
cmovgl %ebx, %ebp
cmpq %rbp, %rax
je 0x41a3
imulq $0x28, %rax, %rcx
addq 0x20(%rsp), %rcx
movq 0x50(%rsp), %rdx
movq %rcx, (%rdx,%rax,8)
incq %rax
jmp 0x4187
movq 0x50(%rsp), %rdi
movq 0x58(%rsp), %rsi
callq 0x4eb3
cmpl $0x2, %ebx
pushq $0x1
popq %r12
movl %ebx, 0x10(%rsp)
cmovgel %ebx, %r12d
decl %r12d
xorl %ebx, %ebx
cmpq %rbx, %r12
je 0x4263
movq 0x50(%rsp), %rax
movq (%rax,%rbx,8), %rax
movl 0x20(%rax), %esi
leaq 0xf8(%rsp), %rdi
callq 0xb6af
testl %eax, %eax
jne 0x425b
movq 0x50(%rsp), %rax
movq (%rax,%rbx,8), %r15
movq 0x8(%rax,%rbx,8), %rax
movq 0x8(%r15), %r14
movq 0x8(%rax), %r13
cmpq %r13, %r14
ja 0x425b
movq (%r15), %rdi
movq (%rax), %rsi
movq %rdi, 0x8(%rsp)
movq %rsi, 0x48(%rsp)
movq %r14, %rdx
callq 0x32e0
testl %eax, %eax
jne 0x425b
testq %r14, %r14
je 0x423d
movq 0x8(%rsp), %rax
movzbl -0x1(%rax,%r14), %eax
cmpl $0x2f, %eax
je 0x4256
cmpl $0x5c, %eax
je 0x4256
cmpq %r13, %r14
jae 0x425b
movq 0x48(%rsp), %rax
movzbl (%rax,%r14), %eax
cmpl $0x5c, %eax
je 0x4256
cmpl $0x2f, %eax
jne 0x425b
orl $-0x1, 0x20(%r15)
incq %rbx
jmp 0x41c6
leaq 0x50(%rsp), %rdi
callq 0x4dda
xorl %ebx, %ebx
pushq $0x20
popq %r14
xorl %r15d, %r15d
movl 0x10(%rsp), %r12d
movslq %r15d, %rsi
cmpq %rbx, %rbp
je 0x42c0
movq 0x20(%rsp), %rcx
movl (%rcx,%r14), %edx
testl %edx, %edx
js 0x42b7
movl %r15d, %eax
cmpq %rax, %rbx
je 0x42b4
leaq (%rcx,%r14), %rax
addq $-0x20, %rax
imulq $0x28, %rsi, %rsi
leaq (%rcx,%rsi), %rdi
movl %edx, 0x20(%rcx,%rsi)
movq %rax, %rsi
callq 0x3240
incl %r15d
incq %rbx
addq $0x28, %r14
jmp 0x427b
leaq 0x20(%rsp), %rdi
callq 0x4a80
movq 0x20(%rsp), %r14
movq 0x28(%rsp), %rbx
movq %rbx, %rax
subq %r14, %rax
pushq $0x28
popq %rcx
cqto
idivq %rcx
movq %rax, 0x48(%rsp)
leaq 0xf8(%rsp), %rdi
callq 0xa7a9
movq %r14, %rdi
movq %rbx, %rsi
movl %eax, %edx
callq 0x550b
subl %r15d, %r12d
movl %r12d, %r15d
xorl %r13d, %r13d
movq 0x48(%rsp), %rcx
testl %ecx, %ecx
movl $0x0, %eax
cmovgl %ecx, %eax
imulq $0x28, %rax, %r14
leaq 0xf8(%rsp), %rbx
pushq $0x11
popq %rbp
xorl %r12d, %r12d
cmpq %r13, %r14
je 0x43c2
movq 0x20(%rsp), %rax
movl 0x20(%rax,%r13), %esi
movl %esi, 0x50(%rsp)
movq %rbx, %rdi
callq 0xa897
testb %al, %al
je 0x4374
incl %r12d
movq 0x70(%rsp), %rax
cmpq 0x78(%rsp), %rax
jae 0x4374
movq 0x20(%rsp), %rsi
addq %r13, %rsi
leaq 0xa0(%rsp), %rdi
callq 0x495e
jmp 0x43a2
movl 0x50(%rsp), %esi
movq %rbx, %rdi
leaq 0x19c62(%rip), %rdx     # 0x1dfe4
movl %ebp, %ecx
callq 0xa945
testb %al, %al
je 0x43a7
movq 0x20(%rsp), %rsi
addq %r13, %rsi
leaq 0xa0(%rsp), %rdi
callq 0x495e
incl %r15d
jmp 0x43b9
leaq 0x80(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x498a
addq $0x28, %r13
jmp 0x432b
movl %r12d, 0x10(%rsp)
movq 0x348(%rsp), %rax
testq %rax, %rax
je 0x43d7
movl %r15d, (%rax)
leaq 0x20(%rsp), %r13
movq %r13, %rdi
callq 0x49a8
pushq $0xa
popq %rdi
callq 0x33a0
movb $0x1, %al
movl %eax, 0x8(%rsp)
xorl %r12d, %r12d
leaq 0x50(%rsp), %r15
leaq 0xf8(%rsp), %rbp
leaq 0xd8(%rsp), %r14
movq 0x80(%rsp), %rax
movq 0x88(%rsp), %rcx
subq %rax, %rcx
shrq $0x2, %rcx
movslq %ecx, %rcx
cmpq %rcx, %r12
jge 0x458c
movl (%rax,%r12,4), %ebx
movq %r15, %rdi
movq %rbp, %rsi
movl %ebx, %edx
callq 0x48e5
cmpb $0x1, 0x2be9b(%rip)     # 0x302e0
jne 0x4485
movq %r14, %rdi
leaq 0x1a1b2(%rip), %rsi     # 0x1e603
movq %r15, %rdx
callq 0x49c9
movq %r13, %rdi
movq %r14, %rsi
leaq 0x18bb1(%rip), %rdx     # 0x1d017
callq 0x3e41
movq 0x20(%rsp), %rdi
callq 0x11fb4
movq %r13, %rdi
callq 0x3160
movq %r14, %rdi
callq 0x3160
cmpl $0x0, 0x14(%rsp)
je 0x4517
movq %rbp, %rdi
movl %ebx, %esi
callq 0x4930
testb %al, %al
je 0x4543
cmpb $0x0, 0x1c(%rsp)
je 0x4533
leaq 0x1a8(%rsp), %rdi
xorl %esi, %esi
callq 0xd872
leaq 0x19d2a(%rip), %rdi     # 0x1e1ed
testb %al, %al
je 0x4565
movq %r14, %rdi
leaq 0x19933(%rip), %rsi     # 0x1de08
movq %r15, %rdx
callq 0x49c9
movq %r13, %rdi
movq %r14, %rsi
leaq 0x1a119(%rip), %rdx     # 0x1e603
callq 0x3e41
movq 0x20(%rsp), %rdi
callq 0x11fb4
movq %r13, %rdi
callq 0x3160
movq %r14, %rdi
callq 0x3160
leaq 0x19c17(%rip), %rdi     # 0x1e127
callq 0x3440
jmp 0x4543
leaq 0x1a8(%rsp), %rdi
xorl %esi, %esi
callq 0xd872
leaq 0x19cc0(%rip), %rdi     # 0x1e1ed
testb %al, %al
jne 0x4543
jmp 0x4565
leaq 0xc0(%rsp), %rdi
movq %r15, %rsi
callq 0x495e
leaq 0x1a8(%rsp), %rdi
movq %rbp, %rsi
movl %ebx, %edx
pushq $0x1
popq %rcx
callq 0xd542
movb $0x1, %bl
leaq 0x19bfb(%rip), %rdi     # 0x1e15c
testb %al, %al
jne 0x4574
callq 0x3440
xorl %ebx, %ebx
movl $0x0, 0x8(%rsp)
movq %r15, %rdi
callq 0x3160
incq %r12
testb %bl, %bl
jne 0x440a
jmp 0x40d7
pushq $0xa
popq %rdi
callq 0x33a0
xorl %r15d, %r15d
leaq 0x1a8(%rsp), %rbx
leaq 0xf8(%rsp), %r14
movq 0x80(%rsp), %rax
movq 0x88(%rsp), %rcx
subq %rax, %rcx
shrq $0x2, %rcx
movslq %ecx, %rcx
cmpq %rcx, %r15
jge 0x462b
movl (%rax,%r15,4), %ebp
cmpl $0x0, 0x14(%rsp)
je 0x45f9
cmpb $0x0, 0x1c(%rsp)
je 0x460b
movq %r14, %rdi
movl %ebp, %esi
callq 0x4930
testb %al, %al
je 0x460b
movq %rbx, %rdi
xorl %esi, %esi
callq 0xd8ac
testb %al, %al
jne 0x460b
jmp 0x47fe
movq %rbx, %rdi
xorl %esi, %esi
callq 0xd872
testb %al, %al
je 0x47f2
movq %rbx, %rdi
movq %r14, %rsi
movl %ebp, %edx
callq 0xd608
incq %r15
testb %al, %al
jne 0x45a7
leaq 0x19c03(%rip), %rdi     # 0x1e229
jmp 0x40ca
leaq 0x1a8(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
callq 0xd657
testb %al, %al
je 0x46ac
xorl %r12d, %r12d
leaq 0x197c2(%rip), %rbx     # 0x1de10
leaq 0x50(%rsp), %r14
leaq 0x19c86(%rip), %r15     # 0x1e2e0
xorl %r13d, %r13d
movq 0xc0(%rsp), %rdx
movq 0xc8(%rsp), %rax
subq %rdx, %rax
shrq $0x5, %rax
cltq
cmpq %rax, %r13
jge 0x46b8
addq %r12, %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x49c9
movq 0x50(%rsp), %rdi
callq 0x11fb4
movq %r14, %rdi
callq 0x3160
movq %r15, %rdi
callq 0x3440
incq %r13
addq $0x20, %r12
jmp 0x465d
leaq 0x19bb3(%rip), %rdi     # 0x1e266
jmp 0x40ca
movl 0x10(%rsp), %esi
testl %esi, %esi
jle 0x46e3
movq 0x70(%rsp), %rax
cmpq 0x78(%rsp), %rax
leaq 0x1974a(%rip), %rax     # 0x1de1b
leaq 0x19784(%rip), %rdi     # 0x1de5c
cmovbq %rax, %rdi
xorl %eax, %eax
callq 0x3050
xorl %r12d, %r12d
leaq 0xd8(%rsp), %r14
leaq 0x20(%rsp), %r13
leaq 0x1891d(%rip), %rbp     # 0x1d017
leaq 0x50(%rsp), %rbx
xorl %r15d, %r15d
movq 0xa8(%rsp), %rax
subq 0xa0(%rsp), %rax
sarq $0x5, %rax
cmpq %rax, %r15
jae 0x477e
movq %r14, %rdi
leaq 0x19786(%rip), %rsi     # 0x1deab
leaq 0x1b(%rsp), %rdx
callq 0x3e60
movq 0xa0(%rsp), %rdx
addq %r12, %rdx
movq %r13, %rdi
movq %r14, %rsi
callq 0x4a3f
movq %rbx, %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0x3e41
movq 0x50(%rsp), %rdi
callq 0x11fb4
movq %rbx, %rdi
callq 0x3160
movq %r13, %rdi
callq 0x3160
movq %r14, %rdi
callq 0x3160
incq %r15
addq $0x20, %r12
jmp 0x4702
movq 0x70(%rsp), %rax
cmpq 0x78(%rsp), %rax
jae 0x47b6
leaq 0x19735(%rip), %rax     # 0x1dec6
leaq 0x19778(%rip), %rdi     # 0x1df10
cmpb $0x0, 0x7(%rsp)
cmovneq %rax, %rdi
movl 0x148(%rsp), %esi
subl 0x190(%rsp), %esi
xorl %eax, %eax
callq 0x3050
movq 0x108(%rsp), %rdx
movq 0x88(%rsp), %rcx
subq 0x80(%rsp), %rcx
shrq $0x2, %rcx
movq 0x1f8(%rsp), %r8
leaq 0x1976c(%rip), %rdi     # 0x1df4d
movq 0x48(%rsp), %rsi
xorl %eax, %eax
callq 0x3050
jmp 0x40d7
leaq 0x199f4(%rip), %rdi     # 0x1e1ed
jmp 0x40ca
leaq 0x199a6(%rip), %rdi     # 0x1e1ab
jmp 0x40ca
jmp 0x4898
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x3160
jmp 0x486f
movq %rax, %rbx
jmp 0x486f
jmp 0x4884
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x3160
jmp 0x4837
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x3160
jmp 0x4848
jmp 0x4893
movq %rax, %rbx
leaq 0xd8(%rsp), %rdi
jmp 0x488c
movq %rax, %rbx
jmp 0x4887
jmp 0x4893
jmp 0x48a9
jmp 0x4884
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x3160
jmp 0x486f
movq %rax, %rbx
leaq 0xd8(%rsp), %rdi
callq 0x3160
jmp 0x4887
jmp 0x4884
jmp 0x4893
jmp 0x4893
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x3160
jmp 0x48b6
movq %rax, %rbx
jmp 0x48b6
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x4dda
jmp 0x48ac
jmp 0x48a9
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x49a8
leaq 0xc0(%rsp), %rdi
callq 0x4a5e
leaq 0xa0(%rsp), %rdi
callq 0x4a5e
leaq 0x80(%rsp), %rdi
callq 0x5458
movq %rbx, %rdi
callq 0x34f0