// File: /workspace/github_cpp_makefile_star2_O3/night-shift[P]Srl/src/lib/In.cpp
// Function: Srl::Lib::In::try_fetch_data(unsigned long, unsigned long)
bool In::try_fetch_data(size_t nbytes, size_t read_len)
{
    /*           (   <--------->   ) -> this needs to be preserved
     * [.........*.............*...] -> buffer
     *           |             |->  current pos
     *           |
     *           |-> possible buffer anchor
     *
     * after reading new chunk:
     *
     * ( <- preserved -> )(      <- new data ->      )
     * [*.............*..............................]
     *  |             |-> new current pos
     *  |
     *  |-> new buffer anchor
     */

    if(this->eof_reached || !this->streaming) {
        return false;
    }

    auto left = this->end - this->pos;

    read_len = (nbytes < read_len ? read_len : nbytes) - left;

    auto preserve_pos = this->anchor != nullptr
        ? this->anchor - start
        : (this->end - start) - left;

    /* small extra margin to make sure memory around the current position will be preserved in any case */
    const auto margin_sz = 32;
    auto margin = preserve_pos < margin_sz ? margin_sz - (margin_sz - preserve_pos) : margin_sz;

    auto preserve_sz = this->end - (this->start + preserve_pos - margin);
    auto bufsz = preserve_sz + read_len;

    if(this->buffer.size() < bufsz) {
        this->buffer.resize(bufsz);
    }

    if(preserve_sz > 0) {
        memmove(this->buffer.data(), &this->buffer[preserve_pos - margin], preserve_sz);
    }

    this->stream->read((char*)&this->buffer[preserve_sz], read_len);
    auto bytes_read = (size_t)this->stream->gcount();

    this->pos  = &this->buffer[preserve_sz - left];
    anchor = anchor ? nullptr : &this->buffer[margin];

    this->start = this->buffer.data();
    this->end   = this->buffer.data() + bytes_read + preserve_sz;

    if(bytes_read + left < nbytes) {
        this->eof_reached = true;

        return false;
    }

    return true;
}

// Assembly:
cmpb $0x0, 0x28(%rdi)
je 0x1050f
xorl %eax, %eax
retq
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
cmpb $0x1, 0x18(%rdi)
jne 0x10621
movq %rdx, %r15
movq %rsi, %r14
movq 0x8(%rbx), %rax
movq 0x10(%rbx), %rcx
movq %rax, %rdx
subq %rcx, %rdx
cmpq %r15, %rsi
cmovaq %rsi, %r15
movq %rdx, 0x10(%rsp)
subq %rdx, %r15
movq 0x48(%rbx), %rdx
testq %rdx, %rdx
cmoveq %rcx, %rdx
movq %rdx, %r13
subq (%rbx), %r13
cmpq $0x20, %r13
movl $0x20, %ebp
cmovlq %r13, %rbp
movq %rbp, %r12
subq %rdx, %r12
addq %rax, %r12
leaq (%r12,%r15), %rax
leaq 0x30(%rbx), %rcx
movq %rcx, 0x8(%rsp)
movq 0x38(%rbx), %rcx
movq 0x30(%rbx), %rsi
subq %rsi, %rcx
cmpq %rax, %rcx
jae 0x105a6
movq 0x8(%rsp), %rdi
movq %rax, %rsi
callq 0xb980
movq 0x8(%rsp), %rax
movq (%rax), %rsi
testq %r12, %r12
jle 0x105c7
subq %rbp, %r13
addq %rsi, %r13
movq %rsi, %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0xbd70
movq 0x8(%rsp), %rax
movq (%rax), %rsi
movq 0x20(%rbx), %rdi
addq %r12, %rsi
movq %r15, %rdx
callq 0xbae0
movq 0x20(%rbx), %rax
movq 0x30(%rbx), %rcx
movq 0x8(%rax), %rdx
movq %r12, %rax
movq 0x10(%rsp), %rsi
subq %rsi, %rax
addq %rcx, %rax
movq %rax, 0x10(%rbx)
addq %rcx, %rbp
xorl %eax, %eax
cmpq $0x0, 0x48(%rbx)
cmoveq %rbp, %rax
movq %rax, 0x48(%rbx)
movq %rcx, (%rbx)
addq %rdx, %rcx
addq %r12, %rcx
movq %rcx, 0x8(%rbx)
addq %rsi, %rdx
movb $0x1, %al
cmpq %r14, %rdx
jae 0x10623
movb $0x1, 0x28(%rbx)
xorl %eax, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq