// File: /workspace/github_cpp_makefile_star2_O2/Computer-Kids-Club[P]screenshare-pro-backend/http.cpp
// Function: parse_header[abi:cxx11](char const*, char const*)
std::unordered_map<std::string, std::string> parse_header(const char *msg, const char *msg_end) {
    const char *head = msg;
    const char *tail = msg;

    std::unordered_map<std::string, std::string> http_request;

    // Find request type
    while (tail != msg_end && *tail != ' ')
        ++tail;
    http_request["Type"] = std::string(head, tail);

    // Find path
    while (tail != msg_end && *tail == ' ')
        ++tail;
    head = tail;
    while (tail != msg_end && *tail != ' ')
        ++tail;
    http_request["Path"] = std::string(head, tail);

    // Find HTTP version
    while (tail != msg_end && *tail == ' ')
        ++tail;
    head = tail;
    while (tail != msg_end && *tail != '\r')
        ++tail;
    http_request["Version"] = std::string(head, tail);
    if (tail != msg_end)
        ++tail;  // skip '\r'
    // TODO: what about the trailing '\n'?

    // Map all headers from a key to a value
    head = tail;
    while (head < msg_end && *head != '\r') {
        tail = head;
        while (tail < msg_end && *tail != '\r')
            ++tail;
        const char *colon = (const char *)memchr(head, ':', tail - head);
        if (colon == NULL) {
            // TODO: malformed headers, what should happen?
            break;
        }
        const char *value = colon + 1;
        while (value < tail && *value == ' ')
            ++value;
        if (head < colon && value < tail && tail <= msg_end) {
            http_request[std::string(head, colon)] = std::string(value, tail);
        }
        head = tail + 1;
        while (head < msg_end && (*head == '\n' || *head == '\r' || *head == ' '))
            head++;
        //printf("%d\n", head - msg);
        // TODO: what about the trailing '\n'?
    }

    return http_request;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rdx, %r15
leaq 0x30(%rdi), %rax
movq %rax, (%rdi)
movq $0x1, 0x8(%rdi)
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%rdi)
movl $0x3f800000, 0x20(%rdi) # imm = 0x3F800000
movq %rdi, -0x38(%rbp)
movups %xmm0, 0x28(%rdi)
movq %rdx, %rbx
movq %rsi, %rax
cmpq %r15, %rax
je 0x5a49
cmpb $0x20, (%rax)
je 0x5a46
incq %rax
jmp 0x5a37
movq %rax, %rbx
leaq -0x48(%rbp), %rax
movq %rax, -0x10(%rax)
leaq -0x58(%rbp), %rdi
movq %rbx, %rdx
callq 0x422a
leaq 0x1b27(%rip), %rsi      # 0x758b
leaq -0x78(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x3606
leaq -0x78(%rbp), %rsi
movq -0x38(%rbp), %rdi
callq 0x5468
leaq -0x58(%rbp), %r14
movq %rax, %rdi
movq %r14, %rsi
callq 0x2290
leaq -0x78(%rbp), %rdi
callq 0x2130
movq %r14, %rdi
callq 0x2130
cmpq %r15, %rbx
je 0x5aad
cmpb $0x20, (%rbx)
jne 0x5ab0
incq %rbx
jmp 0x5a9e
movq %r15, %rbx
movq %rbx, %r12
cmpq %r15, %r12
je 0x5ac4
cmpb $0x20, (%r12)
je 0x5ac7
incq %r12
jmp 0x5ab3
movq %r15, %r12
leaq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rax
movq %rax, (%rdi)
movq %rbx, %rsi
movq %r12, %rdx
callq 0x422a
leaq 0x1aac(%rip), %rsi      # 0x7590
leaq -0x78(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x3606
leaq -0x78(%rbp), %rsi
movq -0x38(%rbp), %rdi
callq 0x5468
leaq -0x58(%rbp), %rbx
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2290
leaq -0x78(%rbp), %rdi
callq 0x2130
movq %rbx, %rdi
callq 0x2130
cmpq %r15, %r12
je 0x5b2f
cmpb $0x20, (%r12)
jne 0x5b32
incq %r12
jmp 0x5b1e
movq %r15, %r12
movq %r12, %rbx
cmpq %r15, %rbx
je 0x5b44
cmpb $0xd, (%rbx)
je 0x5b49
incq %rbx
jmp 0x5b35
movq %r15, %r14
jmp 0x5b4c
movq %rbx, %r14
leaq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rax
movq %rax, (%rdi)
movq %r12, %rsi
movq %r14, %rdx
callq 0x422a
leaq 0x1a2c(%rip), %rsi      # 0x7595
leaq -0x78(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x3606
leaq -0x78(%rbp), %rsi
movq -0x38(%rbp), %rdi
callq 0x5468
xorl %r12d, %r12d
cmpq %r15, %rbx
setne %r12b
leaq -0x58(%rbp), %rbx
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2290
leaq -0x78(%rbp), %rdi
callq 0x2130
movq %rbx, %rdi
callq 0x2130
addq %r12, %r14
cmpq %r15, %r14
jae 0x5ca2
cmpb $0xd, (%r14)
je 0x5ca2
leaq 0x1(%r14), %r13
xorl %edx, %edx
leaq (%r14,%rdx), %rbx
cmpq %r15, %rbx
jae 0x5bdf
cmpb $0xd, (%rbx)
je 0x5bdf
incq %rdx
incq %r13
jmp 0x5bc9
movq %r14, %rdi
pushq $0x3a
popq %rsi
callq 0x2240
testq %rax, %rax
je 0x5ca2
movq %rax, %r12
incq %rax
movq %rax, %rsi
cmpq %rbx, %rax
jae 0x5c0a
leaq 0x1(%rsi), %rax
cmpb $0x20, (%rsi)
je 0x5bf9
cmpq %r15, %rbx
ja 0x5c75
cmpq %r12, %r14
jae 0x5c75
cmpq %rbx, %rsi
jae 0x5c75
leaq -0x48(%rbp), %rax
movq %rax, -0x58(%rbp)
leaq -0x58(%rbp), %rdi
movq %rbx, %rdx
callq 0x422a
leaq -0x68(%rbp), %rax
movq %rax, -0x78(%rbp)
leaq -0x78(%rbp), %rbx
movq %rbx, %rdi
movq %r14, %rsi
movq %r12, %rdx
callq 0x422a
movq -0x38(%rbp), %rdi
movq %rbx, %rsi
callq 0x5468
movq %rbx, %r14
movq %rax, %rdi
leaq -0x58(%rbp), %rbx
movq %rbx, %rsi
callq 0x2290
movq %r14, %rdi
callq 0x2130
movq %rbx, %rdi
callq 0x2130
movabsq $0x100002400, %rcx      # imm = 0x100002400
cmpq %r15, %r13
jae 0x5c9a
movzbl (%r13), %eax
cmpq $0x20, %rax
ja 0x5c9a
btq %rax, %rcx
jae 0x5c9a
incq %r13
jmp 0x5c7f
movq %r13, %r14
jmp 0x5bb0
movq -0x38(%rbp), %rax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x5cd1
jmp 0x5cc7
jmp 0x5ccc
jmp 0x5cd1
jmp 0x5cc7
jmp 0x5ccc
jmp 0x5cd1
jmp 0x5cc7
jmp 0x5ccc
movq %rax, %rbx
jmp 0x5cdd
movq %rax, %rbx
jmp 0x5ce6
movq %rax, %rbx
leaq -0x78(%rbp), %rdi
callq 0x2130
leaq -0x58(%rbp), %rdi
callq 0x2130
movq -0x38(%rbp), %rdi
callq 0x3a04
movq %rbx, %rdi
callq 0x2380
nop