// File: BelfordZ[P]SimpleFileServer/Client.cpp
// Function: Client::listen()
void Client::listen() {
   // Need to know if it's our first SYNC frame, because we don't want to
   // output an empty buffer to our file...
   bool isFirstSYNC = true;

   // Transfer Stats
   int totalFrames = 0;
   int badFrames = 0;

   // Main listening loop
   while(true) {
      Frame f = receive_frame();
      totalFrames++;
      
      if(f.is_good()) {

	 switch(f.get_frame_type()) {
	    case SYNC:
	    {
	       // Display line, append to file, and erase line buffer
	       if(!isFirstSYNC) {
		  std::cout << lineBuffer << std::endl;
		  lineBuffer = lineBuffer.substr(0, previousLineLength);
		  lineBuffer.append("\n");
		  *outFile << lineBuffer;
		  lineBuffer = "";
	       }
	       
	       isFirstSYNC = false;

	       // ACK our good SYNC frame, next will be DATA frames
	       Frame ackFrame(ACK, "MOAR FRAMEZ PLZ");
	       send_frame(ackFrame);
	       previousLineLength = atoi(f.get_data().c_str());
	       break;
	    }
	    case DATA:
	    {
	       // Data frame, so just append it to the current line buffer
	       lineBuffer.append(f.get_data());

	       Frame ackFrame(ACK, "KAYPE");
	       send_frame(ackFrame);
	       break;
	    }
	    case GOODBYE:
	    {
	       transfer_stats(totalFrames, badFrames);
	       return; // We're done here
	    }
	    default:
	    {
	       // WE SHOULD NEVER GET HERE!!!
	       std::cout << "Invalid frame type received!" << std::endl;
	       return;
	    }
	 }
	 
      } else {

	 if(f.get_frame_type() == GOODBYE) {
	    transfer_stats(totalFrames, badFrames);
	    return; // We can't ACK GOODBYE frames... duh.
	 }

	 badFrames++;
	 
	 // Send NAK and wait for the server to retransmit the frame
	 // Next one is guaranteed to be okay, since we just send a NAK
	 std::cout << "\t\t[Bad frame! Requesting retransmission... Type: " << f.get_frame_type() << "]"
		   << std::endl;
	 Frame nakFrame(NAK, "LOLWUT SEND AGAIN");
	 send_frame(nakFrame);
      }
   }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2c0, %rsp            # imm = 0x2C0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x240(%rbp)
movb $0x1, -0x9(%rbp)
movl $0x0, -0x10(%rbp)
movl $0x0, -0x14(%rbp)
movq -0x240(%rbp), %rsi
leaq -0x60(%rbp), %rdi
movq %rdi, -0x250(%rbp)
callq 0x4930
movq -0x250(%rbp), %rdi
movl -0x10(%rbp), %eax
incl %eax
movl %eax, -0x10(%rbp)
callq 0x54d0
movb %al, -0x241(%rbp)
jmp 0x4b8f
movb -0x241(%rbp), %al
testb $0x1, %al
jne 0x4b9e
jmp 0x4fb0
leaq -0x60(%rbp), %rdi
callq 0x5510
movl %eax, -0x254(%rbp)
jmp 0x4baf
movl -0x254(%rbp), %eax
subl $0x2, %eax
je 0x4bf2
jmp 0x4bbc
movl -0x254(%rbp), %eax
subl $0x3, %eax
je 0x4f48
jmp 0x4bcd
movl -0x254(%rbp), %eax
subl $0x4, %eax
je 0x4dfa
jmp 0x4f6b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x5179
testb $0x1, -0x9(%rbp)
jne 0x4ccc
movq -0x240(%rbp), %rsi
addq $0x10, %rsi
movq 0x73c2(%rip), %rdi      # 0xbfd0
callq 0x3250
movq %rax, -0x260(%rbp)
jmp 0x4c1c
movq -0x260(%rbp), %rdi
movq 0x738e(%rip), %rsi      # 0xbfb8
callq 0x32d0
jmp 0x4c31
movq -0x240(%rbp), %rax
movq %rax, %rsi
addq $0x10, %rsi
movslq 0x4(%rax), %rcx
xorl %eax, %eax
movl %eax, %edx
leaq -0x90(%rbp), %rdi
callq 0x32c0
jmp 0x4c55
movq -0x240(%rbp), %rdi
addq $0x10, %rdi
movq %rdi, -0x268(%rbp)
leaq -0x90(%rbp), %rsi
movq %rsi, -0x270(%rbp)
callq 0x3360
movq -0x270(%rbp), %rdi
callq 0x3518
movq -0x268(%rbp), %rdi
leaq 0x3815(%rip), %rsi      # 0x84a9
callq 0x34c0
jmp 0x4c9b
movq -0x240(%rbp), %rsi
movq 0x30(%rsi), %rdi
addq $0x10, %rsi
callq 0x3250
jmp 0x4cb1
movq -0x240(%rbp), %rdi
addq $0x10, %rdi
leaq 0x3614(%rip), %rsi      # 0x82d7
callq 0x33b0
jmp 0x4cca
jmp 0x4ccc
movb $0x0, -0x9(%rbp)
movl $0x5, -0xdc(%rbp)
leaq -0x101(%rbp), %rdi
movq %rdi, -0x278(%rbp)
callq 0x3470
movq -0x278(%rbp), %rdx
leaq 0x34db(%rip), %rsi      # 0x81d6
leaq -0x100(%rbp), %rdi
callq 0x3aa0
jmp 0x4d09
leaq -0xd8(%rbp), %rdi
leaq -0xdc(%rbp), %rsi
leaq -0x100(%rbp), %rdx
movl $0x1, %ecx
callq 0x5530
jmp 0x4d2a
leaq -0x100(%rbp), %rdi
callq 0x3518
leaq -0x101(%rbp), %rdi
callq 0x32f0
movq -0x240(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x48c0
jmp 0x4d57
leaq -0x128(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x5470
jmp 0x4d69
leaq -0x128(%rbp), %rdi
callq 0x3110
movq %rax, %rdi
callq 0x3420
movl %eax, %ecx
movq -0x240(%rbp), %rax
movl %ecx, 0x4(%rax)
leaq -0x128(%rbp), %rdi
callq 0x3518
leaq -0xd8(%rbp), %rdi
callq 0x54a0
jmp 0x4fab
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x4dcc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x3518
leaq -0x101(%rbp), %rdi
callq 0x32f0
jmp 0x5179
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x54a0
jmp 0x5179
movq -0x240(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x280(%rbp)
leaq -0x148(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x5470
jmp 0x4e1e
movq -0x280(%rbp), %rdi
leaq -0x148(%rbp), %rsi
callq 0x34d0
jmp 0x4e33
leaq -0x148(%rbp), %rdi
callq 0x3518
movl $0x5, -0x194(%rbp)
leaq -0x1b9(%rbp), %rdi
movq %rdi, -0x288(%rbp)
callq 0x3470
movq -0x288(%rbp), %rdx
leaq 0x337c(%rip), %rsi      # 0x81e6
leaq -0x1b8(%rbp), %rdi
callq 0x3aa0
jmp 0x4e78
leaq -0x190(%rbp), %rdi
leaq -0x194(%rbp), %rsi
leaq -0x1b8(%rbp), %rdx
movl $0x1, %ecx
callq 0x5530
jmp 0x4e99
leaq -0x1b8(%rbp), %rdi
callq 0x3518
leaq -0x1b9(%rbp), %rdi
callq 0x32f0
movq -0x240(%rbp), %rdi
leaq -0x190(%rbp), %rsi
callq 0x48c0
jmp 0x4ec6
leaq -0x190(%rbp), %rdi
callq 0x54a0
jmp 0x4fab
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x148(%rbp), %rdi
callq 0x3518
jmp 0x5179
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x4f1a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x1b8(%rbp), %rdi
callq 0x3518
leaq -0x1b9(%rbp), %rdi
callq 0x32f0
jmp 0x5179
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x190(%rbp), %rdi
callq 0x54a0
jmp 0x5179
movq -0x240(%rbp), %rdi
movl -0x10(%rbp), %esi
movl -0x14(%rbp), %edx
callq 0x51a0
jmp 0x4f5c
movl $0x1, -0x1c0(%rbp)
jmp 0x515d
movq 0x705e(%rip), %rdi      # 0xbfd0
leaq 0x3273(%rip), %rsi      # 0x81ec
callq 0x3280
movq %rax, -0x290(%rbp)
jmp 0x4f87
movq -0x290(%rbp), %rdi
movq 0x7023(%rip), %rsi      # 0xbfb8
callq 0x32d0
jmp 0x4f9c
movl $0x1, -0x1c0(%rbp)
jmp 0x515d
jmp 0x5153
leaq -0x60(%rbp), %rdi
callq 0x5510
movl %eax, -0x294(%rbp)
jmp 0x4fc1
movl -0x294(%rbp), %eax
cmpl $0x3, %eax
jne 0x4fef
movq -0x240(%rbp), %rdi
movl -0x10(%rbp), %esi
movl -0x14(%rbp), %edx
callq 0x51a0
jmp 0x4fe0
movl $0x1, -0x1c0(%rbp)
jmp 0x515d
movl -0x14(%rbp), %eax
incl %eax
movl %eax, -0x14(%rbp)
movq 0x6fd2(%rip), %rdi      # 0xbfd0
leaq 0x3204(%rip), %rsi      # 0x8209
callq 0x3280
movq %rax, -0x2a0(%rbp)
jmp 0x5013
leaq -0x60(%rbp), %rdi
callq 0x5510
movl %eax, -0x2a4(%rbp)
jmp 0x5024
movl -0x2a4(%rbp), %esi
movq -0x2a0(%rbp), %rdi
callq 0x3450
movq %rax, -0x2b0(%rbp)
jmp 0x503f
movq -0x2b0(%rbp), %rdi
leaq 0x31ee(%rip), %rsi      # 0x823b
callq 0x3280
movq %rax, -0x2b8(%rbp)
jmp 0x505b
movq -0x2b8(%rbp), %rdi
movq 0x6f4f(%rip), %rsi      # 0xbfb8
callq 0x32d0
jmp 0x5070
movl $0x6, -0x20c(%rbp)
leaq -0x231(%rbp), %rdi
movq %rdi, -0x2c0(%rbp)
callq 0x3470
movq -0x2c0(%rbp), %rdx
leaq 0x31a2(%rip), %rsi      # 0x823d
leaq -0x230(%rbp), %rdi
callq 0x3aa0
jmp 0x50a9
leaq -0x208(%rbp), %rdi
leaq -0x20c(%rbp), %rsi
leaq -0x230(%rbp), %rdx
movl $0x1, %ecx
callq 0x5530
jmp 0x50ca
leaq -0x230(%rbp), %rdi
callq 0x3518
leaq -0x231(%rbp), %rdi
callq 0x32f0
movq -0x240(%rbp), %rdi
leaq -0x208(%rbp), %rsi
callq 0x48c0
jmp 0x50f7
leaq -0x208(%rbp), %rdi
callq 0x54a0
jmp 0x5153
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x512b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x3518
leaq -0x231(%rbp), %rdi
callq 0x32f0
jmp 0x5179
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x208(%rbp), %rdi
callq 0x54a0
jmp 0x5179
movl $0x0, -0x1c0(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x54a0
movl -0x1c0(%rbp), %eax
testl %eax, %eax
je 0x5174
jmp 0x5172
jmp 0x5184
jmp 0x4b5c
leaq -0x60(%rbp), %rdi
callq 0x54a0
jmp 0x518d
addq $0x2c0, %rsp            # imm = 0x2C0
popq %rbp
retq
movq -0x68(%rbp), %rdi
callq 0x3460
nopw %cs:(%rax,%rax)