You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/CryEngine/CrySystem/RemoteCommandHelpers.cpp

362 lines
9.5 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Helper classes for remote command system
#include "CrySystem_precompiled.h"
#include "IServiceNetwork.h"
#include "RemoteCommandHelpers.h"
//-----------------------------------------------------------------------------
CDataReadStreamFormMessage::CDataReadStreamFormMessage(const IServiceNetworkMessage* message)
: m_pMessage(message)
, m_size(message->GetSize())
, m_pData(static_cast<const char*>(message->GetPointer()))
, m_offset(0)
{
// AddRef() is not const unfortunatelly
const_cast<IServiceNetworkMessage*>(m_pMessage)->AddRef();
}
CDataReadStreamFormMessage::~CDataReadStreamFormMessage()
{
// Release() is not const unfortunatelly
const_cast<IServiceNetworkMessage*>(m_pMessage)->Release();
}
void CDataReadStreamFormMessage::Delete()
{
delete this;
}
void CDataReadStreamFormMessage::Skip(const uint32 size)
{
CRY_ASSERT(m_offset + size < m_size);
m_offset += size;
}
void CDataReadStreamFormMessage::Read(void* pData, const uint32 size)
{
CRY_ASSERT(m_offset + size < m_size);
const char* pReadPtr = m_pData + m_offset;
memcpy(pData, pReadPtr, size);
m_offset += size;
}
void CDataReadStreamFormMessage::Read8(void* pData)
{
// it does not actually matter if its uint64, int64 or double so use any
ReadType<uint64>(pData);
}
void CDataReadStreamFormMessage::Read4(void* pData)
{
// it does not actually matter if its uint32, int32 or float so use any
ReadType<uint32>(pData);
}
void CDataReadStreamFormMessage::Read2(void* pData)
{
// it does not actually matter if its uint16, int16 so use any
ReadType<uint16>(pData);
}
void CDataReadStreamFormMessage::Read1(void* pData)
{
// it does not actually matter if its uint8, int8 so use any
ReadType<uint8>(pData);
}
const void* CDataReadStreamFormMessage::GetPointer()
{
const char* pReadPtr = m_pData + m_offset;
return pReadPtr;
}
//-----------------------------------------------------------------------------
CDataWriteStreamToMessage::CDataWriteStreamToMessage(IServiceNetworkMessage* pMessage)
: m_pMessage(pMessage)
, m_size(pMessage->GetSize())
, m_pData(static_cast<char*>(pMessage->GetPointer()))
, m_offset(0)
{
m_pMessage->AddRef();
}
CDataWriteStreamToMessage::~CDataWriteStreamToMessage()
{
m_pMessage->Release();
}
void CDataWriteStreamToMessage::Delete()
{
delete this;
}
const uint32 CDataWriteStreamToMessage::GetSize() const
{
return m_size;
}
void CDataWriteStreamToMessage::CopyToBuffer(void* pData) const
{
memcpy(pData, m_pData, m_size);
}
IServiceNetworkMessage* CDataWriteStreamToMessage::BuildMessage() const
{
m_pMessage->AddRef();
return m_pMessage;
}
void CDataWriteStreamToMessage::Write(const void* pData, const uint32 size)
{
CRY_ASSERT(m_offset + size < m_size);
memcpy((char*)m_pData + m_offset, pData, size);
m_offset += size;
}
void CDataWriteStreamToMessage::Write8(const void* pData)
{
// it does not actually matter if its uint64, int64 or double so use any
WriteType<uint64>(pData);
}
void CDataWriteStreamToMessage::Write4(const void* pData)
{
// it does not actually matter if its uint32, int32 or float so use any
WriteType<uint32>(pData);
}
void CDataWriteStreamToMessage::Write2(const void* pData)
{
// it does not actually matter if its uint16, int16 so use any
WriteType<uint16>(pData);
}
void CDataWriteStreamToMessage::Write1(const void* pData)
{
// it does not actually matter if its uint8, int8 so use any
WriteType<uint8>(pData);
}
//-----------------------------------------------------------------------------
CDataReadStreamMemoryBuffer::CDataReadStreamMemoryBuffer(const void* pData, const uint32 size)
: m_size(size)
, m_offset(0)
{
m_pData = new uint8 [size];
memcpy(m_pData, pData, size);
}
CDataReadStreamMemoryBuffer::~CDataReadStreamMemoryBuffer()
{
delete [] m_pData;
m_pData = NULL;
}
void CDataReadStreamMemoryBuffer::Delete()
{
delete this;
}
void CDataReadStreamMemoryBuffer::Skip(const uint32 size)
{
CRY_ASSERT(m_offset + size <= m_size);
m_offset += size;
}
void CDataReadStreamMemoryBuffer::Read8(void* pData)
{
Read(pData, 8);
SwapEndian(*reinterpret_cast<uint64*>(pData));
}
void CDataReadStreamMemoryBuffer::Read4(void* pData)
{
Read(pData, 4);
SwapEndian(*reinterpret_cast<uint32*>(pData));
}
void CDataReadStreamMemoryBuffer::Read2(void* pData)
{
Read(pData, 2);
SwapEndian(*reinterpret_cast<uint16*>(pData));
}
void CDataReadStreamMemoryBuffer::Read1(void* pData)
{
return Read(pData, 1);
}
const void* CDataReadStreamMemoryBuffer::GetPointer()
{
return m_pData + m_offset;
};
void CDataReadStreamMemoryBuffer::Read(void* pData, const uint32 size)
{
CRY_ASSERT(m_offset + size <= m_size);
memcpy(pData, m_pData + m_offset, size);
m_offset += size;
}
//-----------------------------------------------------------------------------
CDataWriteStreamBuffer::CDataWriteStreamBuffer()
: m_size(0)
{
// Start with the initial (preallocated) partition
// This optimization assumes that initial size of most of the messages will be small.
// NOTE: default partition is not added to the partition table (that would require push_backs to vector)
char* partitionMemory = &m_defaultPartition[0];
m_pCurrentPointer = partitionMemory;
m_leftInPartition = sizeof(m_defaultPartition);
}
CDataWriteStreamBuffer::~CDataWriteStreamBuffer()
{
// Free all memory partitions that were allocated dynamically
for (size_t i = 0; i < m_pPartitions.size(); ++i)
{
CryModuleFree(m_pPartitions[i]);
}
}
void CDataWriteStreamBuffer::Delete()
{
delete this;
}
const uint32 CDataWriteStreamBuffer::GetSize() const
{
return m_size;
}
void CDataWriteStreamBuffer::CopyToBuffer(void* pData) const
{
uint32 dataLeft = m_size;
char* pWritePtr = (char*)pData;
// Copy data from default (preallocated) partition
{
const uint32 partitionSize = sizeof(m_defaultPartition);
const uint32 dataToCopy = min<uint32>(partitionSize, dataLeft);
memcpy(pWritePtr, &m_defaultPartition[0], dataToCopy);
// advance
pWritePtr += dataToCopy;
dataLeft -= dataToCopy;
}
// Copy data from dynamic partitions
for (uint32 i = 0; i < m_pPartitions.size(); ++i)
{
// get size of data to copy
const uint32 partitionSize = m_partitionSizes[i];
const uint32 dataToCopy = min<uint32>(partitionSize, dataLeft);
memcpy(pWritePtr, m_pPartitions[i], dataToCopy);
// advance
pWritePtr += dataToCopy;
dataLeft -= dataToCopy;
}
// Make sure all data was written
CRY_ASSERT(dataLeft == 0);
}
IServiceNetworkMessage* CDataWriteStreamBuffer::BuildMessage() const
{
// No data written, no message created
if (0 == m_size)
{
return NULL;
}
// Create message to hold all the data
IServiceNetworkMessage* pMessage = gEnv->pServiceNetwork->AllocMessageBuffer(m_size);
if (NULL == pMessage)
{
return NULL;
}
// Copy data to messages
CopyToBuffer(pMessage->GetPointer());
return pMessage;
}
void CDataWriteStreamBuffer::Write(const void* pData, const uint32 size)
{
static const uint32 kAdditionalPartitionSize = 65536;
uint32 dataLeft = size;
while (dataLeft > 0)
{
// new partition needed
if (m_leftInPartition == 0)
{
// Allocate new partition data
char* partitionMemory = (char*)CryModuleMalloc(kAdditionalPartitionSize);
CRY_ASSERT(partitionMemory != NULL);
// add new partition to list
m_partitionSizes.push_back(kAdditionalPartitionSize);
m_pPartitions.push_back(partitionMemory);
m_pCurrentPointer = partitionMemory;
m_leftInPartition = kAdditionalPartitionSize;
}
// how many bytes can we write to current partition ?
const uint32 maxToWrite = min<uint32>(m_leftInPartition, dataLeft);
memcpy(m_pCurrentPointer, pData, maxToWrite);
// advance
m_size += maxToWrite;
dataLeft -= maxToWrite;
pData = (const char*)pData + maxToWrite;
m_pCurrentPointer += maxToWrite;
m_leftInPartition -= maxToWrite;
}
}
void CDataWriteStreamBuffer::Write8(const void* pData)
{
// it does not actually matter if its uint64, int64 or double so use any
WriteType<uint64>(pData);
}
void CDataWriteStreamBuffer::Write4(const void* pData)
{
// it does not actually matter if its uint32, int32 or float so use any
WriteType<uint32>(pData);
}
void CDataWriteStreamBuffer::Write2(const void* pData)
{
// it does not actually matter if its uint16, int16 so use any
WriteType<uint16>(pData);
}
void CDataWriteStreamBuffer::Write1(const void* pData)
{
// it does not actually matter if its uint8, int8 so use any
WriteType<uint8>(pData);
}
//-----------------------------------------------------------------------------