Add an array operations to CDataPack (#1219)
This commit is contained in:
parent
bc89e54f6d
commit
13621a1274
@ -123,6 +123,28 @@ void CDataPack::PackString(const char *string)
|
||||
elements.insert(position++, val);
|
||||
}
|
||||
|
||||
void CDataPack::PackCellArray(cell_t const *vals, cell_t count)
|
||||
{
|
||||
InternalPack val;
|
||||
val.type = CDataPackType::CellArray;
|
||||
|
||||
val.pData.aval = new cell_t [count + 1];
|
||||
memcpy(&val.pData.aval[1], vals, sizeof(cell_t) * (count + 1));
|
||||
val.pData.aval[0] = count;
|
||||
elements.insert(position++, val);
|
||||
}
|
||||
|
||||
void CDataPack::PackFloatArray(cell_t const *vals, cell_t count)
|
||||
{
|
||||
InternalPack val;
|
||||
val.type = CDataPackType::FloatArray;
|
||||
|
||||
val.pData.aval = new cell_t [count + 1];
|
||||
memcpy(&val.pData.aval[1], vals, sizeof(cell_t) * (count + 1));
|
||||
val.pData.aval[0] = count;
|
||||
elements.insert(position++, val);
|
||||
}
|
||||
|
||||
void CDataPack::Reset() const
|
||||
{
|
||||
position = 0;
|
||||
@ -188,6 +210,46 @@ const char *CDataPack::ReadString(size_t *len) const
|
||||
return val.chars();
|
||||
}
|
||||
|
||||
cell_t *CDataPack::ReadCellArray(cell_t *size) const
|
||||
{
|
||||
if (!IsReadable() || elements[position].type != CDataPackType::CellArray)
|
||||
{
|
||||
if(size)
|
||||
*size = 0;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
cell_t *val = elements[position].pData.aval;
|
||||
cell_t *ptr = &(val[1]);
|
||||
++position;
|
||||
|
||||
if (size)
|
||||
*size = val[0];
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
cell_t *CDataPack::ReadFloatArray(cell_t *size) const
|
||||
{
|
||||
if (!IsReadable() || elements[position].type != CDataPackType::FloatArray)
|
||||
{
|
||||
if(size)
|
||||
*size = 0;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
cell_t *val = elements[position].pData.aval;
|
||||
cell_t *ptr = &(val[1]);
|
||||
++position;
|
||||
|
||||
if (size)
|
||||
*size = val[0];
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *CDataPack::ReadMemory(size_t *size) const
|
||||
{
|
||||
void *ptr = nullptr;
|
||||
@ -239,6 +301,13 @@ bool CDataPack::RemoveItem(size_t pos)
|
||||
delete elements[pos].pData.sval;
|
||||
break;
|
||||
}
|
||||
|
||||
case CDataPackType::CellArray:
|
||||
case CDataPackType::FloatArray:
|
||||
{
|
||||
delete elements[pos].pData.aval;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
elements.remove(pos);
|
||||
|
@ -43,7 +43,9 @@ enum CDataPackType {
|
||||
Cell,
|
||||
Float,
|
||||
String,
|
||||
Function
|
||||
Function,
|
||||
CellArray,
|
||||
FloatArray,
|
||||
};
|
||||
|
||||
class CDataPack
|
||||
@ -90,6 +92,21 @@ public: // Originally IDataReader
|
||||
*/
|
||||
float ReadFloat() const;
|
||||
|
||||
/**
|
||||
* @brief Reads an array of values from the data stream.
|
||||
*
|
||||
* @param len The size of the array stored at this position to return.
|
||||
* @return A cell array read from the current position.
|
||||
*/
|
||||
cell_t *ReadCellArray(cell_t *len) const;
|
||||
/**
|
||||
* @brief Reads an array of values from the data stream.
|
||||
*
|
||||
* @param len The size of the array stored at this position to return.
|
||||
* @return A cell array read from the current position.
|
||||
*/
|
||||
cell_t *ReadFloatArray(cell_t *len) const;
|
||||
|
||||
/**
|
||||
* @brief Returns whether or not a specified number of bytes from the current stream
|
||||
* position to the end can be read.
|
||||
@ -150,6 +167,21 @@ public: // Originally IDataPack
|
||||
*/
|
||||
void PackString(const char *string);
|
||||
|
||||
/**
|
||||
* @brief Packs an array of cells into the data stream.
|
||||
*
|
||||
* @param vals Cells to write.
|
||||
* @param count Number of cells.
|
||||
*/
|
||||
void PackCellArray(cell_t const *vals, cell_t count);
|
||||
/**
|
||||
* @brief Packs an array of cells into the data stream.
|
||||
*
|
||||
* @param vals Cells to write.
|
||||
* @param count Number of cells.
|
||||
*/
|
||||
void PackFloatArray(cell_t const *vals, cell_t count);
|
||||
|
||||
/**
|
||||
* @brief Creates a generic block of memory in the stream.
|
||||
*
|
||||
@ -182,6 +214,7 @@ private:
|
||||
float fval;
|
||||
uint8_t *vval;
|
||||
ke::AString *sval;
|
||||
cell_t *aval;
|
||||
} InternalPackValue;
|
||||
|
||||
typedef struct {
|
||||
|
@ -166,6 +166,62 @@ static cell_t smn_WritePackString(IPluginContext *pContext, const cell_t *params
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_WritePackCellArray(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
sec.pOwner = pContext->GetIdentity();
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
CDataPack *pDataPack = nullptr;
|
||||
if ((herr = handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
|
||||
!= HandleError_None)
|
||||
{
|
||||
pContext->ReportError("Invalid data pack handle %x (error %d).", hndl, herr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!params[4])
|
||||
{
|
||||
pDataPack->RemoveItem();
|
||||
}
|
||||
|
||||
cell_t *pArray;
|
||||
pContext->LocalToPhysAddr(params[2], &pArray);
|
||||
pDataPack->PackCellArray(pArray, params[3]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_WritePackFloatArray(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
sec.pOwner = pContext->GetIdentity();
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
CDataPack *pDataPack = nullptr;
|
||||
if ((herr = handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
|
||||
!= HandleError_None)
|
||||
{
|
||||
pContext->ReportError("Invalid data pack handle %x (error %d).", hndl, herr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!params[4])
|
||||
{
|
||||
pDataPack->RemoveItem();
|
||||
}
|
||||
|
||||
cell_t *pArray;
|
||||
pContext->LocalToPhysAddr(params[2], &pArray);
|
||||
pDataPack->PackFloatArray(pArray, params[3]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_WritePackFunction(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
@ -312,6 +368,108 @@ static cell_t smn_ReadPackFunction(IPluginContext *pContext, const cell_t *param
|
||||
return pDataPack->ReadFunction();
|
||||
}
|
||||
|
||||
static cell_t smn_ReadPackCellArray(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
sec.pOwner = pContext->GetIdentity();
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
CDataPack *pDataPack = nullptr;
|
||||
if ((herr = handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
|
||||
!= HandleError_None)
|
||||
{
|
||||
pContext->ReportError("Invalid data pack handle %x (error %d).", hndl, herr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!pDataPack->IsReadable())
|
||||
{
|
||||
pContext->ReportError("Data pack operation is out of bounds.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pDataPack->GetCurrentType() != CDataPackType::CellArray)
|
||||
{
|
||||
pContext->ReportError("Invalid data pack type (got %d / expected %d).", pDataPack->GetCurrentType(), CDataPackType::CellArray);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cell_t packCount = 0;
|
||||
cell_t *pData = pDataPack->ReadCellArray(&packCount);
|
||||
if(pData == nullptr || packCount == 0)
|
||||
{
|
||||
pContext->ReportError("Invalid data pack operation: current position isn't an array!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cell_t count = params[3];
|
||||
if(packCount > count)
|
||||
{
|
||||
pContext->ReportError("Input buffer too small (needed %d, got %d).", packCount, count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cell_t *pArray;
|
||||
pContext->LocalToPhysAddr(params[2], &pArray);
|
||||
|
||||
memcpy(pArray, pData, sizeof(cell_t) * count);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_ReadPackFloatArray(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
sec.pOwner = pContext->GetIdentity();
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
CDataPack *pDataPack = nullptr;
|
||||
if ((herr = handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
|
||||
!= HandleError_None)
|
||||
{
|
||||
pContext->ReportError("Invalid data pack handle %x (error %d).", hndl, herr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!pDataPack->IsReadable())
|
||||
{
|
||||
pContext->ReportError("Data pack operation is out of bounds.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pDataPack->GetCurrentType() != CDataPackType::FloatArray)
|
||||
{
|
||||
pContext->ReportError("Invalid data pack type (got %d / expected %d).", pDataPack->GetCurrentType(), CDataPackType::FloatArray);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cell_t packCount = 0;
|
||||
cell_t *pData = pDataPack->ReadFloatArray(&packCount);
|
||||
if(pData == nullptr || packCount == 0)
|
||||
{
|
||||
pContext->ReportError("Invalid data pack operation: current position isn't an array!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cell_t count = params[3];
|
||||
if(packCount > count)
|
||||
{
|
||||
pContext->ReportError("Input buffer too small (needed %d, got %d).", packCount, count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cell_t *pArray;
|
||||
pContext->LocalToPhysAddr(params[2], &pArray);
|
||||
|
||||
memcpy(pArray, pData, sizeof(cell_t) * count);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_ResetPack(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
@ -426,10 +584,14 @@ REGISTER_NATIVES(datapacknatives)
|
||||
{"DataPack.WriteFloat", smn_WritePackFloat},
|
||||
{"DataPack.WriteString", smn_WritePackString},
|
||||
{"DataPack.WriteFunction", smn_WritePackFunction},
|
||||
{"DataPack.WriteCellArray", smn_WritePackCellArray},
|
||||
{"DataPack.WriteFloatArray", smn_WritePackFloatArray},
|
||||
{"DataPack.ReadCell", smn_ReadPackCell},
|
||||
{"DataPack.ReadFloat", smn_ReadPackFloat},
|
||||
{"DataPack.ReadString", smn_ReadPackString},
|
||||
{"DataPack.ReadFunction", smn_ReadPackFunction},
|
||||
{"DataPack.ReadCellArray", smn_ReadPackCellArray},
|
||||
{"DataPack.ReadFloatArray", smn_ReadPackFloatArray},
|
||||
{"DataPack.Reset", smn_ResetPack},
|
||||
{"DataPack.Position.get", smn_GetPackPosition},
|
||||
{"DataPack.Position.set", smn_SetPackPosition},
|
||||
|
@ -71,6 +71,20 @@ methodmap DataPack < Handle
|
||||
// @param insert Determines whether mid-pack writes will insert instead of overwrite.
|
||||
public native void WriteFunction(Function fktptr, bool insert = false);
|
||||
|
||||
// Packs an array of cells into a data pack.
|
||||
//
|
||||
// @param array Array to add.
|
||||
// @param count Number of elements
|
||||
// @param insert Determines whether mid-pack writes will insert instead of overwrite.
|
||||
public native void WriteCellArray(const any[] array, int count, bool insert = false);
|
||||
|
||||
// Packs an array of floats into a data pack.
|
||||
//
|
||||
// @param array Array to add.
|
||||
// @param count Number of elements
|
||||
// @param insert Determines whether mid-pack writes will insert instead of overwrite.
|
||||
public native void WriteFloatArray(const float[] array, int count, bool insert = false);
|
||||
|
||||
// Reads a cell from a data pack.
|
||||
//
|
||||
// @return A cell at this position
|
||||
@ -92,6 +106,18 @@ methodmap DataPack < Handle
|
||||
// @return Function pointer.
|
||||
public native Function ReadFunction();
|
||||
|
||||
// Reads an array of cells a data pack.
|
||||
//
|
||||
// @param buffer Destination buffer.
|
||||
// @param count Maximum length of output buffer.
|
||||
public native void ReadCellArray(any[] buffer, int count);
|
||||
|
||||
// Reads an array of floats from a data pack.
|
||||
//
|
||||
// @param buffer Destination buffer.
|
||||
// @param count Maximum length of output buffer.
|
||||
public native void ReadFloatArray(float[] buffer, int count);
|
||||
|
||||
// Resets the position in a data pack.
|
||||
//
|
||||
// @param clear If true, clears the contained data.
|
||||
|
Loading…
Reference in New Issue
Block a user