// File: tylerkaraszewski[P]Argyle/HttpRequest.cpp
// Function: HttpRequest::parse(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
size_t HttpRequest::parse(const string& buffer)
{
  size_t headerEnd = buffer.find("\r\n\r\n");
  if (headerEnd == buffer.npos)
  {
    return 0;
  }

  // Ok, now we parse this.
  size_t startOffset = 0;
  size_t endOffset = 0;

  // Special handling for the first line.
  endOffset = buffer.find_first_of(SPACES);
  if (endOffset == buffer.npos)
  {
    m_httpError = 400;
    return headerEnd + 4;
  }
  m_method = buffer.substr(startOffset, endOffset);
  startOffset = buffer.find_first_not_of(SPACES, endOffset);
  if (startOffset == buffer.npos)
  {
    m_httpError = 400;
    return headerEnd + 4;
  }
  endOffset = buffer.find_first_of(SPACES, startOffset);
  if (endOffset == buffer.npos)
  {
    m_httpError = 400;
    return headerEnd + 4;
  }
  m_path = buffer.substr(startOffset, endOffset - startOffset);
  startOffset = buffer.find_first_not_of(SPACES, endOffset);
  if (startOffset == buffer.npos)
  {
    m_httpError = 400;
    return headerEnd + 4;
  }
  endOffset = buffer.find_first_of(NEWLINES, startOffset);
  if (endOffset == buffer.npos)
  {
    m_httpError = 400;
    return headerEnd + 4;
  }
  m_httpVersion = buffer.substr(startOffset, endOffset - startOffset);

  size_t pathOffset = m_path.find_first_of("#");
  if (pathOffset != m_path.npos)
  {
    m_path = m_path.substr(0, pathOffset);
  }
  pathOffset = m_path.find_first_of("?");
  if (pathOffset != m_path.npos)
  {
    m_queryString = m_path.substr(pathOffset);
    m_path = m_path.substr(0, pathOffset);
  }

  // Now we loop across all the headers we've got.
  startOffset = buffer.find_first_not_of(NEWLINES, endOffset);
  while (endOffset < headerEnd)
  {
    endOffset = buffer.find_first_of(SEPARATOR, startOffset);
    if (endOffset == buffer.npos)
    {
      break;
    }
    string headerName = buffer.substr(startOffset, endOffset - startOffset);
    headerName = headerName.substr(0, headerName.find_last_not_of(SPACES) + 1);
    startOffset = buffer.find_first_not_of(SPACES, endOffset + 1);
    if (startOffset == buffer.npos)
    {
      break;
    }
    endOffset = buffer.find_first_of(NEWLINES, startOffset);
    if (endOffset == buffer.npos)
    {
      break;
    }
    string value = buffer.substr(startOffset, endOffset - startOffset);
    startOffset = buffer.find_first_not_of(NEWLINES, endOffset);
    while ((buffer.find_first_of(SPACES) == startOffset) && (startOffset < headerEnd))
    {
      endOffset = buffer.find_first_of(NEWLINES, startOffset);
      if (endOffset == buffer.npos)
      {
        break;
      }
      value += buffer.substr(startOffset, endOffset - startOffset);
      startOffset = buffer.find_first_not_of(NEWLINES, endOffset);
      if (startOffset == buffer.npos)
      {
        break;
      }
    }

    toLower(headerName);
    if (headerName == "user-agent")
    {
      m_userAgent = value;
    }
    else if (headerName == "if-modified-since")
    {
      m_ifModifiedSince = Utils::parseHttpDate(value);
    }
    m_headers.insert(pair<string, string>(headerName, value));
  }

  // Set our keep-alive flag.
  HeaderMap::const_iterator it = m_headers.find("connection");
  {
    string c = it->second;
    toLower(c);
    if (c.find("keep-alive") != c.npos)
    {
      m_keepAlive = true;
    }
  }

  // Now we need to parse the request body.
  it = m_headers.find("content-length");
  if (it != m_headers.end())
  {
    const string& l = it->second;
    m_contentLength = strtoll(l.c_str(), NULL, 10);
  }

  // '4' is the \r\n\r\n following the headers.
  unsigned long long totalSize = headerEnd + 4 + m_contentLength;
  if (buffer.size() >= totalSize)
  {
    m_body = buffer.substr(headerEnd + 4, m_contentLength);
  }
  else
  {
    totalSize = 0;
  }

  return totalSize;
}

