// File: /workspace/github_c_makefile_star2_O3/DeforaOS[P]libSystem/src/variable.c
// Function: variable_serialize
VariableError variable_serialize(Variable * variable, Buffer * buffer,
		bool prefix)
{
	size_t size = 0;
	size_t offset;
	void * p;
	uint8_t u8;
	int16_t i16;
	uint16_t u16;
	int32_t i32;
	int64_t i64;
	uint32_t u32;
	uint64_t u64;
	char buf[16];
	Array const * array;
	size_t i;

#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s(%u)\n", __func__, variable->type);
#endif
	switch(variable->type)
	{
		case VT_NULL:
			p = NULL;
			break;
		case VT_BOOL:
		case VT_INT8:
		case VT_UINT8:
			size = sizeof(variable->u.int8);
			p = &variable->u.int8;
			break;
		case VT_INT16:
			size = sizeof(i16);
			i16 = _bswap16(variable->u.int16);
			p = &i16;
			break;
		case VT_UINT16:
			size = sizeof(u16);
			u16 = _bswap16(variable->u.uint16);
			p = &u16;
			break;
		case VT_INT32:
			size = sizeof(i32);
			i32 = _bswap32(variable->u.int32);
			p = &i32;
			break;
		case VT_UINT32:
			size = sizeof(u32);
			u32 = _bswap32(variable->u.uint32);
			p = &u32;
			break;
		case VT_INT64:
			size = sizeof(i64);
			i64 = _bswap64(variable->u.int64);
			p = &i64;
			break;
		case VT_UINT64:
			size = sizeof(u64);
			u64 = _bswap64(variable->u.uint64);
			p = &u64;
			break;
		case VT_FLOAT:
			size = snprintf(buf, sizeof(buf), "%.e", variable->u.f);
			p = buf;
			break;
		case VT_DOUBLE:
			size = snprintf(buf, sizeof(buf), "%.e", variable->u.d);
			p = buf;
			break;
		case VT_BUFFER:
			size = buffer_get_size(variable->u.buffer);
			u32 = buffer_get_size(variable->u.buffer);
			u32 = _bswap32(u32);
			p = (void *)buffer_get_data(variable->u.buffer);
			break;
		case VT_STRING:
			size = string_get_length(variable->u.string) + 1;
			p = variable->u.string;
			break;
		case VT_ARRAY:
			array = variable->u.array.array;
			size = sizeof(u32);
			u32 = array_count(array);
			u32 = _bswap32(u32);
			p = &u32;
			break;
		case VT_POINTER:
			size = sizeof(u64);
			u64 = (uint64_t)variable->u.pointer;
			u64 = _bswap64(u64);
			p = &u64;
			break;
	}
#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s() %lu\n", __func__, size);
#endif
	if(size == 0 && variable->type != VT_NULL)
		return -error_set_code(1, "Unable to serialize type %u",
				variable->type);
	offset = 0;
	if(prefix)
	{
		/* prefix with the type */
		u8 = variable->type;
		if(buffer_set(buffer, sizeof(u8), (char const *)&u8) != 0)
			return -1;
		offset = sizeof(u8);
		if(variable->type == VT_BUFFER)
		{
			if(buffer_set_data(buffer, offset, (char const *)&u32,
						sizeof(u32)) != 0)
				return -1;
			offset += sizeof(u32);
		}
		else if(variable->type != VT_ARRAY)
			return buffer_set_data(buffer, offset, (char const *)p,
					size);
	}
	if(variable->type == VT_BUFFER)
	{
		if(buffer_set(buffer, sizeof(u32), (char const *)&u32) != 0)
			return -1;
		return buffer_set_data(buffer, sizeof(u32), (char const *)p,
				size);
	}
	else if(variable->type == VT_ARRAY)
	{
		array = variable->u.array.array;
		u8 = variable->u.array.type;
		if(buffer_set_data(buffer, offset, (char const *)&u8,
					sizeof(u8)) != 0)
			return -1;
		offset += sizeof(u8);
		if(buffer_set_data(buffer, offset, p, size) != 0)
			return -1;
		offset += sizeof(u32);
		size = array_get_size(array);
		for(i = 0; i < array_count(array); i++)
			if(buffer_set_data(buffer, offset, array_get(array, i),
						size) != 0)
				return -1;
			else
				offset += size;
		return 0;
	}
	return buffer_set(buffer, size, (char const *)p);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movl %edx, %r13d
movq %rsi, %rbx
movq %rdi, %r14
movl (%rdi), %edx
leal -0x1(%rdx), %eax
cmpl $0xf, %eax
ja 0xa314
leaq 0x11fe(%rip), %rcx      # 0xb46c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x8(%r14), %rbp
movl $0x1, %r15d
jmp 0xa428
movq 0x10(%r14), %rdi
callq 0x4250
bswapl %eax
leaq 0xc(%rsp), %rbp
movl %eax, (%rbp)
movl (%r14), %edx
movl $0x4, %r15d
jmp 0xa428
movsd 0x8(%r14), %xmm0
jmp 0xa3c0
movq 0x8(%r14), %rdi
callq 0x4330
movq %rax, %r15
incq %r15
movq 0x8(%r14), %rbp
jmp 0xa3de
movl 0x8(%r14), %eax
bswapl %eax
leaq 0x10(%rsp), %rbp
movl %eax, (%rbp)
movl $0x4, %r15d
movl $0x6, %edx
jmp 0xa428
movq 0x8(%r14), %rdi
callq 0x4270
movq %rax, %r15
movq 0x8(%r14), %rdi
callq 0x4270
bswapl %eax
movl %eax, 0xc(%rsp)
movq 0x8(%r14), %rdi
callq 0x4500
movq %rax, %rbp
jmp 0xa3de
xorl %ebp, %ebp
jmp 0xa3e6
movl 0x8(%r14), %eax
bswapl %eax
leaq 0xc(%rsp), %rbp
movl %eax, (%rbp)
movl $0x4, %r15d
movl $0x7, %edx
jmp 0xa428
movq 0x8(%r14), %rax
bswapq %rax
leaq 0x10(%rsp), %rbp
movq %rax, (%rbp)
movl $0x8, %r15d
movl $0x8, %edx
jmp 0xa428
movq 0x8(%r14), %rax
bswapq %rax
leaq 0x10(%rsp), %rbp
movq %rax, (%rbp)
movl $0x8, %r15d
movl $0x10, %edx
jmp 0xa428
movzwl 0x8(%r14), %eax
rolw $0x8, %ax
leaq 0x10(%rsp), %rbp
movw %ax, (%rbp)
movl $0x2, %r15d
movl $0x4, %edx
jmp 0xa428
movzwl 0x8(%r14), %eax
rolw $0x8, %ax
leaq 0x10(%rsp), %rbp
movw %ax, (%rbp)
movl $0x2, %r15d
movl $0x5, %edx
jmp 0xa428
cvtss2sd 0x8(%r14), %xmm0
leaq 0x122b(%rip), %rdx      # 0xb5f2
leaq 0x10(%rsp), %rbp
movl $0x10, %esi
movq %rbp, %rdi
movb $0x1, %al
callq 0x42a0
movslq %eax, %r15
movl (%r14), %edx
testq %r15, %r15
jne 0xa428
testl %edx, %edx
je 0xa423
leaq 0x1205(%rip), %rsi      # 0xb5f6
movl $0x1, %edi
xorl %eax, %eax
callq 0x45d0
movl %eax, %ebx
negl %ebx
jmp 0xa52c
movq 0x8(%r14), %rax
bswapq %rax
leaq 0x10(%rsp), %rbp
movq %rax, (%rbp)
movl $0x8, %r15d
movl $0x9, %edx
jmp 0xa428
xorl %edx, %edx
xorl %r15d, %r15d
testb %r13b, %r13b
je 0xa495
leaq 0xb(%rsp), %rax
movb %dl, (%rax)
movl $0x1, %r13d
movl $0x1, %esi
movq %rbx, %rdi
movq %rax, %rdx
callq 0x4450
movq %rbx, %r12
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
testl %eax, %eax
jne 0xa52c
movl (%r14), %eax
cmpl $0xe, %eax
je 0xa4c7
cmpl $0xc, %eax
jne 0xa517
leaq 0xc(%rsp), %rdx
movl $0x1, %esi
movl $0x4, %ecx
movq %r12, %rdi
callq 0x40d0
testl %eax, %eax
jne 0xa52c
movl (%r14), %edx
movl $0x5, %r13d
jmp 0xa49b
movq %rbx, %r12
xorl %r13d, %r13d
cmpl $0xe, %edx
je 0xa4c7
cmpl $0xc, %edx
jne 0xa507
leaq 0xc(%rsp), %rdx
movl $0x4, %esi
movq %r12, %rdi
callq 0x4450
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
testl %eax, %eax
jne 0xa52c
movl $0x4, %esi
jmp 0xa51c
movq 0x10(%r14), %rbx
movb 0x8(%r14), %al
leaq 0xb(%rsp), %rdx
movb %al, (%rdx)
movl $0x1, %ecx
movq %r12, %rdi
movq %r13, %rsi
callq 0x40d0
testl %eax, %eax
jne 0xa500
leaq 0x1(%r13), %rsi
movq %r12, %rdi
movq %rbp, %rdx
movq %r15, %rcx
callq 0x40d0
testl %eax, %eax
je 0xa53d
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
jmp 0xa52c
movq %r12, %rdi
movq %r15, %rsi
movq %rbp, %rdx
callq 0x4450
jmp 0xa52a
movl $0x1, %esi
movq %r12, %rdi
movq %rbp, %rdx
movq %r15, %rcx
callq 0x40d0
movl %eax, %ebx
movl %ebx, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rbx, %rbp
movq %rbx, %rdi
callq 0x4320
movq %rax, %r14
movq %rbx, %rdi
callq 0x4250
testq %rax, %rax
je 0xa59a
addq $0x5, %r13
xorl %r15d, %r15d
xorl %ebx, %ebx
movq %rbp, %rdi
movq %r15, %rsi
callq 0x4590
movq %r12, %rdi
movq %r13, %rsi
movq %rax, %rdx
movq %r14, %rcx
callq 0x40d0
testl %eax, %eax
jne 0xa500
addq %r14, %r13
incq %r15
movq %rbp, %rdi
callq 0x4250
cmpq %rax, %r15
jb 0xa561
jmp 0xa52c
xorl %ebx, %ebx
jmp 0xa52c