fuse_message.h

00001
00002 /***************************************************************************
00003  *  fuse_message.h - FireVision Remote Control Protocol Message Type
00004  *
00005  *  Created: Wed Nov 07 12:56:18 2007
00006  *  Copyright  2005-2007  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 __FIREVISION_FVUTILS_NET_FUSE_MESSAGE_H_
00025 #define __FIREVISION_FVUTILS_NET_FUSE_MESSAGE_H_
00026 
00027 #include <core/utils/refcount.h>
00028 #include <core/exceptions/software.h>
00029 #include <fvutils/net/fuse.h>
00030 #include <sys/types.h>
00031 #include <cstdlib>
00032 #include <cstring>
00033
00034 class FuseMessageContent;
00035
00036 class FuseNetworkMessage : public fawkes::RefCount
00037 {
00038  public:
00039   FuseNetworkMessage();
00040   FuseNetworkMessage(FUSE_message_t *msg);
00041   FuseNetworkMessage(FUSE_message_type_t type, void *payload, size_t payload_size,
00042                      bool copy_payload = false);
00043   FuseNetworkMessage(FUSE_message_type_t type, FuseMessageContent *content);
00044   FuseNetworkMessage(FUSE_message_type_t type);
00045   ~FuseNetworkMessage();
00046
00047   uint32_t  type() const;
00048   size_t    payload_size() const;
00049   void *    payload() const;
00050
00051   const FUSE_message_t &  fmsg() const;
00052 
00053   /** Get correctly casted payload.
00054    * Use this method to cast the payload to a specific type. The size is
00055    * check as a sanity check and a TypeMismatchException is thrown if the
00056    * size does not match.
00057    * @return casted message
00058    * @exception TypeMismatchException payload size does not match requested type
00059    */
00060   template <typename MT>
00061     MT *
00062     msg() const
00063     {
00064       if ( payload_size() != sizeof(MT) ) {
00065         throw fawkes::TypeMismatchException("FawkesNetworkMessage: message has incorrect size for this type");
00066       }
00067       return (MT *)(_msg.payload);
00068     }
00069
00070 
00071   /** Get copy of correctly casted payload.
00072    * Use this method to cast the payload to a specific type. The size is
00073    * check as a sanity check and a TypeMismatchException is thrown if the
00074    * size does not match.
00075    * @return copy of casted message
00076    * @exception TypeMismatchException payload size does not match requested type
00077    */
00078   template <typename MT>
00079     MT *
00080     msg_copy() const
00081     {
00082       if ( payload_size() != sizeof(MT) ) {
00083         throw fawkes::TypeMismatchException("FawkesNetworkMessage: message has incorrect size for this type");
00084       }
00085       void *tmp = malloc(sizeof(MT));
00086       memcpy(tmp, _msg.payload, sizeof(MT));
00087       return (MT *)tmp;
00088     }
00089 
00090   /** Get correctly parsed output.
00091    * Use this method to cast the payload to a specific complex type. You can use this
00092    * routine to parse complex messages that are derived from FuseComplexMessageContent.
00093    * Note that the class must provide a constructor that takes three parameters: The
00094    * message type, a pointer to the payload and the payload size. From this
00095    * the class shall parse  the output and throw an exception if that for whatever
00096    * reason fails.
00097    * @return casted message
00098    * @exception TypeMismatchException payload size does not match requested type
00099    */
00100   template <typename MT>
00101     MT *
00102     msgc() const
00103     {
00104       try {
00105         MT *m = new MT(type(), _msg.payload, payload_size());
00106         return m;
00107       } catch (fawkes::Exception &e) {
00108         throw;
00109       } catch (...) {
00110         throw fawkes::Exception("Unknown exception caught while parsing complex network message");
00111       }
00112     }
00113
00114   void pack();
00115
00116   void set_payload(void *payload, size_t payload_size);
00117   void set(FUSE_message_t &msg);
00118   //void set_content(FuseComplexMessageContent *content);
00119
00120  protected:
00121   /** Internal message. Fill in derivatives. */
00122   FUSE_message_t _msg;
00123
00124  private:
00125   FuseMessageContent *__content;
00126 };
00127
00128 #endif