Ver Fonte

Merge branch 'master' of https://github.com/taylor001/crown

Conflicts:
	src/os/OS.h
Daniele Bartolini há 13 anos atrás
pai
commit
a3c733f9fe
4 ficheiros alterados com 619 adições e 5 exclusões
  1. 10 0
      src/CMakeLists.txt
  2. 500 0
      src/network/Message.cpp
  3. 101 0
      src/network/Message.h
  4. 8 5
      src/os/OS.h

+ 10 - 0
src/CMakeLists.txt

@@ -236,6 +236,14 @@ set (WIN_SRC
 #	os/win/WinUDPSocket.cpp
 #	os/win/WinUDPSocket.cpp
 )
 )
 
 
+set (NETWORK_SRC
+	network/Message.h
+)
+
+set (NETWORK_HEADERS
+	network/Message.cpp
+)
+
 set (SOURCES
 set (SOURCES
 	${SRC}
 	${SRC}
 	${INCLUDES}
 	${INCLUDES}
@@ -261,6 +269,8 @@ set (SOURCES
 	${LINUX_SRC}
 	${LINUX_SRC}
 	${LINUX_HEADERS}
 	${LINUX_HEADERS}
 	${WIN_SRC}
 	${WIN_SRC}
+	${NETWORK_SRC}
+	${NETWORK_HEADERS}
 
 
 	${GL_SRC}
 	${GL_SRC}
 	${GL_HEADERS}
 	${GL_HEADERS}

+ 500 - 0
src/network/Message.cpp

@@ -0,0 +1,500 @@
+#include <cassert>
+
+#include "Message.h"
+
+namespace crown
+{
+  
+namespace network
+{
+  
+Message::Message() : w_data(NULL), r_data(NULL), max_size(0), cur_size(0), write_bit(0), read_count(0), read_bit(0)
+{
+  
+}
+
+Message::~Message()
+{
+  
+}
+
+uchar* Message::get_byte_space(int len)
+{
+	byte *ptr;
+
+	if (!w_data) 
+	{
+		os::printf( "idBitMsg::GetByteSpace: cannot write to message" );
+	}
+
+	// round up to the next byte
+	write_byte_align();
+
+	// check for overflow
+	check_overflow(len << 3);
+
+	// allocate space
+	ptr = w_data + cur_size;
+	cur_size += len;
+	
+	return ptr;  
+}
+
+bool Message::check_overflow(int num_bits)
+{
+	assert( num_bits >= 0 );
+	
+	if (num_bits > get_remaining_write_bits()) 
+	{
+		if (num_bits > (max_size << 3)) 
+		{
+			os::printf(" %i bits is > full message size", num_bits );
+		}
+		os::printf("overflow\n");
+		begin_writing();
+		overflowed = true;
+		return true;
+	}
+	return false;  
+}
+
+void Message::init(uchar *data, int len)
+{
+	w_data = data;
+	r_data = data;
+	max_size = len;
+}
+
+void Message::init(const uchar *data, int len)
+{
+	w_data = NULL;
+	r_data = data;
+	max_size = len;
+}
+
+uchar* Message::get_data()
+{
+	return w_data;
+}
+
+const uchar* Message::get_data() const
+{
+	return r_data;
+}
+
+int Message::get_max_size() const
+{
+	return max_size;
+}
+
+bool Message::is_overflowed()
+{
+	return overflowed;
+}
+
+
+int Message::get_size() const
+{
+	return cur_size;
+}
+
+void Message::set_size(int size)
+{
+	if (size > max_size)
+	{
+		cur_size = max_size;
+	}
+	else
+	{
+		cur_size = size;
+	}
+}
+
+int Message::get_write_bit() const
+{
+	return write_bit;
+}
+
+void Message::set_write_bit(int bit)
+{
+	write_bit = bit & 7;
+	if (write_bit) 
+	{
+		w_data[cur_size-1] &= (1 << write_bit) - 1;
+	}
+}
+
+int Message::get_num_bits_written() const
+{
+	return ((cur_size << 3) - ((8 - write_bit) & 7));  
+}
+  
+int Message::get_remaining_write_bits() const
+{
+	return (max_size << 3) - get_num_bits_written(); 
+}
+
+void Message::save_write_state(int& s,int& b) const
+{
+	s = cur_size;
+	b = write_bit;
+}
+
+void Message::restore_write_state(int s,int b)
+{
+	cur_size = s;
+	write_bit = b & 7;
+	
+	if (write_bit) 
+	{
+		w_data[cur_size-1] &= (1 << write_bit) - 1;
+	}  
+}
+
+int Message::get_read_count() const
+{
+	return read_count;
+}
+
+void Message::set_read_count(int bytes)
+{
+	read_count = bytes;
+}
+
+int Message::get_read_bit() const
+{
+	return read_bit;
+}
+
+void Message::set_read_bit(int bit)
+{
+	read_bit = bit & 7;
+}
+
+int Message::get_num_bits_read() const
+{
+	return ((read_count << 3) - ((8 - read_bit) & 7));  
+}
+
+int Message::get_remaining_read_bits() const
+{
+	return (cur_size << 3) - get_num_bits_read();
+}
+
+void Message::save_read_state(int& c, int& b) const
+{
+	c = read_count;
+	b = read_bit;
+}
+
+void Message::restore_read_state(int c, int b)
+{
+	read_count = c;
+	read_bit = b & 7;
+}
+
+void Message::begin_writing()
+{
+	cur_size = 0;
+	write_bit = 0;
+	overflowed = false;
+}
+
+int Message::get_remaining_space() const
+{
+	return max_size - cur_size;
+}
+
+void Message::write_byte_align()
+{
+	write_bit = 0;
+}
+
+void Message::write_bits(int value, int num_bits)
+{
+	int		put;
+	int		fraction;
+
+	// check if w_data is void
+	if (!w_data) 
+	{
+		os::printf( "cannot write to message" );
+	}
+	// check if the number of bits is valid
+	if (num_bits == 0 || num_bits < -31 || num_bits > 32) 
+	{
+		os::printf( "bad numBits %i", num_bits);
+	}
+
+	// check for value overflows
+	// this should be an error really, as it can go unnoticed and cause either bandwidth or corrupted data transmitted
+	if (num_bits != 32) 
+	{
+		if (num_bits > 0) 
+		{
+			if (value > (1 << num_bits) - 1) 
+			{
+				os::printf( "value overflow %d %d", value, num_bits );
+			} 
+			else if (value < 0) 
+			{
+				os::printf( "value overflow %d %d", value, num_bits );
+			}
+		} 
+		else 
+		{
+			int r = 1 << (-1 - num_bits);
+			if (value > r - 1) 
+			{
+				os::printf( "value overflow %d %d", value, num_bits );
+			} 
+			else if (value < -r) 
+			{
+				os::printf( "value overflow %d %d", value, num_bits );
+			}
+		}
+	}
+
+	// Change sign if it is negative
+	if (num_bits < 0 ) 
+	{
+		num_bits = -num_bits;
+	}
+
+	// check for msg overflow
+	if (check_overflow(num_bits)) 
+	{
+		return;	
+	}
+
+	// write the bits
+	while(num_bits) 
+	{
+		if (write_bit == 0) 
+		{
+			w_data[cur_size] = 0;
+			cur_size++;
+		}
+		
+		put = 8 - write_bit;
+		if (put > num_bits) 
+		{
+			put = num_bits;
+		}
+		
+		fraction = value & ((1 << put) - 1);
+		w_data[cur_size - 1] |= fraction << write_bit;
+		num_bits -= put;
+		value >>= put;
+		write_bit = (write_bit + put) & 7;
+	}
+}
+
+void Message::write_char(int c)
+{
+	write_bits(c, -8);
+}
+
+void Message::write_uchar(int c)
+{
+	write_bits(c, 8);  
+}
+
+void Message::write_short(int c)
+{
+	write_bits(c, -16);  
+}
+
+void Message::write_ushort(int c)
+{
+	write_bits(c, 16);
+}
+
+void Message::write_long(int c)
+{
+	write_bits(c, 32);
+}
+
+void Message::write_real(real f)
+{
+	write_bits(*reinterpret_cast<int *>(&f), 32);  
+}
+
+void Message::write_real(real f, int exp_bits, int mant_bits)
+{
+	//TODO:need to implement floatToBits function
+}
+
+void Message::write_angle(real f)
+{
+	// needs to be implemented
+}
+
+void Message::write_vec3(const Vec3& v, int num_bits)
+{
+	
+}
+
+void Message::write_string(const char* s, int max_len, bool make7Bit)
+{
+  
+}
+
+void Message::write_data(const void* data, int length)
+{
+
+}
+
+void Message::write_ipv4addr(const os::IPv4Address addr)
+{
+  
+}
+
+void Message::begin_reading() const
+{
+  
+}
+
+int Message::get_remaing_data() const
+{
+  
+}
+
+void Message::read_byte_align() const
+{
+  
+}
+
+int Message::read_bits(int num_bits) const
+{
+	int		value;
+	int		value_bits;
+	int		get;
+	int		fraction;
+	bool	sgn;
+
+	if ( !r_data ) {
+		os::printf("cannot read from message");
+	}
+
+	// check if the number of bits is valid
+	if ( num_bits == 0 || num_bits < -31 || num_bits > 32 ) {
+		os::printf("bad number of bits %i", num_bits );
+	}
+
+	value = 0;
+	value_bits = 0;
+
+	// change sign if it is negative
+	if (num_bits < 0) 
+	{
+		num_bits = -num_bits;
+		sgn = true;
+	}
+	else 
+	{
+		sgn = false;
+	}
+
+	// check for overflow
+	if (num_bits > get_remaining_read_bits()) 
+	{
+		return -1;
+	}
+
+	while (value_bits < num_bits ) 
+	{
+		if (read_bit == 0) 
+		{
+			read_count++;
+		}
+		
+		get = 8 - read_bit;
+		
+		if (get > (num_bits - value_bits)) 
+		{
+			get = num_bits - value_bits;
+		}
+		
+		fraction = r_data[read_count - 1];
+		fraction >>= read_bit;
+		fraction &= (1 << get) - 1;
+		value |= fraction << value_bits;
+
+		value_bits += get;
+		read_bit = (read_bit + get) & 7;
+	}
+
+	if (sgn) 
+	{
+		if (value & (1 << (num_bits - 1))) 
+		{
+			value |= -1 ^ (( 1 << num_bits) - 1);
+		}
+	}
+
+	return value;  
+}
+
+int Message::read_char() const
+{
+}
+
+int Message::read_uchar() const
+{
+}
+
+int Message::read_short() const
+{
+  
+}
+
+int Message::read_ushort() const
+{
+  
+}
+
+int Message::read_long() const
+{
+  
+}
+
+real Message::read_real() const
+{
+  
+}
+
+real Message::read_real(int exp_bits, int mant_bits) const
+{
+  
+}
+
+real Message::read_angle() const
+{
+  
+}
+
+Vec3 Message::read_vec3(int num_bits) const
+{
+  
+}
+
+int Message::read_string(char* buffer, int buffer_size) const
+{
+  
+}
+
+int Message::read_data(void* data, int length) const
+{
+  
+}
+
+void Message::read_ipv4addr(os::IPv4Address* addr) const
+{
+  
+}
+
+// static int		vec3_to_bits(const Vec3& v, int num_bits);
+// static Vec3		bits_to_vec3(int bits, int num_bits);
+}
+}

+ 101 - 0
src/network/Message.h

@@ -0,0 +1,101 @@
+#pragma once
+
+#include "Types.h"
+#include "OS.h"
+#include "Vec3.h"
+
+namespace crown
+{
+namespace network
+{
+	/**
+	* bit-packet reliable message
+	*/
+	
+	class Message
+	{
+						Message();
+						~Message();
+
+		void			init(uchar *data, int len);
+		void			init(const uchar *data, int len);
+		uchar*			get_data();								// get data for writing
+		const uchar*	get_data() const;						// get data for reading
+		int				get_max_size() const;					// get the maximum message size
+		bool 			is_overflowed();						// get overflowed flag
+
+
+		int				get_size() const;						// size of the message in bytes
+		void			set_size(int size);						// set the message size
+		int				get_write_bit() const;					// get current write bit
+		void			set_write_bit(int bit);					// set current write bit
+		int				get_num_bits_written() const;			// returns number of bits written
+		int				get_remaining_write_bits() const;		// space left in bits for writing
+		void			save_write_state(int& s,int& b) const;	// save the write state
+		void			restore_write_state(int s,int b);		// restore the write state
+
+		int				get_read_count() const;					// bytes read so far
+		void			set_read_count(int bytes);				// set the number of bytes and bits read
+		int				get_read_bit() const;					// get current read bit
+		void			set_read_bit(int bit);					// set current read bit
+		int				get_num_bits_read() const;				// returns number of bits read
+		int				get_remaining_read_bits() const;		// number of bits left to read
+		void			save_read_state(int& c, int& b) const;	// save the read state
+		void			restore_read_state(int c, int b);		// restore the read state
+
+		void			begin_writing();						// begin writing
+		int				get_remaining_space() const;			// space left in bytes
+		void			write_byte_align();						// write up to the next byte boundary
+		void			write_bits(int value, int num_bits);	// write the specified number of bits
+		void			write_char(int c);
+		void			write_uchar(int c);
+		void			write_short(int c);
+		void			write_ushort(int c);
+		void			write_long(int c);
+		void			write_real(real f);
+		void			write_real(real f, int exp_bits, int mant_bits);
+		void			write_angle(real f);
+		void			write_vec3(const Vec3& v, int num_bits);
+		void			write_string(const char* s, int max_len = -1, bool make7Bit = true);
+		void			write_data(const void* data, int length);
+		void			write_ipv4addr(const os::IPv4Address addr);
+
+		void			begin_reading() const;					// begin reading.
+		int				get_remaing_data() const;				// number of bytes left to read
+		void			read_byte_align() const;				// read up to the next byte boundary
+		int				read_bits(int num_bits) const;			// read the specified number of bits
+		int				read_char() const;
+		int				read_uchar() const;
+		int				read_short() const;
+		int				read_ushort() const;
+		int				read_long() const;
+		real			read_real() const;
+		real			read_real(int exp_bits, int mant_bits) const;
+		real			read_angle() const;
+		Vec3			read_vec3(int num_bits) const;
+		int				read_string(char* buffer, int buffer_size) const;
+		int				read_data(void* data, int length) const;
+		void			read_ipv4addr(os::IPv4Address* addr) const;
+
+// 		static int		vec3_to_bits(const Vec3& v, int num_bits);
+// 		static Vec3		bits_to_vec3(int bits, int num_bits);
+
+	private:
+	  
+		uchar*			w_data;			// pointer to data for writing
+		const uchar*	r_data;			// pointer to data for reading
+		int				max_size;			// maximum size of message in bytes
+		int				cur_size;			// current size of message in bytes
+		int				write_bit;			// number of bits written to the last written byte
+		mutable int		read_count;			// number of bytes read so far
+		mutable int		read_bit;			// number of bits read from the last read byte
+		bool 			overflowed;			// overflow flag
+
+	private:
+	  
+		uchar*			get_byte_space(int len);
+		bool 			check_overflow(int num_bits);			// check buffer overflow	
+  };
+
+}
+}

+ 8 - 5
src/os/OS.h

@@ -159,6 +159,8 @@ struct IPv4Address
 	}
 	}
 };
 };
 
 
+//-----------------------------------------------------------------------------
+
 class UDPSocket
 class UDPSocket
 {
 {
 	public:
 	public:
@@ -182,15 +184,16 @@ class UDPSocket
 					// Socket descriptor
 					// Socket descriptor
 		int 		m_socket;  
 		int 		m_socket;  
 };
 };
+//-----------------------------------------------------------------------------
 
 
 class TCPSocket
 class TCPSocket
 {
 {
 	public:
 	public:
 
 
-					// Constructor
-					TCPSocket();
-					// Destructor
-					~TCPSocket();
+				// Constructor
+				TCPSocket();
+				// Destructor
+				~TCPSocket();
 					// Open connection (server side)
 					// Open connection (server side)
 		bool 		open(uint16_t port);
 		bool 		open(uint16_t port);
 					// Connect (client side)
 					// Connect (client side)
@@ -223,4 +226,4 @@ class TCPSocket
 
 
 } // namespace os
 } // namespace os
 
 
-} // namespace crown
+} // namespace crown