// Assembly:
subq $0x318, %rsp            # imm = 0x318
movq %rdi, 0x308(%rsp)
movq %rsi, 0x300(%rsp)
movq 0x308(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x300(%rsp), %rdi
leaq 0x8901(%rip), %rsi      # 0x13214
xorl %eax, %eax
movl %eax, %edx
callq 0x4770
movq %rax, 0x2f8(%rsp)
cmpq $-0x1, 0x2f8(%rsp)
jne 0xa940
movq $0x0, 0x310(%rsp)
jmp 0xb52c
movq $0x0, 0x2f0(%rsp)
movq $0x0, 0x2e8(%rsp)
movq 0x300(%rsp), %rdi
leaq 0xea91(%rip), %rsi      # 0x193f8
xorl %eax, %eax
movl %eax, %edx
callq 0x4360
movq %rax, 0x2e8(%rsp)
cmpq $-0x1, 0x2e8(%rsp)
jne 0xa9ab
movq 0x70(%rsp), %rax
movl $0x190, 0xe0(%rax)      # imm = 0x190
movq 0x2f8(%rsp), %rax
addq $0x4, %rax
movq %rax, 0x310(%rsp)
jmp 0xb52c
movq 0x300(%rsp), %rsi
movq 0x2f0(%rsp), %rdx
movq 0x2e8(%rsp), %rcx
leaq 0x2c8(%rsp), %rdi
callq 0x43d0
movq 0x70(%rsp), %rdi
addq $0x10, %rdi
leaq 0x2c8(%rsp), %rsi
callq 0x44d0
leaq 0x2c8(%rsp), %rdi
callq 0x4788
movq 0x300(%rsp), %rdi
movq 0x2e8(%rsp), %rdx
leaq 0xe9ee(%rip), %rsi      # 0x193f8
callq 0x4310
movq %rax, 0x2f0(%rsp)
cmpq $-0x1, 0x2f0(%rsp)
jne 0xaa4a
movq 0x70(%rsp), %rax
movl $0x190, 0xe0(%rax)      # imm = 0x190
movq 0x2f8(%rsp), %rax
addq $0x4, %rax
movq %rax, 0x310(%rsp)
jmp 0xb52c
movq 0x300(%rsp), %rdi
movq 0x2f0(%rsp), %rdx
leaq 0xe997(%rip), %rsi      # 0x193f8
callq 0x4360
movq %rax, 0x2e8(%rsp)
cmpq $-0x1, 0x2e8(%rsp)
jne 0xaaa1
movq 0x70(%rsp), %rax
movl $0x190, 0xe0(%rax)      # imm = 0x190
movq 0x2f8(%rsp), %rax
addq $0x4, %rax
movq %rax, 0x310(%rsp)
jmp 0xb52c
movq 0x300(%rsp), %rsi
movq 0x2f0(%rsp), %rdx
movq 0x2e8(%rsp), %rcx
subq 0x2f0(%rsp), %rcx
leaq 0x2a8(%rsp), %rdi
callq 0x43d0
movq 0x70(%rsp), %rdi
addq $0x30, %rdi
leaq 0x2a8(%rsp), %rsi
callq 0x44d0
leaq 0x2a8(%rsp), %rdi
callq 0x4788
movq 0x300(%rsp), %rdi
movq 0x2e8(%rsp), %rdx
leaq 0xe8f0(%rip), %rsi      # 0x193f8
callq 0x4310
movq %rax, 0x2f0(%rsp)
cmpq $-0x1, 0x2f0(%rsp)
jne 0xab48
movq 0x70(%rsp), %rax
movl $0x190, 0xe0(%rax)      # imm = 0x190
movq 0x2f8(%rsp), %rax
addq $0x4, %rax
movq %rax, 0x310(%rsp)
jmp 0xb52c
movq 0x300(%rsp), %rdi
movq 0x2f0(%rsp), %rdx
leaq 0xe8b9(%rip), %rsi      # 0x19418
callq 0x4360
movq %rax, 0x2e8(%rsp)
cmpq $-0x1, 0x2e8(%rsp)
jne 0xab9f
movq 0x70(%rsp), %rax
movl $0x190, 0xe0(%rax)      # imm = 0x190
movq 0x2f8(%rsp), %rax
addq $0x4, %rax
movq %rax, 0x310(%rsp)
jmp 0xb52c
movq 0x300(%rsp), %rsi
movq 0x2f0(%rsp), %rdx
movq 0x2e8(%rsp), %rcx
subq 0x2f0(%rsp), %rcx
leaq 0x288(%rsp), %rdi
callq 0x43d0
movq 0x70(%rsp), %rdi
addq $0x50, %rdi
leaq 0x288(%rsp), %rsi
callq 0x44d0
leaq 0x288(%rsp), %rdi
callq 0x4788
movq 0x70(%rsp), %rdi
addq $0x30, %rdi
leaq 0x861a(%rip), %rsi      # 0x13219
xorl %eax, %eax
movl %eax, %edx
callq 0x41f0
movq %rax, 0x280(%rsp)
cmpq $-0x1, 0x280(%rsp)
je 0xac60
movq 0x70(%rsp), %rsi
addq $0x30, %rsi
movq 0x280(%rsp), %rcx
leaq 0x260(%rsp), %rdi
xorl %eax, %eax
movl %eax, %edx
callq 0x43d0
movq 0x70(%rsp), %rdi
addq $0x30, %rdi
leaq 0x260(%rsp), %rsi
callq 0x44d0
leaq 0x260(%rsp), %rdi
callq 0x4788
movq 0x70(%rsp), %rdi
addq $0x30, %rdi
leaq 0x85ab(%rip), %rsi      # 0x1321b
xorl %eax, %eax
movl %eax, %edx
callq 0x41f0
movq %rax, 0x280(%rsp)
cmpq $-0x1, 0x280(%rsp)
je 0xad20
movq 0x70(%rsp), %rsi
addq $0x30, %rsi
movq 0x280(%rsp), %rdx
leaq 0x240(%rsp), %rdi
movq $-0x1, %rcx
callq 0x43d0
movq 0x70(%rsp), %rdi
addq $0xc0, %rdi
leaq 0x240(%rsp), %rsi
callq 0x44d0
leaq 0x240(%rsp), %rdi
callq 0x4788
movq 0x70(%rsp), %rsi
addq $0x30, %rsi
movq 0x280(%rsp), %rcx
leaq 0x220(%rsp), %rdi
xorl %eax, %eax
movl %eax, %edx
callq 0x43d0
movq 0x70(%rsp), %rdi
addq $0x30, %rdi
leaq 0x220(%rsp), %rsi
callq 0x44d0
leaq 0x220(%rsp), %rdi
callq 0x4788
movq 0x300(%rsp), %rdi
movq 0x2e8(%rsp), %rdx
leaq 0xe6e1(%rip), %rsi      # 0x19418
callq 0x4310
movq %rax, 0x2f0(%rsp)
movq 0x2e8(%rsp), %rax
cmpq 0x2f8(%rsp), %rax
jae 0xb1b6
movq 0x300(%rsp), %rdi
movq 0x2f0(%rsp), %rdx
leaq 0xe6c7(%rip), %rsi      # 0x19438
callq 0x4360
movq %rax, 0x2e8(%rsp)
cmpq $-0x1, 0x2e8(%rsp)
jne 0xad8e
jmp 0xb1b6
movq 0x300(%rsp), %rsi
movq 0x2f0(%rsp), %rdx
movq 0x2e8(%rsp), %rcx
subq %rdx, %rcx
leaq 0x200(%rsp), %rdi
movq %rdi, 0x68(%rsp)
callq 0x43d0
movq 0x68(%rsp), %rdi
leaq 0xe631(%rip), %rsi      # 0x193f8
movq $-0x1, %rdx
callq 0x46f0
movq 0x68(%rsp), %rsi
movq %rax, %rcx
incq %rcx
xorl %eax, %eax
movl %eax, %edx
leaq 0x1e0(%rsp), %rdi
callq 0x43d0
jmp 0xadf1
leaq 0x200(%rsp), %rdi
leaq 0x1e0(%rsp), %rsi
callq 0x44d0
leaq 0x1e0(%rsp), %rdi
callq 0x4788
movq 0x300(%rsp), %rdi
movq 0x2e8(%rsp), %rdx
addq $0x1, %rdx
leaq 0xe5ca(%rip), %rsi      # 0x193f8
callq 0x4310
movq %rax, 0x2f0(%rsp)
cmpq $-0x1, 0x2f0(%rsp)
jne 0xae6f
movl $0x3, 0x1d0(%rsp)
jmp 0xb155
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1d8(%rsp)
movl %eax, 0x1d4(%rsp)
jmp 0xb1a4
movq 0x300(%rsp), %rdi
movq 0x2f0(%rsp), %rdx
leaq 0xe592(%rip), %rsi      # 0x19418
callq 0x4360
movq %rax, 0x2e8(%rsp)
cmpq $-0x1, 0x2e8(%rsp)
jne 0xaeae
movl $0x3, 0x1d0(%rsp)
jmp 0xb155
movq 0x300(%rsp), %rsi
movq 0x2f0(%rsp), %rdx
movq 0x2e8(%rsp), %rcx
subq %rdx, %rcx
leaq 0x1b0(%rsp), %rdi
callq 0x43d0
jmp 0xaed8
movq 0x300(%rsp), %rdi
movq 0x2e8(%rsp), %rdx
leaq 0xe529(%rip), %rsi      # 0x19418
callq 0x4310
movq %rax, 0x2f0(%rsp)
movq 0x300(%rsp), %rdi
leaq 0xe4ed(%rip), %rsi      # 0x193f8
xorl %eax, %eax
movl %eax, %edx
callq 0x4360
movq %rax, %rcx
xorl %eax, %eax
cmpq 0x2f0(%rsp), %rcx
movb %al, 0x67(%rsp)
jne 0xaf3e
movq 0x2f0(%rsp), %rax
cmpq 0x2f8(%rsp), %rax
setb %al
movb %al, 0x67(%rsp)
movb 0x67(%rsp), %al
testb $0x1, %al
jne 0xaf4b
jmp 0xb042
movq 0x300(%rsp), %rdi
movq 0x2f0(%rsp), %rdx
leaq 0xe4b6(%rip), %rsi      # 0x19418
callq 0x4360
movq %rax, 0x2e8(%rsp)
cmpq $-0x1, 0x2e8(%rsp)
jne 0xaf7f
jmp 0xb042
movq 0x300(%rsp), %rsi
movq 0x2f0(%rsp), %rdx
movq 0x2e8(%rsp), %rcx
subq %rdx, %rcx
leaq 0x190(%rsp), %rdi
callq 0x43d0
jmp 0xafa9
leaq 0x1b0(%rsp), %rdi
leaq 0x190(%rsp), %rsi
callq 0x44f0
jmp 0xafc0
leaq 0x190(%rsp), %rdi
callq 0x4788
movq 0x300(%rsp), %rdi
movq 0x2e8(%rsp), %rdx
leaq 0xe434(%rip), %rsi      # 0x19418
callq 0x4310
movq %rax, 0x2f0(%rsp)
cmpq $-0x1, 0x2f0(%rsp)
jne 0xb03d
jmp 0xb042
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1d8(%rsp)
movl %eax, 0x1d4(%rsp)
jmp 0xb197
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1d8(%rsp)
movl %eax, 0x1d4(%rsp)
leaq 0x190(%rsp), %rdi
callq 0x4788
jmp 0xb197
jmp 0xaefc
leaq 0x200(%rsp), %rdi
callq 0xb550
jmp 0xb051
leaq 0x81c5(%rip), %rsi      # 0x1321d
leaq 0x200(%rsp), %rdi
callq 0xb7c0
movb %al, 0x66(%rsp)
jmp 0xb06b
movb 0x66(%rsp), %al
testb $0x1, %al
jne 0xb075
jmp 0xb092
movq 0x70(%rsp), %rdi
addq $0xe8, %rdi
leaq 0x1b0(%rsp), %rsi
callq 0x4050
jmp 0xb090
jmp 0xb0dd
leaq 0x80b4(%rip), %rsi      # 0x1314d
leaq 0x200(%rsp), %rdi
callq 0xb7c0
movb %al, 0x65(%rsp)
jmp 0xb0ac
movb 0x65(%rsp), %al
testb $0x1, %al
jne 0xb0b6
jmp 0xb0db
leaq 0x1b0(%rsp), %rdi
callq 0x11260
movq %rax, 0x58(%rsp)
jmp 0xb0ca
movq 0x70(%rsp), %rax
movq 0x58(%rsp), %rcx
movq %rcx, 0x108(%rax)
jmp 0xb0dd
movq 0x70(%rsp), %rax
addq $0x70, %rax
movq %rax, 0x50(%rsp)
leaq 0x150(%rsp), %rdi
leaq 0x200(%rsp), %rsi
leaq 0x1b0(%rsp), %rdx
callq 0xb820
jmp 0xb10a
movq 0x50(%rsp), %rdi
leaq 0x150(%rsp), %rsi
callq 0xb7f0
movq %rax, 0x48(%rsp)
jmp 0xb123
movq 0x48(%rsp), %rax
movq %rax, 0x148(%rsp)
leaq 0x150(%rsp), %rdi
callq 0xb890
leaq 0x1b0(%rsp), %rdi
callq 0x4788
movl $0x0, 0x1d0(%rsp)
leaq 0x200(%rsp), %rdi
callq 0x4788
movl 0x1d0(%rsp), %eax
testl %eax, %eax
je 0xb171
jmp 0xb16f
jmp 0xb1b6
jmp 0xad44
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1d8(%rsp)
movl %eax, 0x1d4(%rsp)
leaq 0x150(%rsp), %rdi
callq 0xb890
leaq 0x1b0(%rsp), %rdi
callq 0x4788
leaq 0x200(%rsp), %rdi
callq 0x4788
jmp 0xb53c
movq 0x70(%rsp), %rax
addq $0x70, %rax
movq %rax, 0x38(%rsp)
leaq 0x117(%rsp), %rdi
movq %rdi, 0x40(%rsp)
callq 0x46c0
movq 0x40(%rsp), %rdx
leaq 0x8046(%rip), %rsi      # 0x13228
leaq 0x118(%rsp), %rdi
callq 0x6450
jmp 0xb1f1
movq 0x38(%rsp), %rdi
leaq 0x118(%rsp), %rsi
callq 0xb8c0
movq %rax, 0x30(%rsp)
jmp 0xb20a
movq 0x30(%rsp), %rax
movq %rax, 0x138(%rsp)
leaq 0x140(%rsp), %rdi
movq %rdi, 0x20(%rsp)
leaq 0x138(%rsp), %rsi
callq 0xb8f0
leaq 0x118(%rsp), %rdi
callq 0x4788
leaq 0x117(%rsp), %rdi
callq 0x4400
movq 0x20(%rsp), %rdi
callq 0xb910
movq %rax, %rsi
addq $0x20, %rsi
leaq 0xf0(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x41b0
movq 0x28(%rsp), %rdi
callq 0xb550
jmp 0xb27a
leaq 0xf0(%rsp), %rdi
leaq 0x7faa(%rip), %rsi      # 0x13233
xorl %eax, %eax
movl %eax, %edx
callq 0x4770
cmpq $-0x1, %rax
je 0xb312
movq 0x70(%rsp), %rax
movb $0x1, 0x8(%rax)
jmp 0xb312
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1d8(%rsp)
movl %eax, 0x1d4(%rsp)
jmp 0xb2da
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1d8(%rsp)
movl %eax, 0x1d4(%rsp)
leaq 0x118(%rsp), %rdi
callq 0x4788
leaq 0x117(%rsp), %rdi
callq 0x4400
jmp 0xb53c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1d8(%rsp)
movl %eax, 0x1d4(%rsp)
leaq 0xf0(%rsp), %rdi
callq 0x4788
jmp 0xb53c
leaq 0xf0(%rsp), %rdi
callq 0x4788
movq 0x70(%rsp), %rax
addq $0x70, %rax
movq %rax, 0x10(%rsp)
leaq 0xbf(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x46c0
movq 0x18(%rsp), %rdx
leaq 0x7ef3(%rip), %rsi      # 0x1323e
leaq 0xc0(%rsp), %rdi
callq 0x6450
jmp 0xb35a
movq 0x10(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0xb8c0
movq %rax, 0x8(%rsp)
jmp 0xb373
movq 0x8(%rsp), %rax
movq %rax, 0xe0(%rsp)
leaq 0xe8(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
callq 0xb8f0
movq 0xe8(%rsp), %rax
movq %rax, 0x140(%rsp)
leaq 0xc0(%rsp), %rdi
callq 0x4788
leaq 0xbf(%rsp), %rdi
callq 0x4400
movq 0x70(%rsp), %rdi
addq $0x70, %rdi
callq 0xb950
movq %rax, 0xa8(%rsp)
leaq 0xb0(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0xb8f0
leaq 0x140(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0xb930
testb $0x1, %al
jne 0xb408
jmp 0xb495
leaq 0x140(%rsp), %rdi
callq 0xb910
addq $0x20, %rax
movq %rax, 0xa0(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x4190
movq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0xa, %edx
callq 0x40b0
movq %rax, %rcx
movq 0x70(%rsp), %rax
movq %rcx, (%rax)
jmp 0xb495
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1d8(%rsp)
movl %eax, 0x1d4(%rsp)
jmp 0xb483
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1d8(%rsp)
movl %eax, 0x1d4(%rsp)
leaq 0xc0(%rsp), %rdi
callq 0x4788
leaq 0xbf(%rsp), %rdi
callq 0x4400
jmp 0xb53c
movq 0x70(%rsp), %rcx
movq 0x2f8(%rsp), %rax
addq $0x4, %rax
addq (%rcx), %rax
movq %rax, 0x98(%rsp)
movq 0x300(%rsp), %rdi
callq 0x42a0
cmpq 0x98(%rsp), %rax
jb 0xb510
movq 0x70(%rsp), %rax
movq 0x300(%rsp), %rsi
movq 0x2f8(%rsp), %rdx
addq $0x4, %rdx
movq (%rax), %rcx
leaq 0x78(%rsp), %rdi
callq 0x43d0
movq 0x70(%rsp), %rdi
addq $0xa0, %rdi
leaq 0x78(%rsp), %rsi
callq 0x44d0
leaq 0x78(%rsp), %rdi
callq 0x4788
jmp 0xb51c
movq $0x0, 0x98(%rsp)
movq 0x98(%rsp), %rax
movq %rax, 0x310(%rsp)
movq 0x310(%rsp), %rax
addq $0x318, %rsp            # imm = 0x318
retq
movq 0x1d8(%rsp), %rdi
callq 0x46b0
nopl (%rax)