// File: ivanoleinik[P]archiver/src/main.cpp
// Function: main
int main(int argc, char** argv) {
    int action = -1;
    enum {
        COMPRESS,
        UNCOMPRESS
    };
    std::string filename_in, filename_out;

    try {
        for (int i = 1; i < argc; i++) {
            std::string option(argv[i]);
            if (option == "-c") {
                action = COMPRESS;
            } else if (option == "-u") {
                action = UNCOMPRESS;
            } else if (option == "-f" || option == "--file") {
                filename_in = std::string(argv[i + 1]);
                i++;
            } else if (option == "-o" || option == "--output") {
                if (i + 1 >= argc)
                    throw HuffException("Bad input");
                filename_out = std::string(argv[i + 1]);
                i++;
            } else {
                throw HuffException("Bad input");
            }
        }

        std::ifstream in(filename_in, std::ifstream::binary);
        if (!in)
            throw HuffException("Bad filename");
        std::ofstream out(filename_out, std::ofstream::binary);

        if (action == COMPRESS) {
            HuffEncode encode = HuffEncode(in);
            encode.write(out);
            encode.write_info();
        } else if (action == UNCOMPRESS) {
            HuffDecode decode = HuffDecode(in);
            decode.write(out);
            decode.write_info();
        } else {
            throw HuffException("Bad action");
        }

        return 0;
    } catch(HuffException &ex) {
        std::cout << ex.what() << std::endl;
        return 1;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x6f0, %rsp            # imm = 0x6F0
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0xffffffff, -0x14(%rbp) # imm = 0xFFFFFFFF
leaq -0x38(%rbp), %rdi
callq 0x32f0
leaq -0x58(%rbp), %rdi
callq 0x32f0
movl $0x1, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
cmpl -0x8(%rbp), %eax
jge 0xe497
movq -0x10(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x670(%rbp)
leaq -0x81(%rbp), %rdi
movq %rdi, -0x668(%rbp)
callq 0x33e0
movq -0x670(%rbp), %rsi
movq -0x668(%rbp), %rdx
leaq -0x80(%rbp), %rdi
callq 0xe910
jmp 0xe034
leaq -0x81(%rbp), %rdi
callq 0x3270
leaq 0x115c(%rip), %rsi      # 0xf1a3
leaq -0x80(%rbp), %rdi
callq 0xe9c0
movb %al, -0x671(%rbp)
jmp 0xe058
movb -0x671(%rbp), %al
testb $0x1, %al
jne 0xe064
jmp 0xe0aa
movl $0x0, -0x14(%rbp)
jmp 0xe472
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0x81(%rbp), %rdi
callq 0x3270
jmp 0xe81e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0xe489
leaq 0x10f5(%rip), %rsi      # 0xf1a6
leaq -0x80(%rbp), %rdi
callq 0xe9c0
movb %al, -0x672(%rbp)
jmp 0xe0c2
movb -0x672(%rbp), %al
testb $0x1, %al
jne 0xe0ce
jmp 0xe0da
movl $0x1, -0x14(%rbp)
jmp 0xe470
leaq 0x10c8(%rip), %rsi      # 0xf1a9
leaq -0x80(%rbp), %rdi
callq 0xe9c0
movb %al, -0x673(%rbp)
jmp 0xe0f2
movb -0x673(%rbp), %al
testb $0x1, %al
jne 0xe125
jmp 0xe0fe
leaq 0x10a7(%rip), %rsi      # 0xf1ac
leaq -0x80(%rbp), %rdi
callq 0xe9c0
movb %al, -0x674(%rbp)
jmp 0xe116
movb -0x674(%rbp), %al
testb $0x1, %al
jne 0xe125
jmp 0xe1c1
movq -0x10(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movq 0x8(%rax,%rcx,8), %rax
movq %rax, -0x688(%rbp)
leaq -0xb9(%rbp), %rdi
movq %rdi, -0x680(%rbp)
callq 0x33e0
movq -0x688(%rbp), %rsi
movq -0x680(%rbp), %rdx
leaq -0xb8(%rbp), %rdi
callq 0xe910
jmp 0xe168
leaq -0x38(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x32a0
leaq -0xb8(%rbp), %rdi
callq 0x3150
leaq -0xb9(%rbp), %rdi
callq 0x3270
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0xe46e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0xb9(%rbp), %rdi
callq 0x3270
jmp 0xe489
leaq 0xfeb(%rip), %rsi       # 0xf1b3
leaq -0x80(%rbp), %rdi
callq 0xe9c0
movb %al, -0x689(%rbp)
jmp 0xe1d9
movb -0x689(%rbp), %al
testb $0x1, %al
jne 0xe20c
jmp 0xe1e5
leaq 0xfca(%rip), %rsi       # 0xf1b6
leaq -0x80(%rbp), %rdi
callq 0xe9c0
movb %al, -0x68a(%rbp)
jmp 0xe1fd
movb -0x68a(%rbp), %al
testb $0x1, %al
jne 0xe20c
jmp 0xe393
movl -0x5c(%rbp), %eax
addl $0x1, %eax
cmpl -0x8(%rbp), %eax
jl 0xe2f7
movb $0x1, -0xe2(%rbp)
movl $0x28, %edi
callq 0x3100
movq %rax, -0x6a0(%rbp)
leaq -0xe1(%rbp), %rdi
movq %rdi, -0x698(%rbp)
callq 0x33e0
movq -0x698(%rbp), %rdx
leaq 0xf6b(%rip), %rsi       # 0xf1bf
leaq -0xe0(%rbp), %rdi
callq 0xe910
jmp 0xe262
movq -0x6a0(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0xe9f0
jmp 0xe277
movq -0x6a0(%rbp), %rdi
movb $0x0, -0xe2(%rbp)
leaq 0x8ad4(%rip), %rsi      # 0x16d60
leaq 0x7dd(%rip), %rdx       # 0xea70
callq 0x33a0
jmp 0xe90e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0xe2cf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0x3150
leaq -0xe1(%rbp), %rdi
callq 0x3270
testb $0x1, -0xe2(%rbp)
jne 0xe2e6
jmp 0xe2f2
movq -0x6a0(%rbp), %rdi
callq 0x31a0
jmp 0xe489
movq -0x10(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movq 0x8(%rax,%rcx,8), %rax
movq %rax, -0x6b0(%rbp)
leaq -0x109(%rbp), %rdi
movq %rdi, -0x6a8(%rbp)
callq 0x33e0
movq -0x6b0(%rbp), %rsi
movq -0x6a8(%rbp), %rdx
leaq -0x108(%rbp), %rdi
callq 0xe910
jmp 0xe33a
leaq -0x58(%rbp), %rdi
leaq -0x108(%rbp), %rsi
callq 0x32a0
leaq -0x108(%rbp), %rdi
callq 0x3150
leaq -0x109(%rbp), %rdi
callq 0x3270
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0xe46c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0x109(%rbp), %rdi
callq 0x3270
jmp 0xe489
movb $0x1, -0x132(%rbp)
movl $0x28, %edi
callq 0x3100
movq %rax, -0x6c0(%rbp)
leaq -0x131(%rbp), %rdi
movq %rdi, -0x6b8(%rbp)
callq 0x33e0
movq -0x6b8(%rbp), %rdx
leaq 0xdf3(%rip), %rsi       # 0xf1bf
leaq -0x130(%rbp), %rdi
callq 0xe910
jmp 0xe3da
movq -0x6c0(%rbp), %rdi
leaq -0x130(%rbp), %rsi
callq 0xe9f0
jmp 0xe3ef
movq -0x6c0(%rbp), %rdi
movb $0x0, -0x132(%rbp)
leaq 0x895c(%rip), %rsi      # 0x16d60
leaq 0x665(%rip), %rdx       # 0xea70
callq 0x33a0
jmp 0xe90e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0xe447
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0x130(%rbp), %rdi
callq 0x3150
leaq -0x131(%rbp), %rdi
callq 0x3270
testb $0x1, -0x132(%rbp)
jne 0xe45e
jmp 0xe46a
movq -0x6c0(%rbp), %rdi
callq 0x31a0
jmp 0xe489
jmp 0xe46e
jmp 0xe470
jmp 0xe472
leaq -0x80(%rbp), %rdi
callq 0x3150
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0xdfe9
leaq -0x80(%rbp), %rdi
callq 0x3150
jmp 0xe81e
leaq -0x340(%rbp), %rdi
leaq -0x38(%rbp), %rsi
movl $0x4, %edx
callq 0x3370
jmp 0xe4ae
movq -0x340(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x340(%rbp,%rax), %rdi
callq 0x30f0
movb %al, -0x6c1(%rbp)
jmp 0xe4ce
movb -0x6c1(%rbp), %al
testb $0x1, %al
jne 0xe4dd
jmp 0xe5e7
movb $0x1, -0x362(%rbp)
movl $0x28, %edi
callq 0x3100
movq %rax, -0x6d8(%rbp)
leaq -0x361(%rbp), %rdi
movq %rdi, -0x6d0(%rbp)
callq 0x33e0
movq -0x6d0(%rbp), %rdx
leaq 0xcb3(%rip), %rsi       # 0xf1c9
leaq -0x360(%rbp), %rdi
callq 0xe910
jmp 0xe524
movq -0x6d8(%rbp), %rdi
leaq -0x360(%rbp), %rsi
callq 0xe9f0
jmp 0xe539
movq -0x6d8(%rbp), %rdi
movb $0x0, -0x362(%rbp)
leaq 0x8812(%rip), %rsi      # 0x16d60
leaq 0x51b(%rip), %rdx       # 0xea70
callq 0x33a0
jmp 0xe90e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0xe81e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0xe812
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0xe5bf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0x360(%rbp), %rdi
callq 0x3150
leaq -0x361(%rbp), %rdi
callq 0x3270
testb $0x1, -0x362(%rbp)
jne 0xe5d6
jmp 0xe5e2
movq -0x6d8(%rbp), %rdi
callq 0x31a0
jmp 0xe812
leaq -0x568(%rbp), %rdi
leaq -0x58(%rbp), %rsi
movl $0x4, %edx
callq 0x3410
jmp 0xe5fe
cmpl $0x0, -0x14(%rbp)
jne 0xe68b
leaq -0x5c8(%rbp), %rdi
leaq -0x340(%rbp), %rsi
callq 0x3fd0
jmp 0xe61d
leaq -0x5c8(%rbp), %rdi
leaq -0x568(%rbp), %rsi
callq 0x42b0
jmp 0xe632
leaq -0x5c8(%rbp), %rdi
callq 0x4480
jmp 0xe640
leaq -0x5c8(%rbp), %rdi
callq 0xeab0
jmp 0xe7d8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0xe806
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0x5c8(%rbp), %rdi
callq 0xeab0
jmp 0xe806
cmpl $0x1, -0x14(%rbp)
jne 0xe6fd
leaq -0x630(%rbp), %rdi
leaq -0x340(%rbp), %rsi
callq 0x4500
jmp 0xe6a6
leaq -0x630(%rbp), %rdi
leaq -0x568(%rbp), %rsi
callq 0x4a70
jmp 0xe6bb
leaq -0x630(%rbp), %rdi
callq 0x4aa0
jmp 0xe6c9
leaq -0x630(%rbp), %rdi
callq 0xeaf0
jmp 0xe7d6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0x630(%rbp), %rdi
callq 0xeaf0
jmp 0xe806
movb $0x1, -0x652(%rbp)
movl $0x28, %edi
callq 0x3100
movq %rax, -0x6e8(%rbp)
leaq -0x651(%rbp), %rdi
movq %rdi, -0x6e0(%rbp)
callq 0x33e0
movq -0x6e0(%rbp), %rdx
leaq 0xaa0(%rip), %rsi       # 0xf1d6
leaq -0x650(%rbp), %rdi
callq 0xe910
jmp 0xe744
movq -0x6e8(%rbp), %rdi
leaq -0x650(%rbp), %rsi
callq 0xe9f0
jmp 0xe759
movq -0x6e8(%rbp), %rdi
movb $0x0, -0x652(%rbp)
leaq 0x85f2(%rip), %rsi      # 0x16d60
leaq 0x2fb(%rip), %rdx       # 0xea70
callq 0x33a0
jmp 0xe90e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0xe7b1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0x650(%rbp), %rdi
callq 0x3150
leaq -0x651(%rbp), %rdi
callq 0x3270
testb $0x1, -0x652(%rbp)
jne 0xe7c8
jmp 0xe7d4
movq -0x6e8(%rbp), %rdi
callq 0x31a0
jmp 0xe806
jmp 0xe7d8
movl $0x0, -0x4(%rbp)
movl $0x1, -0x658(%rbp)
leaq -0x568(%rbp), %rdi
callq 0x3320
leaq -0x340(%rbp), %rdi
callq 0x3060
jmp 0xe8ca
leaq -0x568(%rbp), %rdi
callq 0x3320
leaq -0x340(%rbp), %rdi
callq 0x3060
movl -0x94(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0xe8e8
movq -0x90(%rbp), %rdi
callq 0x30b0
movq %rax, -0x660(%rbp)
movq -0x660(%rbp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq %rax, %rsi
movq 0x877a(%rip), %rdi      # 0x16fd8
callq 0x3220
movq %rax, -0x6f0(%rbp)
jmp 0xe86c
movq -0x6f0(%rbp), %rdi
movq 0x873e(%rip), %rsi      # 0x16fb8
callq 0x3250
jmp 0xe881
movl $0x1, -0x4(%rbp)
movl $0x1, -0x658(%rbp)
callq 0x3390
jmp 0xe8b2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
callq 0x3390
jmp 0xe8c8
jmp 0xe8ca
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0xe8e8
jmp 0xe8e8
leaq -0x58(%rbp), %rdi
callq 0x3150
leaq -0x38(%rbp), %rdi
callq 0x3150
movl -0x4(%rbp), %eax
addq $0x6f0, %rsp            # imm = 0x6F0
popq %rbp
retq
leaq -0x58(%rbp), %rdi
callq 0x3150
leaq -0x38(%rbp), %rdi
callq 0x3150
movq -0x90(%rbp), %rdi
callq 0x33d0
movq %rax, %rdi
callq 0x5e10
nop