// File: /workspace/github_cpp_makefile_star2_O2/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, %rbx
movl %r8d, %ebp
movl %ecx, %r12d
movq %rdx, 0x48(%rsp)
movq %rdi, 0x50(%rsp)
andl $0x0, 0x4(%rsp)
andl $0x0, 0x8(%rsp)
movq (%rsi), %rdi
xorl %r13d, %r13d
pushq $0x2
popq %rsi
xorl %eax, %eax
callq 0x2110
testl %eax, %eax
js 0x2c78
movl %ebp, 0x18(%rsp)
movq 0xc0(%rsp), %rbp
movl %eax, %r14d
movl %eax, %edi
callq 0x28f8
pushq $0x3
popq %rdx
pushq $0x2
popq %rcx
xorl %edi, %edi
movq %rax, 0x40(%rsp)
movq %rax, %rsi
movl %r14d, 0x38(%rsp)
movl %r14d, %r8d
xorl %r9d, %r9d
callq 0x2200
movq %rbx, 0x20(%rsp)
cvtsi2sd %rbx, %xmm0
movq %rax, 0x10(%rsp)
cvtsi2sd %r12d, %xmm1
divsd %xmm1, %xmm0
callq 0x2040
cvttsd2si %xmm0, %ecx
leaq 0x60(%rsp), %rax
andl $0x0, (%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
movl %ecx, 0xc(%rsp)
movslq %ecx, %r15
leaq 0x3c(%rsp), %rbx
movl %r13d, %r13d
movq 0x8(%rbp), %rax
subq (%rbp), %rax
sarq $0x3, %rax
cmpq %r13, %rax
jbe 0x2a37
movq %rbp, %rdi
movq %r13, %rsi
callq 0x2ee6
movq (%rax), %rax
cqto
idivq %r15
movq %rax, %r14
movl %edx, 0x28(%rsp)
leaq 0x58(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x2f08
movl %r14d, 0x3c(%rsp)
movq %rax, %rdi
movq %rbx, %rsi
callq 0x32f2
incl %r13d
jmp 0x29e5
xorl %eax, %eax
leaq 0x58(%rsp), %r13
leaq 0x4(%rsp), %rbp
movl %eax, 0x4(%rsp)
cmpl 0xc(%rsp), %eax
jge 0x2ab8
xorl %r14d, %r14d
xorl %ebx, %ebx
movq %r13, %rdi
movq %rbp, %rsi
callq 0x2f56
movl %ebx, %ebx
movq 0x8(%rax), %rcx
subq (%rax), %rcx
sarq $0x2, %rcx
cmpq %rbx, %rcx
jbe 0x2a92
movq %r13, %rdi
movq %rbp, %rsi
callq 0x2f56
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2fa4
cmpl %r12d, (%rax)
setl %al
orb %al, %r14b
incl %ebx
jmp 0x2a52
testb $0x1, %r14b
jne 0x2ab0
movq %r13, %rdi
movq %rbp, %rsi
callq 0x2f56
movq (%rax), %rcx
cmpq %rcx, 0x8(%rax)
je 0x2ab0
movq %rcx, 0x8(%rax)
movl 0x4(%rsp), %eax
incl %eax
jmp 0x2a43
movslq 0x18(%rsp), %r14
movq %r14, %rdi
callq 0x21a0
leaq 0x28(%rsp), %rcx
movq %rax, (%rcx)
movl %r14d, 0x8(%rcx)
subl %r12d, %r14d
movq 0x10(%rsp), %rax
addq 0x20(%rsp), %rax
movq %rax, 0x18(%rsp)
xorl %eax, %eax
leaq 0x58(%rsp), %r13
leaq 0x8(%rsp), %rbp
movl %eax, 0x8(%rsp)
cmpl 0xc(%rsp), %eax
jge 0x2c13
movq %r13, %rdi
movq %rbp, %rsi
callq 0x2f56
movq 0x8(%rax), %rcx
cmpq (%rax), %rcx
je 0x2c08
xorl %eax, %eax
movl %eax, 0x4(%rsp)
cmpl %r12d, %eax
jge 0x2b54
cltq
movq %rax, %rdx
imulq %r15, %rdx
movslq 0x8(%rsp), %rcx
addq %rdx, %rcx
cmpq 0x20(%rsp), %rcx
jge 0x2b42
movq 0x10(%rsp), %rdx
movb (%rdx,%rcx), %cl
jmp 0x2b44
xorl %ecx, %ecx
movq 0x28(%rsp), %rdx
movb %cl, (%rdx,%rax)
movl 0x4(%rsp), %eax
incl %eax
jmp 0x2b17
xorl %eax, %eax
movl %eax, 0x4(%rsp)
cmpl %r14d, %eax
jge 0x2b88
movslq %eax, %rcx
imulq %r15, %rcx
movslq 0x8(%rsp), %rdx
addq 0x18(%rsp), %rcx
movb (%rdx,%rcx), %cl
movq 0x28(%rsp), %rdx
addl %r12d, %eax
cltq
movb %cl, (%rdx,%rax)
movl 0x4(%rsp), %eax
incl %eax
jmp 0x2b56
movq %r13, %rdi
movq %rbp, %rsi
callq 0x2f56
movq 0x50(%rsp), %rdi
leaq 0x28(%rsp), %rsi
movl %r14d, %edx
movq %rax, %rcx
callq 0x25f4
xorl %ebx, %ebx
movq %r13, %rdi
movq %rbp, %rsi
callq 0x2f56
movl %ebx, %ebx
movq 0x8(%rax), %rcx
subq (%rax), %rcx
sarq $0x2, %rcx
cmpq %rbx, %rcx
jbe 0x2c08
movq %r13, %rdi
movq %rbp, %rsi
callq 0x2f56
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2fa4
movslq (%rax), %rax
cmpl %r12d, %eax
jge 0x2c04
movq 0x28(%rsp), %rcx
movb (%rcx,%rax), %cl
imull 0xc(%rsp), %eax
movslq 0x8(%rsp), %rdx
cltq
addq %rdx, %rax
movq 0x10(%rsp), %rdx
movb %cl, (%rdx,%rax)
incl %ebx
jmp 0x2baa
movl 0x8(%rsp), %eax
incl %eax
jmp 0x2aef
movq 0x48(%rsp), %rax
movq (%rax), %rdi
leaq 0x13e2(%rip), %rsi      # 0x4004
callq 0x2180
movq %rax, %rbx
pushq $0x1
popq %rsi
movq 0x10(%rsp), %r14
movq %r14, %rdi
movq 0x20(%rsp), %rdx
movq %rax, %rcx
callq 0x2230
movq %rbx, %rdi
callq 0x2140
movl 0x38(%rsp), %edi
callq 0x2240
movq %r14, %rdi
movq 0x40(%rsp), %rsi
callq 0x20d0
movq 0x28(%rsp), %rdi
callq 0x2190
leaq 0x58(%rsp), %rdi
callq 0x2fd0
xorl %eax, %eax
jmp 0x2c7b
pushq $0x1
popq %rax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x2c9b
jmp 0x2c9b
jmp 0x2c9b
jmp 0x2c9b
jmp 0x2c9b
jmp 0x2c9b
jmp 0x2c9b
movq %rax, %rbx
leaq 0x58(%rsp), %rdi
callq 0x2fd0
movq %rbx, %rdi
callq 0x21f0