// File: kztomita[P]http-dump/hpack_huffman.cc
// Function: hpack::decode_huffman(unsigned char const*, unsigned long)
std::vector<unsigned char> decode_huffman(const unsigned char* start, std::size_t length) {

  unsigned int offset = 0;
  unsigned int offset_end = length * 8;

  std::vector<unsigned char> decoded;

  auto root = treep->get_root();
  auto node = root;

  while (offset < offset_end) {
    // fetch a bit
    unsigned int bit = (start[offset >> 3] & (0x80 >> (offset & 7))) ? 1 : 0;

    if (bit) {
      if (!node->right) {
        throw std::logic_error("decode error.");
      }
      node = node->right.get();
    } else {
      if (!node->left) {
        throw std::logic_error("decode error.");
      }
      node = node->left.get();
    }
    if (node->value != -1) {
      // found
      if (node->value == 256) {
        break;
      }
      decoded.push_back(node->value);
      node = root;
    }

    offset++;
  }

  return decoded;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x60(%rbp)
movq %rdi, %rax
movq %rax, -0x58(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl $0x0, -0x1c(%rbp)
movq -0x18(%rbp), %rax
shlq $0x3, %rax
movl %eax, -0x20(%rbp)
movb $0x0, -0x21(%rbp)
callq 0x53750
leaq 0x48697(%rip), %rdi     # 0xae838
callq 0x66380
movq %rax, %rdi
callq 0x663a0
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x38(%rbp)
movl -0x1c(%rbp), %eax
cmpl -0x20(%rbp), %eax
jae 0x66343
movq -0x10(%rbp), %rax
movl -0x1c(%rbp), %ecx
shrl $0x3, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %edx
movl -0x1c(%rbp), %ecx
andl $0x7, %ecx
movl $0x80, %eax
sarl %cl, %eax
andl %eax, %edx
xorl %eax, %eax
movl $0x1, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, -0x3c(%rbp)
cmpl $0x0, -0x3c(%rbp)
je 0x6628c
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x669d0
testb $0x1, %al
jne 0x66279
movl $0x10, %edi
callq 0xd580
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x68(%rbp)
leaq 0xfab8(%rip), %rsi      # 0x75ce3
callq 0xdba0
jmp 0x66232
movq -0x68(%rbp), %rdi
movq 0x46d9b(%rip), %rsi     # 0xacfd8
movq 0x46d6c(%rip), %rdx     # 0xacfb0
callq 0xd970
jmp 0x66372
movq -0x68(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
callq 0xdc70
jmp 0x66360
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x66360
movq -0x38(%rbp), %rdi
addq $0x8, %rdi
callq 0x66a00
movq %rax, -0x38(%rbp)
jmp 0x662fb
movq -0x38(%rbp), %rdi
callq 0x669d0
testb $0x1, %al
jne 0x662ee
movl $0x10, %edi
callq 0xd580
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x70(%rbp)
leaq 0xfa2f(%rip), %rsi      # 0x75ce3
callq 0xdba0
jmp 0x662bb
movq -0x70(%rbp), %rdi
movq 0x46d12(%rip), %rsi     # 0xacfd8
movq 0x46ce3(%rip), %rdx     # 0xacfb0
callq 0xd970
jmp 0x66372
movq -0x70(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
callq 0xdc70
jmp 0x66360
movq -0x38(%rbp), %rdi
callq 0x66a00
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
cmpl $-0x1, 0x10(%rax)
je 0x66335
movq -0x38(%rbp), %rax
cmpl $0x100, 0x10(%rax)      # imm = 0x100
jne 0x66314
jmp 0x66343
movq -0x60(%rbp), %rdi
movq -0x38(%rbp), %rax
movb 0x10(%rax), %al
movb %al, -0x4d(%rbp)
leaq -0x4d(%rbp), %rsi
callq 0x5deb0
jmp 0x6632d
movq -0x30(%rbp), %rax
movq %rax, -0x38(%rbp)
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x661ba
movb $0x1, -0x21(%rbp)
testb $0x1, -0x21(%rbp)
jne 0x66356
movq -0x60(%rbp), %rdi
callq 0x18ac0
movq -0x58(%rbp), %rax
addq $0x70, %rsp
popq %rbp
retq
movq -0x60(%rbp), %rdi
callq 0x18ac0
movq -0x48(%rbp), %rdi
callq 0xd990
nopw %cs:(%rax,%rax)