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 namespace firevision {
00035 #if 0 /* just to make Emacs auto-indent happy */
00036 }
00037 #endif
00038 
00039 class FuseMessageContent;
00040 
00041 class FuseNetworkMessage : public fawkes::RefCount
00042 {
00043  public:
00044   FuseNetworkMessage();
00045   FuseNetworkMessage(FUSE_message_t *msg);
00046   FuseNetworkMessage(FUSE_message_type_t type, void *payload, size_t payload_size,
00047                      bool copy_payload = false);
00048   FuseNetworkMessage(FUSE_message_type_t type, FuseMessageContent *content);
00049   FuseNetworkMessage(FUSE_message_type_t type);
00050   ~FuseNetworkMessage();
00051 
00052   uint32_t  type() const;
00053   size_t    payload_size() const;
00054   void *    payload() const;
00055 
00056   const FUSE_message_t &  fmsg() const;
00057 
00058   /** Get correctly casted payload.
00059    * Use this method to cast the payload to a specific type. The size is
00060    * check as a sanity check and a TypeMismatchException is thrown if the
00061    * size does not match.
00062    * @return casted message
00063    * @exception TypeMismatchException payload size does not match requested type
00064    */
00065   template <typename MT>
00066     MT *
00067     msg() const
00068     {
00069       if ( payload_size() != sizeof(MT) ) {
00070         throw fawkes::TypeMismatchException("FawkesNetworkMessage: message has incorrect size for this type");
00071       }
00072       return (MT *)(_msg.payload);
00073     }
00074 
00075 
00076   /** Get copy of correctly casted payload.
00077    * Use this method to cast the payload to a specific type. The size is
00078    * check as a sanity check and a TypeMismatchException is thrown if the
00079    * size does not match.
00080    * @return copy of casted message
00081    * @exception TypeMismatchException payload size does not match requested type
00082    */
00083   template <typename MT>
00084     MT *
00085     msg_copy() const
00086     {
00087       if ( payload_size() != sizeof(MT) ) {
00088         throw fawkes::TypeMismatchException("FawkesNetworkMessage: message has incorrect size for this type");
00089       }
00090       void *tmp = malloc(sizeof(MT));
00091       memcpy(tmp, _msg.payload, sizeof(MT));
00092       return (MT *)tmp;
00093     }
00094 
00095   /** Get correctly parsed output.
00096    * Use this method to cast the payload to a specific complex type. You can use this
00097    * routine to parse complex messages that are derived from FuseComplexMessageContent.
00098    * Note that the class must provide a constructor that takes three parameters: The
00099    * message type, a pointer to the payload and the payload size. From this
00100    * the class shall parse  the output and throw an exception if that for whatever
00101    * reason fails.
00102    * @return casted message
00103    * @exception TypeMismatchException payload size does not match requested type
00104    */
00105   template <typename MT>
00106     MT *
00107     msgc() const
00108     {
00109       try {
00110         MT *m = new MT(type(), _msg.payload, payload_size());
00111         return m;
00112       } catch (fawkes::Exception &e) {
00113         throw;
00114       } catch (...) {
00115         throw fawkes::Exception("Unknown exception caught while parsing complex network message");
00116       }
00117     }
00118 
00119   void pack();
00120 
00121   void set_payload(void *payload, size_t payload_size);
00122   void set(FUSE_message_t &msg);
00123   //void set_content(FuseComplexMessageContent *content);
00124 
00125  protected:
00126   /** Internal message. Fill in derivatives. */
00127   FUSE_message_t _msg;
00128 
00129  private:
00130   FuseMessageContent *__content;
00131 };
00132 
00133 } // end namespace firevision
00134 
00135 #endif