// File: /workspace/github_cpp_makefile_star2_O2/ivan-tkatchev[P]yalz77/./lz77.h
// Function: lz77::compress_t::feed[abi:cxx11](unsigned char const*, unsigned char const*)
std::string feed(const unsigned char* i, const unsigned char* e) {

        const unsigned char* i0 = i;

        std::string ret;
        
        std::string unc;

        push_vlq_uint(e - i, ret);

        offsets.clear();

        size_t blocksize = offsets.blocksize;

        while (i != e) {

            unsigned char c = *i;

            // The last MIN_RUN-1 bytes are uncompressable. (At least MIN_RUN bytes
            // are needed to calculate a prefix hash.)

            if (i > e - MIN_RUN) {

                unc +=c;
                ++i;
                continue;
            }

            size_t maxrun = 0;
            size_t maxoffset = 0;
            size_t maxgain = 0;

            uint16_t packed;

            // The MIN_RUN prefix length was chosen empirically, based on a series
            // of unscientific tests.

            pack_bytes(i, packed, blocksize);

            offsets(packed, i0, i, e, maxrun, maxoffset, maxgain);

            if (maxrun < MIN_RUN) {
                unc += c;
                ++i;
                continue;
            }

            if (unc.size() > 0) {
                // Write a packet of uncompressed data.

                size_t msg = (unc.size() << 1) | 1;
                push_vlq_uint(msg, ret);
                ret += unc;
                unc.clear();
            }

            // A compressed string is a length and an offset.
            // First subtract the minimum length (smaller lengths don't exist).
            // Then check if the length fits in SHORTRUN_BITS bits; if it does, then
            // tack it on to the offset. Otherwise write length and offset separately.
            // The rightmost bit is a zero to differentiate from packets of
            // uncompressed data.

            i += maxrun;
            maxrun = maxrun - MIN_RUN + 1;

            if (maxrun < SHORTRUN_MAX) {

                size_t msg = ((maxoffset << SHORTRUN_BITS) | maxrun) << 1;
                push_vlq_uint(msg, ret);

            } else {

                size_t msg = (maxoffset << (SHORTRUN_BITS + 1));
                push_vlq_uint(msg, ret);
                push_vlq_uint(maxrun, ret);
            }
        }

        if (unc.size() > 0) {

            size_t msg = (unc.size() << 1) | 1;
            push_vlq_uint(msg, ret);
            ret += unc;
            unc.clear();
        }

        return ret;
    }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rcx, %r14
movq %rdi, %rbx
leaq 0x10(%rdi), %rax
movq %rax, (%rdi)
andq $0x0, 0x8(%rdi)
movq %rsi, %r15
xorl %eax, %eax
leaq 0x28(%rsp), %rcx
movq %rcx, -0x10(%rcx)
andq $0x0, -0x8(%rcx)
movb %al, 0x10(%rdi)
movb %al, (%rcx)
movq %r14, %rdi
movq %rdx, 0x38(%rsp)
subq %rdx, %rdi
movq %rbx, %rsi
callq 0x2e2d
movq %r15, %rdi
callq 0x2e6c
movq %r15, 0x48(%rsp)
movq 0x20(%r15), %r13
leaq -0x5(%r14), %r12
movq 0x38(%rsp), %r15
cmpq %r14, %r15
je 0x2db3
movsbl (%r15), %ebp
cmpq %r12, %r15
jbe 0x2cc5
leaq 0x18(%rsp), %rdi
movl %ebp, %esi
callq 0x2100
jmp 0x2d2b
andq $0x0, 0x10(%rsp)
andq $0x0, 0x40(%rsp)
andq $0x0, 0x50(%rsp)
movq %r15, %rdi
leaq 0xe(%rsp), %rsi
movq %r13, %rdx
callq 0x2e87
movzwl 0xe(%rsp), %esi
movq 0x48(%rsp), %rdi
movq 0x38(%rsp), %rdx
movq %r15, %rcx
movq %r14, %r8
leaq 0x10(%rsp), %r9
leaq 0x50(%rsp), %rax
pushq %rax
leaq 0x48(%rsp), %rax
pushq %rax
callq 0x2eb2
popq %rax
popq %rcx
movq 0x10(%rsp), %rax
cmpq $0x4, %rax
ja 0x2d33
leaq 0x18(%rsp), %rdi
movl %ebp, %esi
callq 0x2100
incq %r15
jmp 0x2ca5
movq 0x20(%rsp), %rcx
testq %rcx, %rcx
je 0x2d6d
leaq 0x1(,%rcx,2), %rdi
movq %rbx, %rsi
callq 0x2e2d
movq %rbx, %rdi
leaq 0x18(%rsp), %rsi
callq 0x2210
andq $0x0, 0x20(%rsp)
movq 0x18(%rsp), %rax
movb $0x0, (%rax)
movq 0x10(%rsp), %rax
addq %rax, %r15
addq $-0x4, %rax
movq %rax, 0x10(%rsp)
movq 0x40(%rsp), %rdi
shlq $0x4, %rdi
cmpq $0x7, %rax
ja 0x2d99
leaq (%rdi,%rax,2), %rdi
movq %rbx, %rsi
callq 0x2e2d
jmp 0x2ca5
movq %rbx, %rsi
callq 0x2e2d
movq 0x10(%rsp), %rdi
movq %rbx, %rsi
callq 0x2e2d
jmp 0x2ca5
movq 0x20(%rsp), %rax
testq %rax, %rax
je 0x2de8
leaq 0x1(,%rax,2), %rdi
movq %rbx, %rsi
callq 0x2e2d
leaq 0x18(%rsp), %rsi
movq %rbx, %rdi
callq 0x2210
andq $0x0, 0x20(%rsp)
movq 0x18(%rsp), %rax
movb $0x0, (%rax)
leaq 0x18(%rsp), %rdi
callq 0x2090
movq %rbx, %rax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x2e10
jmp 0x2e10
jmp 0x2e10
jmp 0x2e10
jmp 0x2e10
jmp 0x2e10
movq %rax, %r14
leaq 0x18(%rsp), %rdi
callq 0x2090
movq %rbx, %rdi
callq 0x2090
movq %r14, %rdi
callq 0x21e0