fuse_message.cpp

00001 
00002 /***************************************************************************
00003  *  fuse_message.cpp - FireVision Remote Control Protocol Message Type
00004  *
00005  *  Created: Wed Nov 07 13:01:20 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 #include <core/exceptions/software.h>
00025 #include <fvutils/net/fuse_message.h>
00026 #include <fvutils/net/fuse_message_content.h>
00027 
00028 #include <cstdio>
00029 #include <cstring>
00030 #include <cstdlib>
00031 #include <netinet/in.h>
00032 
00033 namespace firevision {
00034 #if 0 /* just to make Emacs auto-indent happy */
00035 }
00036 #endif
00037 
00038 /** @class FuseNetworkMessage <fvutils/net/fuse_message.h>
00039  * FUSE Network Message.
00040  * This is the basic entity for messages that are sent over the network. Either
00041  * just use this message to send arbitrary payload or derive this class for more
00042  * complex behavior or nice encapsulations of messages.
00043  *
00044  * @ingroup FUSE
00045  * @ingroup FireVision
00046  * @author Tim Niemueller
00047  */
00048 
00049 /** Constructor. */
00050 FuseNetworkMessage::FuseNetworkMessage()
00051 {
00052   memset(&_msg, 0, sizeof(_msg));
00053   __content = NULL;
00054 }
00055 
00056 
00057 /** Constructor.
00058  * @param msg message information to copy
00059  */
00060 FuseNetworkMessage::FuseNetworkMessage(FUSE_message_t *msg)
00061 {
00062   memcpy(&_msg, msg, sizeof(FUSE_message_t));
00063   __content = NULL;
00064 }
00065 
00066 
00067 /** Constructor.
00068  * @param type message type
00069  * @param payload payload
00070  * @param payload_size size of payload
00071  * @param copy_payload if true payload is copied, otherwise payload is referenced
00072  * and ownership of payload is claimed.
00073  */
00074 FuseNetworkMessage::FuseNetworkMessage(FUSE_message_type_t type,
00075                                        void *payload, size_t payload_size,
00076                                        bool copy_payload)
00077 {
00078   __content = NULL;
00079   _msg.header.message_type = htonl(type);
00080   _msg.header.payload_size = htonl(payload_size);
00081 
00082   if ( copy_payload ) {
00083     _msg.payload = malloc(payload_size);
00084     memcpy(_msg.payload, payload, payload_size);
00085   } else {
00086     _msg.payload = payload;
00087   }
00088 }
00089 
00090 
00091 /** Constructor without payload.
00092  * Constructs message without payload.
00093  * @param type FUSE message type
00094  */
00095 FuseNetworkMessage::FuseNetworkMessage(FUSE_message_type_t type)
00096 {
00097   __content = NULL;
00098   _msg.header.message_type = htonl(type);
00099   _msg.header.payload_size = htonl(0);
00100   _msg.payload = NULL;
00101 }
00102 
00103 
00104 /** Content constructor.
00105  * Construct a message with complex message content.
00106  * @param type FUSE message type
00107  * @param content complex message content.
00108  */
00109 FuseNetworkMessage::FuseNetworkMessage(FUSE_message_type_t type, FuseMessageContent *content)
00110 {
00111   __content = content;
00112   _msg.header.message_type = htonl(type);
00113   _msg.header.payload_size = htonl(0);
00114   _msg.payload = NULL;
00115 }
00116 
00117 /** Destructor. */
00118 FuseNetworkMessage::~FuseNetworkMessage()
00119 {
00120   if ( __content == NULL ) {
00121     if ( _msg.payload != NULL ) {
00122       free(_msg.payload);
00123       _msg.payload = NULL;
00124     }
00125   } else {
00126     __content->free_payload();
00127     delete __content;
00128   }
00129 }
00130 
00131 /** Get message type.
00132  * @return message type
00133  */
00134 uint32_t
00135 FuseNetworkMessage::type() const
00136 {
00137   return ntohl(_msg.header.message_type);
00138 }
00139 
00140 
00141 /** Get payload size.
00142  * @return payload size
00143  */
00144 size_t
00145 FuseNetworkMessage::payload_size() const
00146 {
00147   return ntohl(_msg.header.payload_size);
00148 }
00149 
00150 
00151 /** Get pointer to payload.
00152  * @return pointer to payload.
00153  */
00154 void *
00155 FuseNetworkMessage::payload() const
00156 {
00157   return _msg.payload;
00158 }
00159 
00160 
00161 /** Get plain message.
00162  * @return plain message
00163  */
00164 const FUSE_message_t &
00165 FuseNetworkMessage::fmsg() const
00166 {
00167   return _msg;
00168 }
00169 
00170 
00171 /** Set payload.
00172  * Payload is referenced and ownership claimed.
00173  * @param payload payload
00174  * @param payload_size size of payload
00175  */
00176 void
00177 FuseNetworkMessage::set_payload(void *payload, size_t payload_size)
00178 {
00179   if ( payload_size > 0xFFFFFFFF ) {
00180     // cannot carry that many bytes
00181     throw fawkes::OutOfBoundsException("Payload too big", payload_size, 0, 0xFFFFFFFF);
00182   }
00183   _msg.payload = payload;
00184   _msg.header.payload_size = htonl(payload_size);
00185 }
00186 
00187 
00188 /** Set from message.
00189  * @param msg reference to message. Content is deep-copied.
00190  */
00191 void
00192 FuseNetworkMessage::set(FUSE_message_t &msg)
00193 {
00194   memcpy(&_msg, &msg, sizeof(FUSE_message_t));
00195 }
00196 
00197 /** Pack data for sending.
00198  * Use this if any additional packing is needed before sending the data (for
00199  * example if using a DynamicBuffer).
00200  */
00201 void
00202 FuseNetworkMessage::pack()
00203 {
00204   if ( __content != NULL ) {
00205     __content->serialize();
00206     _msg.payload = __content->payload();
00207     _msg.header.payload_size = htonl(__content->payload_size());
00208   }
00209 }
00210 
00211 } // end namespace firevision

Generated on 1 Mar 2011 for Fawkes API by  doxygen 1.6.1