// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x4c8, %rsp            # imm = 0x4C8
movq %rdi, %rbx
leaq 0x2b8(%rsp), %rdi
callq 0x3250
leaq 0xa8(%rsp), %rdi
movq %rbx, %rsi
callq 0x5bf6
movq 0xa8(%rsp), %rsi
leaq 0x2b8(%rsp), %rdi
pushq $0xc
popq %rdx
callq 0x31e0
leaq 0xa8(%rsp), %rdi
callq 0x49f0
movq 0x2b8(%rsp), %rax
movq -0x18(%rax), %rax
testb $0x5, 0x2d8(%rsp,%rax)
jne 0x6a90
movq %rbx, %rdi
callq 0x5bf2
movl %eax, %edx
leaq 0x50(%rsp), %rdi
leaq 0x2b8(%rsp), %rsi
callq 0x6c26
leaq 0xa8(%rsp), %rdi
callq 0x3250
leaq 0x10(%rsp), %rdi
movq %rbx, %rsi
callq 0x5c08
movq 0x10(%rsp), %rsi
leaq 0xa8(%rsp), %rdi
pushq $0x1c
popq %rdx
callq 0x31e0
leaq 0x10(%rsp), %rdi
callq 0x49f0
movq 0xa8(%rsp), %rax
movq -0x18(%rax), %rax
testb $0x5, 0xc8(%rsp,%rax)
jne 0x6ae1
leaq 0xb8(%rsp), %rbx
leaq 0x48(%rsp), %r14
leaq 0x50(%rsp), %r15
leaq 0x38(%rsp), %r12
movq %r15, %rdi
callq 0x6c5c
cmpb $0x0, 0xa0(%rsp)
jne 0x69be
movq %rbx, %rdi
movq %rax, %rsi
xorl %edx, %edx
callq 0x3200
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x6a42
movq %r15, %rdi
callq 0x6c8a
movq %rax, %r13
testq %r13, %r13
je 0x68d6
movq %r12, %rdi
movq %r15, %rsi
movq %r13, %rdx
callq 0x6cb6
movq 0x38(%rsp), %rbp
testq %rbp, %rbp
je 0x695a
movq 0x40(%rsp), %rsi
movq %rbx, %rdi
movq %rbp, %rdx
callq 0x32c0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x69f4
subq 0x38(%rsp), %r13
movq %r14, %rdi
callq 0x3ed0
testq %rbp, %rbp
jne 0x6916
testq %r13, %r13
je 0x68d6
pushq $0x10
popq %rdi
callq 0x3130
movq %rax, %r14
leaq 0x1fa8(%rip), %rsi      # 0x892a
leaq 0x10(%rsp), %rdi
leaq 0x38(%rsp), %rdx
callq 0x3e0e
movb $0x1, %bpl
leaq 0x10(%rsp), %rsi
movq %r14, %rdi
callq 0x6c10
xorl %ebp, %ebp
leaq 0x6336(%rip), %rsi      # 0xcce0
movq 0x65ff(%rip), %rdx      # 0xcfb0
movq %r14, %rdi
callq 0x3330
jmp 0x6b2a
leaq 0xa8(%rsp), %rdi
callq 0x3050
leaq 0x50(%rsp), %rdi
callq 0x3ea6
leaq 0x2b8(%rsp), %rdi
callq 0x3050
addq $0x4c8, %rsp            # imm = 0x4C8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x10
popq %rdi
callq 0x3130
movq %rax, %r15
leaq 0x1f08(%rip), %rsi      # 0x890e
leaq 0x10(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0x3e0e
movb $0x1, %bpl
leaq 0x10(%rsp), %rsi
movq %r15, %rdi
callq 0x6c10
xorl %ebp, %ebp
leaq 0x62b2(%rip), %rsi      # 0xcce0
movq 0x657b(%rip), %rdx      # 0xcfb0
movq %r15, %rdi
callq 0x3330
jmp 0x6b2a
pushq $0x10
popq %rdi
callq 0x3130
movq %rax, %r14
leaq 0x1e9f(%rip), %rsi      # 0x88f3
leaq 0x10(%rsp), %rdi
leaq 0x38(%rsp), %rdx
callq 0x3e0e
movb $0x1, %bpl
leaq 0x10(%rsp), %rsi
movq %r14, %rdi
callq 0x6c10
xorl %ebp, %ebp
leaq 0x6264(%rip), %rsi      # 0xcce0
movq 0x652d(%rip), %rdx      # 0xcfb0
movq %r14, %rdi
callq 0x3330
jmp 0x6b2a
pushq $0x10
popq %rdi
callq 0x3130
movq %rax, %r14
leaq 0x1e3b(%rip), %rsi      # 0x88dd
leaq 0xa8(%rsp), %rdi
leaq 0x50(%rsp), %rdx
callq 0x3e0e
movb $0x1, %bpl
leaq 0xa8(%rsp), %rsi
movq %r14, %rdi
callq 0x6c10
xorl %ebp, %ebp
leaq 0x6210(%rip), %rsi      # 0xcce0
movq 0x64d9(%rip), %rdx      # 0xcfb0
movq %r14, %rdi
callq 0x3330
jmp 0x6b2a
pushq $0x10
popq %rdi
callq 0x3130
movq %rax, %r14
leaq 0x197e(%rip), %rsi      # 0x8471
leaq 0x10(%rsp), %rdi
leaq 0x38(%rsp), %rdx
callq 0x3e0e
movb $0x1, %bpl
leaq 0x10(%rsp), %rsi
movq %r14, %rdi
callq 0x6c10
xorl %ebp, %ebp
leaq 0x61c5(%rip), %rsi      # 0xcce0
movq 0x648e(%rip), %rdx      # 0xcfb0
movq %r14, %rdi
callq 0x3330
jmp 0x6b8e
jmp 0x6ba2
movq %rax, %rbx
leaq 0xa8(%rsp), %rdi
callq 0x3398
testb %bpl, %bpl
jne 0x6b4b
jmp 0x6bfb
movq %rax, %rbx
movq %r14, %rdi
callq 0x3180
jmp 0x6bfb
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x49f0
jmp 0x6be4
jmp 0x6be1
movq %rax, %rbx
jmp 0x6bf1
movq %rax, %rbx
leaq 0xa8(%rsp), %rdi
callq 0x49f0
jmp 0x6bfb
jmp 0x6b85
movq %rax, %rbx
jmp 0x6bfb
jmp 0x6b8e
jmp 0x6ba2
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x3398
testb %bpl, %bpl
jne 0x6ba5
jmp 0x6be4
movq %rax, %rbx
movq %r14, %rdi
callq 0x3180
jmp 0x6be4
jmp 0x6be1
jmp 0x6be1
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x3398
testb %bpl, %bpl
jne 0x6bca
jmp 0x6bd7
movq %rax, %rbx
movq %r15, %rdi
callq 0x3180
jmp 0x6bd7
movq %rax, %rbx
movq %r14, %rdi
callq 0x3ed0
jmp 0x6be4
movq %rax, %rbx
leaq 0xa8(%rsp), %rdi
callq 0x3050
leaq 0x50(%rsp), %rdi
callq 0x3ea6
leaq 0x2b8(%rsp), %rdi
callq 0x3050
movq %rbx, %rdi
callq 0x3340