1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-07-06 00:47:11 +02:00

Implement multi-part messages for ZMQ.

This commit is contained in:
Sandu Liviu Catalin
2021-02-04 07:55:10 +02:00
parent 5d63520c16
commit 89d90971fd
2 changed files with 329 additions and 70 deletions

View File

@ -11,30 +11,109 @@ namespace SqMod {
SQMOD_DECL_TYPENAME(SqZContext, _SC("SqZmqContext"))
SQMOD_DECL_TYPENAME(SqZSocket, _SC("SqZmqSocket"))
// ------------------------------------------------------------------------------------------------
static void FlushSingleString(HSQUIRRELVM, Function & callback, Buffer & data)
{
// Transform the message into a script object
LightObj o(static_cast< const SQChar * >(data.Get()),
static_cast< SQInteger >(data.Position()));
// Forward it to the callback
callback(o, false);
}
// ------------------------------------------------------------------------------------------------
static void FlushSingleBuffer(HSQUIRRELVM vm, Function & callback, Buffer & data)
{
// Transform the message into a script object
LightObj o(SqTypeIdentity< SqBuffer >{}, vm, std::move(data));
// Forward it to the callback
callback(o, false);
}
// ------------------------------------------------------------------------------------------------
static void FlushMultiString(HSQUIRRELVM vm, Function & callback, ZMsg::List & list)
{
// Create a script array
Array a(vm);
// Reserve space upfront
a.Reserve(static_cast< SQInteger >(list.size()));
// Populate the array with elements from the list
a.AppendFromCounted([&list](HSQUIRRELVM vm, SQInteger i) -> bool {
// Are we still withing range of our list?
if (static_cast< size_t >(i) < list.size())
{
// Transform the message into a script object
sq_pushstring(vm, static_cast< const SQChar * >(list[i].Get()),
static_cast< SQInteger >(list[i].Position()));
// We have an element on the stack
return true;
}
// We don't have an element on the stack
return false;
});
// Forward it to the callback
callback(a, true);
}
// ------------------------------------------------------------------------------------------------
static void FlushMultiBuffer(HSQUIRRELVM vm, Function & callback, ZMsg::List & list)
{
// Create a script array
Array a(vm);
// Reserve space upfront
a.Reserve(static_cast< SQInteger >(list.size()));
// Populate the array with elements from the list
a.AppendFromCounted([&list](HSQUIRRELVM vm, SQInteger i) -> bool {
// Are we still withing range of our list?
if (static_cast< size_t >(i) < list.size())
{
// Transform the message into a script object
LightObj o(SqTypeIdentity< SqBuffer >{}, vm, std::move(list[i]));
// Push it on the stack
Var< LightObj >::push(vm, o);
// We have an element on the stack
return true;
}
// We don't have an element on the stack
return false;
});
// Forward it to the callback
callback(a, true);
}
// ------------------------------------------------------------------------------------------------
void ZSkt::Flush(HSQUIRRELVM vm)
{
// Need someone to receive the message
Item data;
Item item;
// Try to get a message from the queue
while (mOutputQueue.try_dequeue(data))
while (mOutputQueue.try_dequeue(item))
{
// Is there a callback to receive the message?
if (!mOnData.IsNull())
{
// Transform the message into a script object
if (mStringMessages)
// Is this a multi-part message?
if (!(item->mMulti))
{
LightObj o(static_cast< const SQChar * >(data->Get()),
static_cast< SQInteger >(data->Size< SQChar >()));
// Forward it to the callback
mOnData(o);
if (mStringMessages)
{
FlushSingleString(vm, mOnData, item->mBuff);
}
else
{
FlushSingleBuffer(vm, mOnData, item->mBuff);
}
}
else
{
LightObj o(SqTypeIdentity< SqBuffer >{}, vm, std::move(*data));
// Forward it to the callback
mOnData(o);
if (mStringMessages)
{
FlushMultiString(vm, mOnData, item->mList);
}
else
{
FlushMultiBuffer(vm, mOnData, item->mList);
}
}
}
}