// File: /workspace/github_c_makefile_star2_O2/aerospike[P]aerospike-common/src/main/aerospike/as_msgpack_serializer.c
// Function: as_msgpack_serializer_serialize
static int as_msgpack_serializer_serialize(as_serializer *s, const as_val *v, as_buffer *buff)
{
	as_packer packer = {
			.buffer = (unsigned char *)cf_malloc(AS_PACKER_BUFFER_SIZE),
			.capacity = AS_PACKER_BUFFER_SIZE,
			.offset = 0,
			.head = 0,
			.tail = 0,
	};

	if (! packer.buffer) {
		return 1;
	}

    int rc = as_pack_val(&packer, v);
	
	if (rc != 0) {
		// Cleanup buffers on error.
		as_packer_buffer *p = packer.head;
		as_packer_buffer *tmp;

		while (p) {
			tmp = p;
			p = p->next;
			
			// Free buffer entry.
			cf_free(tmp->buffer);
			cf_free(tmp);
		}

		// Free main buffer.
		cf_free(packer.buffer);
		return rc;
	}

	if (packer.head) {
		// Combine buffers into a single contiguous buffer.
		as_packer_buffer *p = packer.head;
		int size = packer.offset;

		while (p) {
			size += p->length;
			p = p->next;
		}

		unsigned char *target = (unsigned char *)cf_malloc(size);
		p = packer.head;
		int offset = 0;

		while (p) {
			memcpy(target + offset, p->buffer, p->length);
			offset += p->length;
			
			as_packer_buffer *tmp = p;
			p = p->next;
			
			// Free original buffer entry.
			cf_free(tmp->buffer);
			cf_free(tmp);
		}

		memcpy(target + offset, packer.buffer, packer.offset);

		// Free original main buffer.
		cf_free(packer.buffer);

		// Transfer new buffer.
		buff->data = target;
		buff->size = size;
		buff->capacity = size;
	}
	else {
		// Use existing buffer directly.
		buff->data = packer.buffer;
		buff->size = packer.offset;
		buff->capacity = packer.capacity;
	}
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
xorps %xmm0, %xmm0
movl $0x2000, %edi           # imm = 0x2000
movq %rdx, %rbx
movq %rsi, %r14
movaps %xmm0, (%rsp)
callq 0x8080
testq %rax, %rax
movabsq $0x200000000000, %rcx   # imm = 0x200000000000
movq %rax, 0x10(%rsp)
movq %rcx, 0x18(%rsp)
je 0xd370
movq %rsp, %r15
movq %r14, %rsi
movq %r15, %rdi
callq 0x8ad0
movq (%r15), %r14
testl %eax, %eax
je 0xd378
movl %eax, %ebp
testq %r14, %r14
je 0xd361
movq 0x8(%r14), %rdi
movq (%r14), %rbx
callq 0x8a00
movq %r14, %rdi
callq 0x8a00
movq %rbx, %r14
jmp 0xd343
movq 0x10(%rsp), %rdi
callq 0x8a00
jmp 0xd40f
pushq $0x1
popq %rbp
jmp 0xd40f
testq %r14, %r14
je 0xd3f7
movl 0x18(%rsp), %ebp
testq %r14, %r14
je 0xd38f
addl 0x10(%r14), %ebp
movq (%r14), %r14
jmp 0xd381
movslq %ebp, %rdi
callq 0x8080
movq (%rsp), %r15
movq %rax, %r14
xorl %r12d, %r12d
movslq %r12d, %rdi
addq %r14, %rdi
testq %r15, %r15
je 0xd3d6
movq 0x8(%r15), %rsi
movl 0x10(%r15), %edx
callq 0x8630
movq 0x8(%r15), %rdi
addl 0x10(%r15), %r12d
movq (%r15), %r13
callq 0x8a00
movq %r15, %rdi
callq 0x8a00
movq %r13, %r15
jmp 0xd3a1
movq 0x10(%rsp), %rsi
movl 0x18(%rsp), %edx
callq 0x8630
movq 0x10(%rsp), %rdi
callq 0x8a00
movq %r14, 0x8(%rbx)
movl %ebp, 0x4(%rbx)
jmp 0xd40b
movq 0x10(%rsp), %rax
movq %rax, 0x8(%rbx)
movl 0x18(%rsp), %eax
movl %eax, 0x4(%rbx)
movl 0x1c(%rsp), %ebp
movl %ebp, (%rbx)
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq