// File: /workspace/github_c_makefile_star2_O2/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, %ebp
movq %rsi, %rbx
movq %rdi, %r14
movl (%rdi), %edx
leal -0x1(%rdx), %eax
cmpl $0xf, %eax
ja 0x9cf6
leaq 0x1843(%rip), %rcx      # 0xb49c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
pushq $0x1
popq %r12
leaq 0x8(%r14), %r15
jmp 0x9de3
movq 0x10(%r14), %rdi
callq 0x4250
bswapl %eax
leaq 0xc(%rsp), %r15
movl %eax, (%r15)
movl (%r14), %edx
pushq $0x4
popq %r12
jmp 0x9de3
movsd 0x8(%r14), %xmm0
jmp 0x9d85
movq 0x8(%r14), %rdi
callq 0x4350
movq %rax, %r12
incq %r12
movq 0x8(%r14), %r15
jmp 0x9da1
movl 0x8(%r14), %eax
bswapl %eax
leaq 0x10(%rsp), %r15
movl %eax, (%r15)
pushq $0x4
popq %r12
pushq $0x6
jmp 0x9de2
movq 0x8(%r14), %rdi
callq 0x4270
movq %rax, %r12
movq 0x8(%r14), %rdi
callq 0x4270
bswapl %eax
movl %eax, 0xc(%rsp)
movq 0x8(%r14), %rdi
callq 0x4540
movq %rax, %r15
jmp 0x9da1
xorl %r15d, %r15d
jmp 0x9da9
movl 0x8(%r14), %eax
bswapl %eax
leaq 0xc(%rsp), %r15
movl %eax, (%r15)
pushq $0x4
popq %r12
pushq $0x7
jmp 0x9de2
movq 0x8(%r14), %rax
bswapq %rax
leaq 0x10(%rsp), %r15
movq %rax, (%r15)
pushq $0x8
popq %r12
pushq $0x8
jmp 0x9de2
movq 0x8(%r14), %rax
bswapq %rax
leaq 0x10(%rsp), %r15
movq %rax, (%r15)
pushq $0x8
popq %r12
pushq $0x10
jmp 0x9de2
movzwl 0x8(%r14), %eax
rolw $0x8, %ax
leaq 0x10(%rsp), %r15
movw %ax, (%r15)
pushq $0x2
popq %r12
pushq $0x4
jmp 0x9de2
movzwl 0x8(%r14), %eax
rolw $0x8, %ax
leaq 0x10(%rsp), %r15
movw %ax, (%r15)
pushq $0x2
popq %r12
pushq $0x5
jmp 0x9de2
cvtss2sd 0x8(%r14), %xmm0
leaq 0x1896(%rip), %rdx      # 0xb622
leaq 0x10(%rsp), %r15
pushq $0x10
popq %rsi
movq %r15, %rdi
movb $0x1, %al
callq 0x42a0
movslq %eax, %r12
movl (%r14), %edx
testq %r12, %r12
jne 0x9de3
testl %edx, %edx
je 0x9f25
leaq 0x186e(%rip), %rsi      # 0xb626
pushq $0x1
popq %rdi
xorl %eax, %eax
callq 0x4610
movl %eax, %r13d
negl %r13d
jmp 0x9f13
movq 0x8(%r14), %rax
bswapq %rax
leaq 0x10(%rsp), %r15
movq %rax, (%r15)
pushq $0x8
popq %r12
pushq $0x9
popq %rdx
pushq $-0x1
popq %r13
testb %bpl, %bpl
je 0x9e3c
leaq 0xb(%rsp), %rax
movb %dl, (%rax)
pushq $0x1
popq %rbp
movq %rbx, %rdi
movq %rbp, %rsi
movq %rax, %rdx
callq 0x4490
testl %eax, %eax
jne 0x9f13
movl (%r14), %eax
cmpl $0xe, %eax
je 0x9e7a
pushq $0x1
popq %rsi
cmpl $0xc, %eax
jne 0x9e67
leaq 0xc(%rsp), %rdx
pushq $0x4
popq %rcx
movq %rbx, %rdi
callq 0x40d0
testl %eax, %eax
jne 0x9f13
movl (%r14), %edx
pushq $0x5
popq %rbp
jmp 0x9e3e
xorl %ebp, %ebp
cmpl $0xe, %edx
je 0x9e7a
cmpl $0xc, %edx
jne 0x9f02
pushq $0x4
popq %rsi
leaq 0xc(%rsp), %rdx
movq %rbx, %rdi
callq 0x4490
testl %eax, %eax
jne 0x9f13
pushq $0x4
popq %rsi
movq %rbx, %rdi
movq %r15, %rdx
movq %r12, %rcx
callq 0x40d0
jmp 0x9f10
movq %r12, 0x20(%rsp)
movq %rbx, %r12
movq 0x10(%r14), %rbx
movb 0x8(%r14), %al
leaq 0xb(%rsp), %rdx
movb %al, (%rdx)
pushq $0x1
popq %rcx
movq %r12, %rdi
movq %rbp, %rsi
callq 0x40d0
testl %eax, %eax
jne 0x9f13
leaq 0x1(%rbp), %rsi
movq %r12, %rdi
movq %r15, %rdx
movq 0x20(%rsp), %rcx
callq 0x40d0
testl %eax, %eax
jne 0x9f13
addq $0x5, %rbp
movq %rbx, %rdi
callq 0x4340
movq %rax, %r14
xorl %r15d, %r15d
movq %rbx, %rdi
callq 0x4250
cmpq %rax, %r15
jae 0x9f2f
movq %rbx, %rdi
movq %r15, %rsi
callq 0x45d0
movq %r12, %rdi
movq %rbp, %rsi
movq %rax, %rdx
movq %r14, %rcx
callq 0x40d0
testl %eax, %eax
jne 0x9f13
addq %r14, %rbp
incq %r15
jmp 0x9ecd
movq %rbx, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0x4490
movl %eax, %r13d
movl %r13d, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %edx, %edx
xorl %r12d, %r12d
jmp 0x9de3
xorl %r13d, %r13d
jmp 0x9f13