// File: jansucan[P]diff-dd/src/create.cpp
// Function: create(Options::Create const&)
void
create(const Options::Create &opts)
{
    std::ifstream in_istream{opts.getInFilePath(),
                             std::ifstream::in | std::ifstream::binary};
    if (!in_istream) {
        throw BufferedStream::Error("cannot open input file");
    }

    std::ifstream base_istream{opts.getBaseFilePath(),
                               std::ifstream::in | std::ifstream::binary};
    if (!base_istream) {
        throw BufferedStream::Error("cannot open base file");
    }

    // When backing up, the output file is truncated to hold the new data
    std::ofstream out_ostream{opts.getOutFilePath(), std::ofstream::out |
                                                         std::ofstream::trunc |
                                                         std::ofstream::binary};
    if (!out_ostream) {
        throw BufferedStream::Error("cannot open output file");
    }

    DiffFinder diff_finder(base_istream, in_istream, opts.getBufferSize(),
                           FormatV2::RecordHeaderSize);
    FormatV2::Writer diff_writer(out_ostream, opts.getBufferSize());

    for (;;) {
        const Diff diff{diff_finder.findNextDiff()};
        if (diff.isEmpty()) {
            break;
        }

        diff_writer.writeDiffRecord(diff.getStart(), diff.getSize(),
                                    diff.getData());

        // Here, the diff is destructed and page data reference counters
        // decremented
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x990, %rsp            # imm = 0x990
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rsi
leaq -0x238(%rbp), %rdi
callq 0xaa00
movl $0x8, %edi
movl $0x4, %esi
callq 0x7790
movl %eax, -0x924(%rbp)
jmp 0x6d26
movl -0x924(%rbp), %edx
leaq -0x210(%rbp), %rdi
leaq -0x238(%rbp), %rsi
callq 0x77b0
jmp 0x6d41
leaq -0x238(%rbp), %rdi
callq 0x77f0
movq -0x210(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x210(%rbp,%rax), %rdi
callq 0x3160
movb %al, -0x925(%rbp)
jmp 0x6d6d
movb -0x925(%rbp), %al
testb $0x1, %al
jne 0x6d7c
jmp 0x6e92
movb $0x1, -0x26a(%rbp)
movl $0x10, %edi
callq 0x3180
movq %rax, -0x938(%rbp)
leaq -0x269(%rbp), %rdi
movq %rdi, -0x930(%rbp)
callq 0x34a0
movq -0x930(%rbp), %rdx
leaq 0x768f(%rip), %rsi      # 0xe444
leaq -0x268(%rbp), %rdi
callq 0x47f0
jmp 0x6dc3
movq -0x938(%rbp), %rdi
leaq -0x268(%rbp), %rsi
callq 0x48a0
jmp 0x6dd8
movq -0x938(%rbp), %rdi
movb $0x0, -0x26a(%rbp)
leaq 0xdd0b(%rip), %rsi      # 0x14af8
leaq -0x2514(%rip), %rdx     # 0x48e0
callq 0x3480
jmp 0x7418
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
leaq -0x238(%rbp), %rdi
callq 0x77f0
jmp 0x740c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x7400
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x6e6a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
leaq -0x268(%rbp), %rdi
callq 0x3528
leaq -0x269(%rbp), %rdi
callq 0x32f0
testb $0x1, -0x26a(%rbp)
jne 0x6e81
jmp 0x6e8d
movq -0x938(%rbp), %rdi
callq 0x3200
jmp 0x7400
movq -0x8(%rbp), %rsi
leaq -0x4a0(%rbp), %rdi
callq 0xaa30
jmp 0x6ea4
movl $0x8, %edi
movl $0x4, %esi
callq 0x7790
movl %eax, -0x93c(%rbp)
jmp 0x6ebb
movl -0x93c(%rbp), %edx
leaq -0x478(%rbp), %rdi
leaq -0x4a0(%rbp), %rsi
callq 0x77b0
jmp 0x6ed6
leaq -0x4a0(%rbp), %rdi
callq 0x77f0
movq -0x478(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x478(%rbp,%rax), %rdi
callq 0x3160
movb %al, -0x93d(%rbp)
jmp 0x6f02
movb -0x93d(%rbp), %al
testb $0x1, %al
jne 0x6f11
jmp 0x7027
movb $0x1, -0x4c2(%rbp)
movl $0x10, %edi
callq 0x3180
movq %rax, -0x950(%rbp)
leaq -0x4c1(%rbp), %rdi
movq %rdi, -0x948(%rbp)
callq 0x34a0
movq -0x948(%rbp), %rdx
leaq 0x7511(%rip), %rsi      # 0xe45b
leaq -0x4c0(%rbp), %rdi
callq 0x47f0
jmp 0x6f58
movq -0x950(%rbp), %rdi
leaq -0x4c0(%rbp), %rsi
callq 0x48a0
jmp 0x6f6d
movq -0x950(%rbp), %rdi
movb $0x0, -0x4c2(%rbp)
leaq 0xdb76(%rip), %rsi      # 0x14af8
leaq -0x26a9(%rip), %rdx     # 0x48e0
callq 0x3480
jmp 0x7418
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
leaq -0x4a0(%rbp), %rdi
callq 0x77f0
jmp 0x7400
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x73f4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x6fff
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
leaq -0x4c0(%rbp), %rdi
callq 0x3528
leaq -0x4c1(%rbp), %rdi
callq 0x32f0
testb $0x1, -0x4c2(%rbp)
jne 0x7016
jmp 0x7022
movq -0x950(%rbp), %rdi
callq 0x3200
jmp 0x73f4
movq -0x8(%rbp), %rsi
leaq -0x6f0(%rbp), %rdi
callq 0xaa60
jmp 0x7039
movl $0x10, %edi
movl $0x20, %esi
callq 0x7790
movl %eax, -0x954(%rbp)
jmp 0x7050
movl -0x954(%rbp), %edi
movl $0x4, %esi
callq 0x7790
movl %eax, -0x958(%rbp)
jmp 0x7068
movl -0x958(%rbp), %edx
leaq -0x6c8(%rbp), %rdi
leaq -0x6f0(%rbp), %rsi
callq 0x7820
jmp 0x7083
leaq -0x6f0(%rbp), %rdi
callq 0x77f0
movq -0x6c8(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x6c8(%rbp,%rax), %rdi
callq 0x3160
movb %al, -0x959(%rbp)
jmp 0x70af
movb -0x959(%rbp), %al
testb $0x1, %al
jne 0x70be
jmp 0x71d4
movb $0x1, -0x712(%rbp)
movl $0x10, %edi
callq 0x3180
movq %rax, -0x970(%rbp)
leaq -0x711(%rbp), %rdi
movq %rdi, -0x968(%rbp)
callq 0x34a0
movq -0x968(%rbp), %rdx
leaq 0x737a(%rip), %rsi      # 0xe471
leaq -0x710(%rbp), %rdi
callq 0x47f0
jmp 0x7105
movq -0x970(%rbp), %rdi
leaq -0x710(%rbp), %rsi
callq 0x48a0
jmp 0x711a
movq -0x970(%rbp), %rdi
movb $0x0, -0x712(%rbp)
leaq 0xd9c9(%rip), %rsi      # 0x14af8
leaq -0x2856(%rip), %rdx     # 0x48e0
callq 0x3480
jmp 0x7418
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
leaq -0x6f0(%rbp), %rdi
callq 0x77f0
jmp 0x73f4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x73e8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x71ac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
leaq -0x710(%rbp), %rdi
callq 0x3528
leaq -0x711(%rbp), %rdi
callq 0x32f0
testb $0x1, -0x712(%rbp)
jne 0x71c3
jmp 0x71cf
movq -0x970(%rbp), %rdi
callq 0x3200
jmp 0x73e8
movq -0x8(%rbp), %rdi
callq 0xa9f0
movl %eax, -0x974(%rbp)
jmp 0x71e5
movl -0x974(%rbp), %ecx
leaq -0x888(%rbp), %rdi
leaq -0x478(%rbp), %rsi
leaq -0x210(%rbp), %rdx
movl $0xc, %r8d
callq 0x7860
jmp 0x720d
movq -0x8(%rbp), %rdi
callq 0xa9f0
movl %eax, -0x978(%rbp)
jmp 0x721e
movl -0x978(%rbp), %eax
movl %eax, %eax
movl %eax, %edx
leaq -0x8b0(%rbp), %rdi
leaq -0x6c8(%rbp), %rsi
callq 0x7990
jmp 0x723d
jmp 0x723f
leaq -0x900(%rbp), %rdi
leaq -0x888(%rbp), %rsi
callq 0x79f0
jmp 0x7254
leaq -0x900(%rbp), %rdi
callq 0x7550
movb %al, -0x979(%rbp)
jmp 0x7268
movb -0x979(%rbp), %al
testb $0x1, %al
jne 0x7274
jmp 0x72c8
movl $0x2, -0x904(%rbp)
jmp 0x7340
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x73dc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x73d0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x737d
leaq -0x900(%rbp), %rdi
callq 0x75a0
movq %rax, -0x988(%rbp)
jmp 0x72dd
leaq -0x900(%rbp), %rdi
callq 0x75c0
movq %rax, -0x990(%rbp)
jmp 0x72f2
leaq -0x920(%rbp), %rdi
leaq -0x900(%rbp), %rsi
callq 0x8100
jmp 0x7307
movq -0x990(%rbp), %rdx
movq -0x988(%rbp), %rsi
leaq -0x8b0(%rbp), %rdi
leaq -0x920(%rbp), %rcx
callq 0x8030
jmp 0x732a
leaq -0x920(%rbp), %rdi
callq 0x87a0
movl $0x0, -0x904(%rbp)
leaq -0x900(%rbp), %rdi
callq 0x8800
movl -0x904(%rbp), %eax
testl %eax, %eax
je 0x735a
jmp 0x7358
jmp 0x738b
jmp 0x723f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
leaq -0x920(%rbp), %rdi
callq 0x87a0
leaq -0x900(%rbp), %rdi
callq 0x8800
jmp 0x73d0
leaq -0x8b0(%rbp), %rdi
callq 0x8820
leaq -0x888(%rbp), %rdi
callq 0x8840
leaq -0x6c8(%rbp), %rdi
callq 0x3440
leaq -0x478(%rbp), %rdi
callq 0x3090
leaq -0x210(%rbp), %rdi
callq 0x3090
addq $0x990, %rsp            # imm = 0x990
popq %rbp
retq
leaq -0x8b0(%rbp), %rdi
callq 0x8820
leaq -0x888(%rbp), %rdi
callq 0x8840
leaq -0x6c8(%rbp), %rdi
callq 0x3440
leaq -0x478(%rbp), %rdi
callq 0x3090
leaq -0x210(%rbp), %rdi
callq 0x3090
movq -0x240(%rbp), %rdi
callq 0x3490
nopl (%rax,%rax)