Sirikata
libcore/include/sirikata/core/network/Message.hpp
Go to the documentation of this file.
00001 /*  Sirikata
00002  *  Message.hpp
00003  *
00004  *  Copyright (c) 2009, Ewen Cheslack-Postava
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions are
00009  *  met:
00010  *  * Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer.
00012  *  * Redistributions in binary form must reproduce the above copyright
00013  *    notice, this list of conditions and the following disclaimer in
00014  *    the documentation and/or other materials provided with the
00015  *    distribution.
00016  *  * Neither the name of Sirikata nor the names of its contributors may
00017  *    be used to endorse or promote products derived from this software
00018  *    without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00021  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00022  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00023  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
00024  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00025  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00026  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00027  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00028  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00029  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  */
00032 
00033 #ifndef _SIRIKATA_MESSAGE_HPP_
00034 #define _SIRIKATA_MESSAGE_HPP_
00035 
00036 #include <sirikata/core/util/Platform.hpp>
00037 
00038 namespace Sirikata {
00039 
00040 typedef uint64 UniqueMessageID;
00041 
00042 template<typename PBJMessageType>
00043 std::string serializePBJMessage(const PBJMessageType& contents) {
00044     std::string payload;
00045     bool serialized_success = contents.SerializeToString(&payload);
00046     assert(serialized_success);
00047 
00048     return payload;
00049 }
00050 
00051 template<typename PBJMessageType>
00052 bool serializePBJMessage(std::string* payload, const PBJMessageType& contents) {
00053     return contents.SerializeToString(payload);
00054 }
00055 
00063 template<typename PBJMessageType, typename WireType>
00064 bool parsePBJMessage(PBJMessageType* contents, const WireType& wire, uint32 offset = 0, int32 length = -1) {
00065     assert(contents != NULL);
00066     uint32 rlen = (length == -1) ? (wire.size() - offset) : length;
00067     assert(offset + rlen <= wire.size()); // buffer overrun
00068     return contents->ParseFromArray((void*)&wire[offset], rlen);
00069 }
00070 
00071 
00072 #define MESSAGE_ID_SERVER_SHIFT 52
00073 #define MESSAGE_ID_SERVER_BITS 0xFFF0000000000000LL
00074 
00075 namespace {
00076 
00077 uint64 sIDSource = 0;
00078 
00079 uint64 GenerateUniqueID(const ServerID& origin) {
00080     uint64 id_src = sIDSource++;
00081     uint64 message_id_server_bits=MESSAGE_ID_SERVER_BITS;
00082     uint64 server_int = (uint64)origin;
00083     uint64 server_shifted = server_int << MESSAGE_ID_SERVER_SHIFT;
00084     assert( (server_shifted & ~message_id_server_bits) == 0 );
00085     return (server_shifted & message_id_server_bits) | (id_src & ~message_id_server_bits);
00086 }
00087 
00088 uint64 GenerateUniqueID(const ObjectHostID& origin) {
00089     return GenerateUniqueID(origin.id);
00090 }
00091 
00092 ServerID GetUniqueIDServerID(uint64 uid) {
00093     uint64 message_id_server_bits=MESSAGE_ID_SERVER_BITS;
00094     uint64 server_int = ( uid & message_id_server_bits ) >> MESSAGE_ID_SERVER_SHIFT;
00095     return (ServerID) server_int;
00096 }
00097 
00098 uint64 GetUniqueIDMessageID(uint64 uid) {
00099     uint64 message_id_server_bits=MESSAGE_ID_SERVER_BITS;
00100     return ( uid & ~message_id_server_bits );
00101 }
00102 
00103 }
00104 
00105 #define LOG_INVALID_MESSAGE(module, lvl, msg)                           \
00106     SILOG(module, lvl, "Error parsing message at " << __FILE__ << ":" << __LINE__ << " Contents: (" << msg.size() << " bytes)"); \
00107     for(int _i__ = 0; _i__ < (int)msg.size(); _i__++)                   \
00108         SILOG(module, lvl, "  " << (int)msg[_i__] )
00109 
00110 #define LOG_INVALID_MESSAGE_BUFFER(module, lvl, msg_begin, msg_size)    \
00111     SILOG(module, lvl, "Error parsing message at " << __FILE__ << ":" << __LINE__ << " Contents: (" << msg_size << " bytes)"); \
00112     for(int _i__ = 0; _i__ < (int)msg_size; _i__++)                     \
00113         SILOG(module, lvl, "  " << (int)msg_begin[_i__] )
00114 
00115 } // namespace Sirikata
00116 
00117 #endif //_SIRIKATA_MESSAGE_HPP_