source: source/ariba/utility/messages/Message.h@ 6841

Last change on this file since 6841 was 6786, checked in by mies, 14 years ago

Changed Data to Message conversion constructor in Message to explicit
Fixed some general bugs in Data: operator<<
Fixed bug in DHTMessage: allow unspecified key/values
Added local DHT message delivery
Adapted sources to work with gcc 4.4.1

File size: 6.9 KB
Line 
1// [License]
2// The Ariba-Underlay Copyright
3//
4// Copyright (c) 2008-2009, Institute of Telematics, UniversitÀt Karlsruhe (TH)
5//
6// Institute of Telematics
7// UniversitÀt Karlsruhe (TH)
8// Zirkel 2, 76128 Karlsruhe
9// Germany
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// THIS SOFTWARE IS PROVIDED BY THE INSTITUTE OF TELEMATICS ``AS IS'' AND
22// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ARIBA PROJECT OR
25// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32//
33// The views and conclusions contained in the software and documentation
34// are those of the authors and should not be interpreted as representing
35// official policies, either expressed or implied, of the Institute of
36// Telematics.
37// [License]
38
39#ifndef MESSAGE_H_
40#define MESSAGE_H_
41
42// library includes
43#include<new>
44#include<string>
45#include<iostream>
46#include<boost/shared_array.hpp>
47
48// forward declaration
49#include "_namespace.h"
50NAMESPACE_BEGIN
51class Message;
52typedef size_t seqnum_t;
53NAMESPACE_END
54
55// library includes
56#include <cassert>
57#include<boost/shared_array.hpp>
58#include<boost/cstdint.hpp>
59
60// common includes
61#include "ariba/utility/types/Address.h"
62#include "ariba/utility/serialization.h"
63
64std::ostream& operator<<(std::ostream& stream, const ariba::utility::Message& msg );
65
66#include "_namespace.h"
67NAMESPACE_BEGIN
68
69using_serialization;
70using ariba::utility::Address;
71using boost::shared_array;
72
73/**
74 * This class implements an abstract message format.
75 *
76 * @author Sebastian Mies
77 */
78class Message: public VSerializeable {
79 VSERIALIZEABLE;
80
81protected:
82 friend std::ostream& ::operator<<(std::ostream& stream, const ariba::utility::Message& msg );
83
84 // root binary data
85 shared_array<uint8_t> root;
86
87 // payload
88 bool releasePayload;
89 Data payload; //< messages binary data
90
91 // addresses and control info
92 const Address* srcAddr;
93 const Address* destAddr;
94
95public:
96 /**
97 * Constructor initializing name of message to the given one
98 */
99 inline Message() :
100 root(), releasePayload(true), payload(), srcAddr(NULL),destAddr(NULL) {
101 }
102
103 /**
104 * Constructs a new "root" message by copying the data described by
105 * data.
106 */
107 explicit inline Message( const Data& data ) :
108 srcAddr(NULL),destAddr(NULL), releasePayload(true) {
109 this->payload = data.clone();
110// this->root = shared_array<uint8_t>((uint8_t*)data.getBuffer());
111 }
112
113 inline void dropPayload() {
114 if (this->releasePayload) payload.release();
115 }
116
117 inline void setReleasePayload( bool release ) {
118 this->releasePayload = release;
119 }
120
121 inline Data getPayload() const {
122 return payload;
123 }
124
125 inline void setPayload( const Data& payload ) {
126 this->payload = payload;
127 }
128
129 /**
130 * Default destructor.
131 */
132 virtual ~Message();
133
134 std::string toString() const;
135
136 /**
137 * Sets the destination address
138 *
139 * @param An abstract address representation
140 */
141 inline void setDestinationAddress(const Address* addr) {
142 destAddr = addr;
143 }
144
145 /**
146 * Returns the optional abstract destination address or NULL
147 *
148 * @return the abstract destination address
149 */
150 inline const Address* getDestinationAddress() const {
151 return destAddr;
152 }
153
154 /**
155 * Set the source address of the message
156 *
157 * @param addr The abstract source address
158 */
159 inline void setSourceAddress(const Address* addr) {
160 srcAddr = addr;
161 }
162
163 /**
164 * Returns the optional abstract source address or NULL
165 *
166 * @return The abstract source address
167 */
168 inline const Address* getSourceAddress() const {
169 return srcAddr;
170 }
171
172 /**
173 * Returns a short human-readable description of this message
174 *
175 * @return A short human-readable description of this message
176 */
177 virtual const char* getDescription() const;
178
179 /**
180 * Returns a return message, that can be used to send a message
181 * back to the recipient or NULL if no message can be returned.
182 * The default implementation returns NULL.
183 *
184 * @return Return message.
185 */
186 virtual Message* createReturnMessage() const;
187
188 /**
189 * Encapsulate a message into the payload.
190 *
191 * @param message The message to be encapsulated.
192 */
193 inline void encapsulate( Message* message, int variant = DEFAULT_V ) {
194 if ( !payload.isUnspecified() ) throw "Error: Message already encapsulated";
195 payload = data_serialize( message, variant );
196 message->dropPayload();
197 }
198
199 /**
200 * Decapsulates message. In case the message
201 * has not been deserialized, this method class
202 * serialization to get an object.
203 *
204 * @return The message object or NULL if a deserialization
205 */
206 template<class T>
207 inline T* decapsulate() {
208 if (!payload.isUnspecified()) {
209 T* payloadMsg = new T();
210 data_deserialize( payloadMsg, payload );
211 return payloadMsg;
212 }
213 return NULL;
214 }
215
216 /**
217 * The same as decapsulate, but this function
218 * is used in the samples to make the semantics easier
219 * to understand. The semantics is shown to be: you get
220 * a message and convert it to your type. Not as: you
221 * get a message and have to extract your message from it.
222 */
223 template<class T>
224 inline T* convert() {
225 return decapsulate<T>();
226 }
227
228protected:
229 /**
230 * This class implements an explicit serializer for
231 * the message's payload.
232 */
233 class PayloadSerializer: public ExplicitSerializer {
234 private:
235 Message* msg;
236 size_t len;
237 public:
238 finline PayloadSerializer(Message* msg, size_t length = ~0) {
239 this->msg = msg;
240 this->len = length;
241 }
242
243 sznMethodBegin(X) {
244 if (X.isSerializer()) {
245 if (!msg->payload.isUnspecified()) X && msg->payload;
246 } else {
247 if (msg->payload.isUnspecified()) {
248 size_t l = ((len == ~0) ? X.getRemainingLength() : len);
249 msg->payload = X.getRemainingData(l);
250 msg->releasePayload = false;
251 }
252 }
253 }
254 sznMethodEnd();
255 };
256
257 /**
258 * Returns a serializer of the messages payload/encapsulated
259 * message.
260 *
261 * @param length The length of the payload
262 * @return A explicit payload serializer
263 */
264 finline PayloadSerializer Payload( size_t length = ~0 ) {
265 return PayloadSerializer( this, length );
266 }
267
268};
269
270NAMESPACE_END
271
272sznBeginDefault(ariba::utility::Message, X) {
273 X && Payload();
274} sznEnd();
275
276#endif /* MESSAGE_H_ */
Note: See TracBrowser for help on using the repository browser.