119 | | |
120 | | |
121 | | |
122 | | |
123 | | |
124 | | |
125 | | |
126 | | |
| 121 | Sometimes, 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 |
| 125 | using_serialization; |
| 126 | |
| 127 | class NodeListingReply : public Message { |
| 128 | VSERIALIZEABLE; |
| 129 | public: |
| 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 | |
| 139 | private: |
| 140 | NodeEndpointList descriptors; |
| 141 | }; |
| 142 | |
| 143 | sznBeginDefault( 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 | |
| 152 | In 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 |
| 155 | typedef pair<NodeID,EndpointDescriptor*> NodeEndpoint; |
| 156 | typedef vector<NodeEndpoint> NodeEndpointList; |
| 157 | }}} |
| 158 | |
| 159 | The serializer first gets the size of the vector and stores it: |
| 160 | {{{ |
| 161 | #!cpp |
| 162 | uint16_t len = descriptors.size(); |
| 163 | X && len; |
| 164 | }}} |
| 165 | In 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 |
| 168 | if (X.isDeserializer()) descriptors.resize(len); |
| 169 | }}} |
| 170 | Then, we iterate through the vector size and de/serializa the two items in the vector: |
| 171 | {{{ |
| 172 | #!cpp |
| 173 | for (int i=0; i<len; i++) |
| 174 | X && &descriptors[i].first && VO(descriptors[i].second); |
| 175 | }}} |
| 176 | The 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. |