// File: kztomita[P]http-dump/http2_frame.cc
// Function: dump(http2_frame const&)
void dump(const http2_frame& frame) {
  auto type = frame.type();
  std::string type_str;
  std::vector<std::string> flags;
  std::function<void(const http2_frame::payload_type&, uint8_t)> dump_payload;

  switch (type) {
  case http2_frame_header::TYPE_DATA:
    type_str = "DATA";
    if (frame.flags() & 0x01) { flags.push_back("END_STREAM"); }
    if (frame.flags() & 0x08) { flags.push_back("PADDED"); }
    break;
  case http2_frame_header::TYPE_HEADERS:
    type_str = "HEADERS";
    if (frame.flags() & 0x01) { flags.push_back("END_STREAM"); }
    if (frame.flags() & 0x04) { flags.push_back("END_HEADERS"); }
    if (frame.flags() & 0x08) { flags.push_back("PADDED"); }
    if (frame.flags() & 0x20) { flags.push_back("PRIORITY"); }
    dump_payload = dump_headers_payload;
    break;
  case http2_frame_header::TYPE_PRIORITY:
    type_str = "PRIORITY";
    break;
  case http2_frame_header::TYPE_RST_STREAM:
    type_str = "RST_STREAM";
    dump_payload = dump_rst_stream_payload;
    break;
  case http2_frame_header::TYPE_SETTINGS:
    type_str = "SETTINGS";
    if (frame.flags() & 0x01) { flags.push_back("ACK"); }
    dump_payload = dump_settings_payload;
    break;
  case http2_frame_header::TYPE_PUSH_PROMISE:
    type_str = "PUSH_PROMISE";
    break;
  case http2_frame_header::TYPE_PING:
    type_str = "PING";
    break;
  case http2_frame_header::TYPE_GOAWAY:
    type_str = "GOAWAY";
    dump_payload = dump_goaway_payload;
    break;
  case http2_frame_header::TYPE_WINDOW_UPDATE:
    type_str = "WINDOW_UPDATE";
    dump_payload = dump_window_update_payload;
    break;
  case http2_frame_header::TYPE_CONTINUATION:
    type_str = "CONTINUATION";
    if (frame.flags() & 0x04) { flags.push_back("END_HEADERS"); }
    break;
  default:
    type_str = "Type: " + type;
    break;
  }

  std::cout << "Frame: " << type_str;
  std::cout << std::endl;

  std::cout << "Header:"
            << " Length=" << frame.length()
            << " StreamId=" << frame.stream_id()
            << " Flags=" << string_util::join(",", flags);
  std::cout << std::endl;

  dump(&frame.header(), sizeof(http2_frame_header));
  if (frame.payload().size() > 0) {
    std::cout << "Payload:" << std::endl;
    dump(frame.payload_buffer(), frame.payload().size(), 200);
    if (dump_payload) {
      dump_payload(frame.payload(), frame.flags());
    }
  }
  std::cout << std::endl;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2e0, %rsp            # imm = 0x2E0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
callq 0x59b60
movl %eax, -0xc(%rbp)
leaq -0x30(%rbp), %rdi
callq 0xd510
leaq -0x48(%rbp), %rdi
callq 0x31dd0
leaq -0x68(%rbp), %rdi
callq 0x61010
movl -0xc(%rbp), %eax
movq %rax, -0x1e0(%rbp)
subq $0x9, %rax
ja 0x601dd
movq -0x1e0(%rbp), %rax
leaq 0x15b40(%rip), %rcx     # 0x75628
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x15bb8(%rip), %rsi     # 0x756b0
leaq -0x30(%rbp), %rdi
callq 0xd5c0
jmp 0x5fb03
movq -0x8(%rbp), %rdi
callq 0x59b80
movl %eax, -0x1e4(%rbp)
jmp 0x5fb14
movl -0x1e4(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x5fbc9
leaq -0x99(%rbp), %rdi
movq %rdi, -0x1f0(%rbp)
callq 0xddb0
movq -0x1f0(%rbp), %rdx
leaq 0x15b6e(%rip), %rsi     # 0x756b5
leaq -0x98(%rbp), %rdi
callq 0x10a30
jmp 0x5fb55
leaq -0x48(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x55b00
jmp 0x5fb67
leaq -0x98(%rbp), %rdi
callq 0xdac0
leaq -0x99(%rbp), %rdi
callq 0xe180
jmp 0x5fbc9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x604bf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x5fbb8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x98(%rbp), %rdi
callq 0xdac0
leaq -0x99(%rbp), %rdi
callq 0xe180
jmp 0x604bf
movq -0x8(%rbp), %rdi
callq 0x59b80
movl %eax, -0x1f4(%rbp)
jmp 0x5fbda
movl -0x1f4(%rbp), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x5fc7e
leaq -0xc1(%rbp), %rdi
movq %rdi, -0x200(%rbp)
callq 0xddb0
movq -0x200(%rbp), %rdx
leaq 0x15ab3(%rip), %rsi     # 0x756c0
leaq -0xc0(%rbp), %rdi
callq 0x10a30
jmp 0x5fc1b
leaq -0x48(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x55b00
jmp 0x5fc2d
leaq -0xc0(%rbp), %rdi
callq 0xdac0
leaq -0xc1(%rbp), %rdi
callq 0xe180
jmp 0x5fc7e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x5fc6d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0xc0(%rbp), %rdi
callq 0xdac0
leaq -0xc1(%rbp), %rdi
callq 0xe180
jmp 0x604bf
jmp 0x601f8
leaq 0x15a41(%rip), %rsi     # 0x756cb
leaq -0x30(%rbp), %rdi
callq 0xd5c0
jmp 0x5fc95
movq -0x8(%rbp), %rdi
callq 0x59b80
movl %eax, -0x204(%rbp)
jmp 0x5fca6
movl -0x204(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x5fd4a
leaq -0xe9(%rbp), %rdi
movq %rdi, -0x210(%rbp)
callq 0xddb0
movq -0x210(%rbp), %rdx
leaq 0x159dc(%rip), %rsi     # 0x756b5
leaq -0xe8(%rbp), %rdi
callq 0x10a30
jmp 0x5fce7
leaq -0x48(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x55b00
jmp 0x5fcf9
leaq -0xe8(%rbp), %rdi
callq 0xdac0
leaq -0xe9(%rbp), %rdi
callq 0xe180
jmp 0x5fd4a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x5fd39
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0xdac0
leaq -0xe9(%rbp), %rdi
callq 0xe180
jmp 0x604bf
movq -0x8(%rbp), %rdi
callq 0x59b80
movl %eax, -0x214(%rbp)
jmp 0x5fd5b
movl -0x214(%rbp), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x5fdff
leaq -0x111(%rbp), %rdi
movq %rdi, -0x220(%rbp)
callq 0xddb0
movq -0x220(%rbp), %rdx
leaq 0x15939(%rip), %rsi     # 0x756c7
leaq -0x110(%rbp), %rdi
callq 0x10a30
jmp 0x5fd9c
leaq -0x48(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0x55b00
jmp 0x5fdae
leaq -0x110(%rbp), %rdi
callq 0xdac0
leaq -0x111(%rbp), %rdi
callq 0xe180
jmp 0x5fdff
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x5fdee
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x110(%rbp), %rdi
callq 0xdac0
leaq -0x111(%rbp), %rdi
callq 0xe180
jmp 0x604bf
movq -0x8(%rbp), %rdi
callq 0x59b80
movl %eax, -0x224(%rbp)
jmp 0x5fe10
movl -0x224(%rbp), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x5feb4
leaq -0x139(%rbp), %rdi
movq %rdi, -0x230(%rbp)
callq 0xddb0
movq -0x230(%rbp), %rdx
leaq 0x1587d(%rip), %rsi     # 0x756c0
leaq -0x138(%rbp), %rdi
callq 0x10a30
jmp 0x5fe51
leaq -0x48(%rbp), %rdi
leaq -0x138(%rbp), %rsi
callq 0x55b00
jmp 0x5fe63
leaq -0x138(%rbp), %rdi
callq 0xdac0
leaq -0x139(%rbp), %rdi
callq 0xe180
jmp 0x5feb4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x5fea3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x138(%rbp), %rdi
callq 0xdac0
leaq -0x139(%rbp), %rdi
callq 0xe180
jmp 0x604bf
movq -0x8(%rbp), %rdi
callq 0x59b80
movl %eax, -0x234(%rbp)
jmp 0x5fec5
movl -0x234(%rbp), %eax
andl $0x20, %eax
cmpl $0x0, %eax
je 0x5ff69
leaq -0x161(%rbp), %rdi
movq %rdi, -0x240(%rbp)
callq 0xddb0
movq -0x240(%rbp), %rdx
leaq 0x157db(%rip), %rsi     # 0x756d3
leaq -0x160(%rbp), %rdi
callq 0x10a30
jmp 0x5ff06
leaq -0x48(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x55b00
jmp 0x5ff18
leaq -0x160(%rbp), %rdi
callq 0xdac0
leaq -0x161(%rbp), %rdi
callq 0xe180
jmp 0x5ff69
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x5ff58
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x160(%rbp), %rdi
callq 0xdac0
leaq -0x161(%rbp), %rdi
callq 0xe180
jmp 0x604bf
leaq -0x68(%rbp), %rdi
leaq 0x57c(%rip), %rsi       # 0x604f0
callq 0x61050
jmp 0x601f8
leaq 0x1574e(%rip), %rsi     # 0x756d3
leaq -0x30(%rbp), %rdi
callq 0xd5c0
jmp 0x5ff90
jmp 0x601f8
leaq 0x15740(%rip), %rsi     # 0x756dc
leaq -0x30(%rbp), %rdi
callq 0xd5c0
jmp 0x5ffa7
leaq -0x68(%rbp), %rdi
leaq 0x6be(%rip), %rsi       # 0x60670
callq 0x61050
jmp 0x601f8
leaq 0x15724(%rip), %rsi     # 0x756e7
leaq -0x30(%rbp), %rdi
callq 0xd5c0
jmp 0x5ffce
movq -0x8(%rbp), %rdi
callq 0x59b80
movl %eax, -0x244(%rbp)
jmp 0x5ffdf
movl -0x244(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x60083
leaq -0x189(%rbp), %rdi
movq %rdi, -0x250(%rbp)
callq 0xddb0
movq -0x250(%rbp), %rdx
leaq 0x1480c(%rip), %rsi     # 0x7481e
leaq -0x188(%rbp), %rdi
callq 0x10a30
jmp 0x60020
leaq -0x48(%rbp), %rdi
leaq -0x188(%rbp), %rsi
callq 0x55b00
jmp 0x60032
leaq -0x188(%rbp), %rdi
callq 0xdac0
leaq -0x189(%rbp), %rdi
callq 0xe180
jmp 0x60083
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x60072
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x188(%rbp), %rdi
callq 0xdac0
leaq -0x189(%rbp), %rdi
callq 0xe180
jmp 0x604bf
leaq -0x68(%rbp), %rdi
leaq 0x712(%rip), %rsi       # 0x607a0
callq 0x61050
jmp 0x601f8
leaq 0x15651(%rip), %rsi     # 0x756f0
leaq -0x30(%rbp), %rdi
callq 0xd5c0
jmp 0x600aa
jmp 0x601f8
leaq 0x15647(%rip), %rsi     # 0x756fd
leaq -0x30(%rbp), %rdi
callq 0xd5c0
jmp 0x600c1
jmp 0x601f8
leaq 0x15635(%rip), %rsi     # 0x75702
leaq -0x30(%rbp), %rdi
callq 0xd5c0
jmp 0x600d8
leaq -0x68(%rbp), %rdi
leaq 0x83d(%rip), %rsi       # 0x60920
callq 0x61050
jmp 0x601f8
leaq 0x15615(%rip), %rsi     # 0x75709
leaq -0x30(%rbp), %rdi
callq 0xd5c0
jmp 0x600ff
leaq -0x68(%rbp), %rdi
leaq 0x986(%rip), %rsi       # 0x60a90
callq 0x61050
jmp 0x601f8
leaq 0x155fc(%rip), %rsi     # 0x75717
leaq -0x30(%rbp), %rdi
callq 0xd5c0
jmp 0x60126
movq -0x8(%rbp), %rdi
callq 0x59b80
movl %eax, -0x254(%rbp)
jmp 0x60137
movl -0x254(%rbp), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x601db
leaq -0x1b1(%rbp), %rdi
movq %rdi, -0x260(%rbp)
callq 0xddb0
movq -0x260(%rbp), %rdx
leaq 0x1555d(%rip), %rsi     # 0x756c7
leaq -0x1b0(%rbp), %rdi
callq 0x10a30
jmp 0x60178
leaq -0x48(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
callq 0x55b00
jmp 0x6018a
leaq -0x1b0(%rbp), %rdi
callq 0xdac0
leaq -0x1b1(%rbp), %rdi
callq 0xe180
jmp 0x601db
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x601ca
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x1b0(%rbp), %rdi
callq 0xdac0
leaq -0x1b1(%rbp), %rdi
callq 0xe180
jmp 0x604bf
jmp 0x601f8
movslq -0xc(%rbp), %rax
leaq 0x1553c(%rip), %rsi     # 0x75724
addq %rax, %rsi
leaq -0x30(%rbp), %rdi
callq 0xd5c0
jmp 0x601f6
jmp 0x601f8
movq 0x4cd41(%rip), %rdi     # 0xacf40
leaq 0x15525(%rip), %rsi     # 0x7572b
callq 0xd860
movq %rax, -0x268(%rbp)
jmp 0x60214
movq -0x268(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0xd480
jmp 0x60226
movq 0x4cd13(%rip), %rdi     # 0xacf40
movq 0x4cd64(%rip), %rsi     # 0xacf98
callq 0xde80
jmp 0x6023b
movq 0x4ccfe(%rip), %rdi     # 0xacf40
leaq 0x154ea(%rip), %rsi     # 0x75733
callq 0xd860
movq %rax, -0x270(%rbp)
jmp 0x60257
movq -0x270(%rbp), %rdi
leaq 0x154d6(%rip), %rsi     # 0x7573b
callq 0xd860
movq %rax, -0x278(%rbp)
jmp 0x60273
movq -0x8(%rbp), %rdi
callq 0x5a860
movl %eax, -0x27c(%rbp)
jmp 0x60284
movl -0x27c(%rbp), %esi
movq -0x278(%rbp), %rdi
callq 0xdb80
movq %rax, -0x288(%rbp)
jmp 0x6029f
movq -0x288(%rbp), %rdi
leaq 0x15497(%rip), %rsi     # 0x75744
callq 0xd860
movq %rax, -0x290(%rbp)
jmp 0x602bb
movq -0x8(%rbp), %rdi
callq 0x610a0
movl %eax, -0x294(%rbp)
jmp 0x602cc
movl -0x294(%rbp), %esi
movq -0x290(%rbp), %rdi
callq 0xdb80
movq %rax, -0x2a0(%rbp)
jmp 0x602e7
movq -0x2a0(%rbp), %rdi
leaq 0x1545a(%rip), %rsi     # 0x7574f
callq 0xd860
movq %rax, -0x2a8(%rbp)
jmp 0x60303
leaq 0x1544d(%rip), %rsi     # 0x75757
leaq -0x1d8(%rbp), %rdi
leaq -0x48(%rbp), %rdx
callq 0x610c0
jmp 0x6031c
movq -0x2a8(%rbp), %rdi
leaq -0x1d8(%rbp), %rsi
callq 0xd480
jmp 0x60331
leaq -0x1d8(%rbp), %rdi
callq 0xdac0
movq 0x4cbfc(%rip), %rdi     # 0xacf40
movq 0x4cc4d(%rip), %rsi     # 0xacf98
callq 0xde80
jmp 0x60352
movq -0x8(%rbp), %rdi
callq 0x5c940
movq %rax, -0x2b0(%rbp)
jmp 0x60364
movq -0x2b0(%rbp), %rdi
movl $0x9, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x72b10
jmp 0x6037c
movq -0x8(%rbp), %rdi
callq 0x5c950
movq %rax, -0x2b8(%rbp)
jmp 0x6038e
movq -0x2b8(%rbp), %rdi
callq 0x4e6b0
cmpq $0x0, %rax
jbe 0x60486
movq 0x4cb95(%rip), %rdi     # 0xacf40
leaq 0x153a7(%rip), %rsi     # 0x75759
callq 0xd860
movq %rax, -0x2c0(%rbp)
jmp 0x603c0
movq -0x2c0(%rbp), %rdi
movq 0x4cbca(%rip), %rsi     # 0xacf98
callq 0xde80
jmp 0x603d5
movq -0x8(%rbp), %rdi
callq 0x5c9a0
movq %rax, -0x2c8(%rbp)
jmp 0x603e7
movq -0x8(%rbp), %rdi
callq 0x5c950
movq %rax, -0x2d0(%rbp)
jmp 0x603f9
movq -0x2d0(%rbp), %rdi
callq 0x4e6b0
movq -0x2c8(%rbp), %rdi
movq %rax, %rsi
movl $0xc8, %edx
callq 0x72b10
jmp 0x6041b
leaq -0x68(%rbp), %rdi
callq 0x61220
testb $0x1, %al
jne 0x6042a
jmp 0x60484
movq -0x8(%rbp), %rdi
callq 0x5c950
movq %rax, -0x2d8(%rbp)
jmp 0x6043c
movq -0x8(%rbp), %rdi
callq 0x59b80
movl %eax, -0x2dc(%rbp)
jmp 0x6044d
movq -0x2d8(%rbp), %rsi
movl -0x2dc(%rbp), %eax
movzbl %al, %edx
leaq -0x68(%rbp), %rdi
callq 0x61250
jmp 0x60468
jmp 0x60484
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x1d8(%rbp), %rdi
callq 0xdac0
jmp 0x604bf
jmp 0x60486
movq 0x4cab3(%rip), %rdi     # 0xacf40
movq 0x4cb04(%rip), %rsi     # 0xacf98
callq 0xde80
jmp 0x6049b
leaq -0x68(%rbp), %rdi
callq 0x612a0
leaq -0x48(%rbp), %rdi
callq 0x31f40
leaq -0x30(%rbp), %rdi
callq 0xdac0
addq $0x2e0, %rsp            # imm = 0x2E0
popq %rbp
retq
leaq -0x68(%rbp), %rdi
callq 0x612a0
leaq -0x48(%rbp), %rdi
callq 0x31f40
leaq -0x30(%rbp), %rdi
callq 0xdac0
movq -0x70(%rbp), %rdi
callq 0xd990
nopw %cs:(%rax,%rax)