// File: /workspace/github_c_makefile_star2_O0/TimeToogo[P]ff-proxy/src/parser.c
// Function: ff_request_parse_options
size_t ff_request_parse_options(struct ff_request *request, uint32_t buff_size, void *buff)
{
    struct __raw_ff_request_option_header *option_header = NULL;
    struct ff_request_option_node *options[FF_REQUEST_MAX_OPTIONS];
    uint8_t options_i = 0;
    uint32_t i = 0;
    size_t current_options_size = request->options_length;

    // Parse TLV options
    while (1)
    {
        if (current_options_size + options_i >= FF_REQUEST_MAX_OPTIONS)
        {
            ff_log(FF_WARNING, "Encountered request with too many options");
            goto error;
        }

        if (buff_size < i + sizeof(struct __raw_ff_request_option_header))
        {
            ff_log(FF_WARNING, "Packet buffer ran out while processing TLV options");
            goto error;
        }

        option_header = (struct __raw_ff_request_option_header *)(buff + i);

        // Normalise endianess
        uint16_t option_length = ntohs(option_header->length);

        i += sizeof(struct __raw_ff_request_option_header);

        if (option_header->type == FF_REQUEST_OPTION_TYPE_BREAK)
        {
            if (option_length != 0)
            {
                ff_log(FF_WARNING, "Request option FF_REQUEST_OPTION_TYPE_BREAK must have length = 0");
                goto error;
            }

            request->payload_contains_options = true;
            break;
        }

        if (option_header->type == FF_REQUEST_OPTION_TYPE_EOL)
        {
            if (option_length != 0)
            {
                ff_log(FF_WARNING, "Request option FF_REQUEST_OPTION_TYPE_EOL must have length = 0");
                goto error;
            }

            request->payload_contains_options = false;
            break;
        }

        if (buff_size < i + option_length)
        {
            ff_log(FF_WARNING, "Packet buffer ran out while processing TLV options");
            goto error;
        }

        options[options_i] = ff_request_option_node_alloc();
        options[options_i]->type = option_header->type;
        options[options_i]->length = option_length;
        ff_request_option_load_buff(
            options[options_i],
            option_length,
            buff + i);

        i += option_length;
        options_i++;
    }

    if (options_i == 0)
    {
        return i;
    }

    request->options_length = current_options_size + options_i;

    if (request->options == NULL)
    {
        request->options = malloc(sizeof(struct ff_request_option_node *) * request->options_length);
    }
    else
    {
        request->options = realloc(request->options, sizeof(struct ff_request_option_node *) * request->options_length);
    }

    memcpy(
        request->options + current_options_size,
        options,
        sizeof(struct ff_request_option_node *) * options_i);

    goto done;

done:
    goto cleanup;

error:
    i = 0;

    for (uint8_t j = 0; j < options_i; j++) {
        ff_request_option_node_free(options[j]);
    }

    goto cleanup;

cleanup:
    return i;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movq $0x0, -0x28(%rbp)
movb $0x0, -0xd1(%rbp)
movl $0x0, -0xd8(%rbp)
movq -0x10(%rbp), %rax
movzbl 0x28(%rax), %eax
movq %rax, -0xe0(%rbp)
movq -0xe0(%rbp), %rax
movzbl -0xd1(%rbp), %ecx
addq %rcx, %rax
cmpq $0x14, %rax
jb 0x592d
movl $0x3, %edi
leaq 0x2707(%rip), %rsi      # 0x8028
movb $0x0, %al
callq 0x4d70
jmp 0x5b82
movl -0x14(%rbp), %eax
movl -0xd8(%rbp), %ecx
addq $0x3, %rcx
cmpq %rcx, %rax
jae 0x5957
movl $0x3, %edi
leaq 0x2707(%rip), %rsi      # 0x8052
movb $0x0, %al
callq 0x4d70
jmp 0x5b82
movq -0x20(%rbp), %rax
movl -0xd8(%rbp), %ecx
addq %rcx, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movzwl 0x1(%rax), %edi
callq 0x24d0
movw %ax, -0xe2(%rbp)
movl -0xd8(%rbp), %eax
addq $0x3, %rax
movl %eax, -0xd8(%rbp)
movq -0x28(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x7, %eax
jne 0x59c9
movzwl -0xe2(%rbp), %eax
cmpl $0x0, %eax
je 0x59bc
movl $0x3, %edi
leaq 0x26d5(%rip), %rsi      # 0x8085
movb $0x0, %al
callq 0x4d70
jmp 0x5b82
movq -0x10(%rbp), %rax
movb $0x1, 0x38(%rax)
jmp 0x5acb
movq -0x28(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x0, %eax
jne 0x5a06
movzwl -0xe2(%rbp), %eax
cmpl $0x0, %eax
je 0x59f9
movl $0x3, %edi
leaq 0x26d9(%rip), %rsi      # 0x80c6
movb $0x0, %al
callq 0x4d70
jmp 0x5b82
movq -0x10(%rbp), %rax
movb $0x0, 0x38(%rax)
jmp 0x5acb
movl -0x14(%rbp), %eax
movl -0xd8(%rbp), %ecx
movzwl -0xe2(%rbp), %edx
addl %edx, %ecx
cmpl %ecx, %eax
jae 0x5a34
movl $0x3, %edi
leaq 0x262a(%rip), %rsi      # 0x8052
movb $0x0, %al
callq 0x4d70
jmp 0x5b82
callq 0x5dc0
movq %rax, %rcx
movzbl -0xd1(%rbp), %eax
movq %rcx, -0xd0(%rbp,%rax,8)
movq -0x28(%rbp), %rax
movzbl (%rax), %ecx
movzbl -0xd1(%rbp), %eax
movq -0xd0(%rbp,%rax,8), %rax
movl %ecx, (%rax)
movw -0xe2(%rbp), %cx
movzbl -0xd1(%rbp), %eax
movq -0xd0(%rbp,%rax,8), %rax
movw %cx, 0x4(%rax)
movzbl -0xd1(%rbp), %eax
movq -0xd0(%rbp,%rax,8), %rdi
movzwl -0xe2(%rbp), %esi
movq -0x20(%rbp), %rdx
movl -0xd8(%rbp), %eax
addq %rax, %rdx
callq 0x5e00
movzwl -0xe2(%rbp), %eax
addl -0xd8(%rbp), %eax
movl %eax, -0xd8(%rbp)
movb -0xd1(%rbp), %al
addb $0x1, %al
movb %al, -0xd1(%rbp)
jmp 0x58fe
movzbl -0xd1(%rbp), %eax
cmpl $0x0, %eax
jne 0x5ae6
movl -0xd8(%rbp), %eax
movq %rax, -0x8(%rbp)
jmp 0x5bd5
movq -0xe0(%rbp), %rax
movzbl -0xd1(%rbp), %ecx
addq %rcx, %rax
movb %al, %cl
movq -0x10(%rbp), %rax
movb %cl, 0x28(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x30(%rax)
jne 0x5b2b
movq -0x10(%rbp), %rax
movzbl 0x28(%rax), %eax
movl %eax, %edi
shlq $0x3, %rdi
callq 0x23e0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x30(%rax)
jmp 0x5b51
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rdi
movq -0x10(%rbp), %rax
movzbl 0x28(%rax), %eax
movl %eax, %esi
shlq $0x3, %rsi
callq 0x2460
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rdi
movq -0xe0(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
leaq -0xd0(%rbp), %rsi
movzbl -0xd1(%rbp), %eax
movl %eax, %edx
shlq $0x3, %rdx
callq 0x2270
jmp 0x5bcb
movl $0x0, -0xd8(%rbp)
movb $0x0, -0xe3(%rbp)
movzbl -0xe3(%rbp), %eax
movzbl -0xd1(%rbp), %ecx
cmpl %ecx, %eax
jge 0x5bc9
movzbl -0xe3(%rbp), %eax
movq -0xd0(%rbp,%rax,8), %rdi
callq 0x5e50
movb -0xe3(%rbp), %al
addb $0x1, %al
movb %al, -0xe3(%rbp)
jmp 0x5b93
jmp 0x5bcb
movl -0xd8(%rbp), %eax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xf0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)