// File: /workspace/github_cpp_makefile_star2_O3/NinjaDevelper[P]ReedSolomon/cxx/ReedSolomon.cpp
// Function: ReedSolomon::encodeFile(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)
int ReedSolomon::encodeFile(string origFile,string encodedFile,int K,int N){
    int i=0;
    int k=0;

    int fin=open(origFile.c_str(),O_RDONLY);
    if(fin<0){
        return 1;
    }
    int fout=open(encodedFile.c_str(),O_RDWR|O_CREAT, S_IRUSR | S_IWUSR);
    long size=getSize(fin);

    int interleave=ceil((double)size/K);
    long writeSize=size+interleave*(N-K);

    //write a last byte to ensure the output file size 
    lseek(fout,writeSize-1,SEEK_SET);
    write(fout,"",1);
    lseek(fout,0,SEEK_SET);

    unsigned char *inBuf =
        (unsigned char*) mmap(NULL, size, PROT_READ, MAP_SHARED, fin, 0);
    unsigned char *outBuf = 
        (unsigned char*)mmap(NULL, writeSize, PROT_WRITE, MAP_SHARED,
                               fout, 0);

    POLY generator={(unsigned char*)malloc(N-K+1),N-K+1};
    calcGenerator(generator);
    POLY msgIn={(unsigned char*)calloc(N,1),K}; 

    //collect data in row , encode, and write parities.
    unsigned char c=0;
    long loc=0;
    unsigned char *parity=NULL;
    for(k=0;k<interleave;k++){
        for(i=0;i<K;i++){
            loc=(long)i*interleave+k;
            if(loc<size){
                c=inBuf[loc];
                outBuf[loc]=c;
            }else{
                c=0;
            }
            msgIn.data[i]=c;
        }
        parity=encodeMessage(msgIn,generator);
        for(i=0;i<N-K;i++){
            loc=size+(long)i*interleave+k;
            outBuf[loc]=parity[i];
            parity[i]=0;
        }
    }
    munmap(inBuf,size);
    munmap(outBuf,writeSize);
    close(fin);
    close(fout);
    free(generator.data);
    free(msgIn.data);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movl %r8d, %ebp
movl %ecx, %r12d
movq %rdx, %rbx
movq %rdi, %r15
movq (%rsi), %rdi
xorl %esi, %esi
xorl %eax, %eax
callq 0x2100
testl %eax, %eax
js 0x30f7
movl %eax, %r14d
movq (%rbx), %rdi
movl $0x42, %esi
movl $0x180, %edx            # imm = 0x180
xorl %eax, %eax
callq 0x2100
movl %eax, %ebx
movl %r14d, %edi
xorl %esi, %esi
movl $0x2, %edx
callq 0x2210
movq %rax, %r13
movl %r14d, %edi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2210
cvtsi2sd %r13, %xmm0
cvtsi2sd %r12d, %xmm1
divsd %xmm1, %xmm0
callq 0x2040
cvttsd2si %xmm0, %ecx
movl %ecx, 0x10(%rsp)
movl %ebp, 0x1c(%rsp)
subl %r12d, %ebp
movl %ebp, %eax
imull %ecx, %eax
cltq
movl %r12d, 0x4(%rsp)
leaq (%rax,%r13), %r12
leaq (%rax,%r13), %rsi
decq %rsi
movl %ebx, %edi
xorl %edx, %edx
callq 0x2210
leaq 0x10ec(%rip), %rsi      # 0x4050
movl $0x1, %edx
movl %ebx, %edi
callq 0x2060
movl %ebx, %edi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2210
xorl %edi, %edi
movq %r13, %rsi
movl $0x1, %edx
movl $0x1, %ecx
movl %r14d, 0x24(%rsp)
movl %r14d, %r8d
xorl %r9d, %r9d
callq 0x21f0
movq %rax, 0x30(%rsp)
xorl %edi, %edi
movq %r12, 0x38(%rsp)
movq %r12, %rsi
movl $0x2, %edx
movl $0x1, %ecx
movl %ebx, 0x20(%rsp)
movl %ebx, %r8d
xorl %r9d, %r9d
callq 0x21f0
movq %rax, 0x8(%rsp)
movq %rbp, 0x28(%rsp)
leal 0x1(%rbp), %eax
movslq %eax, %r14
movq %r14, %rdi
callq 0x2190
leaq 0x58(%rsp), %rsi
movq %rax, (%rsi)
movl %r14d, 0x8(%rsi)
movq %r15, 0x40(%rsp)
movq %r15, %rdi
callq 0x24fa
movslq 0x1c(%rsp), %rdi
movl $0x1, %esi
callq 0x20d0
movq %rax, %r14
movl 0x10(%rsp), %eax
movq %r14, 0x48(%rsp)
movl 0x4(%rsp), %ecx
movl %ecx, 0x50(%rsp)
testl %eax, %eax
jle 0x30b3
movl %eax, %ebp
movq 0x8(%rsp), %rdi
addq %r13, %rdi
movl 0x4(%rsp), %r15d
movl 0x28(%rsp), %ebx
xorl %r12d, %r12d
movq %rdi, 0x10(%rsp)
cmpl $0x0, 0x4(%rsp)
movq 0x30(%rsp), %rsi
movq 0x8(%rsp), %rdi
jle 0x306d
movq %r12, %rax
xorl %ecx, %ecx
cmpq %r13, %rax
jge 0x305c
movb (%rsi,%rax), %dl
movb %dl, (%rdi,%rax)
jmp 0x305e
xorl %edx, %edx
movb %dl, (%r14,%rcx)
incq %rcx
addq %rbp, %rax
cmpq %rcx, %r15
jne 0x304f
movq 0x40(%rsp), %rdi
leaq 0x48(%rsp), %rsi
leaq 0x58(%rsp), %rdx
callq 0x258c
cmpl $0x0, 0x28(%rsp)
movq 0x10(%rsp), %rdi
jle 0x30a8
movq %rdi, %rcx
xorl %edx, %edx
movb (%rax,%rdx), %sil
movb %sil, (%rcx)
movb $0x0, (%rax,%rdx)
incq %rdx
addq %rbp, %rcx
cmpq %rdx, %rbx
jne 0x3092
incq %r12
incq %rdi
cmpq %rbp, %r12
jne 0x3034
movq 0x30(%rsp), %rdi
movq %r13, %rsi
callq 0x20c0
movq 0x8(%rsp), %rdi
movq 0x38(%rsp), %rsi
callq 0x20c0
movl 0x24(%rsp), %edi
callq 0x2230
movl 0x20(%rsp), %edi
callq 0x2230
movq 0x58(%rsp), %rdi
callq 0x2180
movq %r14, %rdi
callq 0x2180
xorl %eax, %eax
jmp 0x30fc
movl $0x1, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop