Fawkes API Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * message.h - Fawkes network message 00004 * 00005 * Created: Mon Nov 20 18:00:09 2006 00006 * Copyright 2006 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #ifndef __NETCOMM_FAWKES_MESSAGE_H_ 00025 #define __NETCOMM_FAWKES_MESSAGE_H_ 00026 00027 #include <core/utils/refcount.h> 00028 #include <core/exceptions/software.h> 00029 00030 #include <cstddef> 00031 00032 namespace fawkes { 00033 00034 #pragma pack(push,4) 00035 00036 /** Fawkes network message header. 00037 * Header that is prepended to all following messages. 00038 */ 00039 typedef struct { 00040 unsigned short int cid; /**< component id */ 00041 unsigned short int msg_id; /**< message id */ 00042 unsigned int payload_size; /**< payload size in bytes */ 00043 } fawkes_message_header_t; 00044 00045 #pragma pack(pop) 00046 00047 /** Message as stored in local queues. 00048 * A message takes a header and a pointer to the data that 00049 * has the size mentioned in header.payload_size that is to be 00050 * sent over the network. 00051 */ 00052 typedef struct { 00053 fawkes_message_header_t header; /**< message header */ 00054 void *payload; /**< message payload */ 00055 } fawkes_message_t; 00056 00057 00058 /** Fawkes transfer header. 00059 * This header is prepended to a collection of messages that is sent 00060 * at once. 00061 */ 00062 typedef struct { 00063 unsigned int size; /**< size of the following payload. */ 00064 } fawkes_transfer_header_t; 00065 00066 00067 class FawkesNetworkMessageTooBigException : public Exception 00068 { 00069 public: 00070 FawkesNetworkMessageTooBigException(size_t message_size); 00071 }; 00072 00073 class FawkesNetworkMessageContent; 00074 00075 class FawkesNetworkMessage : public RefCount 00076 { 00077 public: 00078 FawkesNetworkMessage(unsigned int clid, fawkes_message_t &msg); 00079 FawkesNetworkMessage(fawkes_message_t &msg); 00080 FawkesNetworkMessage(unsigned int clid, 00081 unsigned short int cid, unsigned short int msg_id, 00082 void *payload, size_t payload_size); 00083 FawkesNetworkMessage(unsigned int clid, 00084 unsigned short int cid, unsigned short int msg_id); 00085 FawkesNetworkMessage(unsigned short int cid, unsigned short int msg_id, 00086 void *payload, size_t payload_size); 00087 FawkesNetworkMessage(unsigned int clid, 00088 unsigned short int cid, unsigned short int msg_id, 00089 FawkesNetworkMessageContent *content); 00090 FawkesNetworkMessage(unsigned short int cid, unsigned short int msg_id, 00091 FawkesNetworkMessageContent *content); 00092 FawkesNetworkMessage(unsigned short int cid, unsigned short int msg_id, 00093 size_t payload_size); 00094 FawkesNetworkMessage(unsigned short int cid, unsigned short int msg_id); 00095 FawkesNetworkMessage(); 00096 00097 virtual ~FawkesNetworkMessage(); 00098 00099 unsigned int clid() const; 00100 unsigned short int cid() const; 00101 unsigned short int msgid() const; 00102 size_t payload_size() const; 00103 void * payload() const; 00104 const fawkes_message_t & fmsg() const; 00105 00106 /** Get correctly casted payload. 00107 * Use this method to cast the payload to a specific type. The size is 00108 * check as a sanity check and a TypeMismatchException is thrown if the 00109 * size does not match. 00110 * @return casted message 00111 * @exception TypeMismatchException payload size does not match requested type 00112 */ 00113 template <typename MT> 00114 MT * 00115 msg() const 00116 { 00117 if ( payload_size() != sizeof(MT) ) { 00118 throw TypeMismatchException("FawkesNetworkMessage: message has incorrect size for this type"); 00119 } 00120 return (MT *)(_msg.payload); 00121 } 00122 00123 /** Get correctly casted payload. 00124 * Use this method to cast the payload to a specific type. The size is 00125 * check as a sanity check and a TypeMismatchException is thrown if the 00126 * size does not match. The size of the received message must be greater or 00127 * equal to the size of the message type. Useful if message contains a variable 00128 * length string. 00129 * @return casted message 00130 * @exception TypeMismatchException payload size does not match requested type 00131 */ 00132 template <typename MT> 00133 MT * 00134 msgge() const 00135 { 00136 if ( payload_size() < sizeof(MT) ) { 00137 throw TypeMismatchException("FawkesNetworkMessage: message has incorrect size for this type"); 00138 } 00139 return (MT *)(_msg.payload); 00140 } 00141 00142 /** Get correctly parsed output. 00143 * Use this method to cast the payload to a specific complex type. You can use this 00144 * routine to parse complex messages that are derived from FawkesNetworkMessageContent. 00145 * Note that the class must provide a constructor that takes four parameters: The 00146 * component ID, message ID, a pointer to the payload and the payload size. From this 00147 * the class shall parse the output and throw an exception if that for whatever 00148 * reason fails. 00149 * @return casted message 00150 * @exception TypeMismatchException payload size does not match requested type 00151 */ 00152 template <typename MT> 00153 MT * 00154 msgc() const 00155 { 00156 try { 00157 MT *m = new MT(cid(), msgid(), _msg.payload, payload_size()); 00158 return m; 00159 } catch (Exception &e) { 00160 throw; 00161 } catch (...) { 00162 throw Exception("Unknown exception caught while parsing complex network message"); 00163 } 00164 } 00165 00166 void set_client_id(unsigned int clid); 00167 void set_component_id(unsigned short int cid); 00168 void set_message_id(unsigned short int msg_id); 00169 void set_payload(void *payload, size_t payload_size); 00170 void set(fawkes_message_t &msg); 00171 void set_content(FawkesNetworkMessageContent *content); 00172 00173 void pack(); 00174 00175 private: 00176 void init_cid_msgid(unsigned short int cid, unsigned short int msg_id); 00177 void init_payload(size_t payload_size); 00178 00179 unsigned int _clid; 00180 fawkes_message_t _msg; 00181 00182 FawkesNetworkMessageContent *_content; 00183 }; 00184 00185 } // end namespace fawkes 00186 00187 #endif