1 /* 2 * common/PacketReader.hpp 3 * 4 * This file is part of Leges Motus, a networked, 2D shooter set in zero gravity. 5 * 6 * Copyright 2009-2010 Andrew Ayer, Nathan Partlan, Jeffrey Pfau 7 * 8 * Leges Motus is free and open source software. You may redistribute it and/or 9 * modify it under the terms of version 2, or (at your option) version 3, of the 10 * GNU General Public License (GPL), as published by the Free Software Foundation. 11 * 12 * Leges Motus is distributed in the hope that it will be useful, but WITHOUT ANY 13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 14 * PARTICULAR PURPOSE. See the full text of the GNU General Public License for 15 * further detail. 16 * 17 * For a full copy of the GNU General Public License, please see the COPYING file 18 * in the root of the source code tree. You may also retrieve a copy from 19 * <http://www.gnu.org/licenses/gpl-2.0.txt>, or request a copy by writing to the 20 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 21 * 02111-1307 USA 22 * 23 */ 24 25 #ifndef LM_COMMON_PACKETREADER_HPP 26 #define LM_COMMON_PACKETREADER_HPP 27 28 #include "network.hpp" 29 #include "PacketHeader.hpp" 30 #include "StringTokenizer.hpp" 31 #include <string> 32 #include <stdint.h> 33 #include <iosfwd> 34 #include <algorithm> 35 36 namespace LM { 37 class UDPPacket; 38 39 /* 40 * The packet reader provides a convenient inteface for reading fields from packets. 41 * You can access the packet type and packet ID at any time, 42 * and read fields sequentially from the packet using the >> operator. 43 * 44 * Example: 45 * PacketReader reader("4\f15123512\f5\fB\fCover me, I'm going for the gate!"); 46 * reader.packet_type(); // Would return 4 47 * reader.packet_id(); // Would return 15123512 48 * 49 * int sender_id; 50 * std::string recipient_id; 51 * std::string message_text; 52 * reader >> sender_id >> recipient_id >> message_text; 53 * 54 * // sender_id is now 5 55 * // recipient_id is now "B" 56 * // message_text is now "Cover me, I'm going for the gate!" 57 */ 58 59 class PacketReader : public StringTokenizer { 60 private: 61 PacketHeader m_header; 62 63 public: 64 // Construct a packet reader from the given raw packet data 65 explicit PacketReader(const char* packet_data, char separator =PACKET_FIELD_SEPARATOR); 66 explicit PacketReader(const UDPPacket& packet); 67 68 // Get the packet type and sequence NO at any time: packet_type() const69 uint32_t packet_type() const { return m_header.packet_type; } sequence_no() const70 uint64_t sequence_no() const { return m_header.sequence_no; } connection_id() const71 uint32_t connection_id() const { return m_header.connection_id; } 72 73 // Import operations from the base class: 74 using StringTokenizer::discard_next; 75 using StringTokenizer::get_rest; 76 using StringTokenizer::operator>>; 77 using StringTokenizer::has_more; 78 79 // To test whether there are any tokens left for processing operator !() const80 bool operator! () const { return !has_more(); } operator const void*() const81 operator const void* () const { return has_more() ? this : NULL; } 82 83 void swap(PacketReader& other); 84 }; 85 86 // Write the remaining un-processed raw packet data to an output stream: 87 std::ostream& operator<<(std::ostream& out, const PacketReader& packet_reader); 88 } 89 90 namespace std { swap(LM::PacketReader & x,LM::PacketReader & y)91 template<> inline void swap (LM::PacketReader& x, LM::PacketReader& y) { x.swap(y); } 92 } 93 94 #endif 95