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