// File: rellla[P]E3DC-Rscp/RscpProtocol.cpp
// Function: RscpProtocol::createValue(SRscpValue*, unsigned int const&, std::vector<SRscpValue, std::allocator<SRscpValue>> const&)
int32_t RscpProtocol::createValue(SRscpValue* response, const SRscpTag & tag, const std::vector<SRscpValue> & value) {
	// sanity check
	if(response == NULL) {
		return RSCP::ERR_INVALID_INPUT;
	}
	// reset the memory of the response value to zero
	memset(response, 0, sizeof(SRscpValue));
	// calculate the new tag size
	uint32_t newTagLength = 0;
	for(size_t i = 0; i < value.size(); ++i) {
		newTagLength += sizeof(SRscpValue) - sizeof(value[i].data) + value[i].length;
	}
	// check boundaries
	if(newTagLength > 0xFFF8) {
		return RSCP::ERR_DATA_LIMIT_EXCEEDED;
	}
	// re-allocate the structure memory
	if(allocateMemory(response, newTagLength) == false) {
		return RSCP::ERR_NO_MEMORY;
	}
	// first add the TAG for a container
	response->tag = tag;
	response->dataType = RSCP::eTypeContainer;
	response->length = newTagLength;

	// copy data
	size_t sPos = 0;
	for(size_t i = 0; i < value.size(); ++i) {
		SRscpValue *newData = reinterpret_cast<SRscpValue *> (((uint8_t*)response->data) + sPos);
		newData->tag = value[i].tag;
		newData->dataType = value[i].dataType;
		newData->length = value[i].length;
		if(newData->length > 0) {
			// copy into the position of the data pointer and not into the data pointer itself as the data is appended
			memcpy(&newData->data, value[i].data, newData->length);
		}
		sPos += sizeof(SRscpValue) - sizeof(value[i].data) + value[i].length;
	}
	// all added successfully
	return RSCP::OK;
}

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x68(%rsp)
movq %rsi, 0x60(%rsp)
movq %rdx, 0x58(%rsp)
movq %rcx, 0x50(%rsp)
movq 0x68(%rsp), %rax
movq %rax, 0x20(%rsp)
cmpq $0x0, 0x60(%rsp)
jne 0x8ca7
movl $0xffffffff, 0x74(%rsp) # imm = 0xFFFFFFFF
jmp 0x8ea0
movq 0x60(%rsp), %rdi
xorl %esi, %esi
movl $0xf, %edx
callq 0x20e0
movl $0x0, 0x4c(%rsp)
movq $0x0, 0x40(%rsp)
movq 0x40(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x50(%rsp), %rdi
callq 0x5e80
movq %rax, %rcx
movq 0x18(%rsp), %rax
cmpq %rcx, %rax
jae 0x8d1e
movq 0x50(%rsp), %rdi
movq 0x40(%rsp), %rsi
callq 0x95d0
movzwl 0x5(%rax), %eax
movl %eax, %ecx
addq $0x7, %rcx
movl 0x4c(%rsp), %eax
addq %rcx, %rax
movl %eax, 0x4c(%rsp)
movq 0x40(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x40(%rsp)
jmp 0x8cc9
cmpl $0xfff8, 0x4c(%rsp)     # imm = 0xFFF8
jbe 0x8d35
movl $0xfffffff9, 0x74(%rsp) # imm = 0xFFFFFFF9
jmp 0x8ea0
movq 0x20(%rsp), %rdi
movq 0x60(%rsp), %rsi
movl 0x4c(%rsp), %eax
movl %eax, %edx
callq 0x85e0
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x8d61
movl $0xfffffffe, 0x74(%rsp) # imm = 0xFFFFFFFE
jmp 0x8ea0
movq 0x58(%rsp), %rax
movl (%rax), %ecx
movq 0x60(%rsp), %rax
movl %ecx, (%rax)
movq 0x60(%rsp), %rax
movb $0xe, 0x4(%rax)
movl 0x4c(%rsp), %eax
movw %ax, %cx
movq 0x60(%rsp), %rax
movw %cx, 0x5(%rax)
movq $0x0, 0x38(%rsp)
movq $0x0, 0x30(%rsp)
movq 0x30(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x50(%rsp), %rdi
callq 0x5e80
movq %rax, %rcx
movq 0x10(%rsp), %rax
cmpq %rcx, %rax
jae 0x8e98
movq 0x60(%rsp), %rax
movq 0x7(%rax), %rax
addq 0x38(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x50(%rsp), %rdi
movq 0x30(%rsp), %rsi
callq 0x95d0
movl (%rax), %ecx
movq 0x28(%rsp), %rax
movl %ecx, (%rax)
movq 0x50(%rsp), %rdi
movq 0x30(%rsp), %rsi
callq 0x95d0
movb 0x4(%rax), %cl
movq 0x28(%rsp), %rax
movb %cl, 0x4(%rax)
movq 0x50(%rsp), %rdi
movq 0x30(%rsp), %rsi
callq 0x95d0
movw 0x5(%rax), %cx
movq 0x28(%rsp), %rax
movw %cx, 0x5(%rax)
movq 0x28(%rsp), %rax
movzwl 0x5(%rax), %eax
cmpl $0x0, %eax
jle 0x8e64
movq 0x28(%rsp), %rax
addq $0x7, %rax
movq %rax, 0x8(%rsp)
movq 0x50(%rsp), %rdi
movq 0x30(%rsp), %rsi
callq 0x95d0
movq 0x8(%rsp), %rdi
movq 0x7(%rax), %rsi
movq 0x28(%rsp), %rax
movzwl 0x5(%rax), %eax
movl %eax, %edx
callq 0x2130
movq 0x50(%rsp), %rdi
movq 0x30(%rsp), %rsi
callq 0x95d0
movzwl 0x5(%rax), %eax
addq $0x7, %rax
addq 0x38(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x30(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x30(%rsp)
jmp 0x8d9a
movl $0x0, 0x74(%rsp)
movl 0x74(%rsp), %eax
addq $0x78, %rsp
retq
nopl (%rax)