// File: cristian-bicheru[P]arith/./huffman.h
// Function: void huffman::UncompressBuffer<unsigned char, unsigned long>(std::vector<unsigned char, std::allocator<unsigned char>>&, std::vector<unsigned char, std::allocator<unsigned char>>&)
void UncompressBuffer(std::vector<SymbolType>& UncompressedBuffer, std::vector<unsigned char>& CompressedBuffer) {
        std::map<SymbolType, ValueType> SortedFrequencyTable;
        uint16_t mindex;
        uint64_t UncompressedSize;
        buffer::DecodeTypeFromBuffer<uint16_t>(CompressedBuffer, 0, &mindex);
        buffer::DecodeTypeFromBuffer<uint64_t>(CompressedBuffer, sizeof(uint16_t), &UncompressedSize);
        uint16_t index = sizeof(uint16_t)+sizeof(uint64_t);
        SymbolType key;
        ValueType val;

        while (index < mindex) {
            buffer::DecodeTypeFromBuffer<SymbolType>(CompressedBuffer, index, &key);
            index += sizeof(SymbolType);
            buffer::DecodeTypeFromBuffer<ValueType>(CompressedBuffer, index, &val);
            index += sizeof(ValueType);
            SortedFrequencyTable[key] = val;
        }

        HuffmanTree<SymbolType, ValueType> HuffTree(SortedFrequencyTable);

        buffer::CodecBitIterator BitStream(CompressedBuffer, index);
        std::vector<bool> TreeIndex;

        while (UncompressedBuffer.size() < UncompressedSize) {
            TreeIndex.push_back(BitStream.ReadBit());
            if (HuffTree[TreeIndex].IsRoot()) {
                UncompressedBuffer.push_back(HuffTree[TreeIndex].GetSymbol());
                TreeIndex.resize(0);
            }
        }
    }

// Assembly:
subq $0x158, %rsp            # imm = 0x158
movq %rdi, 0x150(%rsp)
movq %rsi, 0x148(%rsp)
leaq 0x118(%rsp), %rdi
callq 0xa0a0
movq 0x148(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
leaq 0x116(%rsp), %rdx
callq 0x16ff0
jmp 0x5cff
movq 0x148(%rsp), %rdi
movl $0x2, %esi
leaq 0x108(%rsp), %rdx
callq 0x5670
movw $0xa, 0xfa(%rsp)
movzwl 0xfa(%rsp), %eax
movzwl 0x116(%rsp), %ecx
cmpl %ecx, %eax
jge 0x5df6
movq 0x148(%rsp), %rdi
movzwl 0xfa(%rsp), %eax
movl %eax, %esi
leaq 0xf9(%rsp), %rdx
callq 0x17050
jmp 0x5d5c
movw 0xfa(%rsp), %ax
incw %ax
movw %ax, 0xfa(%rsp)
movq 0x148(%rsp), %rdi
movzwl 0xfa(%rsp), %eax
movl %eax, %esi
leaq 0xf0(%rsp), %rdx
callq 0x5670
movw 0xfa(%rsp), %ax
addw $0x8, %ax
movw %ax, 0xfa(%rsp)
movq 0xf0(%rsp), %rax
movq %rax, 0x20(%rsp)
leaq 0x118(%rsp), %rdi
leaq 0xf9(%rsp), %rsi
callq 0xada0
movq %rax, 0x28(%rsp)
jmp 0x5dcb
movq 0x28(%rsp), %rax
movq 0x20(%rsp), %rcx
movq %rcx, (%rax)
jmp 0x5d23
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x100(%rsp)
movl %eax, 0xfc(%rsp)
jmp 0x5fb7
leaq 0xa0(%rsp), %rdi
leaq 0x118(%rsp), %rsi
callq 0xa140
jmp 0x5e0d
movq 0x148(%rsp), %rsi
leaq 0x60(%rsp), %rdi
callq 0x4f00
jmp 0x5e21
movzwl 0xfa(%rsp), %eax
movl %eax, %edx
leaq 0x78(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x5000
jmp 0x5e3c
leaq 0x60(%rsp), %rdi
callq 0x5050
leaq 0x38(%rsp), %rdi
callq 0xa7c0
movq 0x150(%rsp), %rdi
callq 0x4b20
cmpq 0x108(%rsp), %rax
jae 0x5f74
leaq 0x78(%rsp), %rdi
callq 0x5160
testb %al, %al
setne %al
movzbl %al, %esi
leaq 0x38(%rsp), %rdi
callq 0x11770
jmp 0x5e89
leaq 0xa0(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x11850
movq %rax, 0x18(%rsp)
jmp 0x5ea2
movq 0x18(%rsp), %rdi
callq 0x11930
testb $0x1, %al
jne 0x5eb5
jmp 0x5f6f
movq 0x150(%rsp), %rax
movq %rax, 0x8(%rsp)
leaq 0xa0(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x11850
movq %rax, 0x10(%rsp)
jmp 0x5edb
movq 0x10(%rsp), %rdi
callq 0x11560
movq 0x8(%rsp), %rdi
movb %al, 0x37(%rsp)
leaq 0x37(%rsp), %rsi
callq 0x6e50
jmp 0x5efa
xorl %edx, %edx
movl %edx, %esi
leaq 0x38(%rsp), %rdi
callq 0x150d0
jmp 0x5f0a
jmp 0x5f6f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x100(%rsp)
movl %eax, 0xfc(%rsp)
jmp 0x5faa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x100(%rsp)
movl %eax, 0xfc(%rsp)
leaq 0x60(%rsp), %rdi
callq 0x5050
jmp 0x5faa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x100(%rsp)
movl %eax, 0xfc(%rsp)
leaq 0x38(%rsp), %rdi
callq 0xabf0
leaq 0x78(%rsp), %rdi
callq 0x5370
jmp 0x5faa
jmp 0x5e50
leaq 0x38(%rsp), %rdi
callq 0xabf0
leaq 0x78(%rsp), %rdi
callq 0x5370
leaq 0xa0(%rsp), %rdi
callq 0xac10
leaq 0x118(%rsp), %rdi
callq 0xacc0
addq $0x158, %rsp            # imm = 0x158
retq
leaq 0xa0(%rsp), %rdi
callq 0xac10
leaq 0x118(%rsp), %rdi
callq 0xacc0
movq 0x100(%rsp), %rdi
callq 0x2310
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)