64 RpcCallee
RpcCallee.h
// RpcCallee.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2020
@import "Rpc.h"
@import "Skeleton.h"
#include <memory>
namespace ceda
{
$adt+ implement RpcCallee final
{
cxNotCloneable(RpcCallee)
public:
RpcCallee(Skeleton* skeleton, AnyInterface receiver);
$implementing adt RpcCallee;
private:
// The skeleton used to handle incoming messages
std::unique_ptr<Skeleton> m_skeleton;
AnyInterface m_receiver;
};
} // namespace ceda
RpcCallee.cpp
// RpcCallee.cpp
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2020
@import "RpcCallee.h"
namespace ceda
{
@api RpcCallee* CreateRpcCallee(ConstStringZ qualifiedInterfaceName, AnyInterface receiver)
{
if (Skeleton* skeleton = CreateSkeleton(qualifiedInterfaceName))
{
return new RpcCallee(skeleton,receiver);
}
else
{
return nullptr;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// RpcCallee
RpcCallee::RpcCallee(Skeleton* skeleton, AnyInterface receiver) :
m_skeleton(skeleton),
m_receiver(receiver)
{
cxAssert(skeleton != nullptr);
cxAssert(receiver);
cxAssert(skeleton->m_skeletonThunkFnTable);
cxAssert(0 <= skeleton->numMethods);
skeleton->m_delegate = m_receiver;
}
void RpcCallee::Close()
{
delete this;
}
bool RpcCallee::PlayMessages(const void* buffer, ssize_t size)
{
// We assume there are no more than 256 methods, allowing the method index to be
// serialised with a single octet.
// todo: Xcpp should allow for an alternative Stub to be used which uses two octets for the
// index when the number of methods exceeds 256
cxAssert(m_skeleton->numMethods <= 256);
InputArchive ar( (const octet_t *) buffer);
const octet_t * buffer_end = (const octet_t *)buffer + size;
while(ar < buffer_end)
{
octet_t index;
ar >> index;
if (index < 0 || index >= m_skeleton->numMethods)
{
// todo : throw exception
return false;
}
cxAssert(m_skeleton);
cxAssert(m_skeleton->m_skeletonThunkFnTable);
m_skeleton->m_ar = ar;
m_skeleton->m_skeletonThunkFnTable[index](m_skeleton.get());
ar = m_skeleton->m_ar;
}
if (ar > buffer_end)
{
// todo : throw exception
return false;
}
return true;
}
} // namespace ceda