Archived

This forum has been archived. Please start a new discussion on GitHub.

Object streaming

I have the following slice definition:
module Demo {

	class Node  {
		string nodeId;
	};

	class SimpleNode extends Node {
	};

	class ComplexNode extends Node {
	};

	sequence<Node> NodeList;

	interface Server {
		void copyNodes(NodeList nodes);
	};
};

My ComplexNode class has some data that I can't define in the slice file but which I know how to serialize. What is the recommended way to handle that serialization?

I made a few tests and found the following code to be working (I serialized a std::string for the test purpose), but I am pretty sure those __read and __write methods are not intended to be overwritten.

Thanks.
class ComplexNodeImp : public Demo::ComplexNode {
public:
	ComplexNodeImp(std::string const & internal = "void")
    : m_internal(internal) {
	}
    virtual void __write(IceInternal::BasicStream* stream) const{
        Demo::ComplexNode::__write(stream);
        stream->write(m_internal);
    }
    virtual void __read(IceInternal::BasicStream* stream, bool rid){
        Demo::ComplexNode::__read(stream, rid);
        stream->read(m_internal);
    }
    
    std::string m_internal;
};

class ComplexNodeFactory : public Ice::ObjectFactory {
public:
    virtual Ice::ObjectPtr create(const std::string& type) {
        return Ice::ObjectPtr( new ComplexNodeImp );
    }
    virtual void destroy() {}
};

Comments

  • mes
    mes California
    Hi,

    Welcome to the forum.

    If you were using Java or C#, I would recommend that you investigate the use of serializable types. However, for C++, the simplest option is to include a sequence<byte> in your Slice definition:
    sequence<byte> Streamable;
    
    class ComplexNode extends Node {
        Streamable bytes;
    };
    

    You can use our public stream API to create the byte sequence. Have a look at the example in demo/Ice/invoke for more details on using the stream API.

    Hope that helps,
    Mark
  • I guess that should do the work, but I see two drawbacks. The client code will have to explicitly prepare the object for serialization and for deserialization. Also, the memory footprint of the object will be doubled.
    Is there any more direct way to do it, like in my sample? Do you plan to add such a feature?
  • bernard
    bernard Jupiter, FL
    Hi Thibaut,

    There is currently no better way to stream a native C++ object with Ice for C++.

    We support today the ability to pass the following types automatically as sequence<byte>:
    - in Java, serializable objects
    - in C#, serializable objects
    - in C++, Java and Python, Google protocol buffers

    An improvement would be to allow you to plug-in your own serialization/deserialization code for your native objects. I am not sure when we will implement it, as this is currently not high priority.

    If this feature would make a big difference for you, you could sponsor its implementation and get a patch as soon as it's ready. Please contact sales@zeroc.com for more information.

    Best regards,
    Bernard