// File: jansucan[P]diff-dd/src/restore.cpp
// Function: restore(Options::Restore const&)
void
restore(const Options::Restore &opts)
{
    std::fstream diff_stream;
    diff_stream.open(opts.getDiffFilePath(),
                     std::ifstream::in | std::ifstream::binary);
    if (!diff_stream) {
        throw RestoreError("cannot open diff file");
    }

    FormatV2::Reader diff_reader(diff_stream, opts.getBufferSize());

    std::fstream out_file;
    out_file.open(opts.getOutFilePath(),
                  std::ios::in | std::ios::out | std::ios::binary);
    if (!out_file) {
        throw RestoreError("cannot open output file");
    }

    for (;;) {
        const uint64_t offset{diff_reader.readOffset()};
        if (diff_reader.eof()) {
            break;
        }

        if (!out_file.seekp(offset, std::ios_base::beg)) {
            throw RestoreError("cannot seek in output file");
        }

        uint64_t size{diff_reader.readSize()};

        while (size > 0) {
            const FormatV2::RecordData rd{diff_reader.readRecordData(size)};
            if (rd.size == 0) {
                break;
            }

            if (!out_file.write(rd.data.get(), rd.size)) {
                throw RestoreError("cannot write to output file");
            }

            size -= rd.size;
        }

        if (size > 0) {
            throw RestoreError("cannot read all the data of the record");
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x680, %rsp            # imm = 0x680
movq %rdi, -0x8(%rbp)
leaq -0x218(%rbp), %rdi
callq 0x3360
movq -0x8(%rbp), %rsi
leaq -0x240(%rbp), %rdi
callq 0xaae0
jmp 0xc76d
movl $0x8, %edi
movl $0x4, %esi
callq 0x7790
movl %eax, -0x5d8(%rbp)
jmp 0xc784
movl -0x5d8(%rbp), %edx
leaq -0x218(%rbp), %rdi
leaq -0x240(%rbp), %rsi
callq 0xd0b0
jmp 0xc79f
leaq -0x240(%rbp), %rdi
callq 0x77f0
movq -0x218(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x218(%rbp,%rax), %rdi
callq 0x3160
movb %al, -0x5d9(%rbp)
jmp 0xc7cb
movb -0x5d9(%rbp), %al
testb $0x1, %al
jne 0xc7da
jmp 0xc8f0
movb $0x1, -0x272(%rbp)
movl $0x10, %edi
callq 0x3180
movq %rax, -0x5f0(%rbp)
leaq -0x271(%rbp), %rdi
movq %rdi, -0x5e8(%rbp)
callq 0x34a0
movq -0x5e8(%rbp), %rdx
leaq 0x20df(%rip), %rsi      # 0xe8f2
leaq -0x270(%rbp), %rdi
callq 0x47f0
jmp 0xc821
movq -0x5f0(%rbp), %rdi
leaq -0x270(%rbp), %rsi
callq 0xd0f0
jmp 0xc836
movq -0x5f0(%rbp), %rdi
movb $0x0, -0x272(%rbp)
leaq 0x8495(%rip), %rsi      # 0x14ce0
leaq 0x8de(%rip), %rdx       # 0xd130
callq 0x3480
jmp 0xcfba
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
jmp 0xcfa2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
leaq -0x240(%rbp), %rdi
callq 0x77f0
jmp 0xcfa2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
jmp 0xc8c8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
leaq -0x270(%rbp), %rdi
callq 0x3528
leaq -0x271(%rbp), %rdi
callq 0x32f0
testb $0x1, -0x272(%rbp)
jne 0xc8df
jmp 0xc8eb
movq -0x5f0(%rbp), %rdi
callq 0x3200
jmp 0xcfa2
movq -0x8(%rbp), %rdi
callq 0xaad0
movl %eax, -0x5f4(%rbp)
jmp 0xc901
movl -0x5f4(%rbp), %eax
movl %eax, %eax
movl %eax, %edx
leaq -0x2d0(%rbp), %rdi
leaq -0x218(%rbp), %rsi
callq 0xd150
jmp 0xc920
leaq -0x4e0(%rbp), %rdi
callq 0x3360
jmp 0xc92e
movq -0x8(%rbp), %rsi
leaq -0x508(%rbp), %rdi
callq 0xab10
jmp 0xc940
movl $0x8, %edi
movl $0x10, %esi
callq 0x7790
movl %eax, -0x5f8(%rbp)
jmp 0xc957
movl -0x5f8(%rbp), %edi
movl $0x4, %esi
callq 0x7790
movl %eax, -0x5fc(%rbp)
jmp 0xc96f
movl -0x5fc(%rbp), %edx
leaq -0x4e0(%rbp), %rdi
leaq -0x508(%rbp), %rsi
callq 0xd0b0
jmp 0xc98a
leaq -0x508(%rbp), %rdi
callq 0x77f0
movq -0x4e0(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x4e0(%rbp,%rax), %rdi
callq 0x3160
movb %al, -0x5fd(%rbp)
jmp 0xc9b6
movb -0x5fd(%rbp), %al
testb $0x1, %al
jne 0xc9c5
jmp 0xcaf2
movb $0x1, -0x52a(%rbp)
movl $0x10, %edi
callq 0x3180
movq %rax, -0x610(%rbp)
leaq -0x529(%rbp), %rdi
movq %rdi, -0x608(%rbp)
callq 0x34a0
movq -0x608(%rbp), %rdx
leaq 0x1a73(%rip), %rsi      # 0xe471
leaq -0x528(%rbp), %rdi
callq 0x47f0
jmp 0xca0c
movq -0x610(%rbp), %rdi
leaq -0x528(%rbp), %rsi
callq 0xd0f0
jmp 0xca21
movq -0x610(%rbp), %rdi
movb $0x0, -0x52a(%rbp)
leaq 0x82aa(%rip), %rsi      # 0x14ce0
leaq 0x6f3(%rip), %rdx       # 0xd130
callq 0x3480
jmp 0xcfba
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
jmp 0xcf96
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
jmp 0xcf8a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
leaq -0x508(%rbp), %rdi
callq 0x77f0
jmp 0xcf8a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
jmp 0xcaca
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
leaq -0x528(%rbp), %rdi
callq 0x3528
leaq -0x529(%rbp), %rdi
callq 0x32f0
testb $0x1, -0x52a(%rbp)
jne 0xcae1
jmp 0xcaed
movq -0x610(%rbp), %rdi
callq 0x3200
jmp 0xcf8a
jmp 0xcaf4
leaq -0x2d0(%rbp), %rdi
callq 0xd1c0
movq %rax, -0x618(%rbp)
jmp 0xcb09
movq -0x618(%rbp), %rax
movq %rax, -0x538(%rbp)
leaq -0x2d0(%rbp), %rdi
callq 0xd210
movb %al, -0x619(%rbp)
jmp 0xcb2b
movb -0x619(%rbp), %al
testb $0x1, %al
jne 0xcb37
jmp 0xcb3c
jmp 0xcf5d
leaq -0x4d0(%rbp), %rdi
movq -0x538(%rbp), %rsi
xorl %edx, %edx
callq 0x32a0
movq %rax, -0x628(%rbp)
jmp 0xcb5a
movq -0x628(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x3160
movb %al, -0x629(%rbp)
jmp 0xcb78
movb -0x629(%rbp), %al
testb $0x1, %al
jne 0xcb87
jmp 0xcc63
movb $0x1, -0x55a(%rbp)
movl $0x10, %edi
callq 0x3180
movq %rax, -0x640(%rbp)
leaq -0x559(%rbp), %rdi
movq %rdi, -0x638(%rbp)
callq 0x34a0
movq -0x638(%rbp), %rdx
leaq 0x1d48(%rip), %rsi      # 0xe908
leaq -0x558(%rbp), %rdi
callq 0x47f0
jmp 0xcbce
movq -0x640(%rbp), %rdi
leaq -0x558(%rbp), %rsi
callq 0xd0f0
jmp 0xcbe3
movq -0x640(%rbp), %rdi
movb $0x0, -0x55a(%rbp)
leaq 0x80e8(%rip), %rsi      # 0x14ce0
leaq 0x531(%rip), %rdx       # 0xd130
callq 0x3480
jmp 0xcfba
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
jmp 0xcc3b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
leaq -0x558(%rbp), %rdi
callq 0x3528
leaq -0x559(%rbp), %rdi
callq 0x32f0
testb $0x1, -0x55a(%rbp)
jne 0xcc52
jmp 0xcc5e
movq -0x640(%rbp), %rdi
callq 0x3200
jmp 0xcf8a
leaq -0x2d0(%rbp), %rdi
callq 0xd230
movq %rax, -0x648(%rbp)
jmp 0xcc78
movq -0x648(%rbp), %rax
movq %rax, -0x568(%rbp)
cmpq $0x0, -0x568(%rbp)
jbe 0xce71
movq -0x568(%rbp), %rdx
leaq -0x580(%rbp), %rdi
leaq -0x2d0(%rbp), %rsi
callq 0xd280
jmp 0xccb0
cmpq $0x0, -0x580(%rbp)
jne 0xccc9
movl $0x5, -0x584(%rbp)
jmp 0xce41
leaq -0x4d0(%rbp), %rax
movq %rax, -0x658(%rbp)
leaq -0x578(%rbp), %rdi
callq 0x4970
movq -0x658(%rbp), %rdi
movq %rax, %rsi
movq -0x580(%rbp), %rdx
callq 0x33f0
movq %rax, -0x650(%rbp)
jmp 0xcd02
movq -0x650(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x3160
movb %al, -0x659(%rbp)
jmp 0xcd20
movb -0x659(%rbp), %al
testb $0x1, %al
jne 0xcd2f
jmp 0xce1f
movb $0x1, -0x5aa(%rbp)
movl $0x10, %edi
callq 0x3180
movq %rax, -0x670(%rbp)
leaq -0x5a9(%rbp), %rdi
movq %rdi, -0x668(%rbp)
callq 0x34a0
movq -0x668(%rbp), %rdx
leaq 0x1bbb(%rip), %rsi      # 0xe923
leaq -0x5a8(%rbp), %rdi
callq 0x47f0
jmp 0xcd76
movq -0x670(%rbp), %rdi
leaq -0x5a8(%rbp), %rsi
callq 0xd0f0
jmp 0xcd8b
movq -0x670(%rbp), %rdi
movb $0x0, -0x5aa(%rbp)
leaq 0x7f40(%rip), %rsi      # 0x14ce0
leaq 0x389(%rip), %rdx       # 0xd130
callq 0x3480
jmp 0xcfba
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
jmp 0xce60
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
jmp 0xcdfa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
leaq -0x5a8(%rbp), %rdi
callq 0x3528
leaq -0x5a9(%rbp), %rdi
callq 0x32f0
testb $0x1, -0x5aa(%rbp)
jne 0xce11
jmp 0xce1d
movq -0x670(%rbp), %rdi
callq 0x3200
jmp 0xce60
movq -0x580(%rbp), %rcx
movq -0x568(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x568(%rbp)
movl $0x0, -0x584(%rbp)
leaq -0x580(%rbp), %rdi
callq 0x9830
movl -0x584(%rbp), %eax
testl %eax, %eax
je 0xce5b
jmp 0xce59
jmp 0xce71
jmp 0xcc86
leaq -0x580(%rbp), %rdi
callq 0x9830
jmp 0xcf8a
cmpq $0x0, -0x568(%rbp)
jbe 0xcf58
movb $0x1, -0x5d2(%rbp)
movl $0x10, %edi
callq 0x3180
movq %rax, -0x680(%rbp)
leaq -0x5d1(%rbp), %rdi
movq %rdi, -0x678(%rbp)
callq 0x34a0
movq -0x678(%rbp), %rdx
leaq 0x1a87(%rip), %rsi      # 0xe93f
leaq -0x5d0(%rbp), %rdi
callq 0x47f0
jmp 0xcec6
movq -0x680(%rbp), %rdi
leaq -0x5d0(%rbp), %rsi
callq 0xd0f0
jmp 0xcedb
movq -0x680(%rbp), %rdi
movb $0x0, -0x5d2(%rbp)
leaq 0x7df0(%rip), %rsi      # 0x14ce0
leaq 0x239(%rip), %rdx       # 0xd130
callq 0x3480
jmp 0xcfba
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
jmp 0xcf33
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x248(%rbp)
movl %eax, -0x24c(%rbp)
leaq -0x5d0(%rbp), %rdi
callq 0x3528
leaq -0x5d1(%rbp), %rdi
callq 0x32f0
testb $0x1, -0x5d2(%rbp)
jne 0xcf4a
jmp 0xcf56
movq -0x680(%rbp), %rdi
callq 0x3200
jmp 0xcf8a
jmp 0xcaf4
leaq -0x4e0(%rbp), %rdi
callq 0x3060
leaq -0x2d0(%rbp), %rdi
callq 0xd2e0
leaq -0x218(%rbp), %rdi
callq 0x3060
addq $0x680, %rsp            # imm = 0x680
popq %rbp
retq
leaq -0x4e0(%rbp), %rdi
callq 0x3060
leaq -0x2d0(%rbp), %rdi
callq 0xd2e0
leaq -0x218(%rbp), %rdi
callq 0x3060
movq -0x248(%rbp), %rdi
callq 0x3490
nopw (%rax,%rax)