// File: /workspace/github_cpp_makefile_star2_O3/NinjaDevelper[P]ReedSolomon/cxx/ReedSolomon.cpp
// Function: ReedSolomon::decodeFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int, int, long, std::vector<long, std::allocator<long>>&)
int ReedSolomon::decodeFile(string inFile,string outFile,int K,int N,
                            long size,vector<long>&errLoc){
    int i=0;
    int k=0;

    int fin=open(inFile.c_str(),O_RDWR);
    if(fin<0){
        return 1;
    }
    long inSize=getSize(fin);

    //use MAP_PRIVATE not to copy mem to file.
    unsigned char *buf = 
        (unsigned char*)mmap(NULL, inSize, PROT_READ|PROT_WRITE, 
                               MAP_PRIVATE, fin, 0);

    int interleave=ceil((double)size/K);
    map<int, vector<int> > errors;

    //translate location in file to column/row number of 
    //K x interleave length matrix.
    for(unsigned int i=0;i<errLoc.size();i++){
        long loc=errLoc.at(i);
        errors[loc%interleave].push_back(loc/interleave);
    }
    //it error does not exist in data area but in parity area, ignore it.
    for(i=0;i<interleave;i++){
        bool existData=false;
        for(unsigned int k=0;k<errors[i].size();k++){
            if(errors[i].at(k)<K) existData=true;
        }
        if(!existData) errors[i].clear();
    }
    POLY msgIn={(unsigned char*)malloc(N),N}; 

    //collect data in row , and execute correction.
    unsigned char c=0;
    long loc=0;
    int e=0;
    for(k=0;k<interleave;k++){
        if(errors[k].size()==0) continue;
        for(i=0;i<K;i++){
            loc=(long)i*interleave+k;
            if(loc<size){
                c=buf[loc];
            }else{
                c=0;
            }
            msgIn.data[i]=c;
        }
        for(i=0;i<N-K;i++){
            loc=size+(long)i*interleave+k;
            c=buf[loc];
            msgIn.data[K+i]=c;
        }
        correct(msgIn,N-K,errors[k]);
        for(unsigned int i=0;i<errors[k].size();i++){
            e=errors[k].at(i);
            if(e<K)
                buf[e*interleave+k]=msgIn.data[e];
        }
    }

    //copy only data area to destination file.
    FILE *fp=fopen(outFile.c_str(),"wb");
    fwrite(buf,1,size,fp);
    fclose(fp);

    close(fin);
    munmap(buf,inSize);
    free(msgIn.data);

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %r9, %r15
movl %r8d, %ebx
movl %ecx, %r13d
movq %rdx, 0x48(%rsp)
movq %rdi, 0x50(%rsp)
xorl %eax, %eax
movl %eax, 0x8(%rsp)
movl %eax, 0xc(%rsp)
movq (%rsi), %rdi
movl $0x2, %esi
xorl %eax, %eax
callq 0x2100
testl %eax, %eax
js 0x2dd2
movl %ebx, 0x14(%rsp)
movq 0xc0(%rsp), %r14
xorl %ebx, %ebx
movl %eax, %ebp
movl %eax, %edi
xorl %esi, %esi
movl $0x2, %edx
callq 0x2210
movq %rax, %r12
movl %ebp, %edi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2210
xorl %edi, %edi
movq %r12, 0x40(%rsp)
movq %r12, %rsi
movl $0x3, %edx
movl $0x2, %ecx
movl %ebp, 0x38(%rsp)
movl %ebp, %r8d
xorl %r9d, %r9d
callq 0x21f0
movq %r15, 0x30(%rsp)
cvtsi2sd %r15, %xmm0
movq %rax, 0x28(%rsp)
cvtsi2sd %r13d, %xmm1
divsd %xmm1, %xmm0
callq 0x2040
cvttsd2si %xmm0, %eax
movl %eax, 0x10(%rsp)
leaq 0x60(%rsp), %rax
movl $0x0, (%rax)
movq %rbx, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
movq %rbx, 0x20(%rax)
movq (%r14), %rax
cmpq %rax, 0x8(%r14)
je 0x2b97
movslq 0x10(%rsp), %r12
movl $0x1, %ebx
xorl %ecx, %ecx
leaq 0x18(%rsp), %r15
movq (%rax,%rcx,8), %rax
cqto
idivq %r12
movq %rax, %rbp
movl %edx, 0x18(%rsp)
leaq 0x58(%rsp), %rdi
movq %r15, %rsi
callq 0x310c
movl %ebp, 0x3c(%rsp)
movq 0x8(%rax), %rsi
cmpq 0x10(%rax), %rsi
je 0x2b73
movl %ebp, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x8(%rax)
jmp 0x2b80
movq %rax, %rdi
leaq 0x3c(%rsp), %rdx
callq 0x3462
movl %ebx, %ecx
movq (%r14), %rax
movq 0x8(%r14), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
incl %ebx
cmpq %rcx, %rdx
ja 0x2b3c
movl $0x0, 0x8(%rsp)
cmpl $0x0, 0x10(%rsp)
movl 0x14(%rsp), %r12d
jle 0x2ddc
xorl %r14d, %r14d
leaq 0x58(%rsp), %r15
leaq 0x8(%rsp), %rbp
xorl %ebx, %ebx
movq %r15, %rdi
movq %rbp, %rsi
callq 0x3172
movl %ebx, %ebx
movq 0x8(%rax), %rcx
subq (%rax), %rcx
sarq $0x2, %rcx
cmpq %rbx, %rcx
jbe 0x2c0e
movq %r15, %rdi
movq %rbp, %rsi
callq 0x3172
movq (%rax), %rcx
movq 0x8(%rax), %rdx
subq %rcx, %rdx
sarq $0x2, %rdx
cmpq %rbx, %rdx
jbe 0x2e80
cmpl %r13d, (%rcx,%rbx,4)
setl %al
orb %r14b, %al
incl %ebx
movl %eax, %r14d
jmp 0x2bbe
testb $0x1, %r14b
jne 0x2c2c
movq %r15, %rdi
movq %rbp, %rsi
callq 0x3172
movq (%rax), %rcx
cmpq %rcx, 0x8(%rax)
je 0x2c2c
movq %rcx, 0x8(%rax)
movl 0x8(%rsp), %eax
incl %eax
movl %eax, 0x8(%rsp)
xorl %r14d, %r14d
movl $0x0, %ebx
cmpl 0x10(%rsp), %eax
jl 0x2bbe
movslq %r12d, %rdi
callq 0x2190
movq %rax, 0x18(%rsp)
movl %r12d, 0x20(%rsp)
movl $0x0, 0xc(%rsp)
cmpl $0x0, 0x10(%rsp)
jle 0x2df8
movl 0x10(%rsp), %r12d
subl %r13d, 0x14(%rsp)
movq 0x28(%rsp), %r14
addq 0x30(%rsp), %r14
leaq 0x58(%rsp), %rbp
leaq 0xc(%rsp), %r15
movq %rbp, %rdi
movq %r15, %rsi
callq 0x3172
movq 0x8(%rax), %rcx
cmpq (%rax), %rcx
je 0x2dbc
movl $0x0, 0x8(%rsp)
testl %r13d, %r13d
jle 0x2ced
xorl %eax, %eax
cltq
movq %rax, %rdx
imulq %r12, %rdx
movslq 0xc(%rsp), %rcx
addq %rdx, %rcx
cmpq 0x30(%rsp), %rcx
jge 0x2cd4
movq 0x28(%rsp), %rdx
movb (%rdx,%rcx), %cl
jmp 0x2cd6
xorl %ecx, %ecx
movq 0x18(%rsp), %rdx
movb %cl, (%rdx,%rax)
movl 0x8(%rsp), %eax
incl %eax
movl %eax, 0x8(%rsp)
cmpl %r13d, %eax
jl 0x2cb2
movl $0x0, 0x8(%rsp)
movl 0x14(%rsp), %esi
testl %esi, %esi
jle 0x2d2e
xorl %eax, %eax
cltq
movq %rax, %rcx
imulq %r12, %rcx
movslq 0xc(%rsp), %rdx
addq %r14, %rcx
movb (%rdx,%rcx), %cl
movq 0x18(%rsp), %rdx
addl %r13d, %eax
cltq
movb %cl, (%rdx,%rax)
movl 0x8(%rsp), %eax
incl %eax
movl %eax, 0x8(%rsp)
cmpl %esi, %eax
jl 0x2cff
movq %rbp, %rdi
movq %r15, %rsi
callq 0x3172
movq 0x50(%rsp), %rdi
leaq 0x18(%rsp), %rsi
movl 0x14(%rsp), %edx
movq %rax, %rcx
callq 0x2652
xorl %ebx, %ebx
movq %rbp, %rdi
movq %r15, %rsi
callq 0x3172
movl %ebx, %ebx
movq 0x8(%rax), %rcx
subq (%rax), %rcx
sarq $0x2, %rcx
cmpq %rbx, %rcx
jbe 0x2dbc
movq %rbp, %rdi
movq %r15, %rsi
callq 0x3172
movq (%rax), %rcx
movq 0x8(%rax), %rdx
subq %rcx, %rdx
sarq $0x2, %rdx
cmpq %rbx, %rdx
jbe 0x2e6f
movslq (%rcx,%rbx,4), %rax
cmpl %r13d, %eax
jge 0x2db8
movq 0x18(%rsp), %rcx
movb (%rcx,%rax), %cl
imull 0x10(%rsp), %eax
movslq 0xc(%rsp), %rdx
cltq
addq %rdx, %rax
movq 0x28(%rsp), %rdx
movb %cl, (%rdx,%rax)
incl %ebx
jmp 0x2d51
movl 0xc(%rsp), %eax
incl %eax
movl %eax, 0xc(%rsp)
cmpl 0x10(%rsp), %eax
jl 0x2c8b
jmp 0x2df8
movl $0x1, %eax
jmp 0x2e5d
movslq %r12d, %rbx
movq %rbx, %rdi
callq 0x2190
movq %rax, 0x18(%rsp)
movl %ebx, 0x20(%rsp)
movl $0x0, 0xc(%rsp)
movq 0x48(%rsp), %rax
movq (%rax), %rdi
leaq 0x11fd(%rip), %rsi      # 0x4004
callq 0x2170
movq %rax, %rbx
movl $0x1, %esi
movq 0x28(%rsp), %r14
movq %r14, %rdi
movq 0x30(%rsp), %rdx
movq %rax, %rcx
callq 0x2220
movq %rbx, %rdi
callq 0x2130
movl 0x38(%rsp), %edi
callq 0x2230
movq %r14, %rdi
movq 0x40(%rsp), %rsi
callq 0x20c0
movq 0x18(%rsp), %rdi
callq 0x2180
leaq 0x58(%rsp), %rdi
callq 0x31e2
xorl %eax, %eax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1191(%rip), %rdi      # 0x4007
movq %rbx, %rsi
xorl %eax, %eax
callq 0x21b0
leaq 0x1180(%rip), %rdi      # 0x4007
movq %rbx, %rsi
xorl %eax, %eax
callq 0x21b0
jmp 0x2ea1
jmp 0x2ea1
jmp 0x2ea1
jmp 0x2ea1
jmp 0x2ea1
jmp 0x2ea1
jmp 0x2ea1
jmp 0x2ea1
movq %rax, %rbx
leaq 0x58(%rsp), %rdi
callq 0x31e2
movq %rbx, %rdi
callq 0x21e0