// File: jansucan[P]diff-dd/src/create.cpp
// Function: DiffFinder::findNextDiff()
Diff findNextDiff()
    {
        for (;;) {
            if (m_search_state == SearchState::ReadPages) {
                m_old_page = m_old_page_reader.getNextPage();
                m_new_page = m_new_page_reader.getNextPage();
                assert(m_old_page.getStart() == m_new_page.getStart());

                if (m_old_page.getSize() != m_new_page.getSize()) {
                    throw CreateError(
                        "cannot read the same amount of data from both files");
                }

                const bool end_of_stream{m_old_page.isEmpty() &&
                                         m_new_page.isEmpty()};
                if (end_of_stream) {
                    const Diff return_diff{m_diff};
                    m_diff = Diff{m_offset_in_stream};
                    return return_diff;
                }

                m_search_state = SearchState::FindDiff;

            } else if (m_search_state == SearchState::FindDiff) {
                Diff diff{findDiffInPages(m_old_page, m_new_page,
                                          m_offset_in_stream)};
                m_offset_in_stream = diff.getEnd();

                if (diff.isEmpty()) {
                    // End of pages. On the next call, read new pages.
                    m_old_page = Page{};
                    m_new_page = Page{};
                    m_search_state = SearchState::ReadPages;
                }

                const MergeState merge_state{diffsTryMerge(
                    m_diff, diff, m_max_merge_gap, m_diff_max_size)};

                if (merge_state == MergeState::Finished) {
                    const Diff return_diff{m_diff};
                    m_diff = diff;
                    if (!return_diff.isEmpty()) {
                        return return_diff;
                    }
                }

            } else {
                assert(false);
            }
        }
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x230, %rsp            # imm = 0x230
movq %rdi, -0x1d0(%rbp)
movq %rdi, %rax
movq %rax, -0x1c8(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x1c0(%rbp)
movq -0x1c0(%rbp), %rax
cmpl $0x0, 0x168(%rax)
jne 0x7d0f
movq -0x1c0(%rbp), %rsi
leaq -0x30(%rbp), %rdi
callq 0x8e20
movq -0x1c0(%rbp), %rdi
addq $0xd0, %rdi
leaq -0x30(%rbp), %rsi
callq 0x8ee0
leaq -0x30(%rbp), %rdi
callq 0x8d80
movq -0x1c0(%rbp), %rsi
addq $0x60, %rsi
leaq -0x50(%rbp), %rdi
callq 0x8e20
movq -0x1c0(%rbp), %rdi
addq $0xf0, %rdi
leaq -0x50(%rbp), %rsi
callq 0x8ee0
leaq -0x50(%rbp), %rdi
callq 0x8d80
movq -0x1c0(%rbp), %rdi
addq $0xd0, %rdi
callq 0x7710
movq -0x1c0(%rbp), %rdi
movq %rax, -0x1d8(%rbp)
addq $0xf0, %rdi
callq 0x7710
movq %rax, %rcx
movq -0x1d8(%rbp), %rax
cmpq %rcx, %rax
jne 0x7ad5
jmp 0x7af4
leaq 0x69d3(%rip), %rdi      # 0xe4af
leaq 0x686e(%rip), %rsi      # 0xe351
movl $0xf8, %edx
leaq 0x69ef(%rip), %rcx      # 0xe4de
callq 0x31c0
movq -0x1c0(%rbp), %rdi
addq $0xd0, %rdi
callq 0x8f20
movq -0x1c0(%rbp), %rdi
movq %rax, -0x1e0(%rbp)
addq $0xf0, %rdi
callq 0x8f20
movq %rax, %rcx
movq -0x1e0(%rbp), %rax
cmpq %rcx, %rax
je 0x7bfb
movb $0x1, -0x85(%rbp)
movl $0x10, %edi
callq 0x3180
movq %rax, -0x1f0(%rbp)
leaq -0x71(%rbp), %rdi
movq %rdi, -0x1e8(%rbp)
callq 0x34a0
movq -0x1e8(%rbp), %rdx
leaq 0x6994(%rip), %rsi      # 0xe4fe
leaq -0x70(%rbp), %rdi
callq 0x47f0
jmp 0x7b75
movq -0x1f0(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x8f40
jmp 0x7b87
movq -0x1f0(%rbp), %rdi
movb $0x0, -0x85(%rbp)
leaq 0xd0c4(%rip), %rsi      # 0x14c60
leaq 0x13dd(%rip), %rdx      # 0x8f80
callq 0x3480
jmp 0x8027
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x7bd6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x3528
leaq -0x71(%rbp), %rdi
callq 0x32f0
testb $0x1, -0x85(%rbp)
jne 0x7bea
jmp 0x7bf6
movq -0x1f0(%rbp), %rdi
callq 0x3200
jmp 0x801e
movq -0x1c0(%rbp), %rdi
addq $0xd0, %rdi
callq 0x8fa0
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x1f1(%rbp)
jne 0x7c1f
jmp 0x7c38
movq -0x1c0(%rbp), %rdi
addq $0xf0, %rdi
callq 0x8fa0
movb %al, -0x1f1(%rbp)
movb -0x1f1(%rbp), %al
andb $0x1, %al
movb %al, -0x86(%rbp)
testb $0x1, -0x86(%rbp)
je 0x7cf9
movq -0x1c0(%rbp), %rsi
movq -0x1d0(%rbp), %rdi
movb $0x0, -0x87(%rbp)
addq $0x118, %rsi            # imm = 0x118
callq 0x8fd0
movq -0x1c0(%rbp), %rax
movq 0x110(%rax), %rsi
leaq -0xd8(%rbp), %rdi
callq 0x8c80
jmp 0x7c90
movq -0x1c0(%rbp), %rdi
addq $0x118, %rdi            # imm = 0x118
leaq -0xd8(%rbp), %rsi
callq 0x9010
leaq -0xd8(%rbp), %rdi
callq 0x8800
movb $0x1, -0x87(%rbp)
testb $0x1, -0x87(%rbp)
jne 0x7cf4
jmp 0x7ce8
movq -0x1d0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
callq 0x8800
jmp 0x801e
movq -0x1d0(%rbp), %rdi
callq 0x8800
jmp 0x800e
movq -0x1c0(%rbp), %rax
movl $0x1, 0x168(%rax)
jmp 0x8009
movq -0x1c0(%rbp), %rax
cmpl $0x1, 0x168(%rax)
jne 0x7fe8
movq -0x1c0(%rbp), %rsi
addq $0xd0, %rsi
leaq -0x148(%rbp), %rdi
movq %rdi, -0x208(%rbp)
callq 0x92e0
movq -0x1c0(%rbp), %rsi
addq $0xf0, %rsi
leaq -0x168(%rbp), %rdi
movq %rdi, -0x200(%rbp)
callq 0x92e0
movq -0x1c0(%rbp), %rsi
movq -0x208(%rbp), %rdx
movq -0x200(%rbp), %rcx
movq 0x110(%rsi), %r8
leaq -0x128(%rbp), %rdi
callq 0x9050
jmp 0x7d8f
leaq -0x168(%rbp), %rdi
callq 0x8d80
leaq -0x148(%rbp), %rdi
callq 0x8d80
leaq -0x128(%rbp), %rdi
movq %rdi, -0x218(%rbp)
callq 0x7580
movq -0x218(%rbp), %rdi
movq %rax, %rcx
movq -0x1c0(%rbp), %rax
movq %rcx, 0x110(%rax)
callq 0x7550
movb %al, -0x209(%rbp)
jmp 0x7ddf
movb -0x209(%rbp), %al
testb $0x1, %al
jne 0x7dee
jmp 0x7eb0
leaq -0x188(%rbp), %rdi
callq 0x8c40
jmp 0x7dfc
movq -0x1c0(%rbp), %rdi
addq $0xd0, %rdi
leaq -0x188(%rbp), %rsi
movq %rsi, -0x220(%rbp)
callq 0x8ee0
movq -0x220(%rbp), %rdi
callq 0x8d80
leaq -0x1a8(%rbp), %rdi
callq 0x8c40
jmp 0x7e37
movq -0x1c0(%rbp), %rdi
addq $0xf0, %rdi
leaq -0x1a8(%rbp), %rsi
callq 0x8ee0
leaq -0x1a8(%rbp), %rdi
callq 0x8d80
movq -0x1c0(%rbp), %rax
movl $0x0, 0x168(%rax)
jmp 0x7eb0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x168(%rbp), %rdi
callq 0x8d80
leaq -0x148(%rbp), %rdi
callq 0x8d80
jmp 0x801e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x7fda
movq -0x1c0(%rbp), %rax
movq %rax, %rdi
addq $0x118, %rdi            # imm = 0x118
movq 0xc0(%rax), %rcx
movq 0xc8(%rax), %rdx
leaq -0x128(%rbp), %rsi
callq 0x6860
movl %eax, -0x224(%rbp)
jmp 0x7ee3
movl -0x224(%rbp), %eax
movl %eax, -0x1ac(%rbp)
cmpl $0x0, -0x1ac(%rbp)
jne 0x7fb4
movq -0x1d0(%rbp), %rdi
movq -0x1c0(%rbp), %rsi
movb $0x0, -0x1ad(%rbp)
addq $0x118, %rsi            # imm = 0x118
movq %rsi, -0x230(%rbp)
callq 0x8fd0
movq -0x230(%rbp), %rdi
leaq -0x128(%rbp), %rsi
callq 0x9320
movq -0x1d0(%rbp), %rdi
callq 0x7550
movb %al, -0x225(%rbp)
jmp 0x7f4b
movb -0x225(%rbp), %al
testb $0x1, %al
jne 0x7f87
jmp 0x7f57
movb $0x1, -0x1ad(%rbp)
movl $0x1, -0x1b4(%rbp)
jmp 0x7f91
movq -0x1d0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
callq 0x8800
jmp 0x7fda
movl $0x0, -0x1b4(%rbp)
testb $0x1, -0x1ad(%rbp)
jne 0x7fa6
movq -0x1d0(%rbp), %rdi
callq 0x8800
movl -0x1b4(%rbp), %eax
testl %eax, %eax
jne 0x7fbe
jmp 0x7fb2
jmp 0x7fb4
movl $0x0, -0x1b4(%rbp)
leaq -0x128(%rbp), %rdi
callq 0x8800
movl -0x1b4(%rbp), %eax
testl %eax, %eax
je 0x7fd8
jmp 0x7fd6
jmp 0x800e
jmp 0x8007
leaq -0x128(%rbp), %rdi
callq 0x8800
jmp 0x801e
leaq 0x6543(%rip), %rdi      # 0xe532
leaq 0x635b(%rip), %rsi      # 0xe351
movl $0x121, %edx            # imm = 0x121
leaq 0x64dc(%rip), %rcx      # 0xe4de
callq 0x31c0
jmp 0x8009
jmp 0x7a1f
movq -0x1c8(%rbp), %rax
addq $0x230, %rsp            # imm = 0x230
popq %rbp
retq
movq -0x80(%rbp), %rdi
callq 0x3490
nopw (%rax,%rax)