//========================================================== // Trames.H // // Handling of network frames, with a try to optimize the // bandwidth usage. // // Note: this class was first designed to work on an intel, // which is little endian. I made it work on big endians by // converting data to and from the network. This is okay, // but I think there is a better solution which consists in // having the sender tag the frame with the byte order used // and the receiver make the conversion if necessary. // // ZNibbles // Vincent Mallet 1997, 1998 //=========================================================== // $Id: Trame.H,v 1.5 1999/05/09 22:58:39 vmallet Exp $ /* ZNibbles - a small multiplayer game * Copyright (C) 1997, 1998, 1999 Vincent Mallet - vmallet@enst.fr * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __H_TRAME__ #define __H_TRAME__ #include // some compilers consider char as unsigned by default. typedef signed char schar; // DEBUG_LOAD: pour essayer de tracer ce qu'on fait passer // sur le reseau, le nombre de trames, leur taille, // leur repartition... // #define DEBUG_LOAD 1 /** * Handling of network frames, with a try to optimize the * bandwidth usage. * *

* Note: this class was first designed to work on an intel, * which is little endian. I made it work on big endians by * converting data to and from the network. This is okay, * but I think there is a better solution which consists in * having the sender tag the frame with the byte order used * and the receiver make the conversion if necessary. * * @author Vincent Mallet */ class Trame { public: Trame(int bufsize = 1024); ~Trame(); void set_timeout(long milli); // set trame timeout (milliseconds) int send_to(int socket_number); // send trame to socket int receive_from(int socket_number); // receive trame from socket void reset(); // clear current trame void rewind(); // move pointer to beginning of trame int eot(); // End Of Trame? int size(); // size of current trame // peek/read functions unsigned char peek_byte(); unsigned char get_byte(); schar peek_char(); schar get_char(); short peek_short(); short get_short(); int peek_int(); int get_int(); long get_long(); char * get_string(); // write functions unsigned char put_byte(unsigned char val); schar put_char(schar val); short put_short(short val); int put_int(int val); long put_long(long val); char * put_string(char *s); void dump_left(); // dump trame bytes from current pos to eot private: schar * rbuf; // real buffer, bah un peu un hack schar * buf; // frame buffer int idx; // index of 'cursor' in the frame int buffersize; // allocated space size of buffer int cursize; // current size of actual data in frame unsigned long timeout_s; // timeout in seconds unsigned long timeout_m; // timeout in microseconds. ( #ifdef DEBUG_LOAD static unsigned long bytes_in; static unsigned long bytes_out; static unsigned long trames_in; static unsigned long trames_out; static unsigned long inf4; static unsigned long inf8; static unsigned long inf16; static unsigned long inf20; static unsigned long inf32; static unsigned long inf64; static unsigned long infelse; #endif // DEBUG_LOAD }; // class Trame //==================================== // inlined constructor and destructor //==================================== // Frame constructor inline Trame::Trame(int bufsize) // default=1024 (see above) : rbuf(new schar[bufsize]), buf(rbuf+2), idx(0), buffersize(bufsize), cursize(0), timeout_s(5), timeout_m(0) { } // Frame destructor inline Trame::~Trame() { delete[] rbuf; #ifdef DEBUG_TRACE cout << "~trame()\n"; #endif #ifdef DEBUG_LOAD cout << "[debug_load: Trames received: " << trames_in \ << " total: " << bytes_in << " bytes]" << endl; cout << "[debug_load: Trames sent : " << trames_out \ << " total: " << bytes_out << " bytes]" << endl; cout << "[debug_load:"; cout << " <=4=" << inf4; cout << " <=8=" << inf8; cout << " <=16=" << inf16; cout << " <=20=" << inf20; cout << " <=32=" << inf32; cout << " <=64=" << inf64; cout << " >64=" << infelse; cout << endl; #endif } //===================================== // Few inlined methods //===================================== inline int Trame::eot() { return idx >= cursize; } // End Of Trame? inline int Trame::size() { return cursize; } inline void Trame::reset() { idx = 0; cursize = 0; } inline void Trame::rewind() { idx = 0; } inline schar Trame::peek_char() { return (idx < cursize) ? *(buf + idx) : -1; } inline schar Trame::get_char() { return (idx < cursize) ? *(buf + idx++) : -1; } #endif // __H_TRAME__