message.h

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

Generated on Tue Feb 22 13:32:24 2011 for Fawkes API by  doxygen 1.4.7