// File: /workspace/github_c_makefile_star2_O3/TimeToogo[P]ff-proxy/client/c/client.c
// Function: ff_client_packetise_request
struct ff_client_packet *ff_client_packetise_request(struct ff_request *request, uint16_t *packet_count)
{
    struct ff_client_packet *packets = calloc(1, sizeof(struct ff_client_packet *) * FF_CLIENT_MAX_PACKETS);
    uint64_t request_id = ff_client_generate_request_id();
    uint32_t chunk_offset = 0;
    uint16_t bytes_left = request->payload_length;

    *packet_count = 0;

    while (bytes_left > 0)
    {
        uint8_t *buffer = calloc(1, FF_CLIENT_MAX_PACKET_LENGTH);
        uint16_t packet_length = 0;
        struct __raw_ff_request_header *header = (struct __raw_ff_request_header *)buffer;

        header->version = htons(FF_VERSION_1);
        header->request_id = htonll(request_id);
        header->total_length = htonl(request->payload_length);
        header->chunk_offset = htonl(chunk_offset);
        packet_length += sizeof(struct __raw_ff_request_header);

        if (*packet_count == 0)
        {
            // If first packet, send options
            packet_length += ff_client_write_options(buffer + packet_length, request->options, request->options_length);
        }
        else
        {
            // If subsequent packet provide empty option list
            struct __raw_ff_request_option_header *option_header = (struct __raw_ff_request_option_header *)(buffer + packet_length);
            option_header->type = FF_REQUEST_OPTION_TYPE_EOL;
            option_header->length = 0;
            packet_length += sizeof(struct __raw_ff_request_option_header);
        }

        uint16_t bytes_left_in_packet = FF_CLIENT_MAX_PACKET_LENGTH - packet_length;
        uint16_t chunk_length = bytes_left > bytes_left_in_packet ? bytes_left_in_packet : bytes_left;

        header->chunk_length = htons(chunk_length);

        memcpy(buffer + packet_length, request->payload->value + chunk_offset, chunk_length);
        packet_length += chunk_length;
        bytes_left -= chunk_length;
        chunk_offset += chunk_length;

        packets[*packet_count].length = packet_length;
        packets[*packet_count].value = buffer;
        (*packet_count)++;
    }

    ff_log(FF_DEBUG, "Packetised payload into %u packets", *packet_count);

    return packets;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rsi, %r14
movq %rdi, %rbx
movl $0x1, %edi
movl $0x2000, %esi           # imm = 0x2000
callq 0x2120
movq %rax, -0x40(%rbp)
callq 0x2dda
movq %rbx, %rcx
movq %rax, %rbx
movl 0x40(%rcx), %r15d
movq %r14, -0x70(%rbp)
movw $0x0, (%r14)
movl %r15d, %eax
andl $0xffff, %eax           # imm = 0xFFFF
movl %eax, -0x2c(%rbp)
je 0x2a51
bswapq %rbx
bswapl %r15d
movq %rcx, -0x50(%rbp)
movq 0x50(%rcx), %rax
movq %rax, -0x60(%rbp)
xorl %eax, %eax
xorl %ecx, %ecx
movq %rbx, -0x68(%rbp)
movl %r15d, -0x34(%rbp)
movl %eax, -0x30(%rbp)
movq %rcx, -0x48(%rbp)
movl $0x1, %edi
movl $0x514, %esi            # imm = 0x514
callq 0x2120
movl -0x30(%rbp), %r14d
movq %rax, %r12
movw $0x100, (%rax)          # imm = 0x100
movq %rbx, 0x2(%rax)
movl %r15d, 0xa(%rax)
movl %r14d, %edx
bswapl %edx
movl %edx, 0xe(%rax)
cmpw $0x0, -0x48(%rbp)
je 0x2945
movb $0x0, 0x14(%r12)
movw $0x0, 0x15(%r12)
movl $0x17, %ebx
jmp 0x29c2
movq -0x50(%rbp), %r13
movzbl 0x28(%r13), %r15d
testq %r15, %r15
je 0x29bd
movq %r12, -0x58(%rbp)
leaq 0x14(%r12), %rbx
movq 0x30(%r13), %r13
xorl %r14d, %r14d
xorl %r12d, %r12d
movl %r12d, %eax
movq (%r13,%r14,8), %rcx
movb (%rcx), %dl
movb %dl, (%rbx,%rax)
movzwl 0x4(%rcx), %edx
movl %edx, %esi
rolw $0x8, %si
movw %si, 0x1(%rbx,%rax)
leal 0x3(%r12), %edi
addq %rbx, %rdi
movq 0x8(%rcx), %rsi
callq 0x2150
movq (%r13,%r14,8), %rax
movzwl 0x4(%rax), %eax
addl %eax, %r12d
addl $0x3, %r12d
incq %r14
cmpq %r14, %r15
jne 0x2966
addl $0x14, %r12d
movzwl %r12w, %ebx
movl -0x30(%rbp), %r14d
movq -0x58(%rbp), %r12
jmp 0x29c2
movl $0x14, %ebx
movl $0x514, %r15d           # imm = 0x514
subl %ebx, %r15d
movl $0xffff, %edx           # imm = 0xFFFF
andl %edx, %r15d
movl -0x2c(%rbp), %r13d
cmpl %r15d, %r13d
cmovbl %r13d, %r15d
movl %r15d, %edx
rolw $0x8, %dx
movw %dx, 0x12(%r12)
movl %ebx, %edx
movq %r12, %rdi
addq %rdx, %rdi
movl %r14d, %esi
movq -0x60(%rbp), %rax
addq 0x8(%rax), %rsi
movq %r15, %rdx
callq 0x2150
addl %r15d, %ebx
subl %r15d, %r13d
addl %r14d, %r15d
movq -0x48(%rbp), %rcx
movzwl %cx, %eax
shll $0x4, %eax
movq -0x40(%rbp), %rdx
movw %bx, 0x8(%rdx,%rax)
movq %r12, (%rdx,%rax)
incl %ecx
movq -0x70(%rbp), %rax
movw %cx, (%rax)
movl %r15d, %eax
movl $0xffff, %edx           # imm = 0xFFFF
andl %edx, %r13d
movl %r13d, -0x2c(%rbp)
movq -0x68(%rbp), %rbx
movl -0x34(%rbp), %r15d
jne 0x28f7
movzwl %cx, %edx
jmp 0x2a53
xorl %edx, %edx
leaq 0x2669(%rip), %rsi      # 0x50c3
movl $0x1, %edi
xorl %eax, %eax
callq 0x3a20
movq -0x40(%rbp), %rax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq