// File: marknelson[P]LZW/./lzw.h
// Function: void lzw::compress<std::istream, std::ostream>(std::istream&, std::ostream&, unsigned int)
void compress( INPUT &input, OUTPUT &output, const unsigned int max_code = 32767 )
{
    input_symbol_stream<INPUT> in( input );
    output_code_stream<OUTPUT> out( output, max_code );

    std::unordered_map<std::string, unsigned int> codes( (max_code * 11)/10 );
    for ( unsigned int i = 0 ; i < 256 ; i++ )
        codes[std::string(1,i)] = i;
    unsigned int next_code = 257;
    std::string current_string;
    char c;
    while ( in >> c ) {
        current_string = current_string + c;
        if ( codes.find(current_string) == codes.end() ) {
            if ( next_code <= max_code )
                codes[ current_string ] = next_code++;
            current_string.erase(current_string.size()-1);
            out << codes[current_string];
            current_string = c;
        }
    }
    if ( current_string.size() )
        out << codes[current_string];
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x190, %rsp            # imm = 0x190
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq -0x8(%rbp), %rsi
leaq -0x20(%rbp), %rdi
callq 0x3180
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
leaq -0x48(%rbp), %rdi
callq 0x31a0
movl -0x14(%rbp), %ecx
movl %ecx, %eax
leal (%rax,%rax,4), %edx
movl %edx, %ecx
leal (%rax,%rcx,2), %eax
movl $0xcccccccd, %ecx       # imm = 0xCCCCCCCD
imulq %rcx, %rax
shrq $0x23, %rax
movq %rax, -0x128(%rbp)
leaq -0x83(%rbp), %rdi
movq %rdi, -0x120(%rbp)
callq 0x31f0
movq -0x128(%rbp), %rsi
movq -0x120(%rbp), %r8
leaq -0x80(%rbp), %rdi
leaq -0x81(%rbp), %rdx
leaq -0x82(%rbp), %rcx
callq 0x3210
jmp 0x299e
leaq -0x83(%rbp), %rdi
callq 0x3250
movl $0x0, -0x98(%rbp)
cmpl $0x100, -0x98(%rbp)     # imm = 0x100
jae 0x2ac0
movl -0x98(%rbp), %eax
movl %eax, -0x134(%rbp)
leaq -0xb9(%rbp), %rdi
movq %rdi, -0x130(%rbp)
callq 0x22c0
movl -0x134(%rbp), %eax
movq -0x130(%rbp), %rcx
movsbl %al, %edx
leaq -0xb8(%rbp), %rdi
movl $0x1, %esi
callq 0x2110
jmp 0x2a06
leaq -0x80(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x3270
movq %rax, -0x140(%rbp)
jmp 0x2a1f
movq -0x140(%rbp), %rax
movl -0x134(%rbp), %ecx
movl %ecx, (%rax)
leaq -0xb8(%rbp), %rdi
callq 0x2100
leaq -0xb9(%rbp), %rdi
callq 0x21c0
movl -0x98(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x98(%rbp)
jmp 0x29b4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0x83(%rbp), %rdi
callq 0x3250
jmp 0x2ce9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x2aaf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0x2100
leaq -0xb9(%rbp), %rdi
callq 0x21c0
jmp 0x2ce0
movl $0x101, -0xc0(%rbp)     # imm = 0x101
leaq -0xe0(%rbp), %rdi
callq 0x2240
leaq -0x20(%rbp), %rdi
leaq -0xe1(%rbp), %rsi
callq 0x32a0
movb %al, -0x141(%rbp)
jmp 0x2aee
movb -0x141(%rbp), %al
testb $0x1, %al
jne 0x2afd
jmp 0x2c7a
movsbl -0xe1(%rbp), %edx
leaq -0x108(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x32f0
jmp 0x2b19
leaq -0xe0(%rbp), %rdi
movq %rdi, -0x158(%rbp)
leaq -0x108(%rbp), %rsi
movq %rsi, -0x160(%rbp)
callq 0x21f0
movq -0x160(%rbp), %rdi
callq 0x2100
movq -0x158(%rbp), %rsi
leaq -0x80(%rbp), %rdi
callq 0x33a0
movq %rax, -0x150(%rbp)
jmp 0x2b5f
movq -0x150(%rbp), %rax
movq %rax, -0x110(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x33d0
movq %rax, -0x118(%rbp)
leaq -0x110(%rbp), %rdi
leaq -0x118(%rbp), %rsi
callq 0x3370
testb $0x1, %al
jne 0x2b99
jmp 0x2c75
movl -0xc0(%rbp), %eax
cmpl -0x14(%rbp), %eax
ja 0x2c05
movl -0xc0(%rbp), %eax
movl %eax, -0x16c(%rbp)
incl %eax
movl %eax, -0xc0(%rbp)
leaq -0x80(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x3400
movq %rax, -0x168(%rbp)
jmp 0x2bd1
movq -0x168(%rbp), %rax
movl -0x16c(%rbp), %ecx
movl %ecx, (%rax)
jmp 0x2c05
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0x2100
jmp 0x2ce0
leaq -0xe0(%rbp), %rdi
movq %rdi, -0x178(%rbp)
callq 0x2120
movq -0x178(%rbp), %rdi
movq %rax, %rsi
decq %rsi
movq $-0x1, %rdx
callq 0x2060
jmp 0x2c33
leaq -0x80(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x3400
movq %rax, -0x180(%rbp)
jmp 0x2c4c
movq -0x180(%rbp), %rsi
leaq -0x48(%rbp), %rdi
callq 0x3430
jmp 0x2c5e
movsbl -0xe1(%rbp), %esi
leaq -0xe0(%rbp), %rdi
callq 0x22a0
jmp 0x2c73
jmp 0x2c75
jmp 0x2ad6
leaq -0xe0(%rbp), %rdi
callq 0x2120
cmpq $0x0, %rax
je 0x2cb9
leaq -0x80(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x3400
movq %rax, -0x188(%rbp)
jmp 0x2ca5
movq -0x188(%rbp), %rsi
leaq -0x48(%rbp), %rdi
callq 0x3430
jmp 0x2cb7
jmp 0x2cb9
leaq -0xe0(%rbp), %rdi
callq 0x2100
leaq -0x80(%rbp), %rdi
callq 0x34b0
leaq -0x48(%rbp), %rdi
callq 0x34d0
addq $0x190, %rsp            # imm = 0x190
popq %rbp
retq
leaq -0x80(%rbp), %rdi
callq 0x34b0
leaq -0x48(%rbp), %rdi
callq 0x34d0
movq -0x90(%rbp), %rdi
callq 0x22b0
nop