1 /*
2  * common/PacketWriter.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_PACKETWRITER_HPP
26 #define LM_COMMON_PACKETWRITER_HPP
27 
28 #include <sstream>
29 #include <string>
30 #include <stdint.h>
31 #include <stddef.h>
32 #include "network.hpp"
33 #include "PacketHeader.hpp"
34 
35 /*
36  * The packet reader provides a convenient inteface for sequentially writing fields to packets.
37  * You construct it with a packet type, and then use the << operator to write fields of any type.
38  *
39  * Example:
40  * 	PacketWriter		packet(MESSAGE_PACKET);
41  * 	packet << this_player_id << recipient_player_id << message_text;
42  *
43  * 	packet.packet_data(); // Would return something like "5\fB\fCover me, I'm going for the gate!"
44  */
45 
46 namespace LM {
47 	class PacketWriter {
48 	private:
49 		// Packet header for this packet:
50 		PacketHeader		m_header;
51 
52 		// Raw packet data is written into this string stream:
53 		// Note: this does NOT include the values in the header - you have to write those to the raw packet yourself
54 		std::ostringstream	m_out;
55 
56 	public:
57 		explicit PacketWriter(uint32_t packet_type);
58 
59 		// Getters
get_header() const60 		const PacketHeader&	get_header () const { return m_header; }
packet_type() const61 		uint32_t		packet_type() const { return m_header.packet_type; }
sequence_no() const62 		uint64_t		sequence_no() const { return m_header.sequence_no; }
connection_id() const63 		uint32_t		connection_id() const { return m_header.connection_id; }
64 
65 		// Get the raw packet data:
packet_data() const66 		std::string		packet_data() const { return m_out.str(); }
67 
68 		// Write a field into the packet:
operator <<(const T & obj)69 		template<class T> PacketWriter& operator<<(const T& obj) {
70 			m_out << PACKET_FIELD_SEPARATOR << obj;
71 			return *this;
72 		}
73 
74 	};
75 }
76 
77 #endif
78