Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | Related Pages | Examples

frameworkpacket.cpp

00001 /***************************************************************************
00002  * The contents of this file are subject to the Mozilla Public             *
00003  * License Version 1.1 (the "License"); you may not use this file          *
00004  * except in compliance with the License. You may obtain a copy of         *
00005  * the License at http://www.mozilla.org/MPL/                              *
00006  *                                                                         *
00007  * Software distributed under the License is distributed on an "AS         *
00008  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or              *
00009  * implied. See the License for the specific language governing            *
00010  * rights and limitations under the License.                               *
00011  *                                                                         *
00012  * The Original Code is Game Network Framework (GaNeF).                    *
00013  *                                                                         *
00014  * The Initial Developers of the Original Code are                         *
00015  * Lars Langer and Emanuel Greisen                                         *
00016  * Copyright (C) 2005. Lars Langer & Emanuel Greisen                       *
00017  * All Rights Reserved.                                                    *
00018  *                                                                         *
00019  * Contributor(s):                                                         *
00020  *   none yet....                                                          *
00021  *                                                                         *
00022  ***************************************************************************/
00023 #include "frameworkpacket.h"
00024 
00025 #include <iostream>
00026 
00027 #include "../server/serverdata.h"
00028 #include "../client/clientdata.h"
00029 
00030 
00031 FrameworkPacket::FrameworkPacket(
00032                unsigned int receiver,
00033                unsigned char type,
00034                unsigned char priority,
00035                unsigned int bodysize,
00036                bool reliable)
00037    : realsize(sizeof(Header)+bodysize),
00038    state(STATE_NEW),
00039    packet_ready_to_transmit(false)
00040 {
00041    data = new char[realsize];
00042 
00043    // set header data
00044    header = (Header *)data;
00045    header->reliable = reliable ? 1 : 0;
00046    header->type = type;
00047    header->priority = priority;
00048    header->receiver = receiver;
00049    header->packet_seq_number = 0;
00050 
00051    // update position
00052    resetPosition();
00053 }
00054 
00055 
00056 
00057 FrameworkPacket::FrameworkPacket( char * srcdata, unsigned int size )
00058    : realsize(size),
00059    state(STATE_RECEIVED),
00060    packet_ready_to_transmit(false)
00061 {
00062    // allocate memory
00063    data = new char[size];
00064 
00065    // copy data
00066    memcpy(data, srcdata, size);
00067 
00068    // set header
00069    header = (Header *)data;
00070    header->receiver  = ntohl(header->receiver);
00071    header->packet_seq_number = ntohl(header->packet_seq_number);
00072 
00073    // update position
00074    resetPosition();
00075 }
00076 
00077 
00078 
00079 FrameworkPacket::~FrameworkPacket()
00080 {
00081    //std::cout << "FrameworkPacket:destructor(" << *this << ")\n";
00082    if(data)
00083    {
00084       char * tmp = data;
00085       header = 0;
00086       data = 0;
00087       delete[] tmp;
00088    }
00089 }
00090 
00091 void FrameworkPacket::before_read_check( unsigned int s )
00092 {
00093    if(!isIncomming())
00094       throw new PacketError("Reading from outgoing packet is not allowed");
00095    if(pos+s > realsize)
00096       throw new PacketError("Reading beyond packet size is not possible");
00097 }
00098 
00099 void FrameworkPacket::before_write_check( unsigned int wanted_s )
00100 {
00101    unsigned int s = wanted_s;
00102    if(isIncomming())
00103       throw new PacketError("Writing to incomming packet is not allowed");
00104    // Space enough ?
00105    if(pos+s < realsize)
00106       return;
00107 
00108    // Make sure we expand enough
00109    if(s < MIN_EXPAND_BODY_SIZE)
00110       s = MIN_EXPAND_BODY_SIZE;
00111 
00112    //std::cout << "expand from: " << realsize << " to " << (realsize + s) << std::endl;
00113    if(realsize + s > MAX_PACKET_SIZE)
00114       s = MAX_PACKET_SIZE - realsize;
00115    if(s == 0)
00116    {
00117       std::cerr << "realsize:" << realsize << "\ns:" << s << "\nMAX_PACKET_SIZE:" << MAX_PACKET_SIZE << "\nwanted_s:" << wanted_s << std::endl;
00118       throw new PacketError("Expand to size beyond max packet size: MAX_PACKET_SIZE is not allowed, due to limitations of UDP packets");
00119    }
00120 
00121    // allocate bigger place
00122    char * n = new char[realsize + s];
00123    // copy data
00124    memcpy(n, data, realsize);
00125 
00126    // delete old data
00127    delete[] data;
00128 
00129    // Increase size
00130    realsize += s;
00131 
00132    // Set data to point at new data
00133    data = n;
00134 
00135    // set header
00136    header = (Header *)data;
00137 }
00138 
00139 std::string FrameworkPacket::readString( )
00140 {
00141    before_read_check(1); // This is odd, but we don't know how long the string is.
00142 
00143    std::string str((char *)(&data[pos]));
00144    pos += str.size() + 1;
00145    return str;
00146 }
00147 
00148 void FrameworkPacket::writeString( const std::string & s )
00149 {
00150    before_write_check(s.size()+1);
00151 
00152    const char *cstr = s.c_str();
00153 
00154    for(int i = 0; i < s.size(); i++)
00155    {
00156       *((char*)&data[pos]) = cstr[i];
00157       pos++;
00158    }
00159    *((char*)&data[pos]) = '\0';
00160    pos++;
00161 }
00162 
00163 
00164 void FrameworkPacket::appendData( FrameworkPacket * packet )
00165 {
00166    //void *  memcpy ( void * dest, const void * src, size_t num );
00167    //OPTIMIZE: we could expand to make room for the data, and then make a memcpy(...) call.
00168    unsigned int datasize = packet->getSize() - sizeof(Header);
00169    if(datasize > 0)
00170    {
00171       before_write_check(datasize);
00172       char * tmpsrcdata = &packet->getData()[sizeof(Header)];
00173       char * tmpdstdata = &getData()[pos];
00174       memcpy(tmpdstdata, tmpsrcdata, datasize);
00175       pos += datasize;
00176    }
00177 }
00178 
00179 void FrameworkPacket::writeData( const void * srcdata, unsigned int bytes )
00180 {
00181    before_write_check(bytes);
00182    char * tmpdstdata = &getData()[pos];
00183    memcpy(tmpdstdata, srcdata, bytes);
00184    pos += bytes;
00185 }
00186 
00187 void FrameworkPacket::readData( void * dstbuff, unsigned int bytes )
00188 {
00189    before_read_check(bytes);
00190    char * tmpsrcdata = &getData()[pos];
00191    memcpy(dstbuff, tmpsrcdata, bytes);
00192    pos += bytes;
00193 }
00194 
00195 
00196 
00197 void FrameworkPacket::writePacket( FrameworkPacket * packet )
00198 {
00199    // First make sure the packet is ready
00200    packet->makeSendReady();
00201 
00202    // Then copy all the data to this packet
00203    before_write_check(packet->getSize());
00204    char * tmpdstdata = &getData()[pos];
00205    memcpy(tmpdstdata, packet->getData(), packet->getSize());
00206    pos += packet->getSize();
00207 }
00208 
00209 
00210 void FrameworkPacket::setPeerFromPacket( FrameworkPacket * packet )
00211 {
00212    if(!packet->isIncomming())
00213       throw new PacketError("Cannot reply an outgoing packet");
00214    peer = packet->peer;
00215    peer.initialized = true;
00216 }
00217 
00218 
00219 void FrameworkPacket::copyData( FrameworkPacket * packet )
00220 {
00221    // Check that size, and everything is identical
00222    if(packet->data != data)
00223       throw new PacketError("You may only use this copy-method if the packets are duplicates");
00224 
00225    // Allocate and copy data
00226    data = new char[realsize];
00227    memcpy(data, packet->data, pos);
00228    header = (Header *)data;
00229 }
00230 
00231 void FrameworkPacket::setStateQueued( )
00232 {
00233    switch(state)
00234    {
00235    // Sending side:
00236    case STATE_NEW: //        = 1000,
00237    case STATE_SENT:
00238       state = STATE_QUEUED_OUT;
00239       break;
00240 
00241    // Receiving side:
00242    case STATE_RECEIVED: //   = 2000,
00243       state = STATE_QUEUED_IN;
00244       break;
00245    default:
00246       std::cout << "You may only enqueue packets with states: STATE_NEW, STATE_RECEIVED and STATE_SENT(this: " <<state<<std::endl;
00247       throw new PacketError("You may only enqueue packets with states: STATE_NEW, STATE_RECEIVED and STATE_SENT");
00248       break;
00249    }
00250 }
00251 
00252 void FrameworkPacket::setStateSent( )
00253 {
00254    switch(state)
00255    {
00256    case STATE_NEW: //        = 1000,
00257    case STATE_QUEUED_OUT:
00258       state = STATE_SENT;
00259       break;
00260    default:
00261       throw new PacketError("You may only send packets with states: STATE_NEW and STATE_QUEUED_OUT");
00262       break;
00263    }
00264 }
00265 
00266 void FrameworkPacket::setStateAborted( )
00267 {
00268    if(state == STATE_QUEUED_OUT)
00269    {
00270       state == STATE_ABORTED;
00271    }
00272    else
00273    {
00274       throw new PacketError("You may only abort packets with state: STATE_QUEUED_OUT");
00275    }
00276 }
00277 
00278 std::ostream & operator <<( std::ostream & o, FrameworkPacket & packet )
00279 {
00280    o << "[Packet]";
00281    o << "typ:" << (unsigned short)packet.getType()<<",";
00282    o << "rec:" << packet.getReceiver() << ",";
00283    o << "pri:" << (unsigned short)packet.getPriority() << ",";
00284    if(packet.isReliable())
00285    {
00286       o << "rel-seq:" << packet.getSequenceNumber() << ",";
00287    }
00288    else
00289    {
00290       o << "unrel-seq:" << packet.getSequenceNumber() << ",";
00291    }
00292    o << "size:" << packet.getSize() << ",";
00293    o << (packet.isIncomming() ? "From:" : "To:");
00294    o << static_cast<int>(packet.peer.host[0]) << ".";
00295    o << static_cast<int>(packet.peer.host[1]) << ".";
00296    o << static_cast<int>(packet.peer.host[2]) << ".";
00297    o << static_cast<int>(packet.peer.host[3]);
00298 o << ":" << packet.peer.port << "[/Packet]";
00299    return o;
00300 }
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308 
00309 
00310 

Generated on Mon Feb 6 12:24:50 2006 for Ganef by  doxygen 1.4.4