Changes between Version 6 and Version 7 of Documentation/Serialization


Ignore:
Timestamp:
Feb 5, 2010, 9:03:35 AM (14 years ago)
Author:
Christoph Mayer
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Documentation/Serialization

    v6 v7  
    7777 * const int support - cI( uintmax_t )
    7878 * const char* support - cT( const char* )
    79  * string and char* support, T( char* | std::string )
     79 * string and char* support - T( char* | std::string )
     80 * pointer serialization - VO( pointer* )
    8081
    8182It is always best to use types that have a specified length, e.g. {{{uint8_t}}}, {{{uint16_t}}}, ... etc. If you are serializing through a inherited type where the serialization is provided in the base class, use the {{{&}}} operator before. Such a case is e.g. the {{{NodeID}}} class:
     
    111112You will find the following code in the !PingPong sample that shows how to convert the incoming message to your format and invoke the deserializer:
    112113{{{
     114#!cpp
    113115void PingPong::onMessage(const DataMessage& msg, const NodeID& remote, const LinkID& lnk) {
    114116    PingPongMessage* pingmsg = msg.getMessage()->convert<PingPongMessage> ();
     
    117119}}}
    118120
    119 
    120 
    121 
    122 
    123 
    124 
    125 
    126 
     121Sometimes, it is necessary to transfer a complete vector of objects through a message. The following code is taken from the {{{NodeListingReply.h}}} file of the OneHop overlay in Ariba.
     122
     123{{{
     124#!cpp
     125using_serialization;
     126
     127class NodeListingReply : public Message {
     128        VSERIALIZEABLE;
     129public:
     130        NodeListingReply();
     131        virtual ~NodeListingReply();
     132
     133        typedef pair<NodeID,EndpointDescriptor*> NodeEndpoint;
     134        typedef vector<NodeEndpoint> NodeEndpointList;
     135
     136        void add(const NodeID& node, EndpointDescriptor* endp);
     137        const NodeEndpointList& getList();
     138
     139private:
     140        NodeEndpointList descriptors;
     141};
     142
     143sznBeginDefault( ariba::overlay::NodeListingReply, X ) {
     144        uint16_t len = descriptors.size();
     145        X && len;
     146        if (X.isDeserializer()) descriptors.resize(len);
     147        for (int i=0; i<len; i++)
     148                X && &descriptors[i].first && VO(descriptors[i].second);
     149} sznEnd();
     150}}}
     151
     152In this message we want to transfer a vector that holds combinations of NodeID and EndpointDescriptor. Also note, that we store pointers to EndpointDescriptors:
     153{{{
     154#!cpp
     155typedef pair<NodeID,EndpointDescriptor*> NodeEndpoint;
     156typedef vector<NodeEndpoint> NodeEndpointList;
     157}}}
     158
     159The serializer first gets the size of the vector and stores it:
     160{{{
     161#!cpp
     162uint16_t len = descriptors.size();
     163X && len;
     164}}}
     165In case of serialization the actual length {{{len}}} will be stored in the serialization, in case of deserialization the len that has been set to the size of the vector will be overwritten with the value stored in the message. Next, in case we are performing a deserialization, we resize the vector according to the size stored in the message:
     166{{{
     167#!cpp
     168if (X.isDeserializer()) descriptors.resize(len);
     169}}}
     170Then, we iterate through the vector size and de/serializa the two items in the vector:
     171{{{
     172#!cpp
     173for (int i=0; i<len; i++)
     174   X && &descriptors[i].first && VO(descriptors[i].second);
     175}}}
     176The following points are of importance: First, note the & before {{{descriptors[i].first}}}. This is required as the actual serialization code of the {{{NodeID}}} class remains in a base class. Second, we use the {{{VO}}} macro to deserialize through a pointer. In case of deserialization, this will directly create a new {{{EndpointDescriptor}}} object through the new operator.
    127177
    128178