Serialise.cpp

// Serialise.cpp
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2007

@import "Ceda/cxObject/Object.h"
@import "Ceda/cxObject/SerialiseReflectedVariable.h"
@import "Ceda/cxObject/PrintReflectedVariable.h"
@import "ExampleUtils.h"
#include "Ceda/cxUtils/PagedBufferAsArchive.h"
#include <assert.h>

///////////////////////////////////////////////////////////////////////////////////////////////////
/*
Serialisation of variables using reflection
-------------------------------------------

Under certain restrictions, reflected types can be serialised or deserialsed to/from a byte stream.

The following example demonstrates that an object can be serialised to a PagedBuffer, and then
deserialised to a different object that ends up with the same state at the original.
*/
namespace Serialise1
{
    $struct+ Point
    {
        Point() : x(0), y(0) {}
        
        $ceda::int32 x;
        $ceda::int32 y;
    };

    $struct+ Line
    {
        $Point p1;
        $Point p2;
    };

    $struct+ X
    {
        X() : v(0) {}
        
        $Line line;
        $ceda::int32 v;
        $ceda::xvector<ceda::int16> L;
    };
    
    void Run()
    {
		ceda::TraceGroup g("Serialise example 1");

        // Look up the interface registry for the interface with given name
        const ceda::ReflectedClass& rc = ceda::FindReflectedClass("Serialise1::X");
        
        ceda::xvector<ceda::octet_t> buffer;
                
        // Serialise a "source" instance of an X to the PagedBuffer
        {
            ceda::PagedBuffer pb;
            {
                ceda::OutputArchiveOnPagedBuffer ar(pb);

                X src;
                src.v = 10;
                src.line.p1.x = 100;
                src.line.p1.y = 200;
                src.line.p2.x = 1000;
                src.line.p2.y = 2000;
                src.L.push_back(1);
                src.L.push_back(2);
                src.L.push_back(3);
                
                ceda::SerialiseReflectedClassVariable(ar, rc, &src);

                Tracer() << "Source\n";
                ceda::PrintReflectedClassVariable(Tracer(),rc,&src);
            }
            pb.WriteTo(buffer);
        }
        
        // Deserialise a "destination" instance of an X from the PagedBuffer
        {
            ceda::InputArchive ar(buffer.data());
            X dst;

            Tracer() << "Destination - before deserialise\n";
            ceda::PrintReflectedClassVariable(Tracer(),rc,&dst);

            ceda::DeserialiseReflectedClassVariable(ar, rc, &dst);
            
            Tracer() << "Destination - after deserialise\n";
            ceda::PrintReflectedClassVariable(Tracer(),rc,&dst);

            cxAssert(ar == buffer.data_end());
        }
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////
namespace Serialise
{
    void Run()
    {
        Serialise1::Run();
    }
}