NLNET::CMessageRecorder Class Reference

#include <message_recorder.h>


Detailed Description

Message recorder. The service performs sends normally. They are intercepted and the recorder plays the receives back. No communication with other hosts. Warning: it works only with messages as plain text.
Author:
Olivier Cado

Nevrax France

Date:
2001

Definition at line 116 of file message_recorder.h.

Public Member Functions

TNetworkEvent checkNextOne (sint64 updatecounter)
 CMessageRecorder ()
 Constructor.

void recordNext (sint64 updatecounter, TNetworkEvent event, TSockId sockid, CMessage &message)
 Add a record.

TNetworkEvent replayConnectionAttempt (const CInetAddress &addr)
 Get the first stored connection attempt corresponding to addr.

void replayNextDataAvailable (sint64 updatecounter)
 Push the received blocks for this counter into the receive queue.

bool startRecord (const std::string &filename, bool recordall=true)
 Start recording.

bool startReplay (const std::string &filename)
 Start replaying.

void stopRecord ()
 Stop recording.

void stopReplay ()
 Stop playback.

 ~CMessageRecorder ()
 Destructor.


Data Fields

std::queue< NLNET::TMessageRecordReceivedMessages
 Receive queue (corresponding to one update count). Use empty(), front(), pop().


Protected Member Functions

bool getNext (TMessageRecord &record, sint64 updatecounter)
 Get the next record (from the preloaded records, or from the file).

bool loadNext (TMessageRecord &record)
 Load the next record from the file (throws EStreamOverflow).


Private Attributes

std::deque< TMessageRecord_ConnectionAttempts
std::fstream _File
std::string _Filename
std::deque< TMessageRecord_PreloadedRecords
bool _RecordAll


Constructor & Destructor Documentation

NLNET::CMessageRecorder::CMessageRecorder  ) 
 

Constructor.

Definition at line 79 of file message_recorder.cpp.

References nlerror.

00079                                    : _RecordAll(true)
00080 {
00081 #ifndef MESSAGES_PLAIN_TEXT
00082         nlerror( "The message recorder works only with plain text messages. Please #define MESSAGES_PLAIN_TEXT" );
00083 #endif
00084 }

NLNET::CMessageRecorder::~CMessageRecorder  ) 
 

Destructor.

Definition at line 90 of file message_recorder.cpp.

References nldebug, stopRecord(), and stopReplay().

00091 {
00092         if ( _Filename != "" )
00093         {
00094                 nldebug( "MR:%s: End of recording", _Filename.c_str() );
00095         }
00096         stopRecord();
00097         stopReplay();
00098 }


Member Function Documentation

TNetworkEvent NLNET::CMessageRecorder::checkNextOne sint64  updatecounter  ) 
 

Returns the event type if the counter of the next event is updatecounter, and skip it; otherwise return Error.

Definition at line 308 of file message_recorder.cpp.

References NLNET::Error, NLNET::TMessageRecord::Event, NLNET::EventToString(), getNext(), NL_I64, nldebug, sint64, and NLNET::TNetworkEvent.

00309 {
00310         TMessageRecord record;
00311         if ( getNext( record, updatecounter ) )
00312         {
00313                 nldebug( "MR: Check next one: %s at update %"NL_I64"u", EventToString(record.Event).c_str(), updatecounter );
00314                 return record.Event;
00315         }
00316         else
00317         {
00318                 return Error;
00319         }
00320 }

bool NLNET::CMessageRecorder::getNext TMessageRecord record,
sint64  updatecounter
[protected]
 

Get the next record (from the preloaded records, or from the file).

Definition at line 230 of file message_recorder.cpp.

References _PreloadedRecords, loadNext(), nlassert, and sint64.

Referenced by checkNextOne(), and replayNextDataAvailable().

00231 {
00232         if ( ! _PreloadedRecords.empty() )
00233         {
00234                 if ( _PreloadedRecords.front().UpdateCounter == updatecounter )
00235                 {
00236                         // The requested record is in the preload
00237                         record = _PreloadedRecords.front();
00238                         _PreloadedRecords.pop_front();
00239                         return true;
00240                 }
00241                 else
00242                 {
00243                         // The requested record is not in the file
00244                         nlassert( updatecounter < _PreloadedRecords.front().UpdateCounter ); // not >
00245                         return false;
00246                 }
00247         }
00248         else
00249         {
00250                 if ( loadNext( record ) )
00251                 {
00252                         if ( record.UpdateCounter == updatecounter )
00253                         {
00254                                 // The requested record has been loaded
00255                                 return true;
00256                         }
00257                         else
00258                         {
00259                                 // The next loaded record is a new one
00260                                 nlassert( updatecounter < record.UpdateCounter ); // not >
00261                                 _PreloadedRecords.push_back( record ); // when we read one too far
00262                                 return false;
00263                         }
00264                 }
00265                 else
00266                 {
00267                         return false;
00268                 }
00269         }
00270 }

bool NLNET::CMessageRecorder::loadNext TMessageRecord record  )  [protected]
 

Load the next record from the file (throws EStreamOverflow).

Definition at line 198 of file message_recorder.cpp.

References _File, len, nlassert, nldebug, nlstop, NLNET::TMessageRecord::serial(), and uint32.

Referenced by getNext(), and replayConnectionAttempt().

00199 {
00200         // WARNING!!! This features doesn't work anymore becaues bufferAsVector() is not available with new CMemStream
00201         nlstop;
00202         return false;
00203 
00204         nlassert( _File.is_open() );
00205 
00206         // Dump from file
00207         CMemStream stream ( true, true );
00208         uint32 len;
00209         char c;
00210         _File >> c; // skip "* ";
00211         _File >> (int&)len;
00212         _File.ignore(); // skip delimiter
00213         if ( ! _File.fail() )
00214         {
00215                 _File.get( (char*)stream.bufferToFill( len+1 ), len+1, '\0' );
00216                 //stream.bufferAsVector().resize( len ); // cut end of cstring
00217                 nldebug( "MR:%s: Reading [%s]", _Filename.c_str(), stream.buffer() );
00218 
00219                 // Serial from stream
00220                 record.serial( stream ); // may throw EStreamOverflow if _File.fail()
00221         }
00222 
00223         return ! _File.fail(); // retest
00224 }

void NLNET::CMessageRecorder::recordNext sint64  updatecounter,
TNetworkEvent  event,
TSockId  sockid,
CMessage message
 

Add a record.

Todo:
cado: Does a silent Access Violation

Definition at line 141 of file message_recorder.cpp.

References _File, _RecordAll, len, nlassert, nldebug, NLNET::Sending, NLNET::TMessageRecord::serial(), sint64, and NLNET::TSockId.

00142 {
00143         nlassert( _File.is_open() );
00144 
00145         if ( (_RecordAll) || (event != Sending) )
00146         {
00147                 // Serial to stream
00148                 TMessageRecord rec ( event, sockid, message, updatecounter /*CTime::getLocalTime()*/ );
00149                 CMemStream stream ( false, true );
00150                 rec.serial( stream );
00151                 char c = '\0';      // end of cstring
00152                 stream.serial( c ); // added to the stream for _File << (char*)stream.buffer()
00153 
00154                 // Dump to file
00155                 nldebug( "MR:%s: Recording [%s]", _Filename.c_str(), stream.buffer() );
00156                 int len = (int)(stream.length()-2); // not the null character (and its separator) at the end of the buffer
00157                 _File << "* ";
00158                 _File <<  len; // if we put the expression directly, it makes an access violation ! Weird.
00159                 _File << " ";
00160                 _File << (char*)stream.buffer() << endl; 
00161         }
00162 }

TNetworkEvent NLNET::CMessageRecorder::replayConnectionAttempt const CInetAddress addr  ) 
 

Get the first stored connection attempt corresponding to addr.

Definition at line 326 of file message_recorder.cpp.

References _ConnectionAttempts, _PreloadedRecords, addr, NLNET::Connecting, NLNET::ConnFailing, NLNET::Error, NLNET::TMessageRecord::Event, loadNext(), NLNET::TMessageRecord::Message, NL_I64, nldebug, nlstop, NLMISC::CMemStream::serial(), NLNET::TNetworkEvent, and NLNET::TMessageRecord::UpdateCounter.

00327 {
00328         TNetworkEvent event;
00329         deque<TMessageRecord>::iterator ipr;
00330         
00331         if ( ! _ConnectionAttempts.empty() )
00332         {
00333                 // Search in the already processed connection attempts
00334                 for ( ipr=_ConnectionAttempts.begin(); ipr!=_ConnectionAttempts.end(); ++ipr )
00335                 {
00336                         CInetAddress stored_addr;
00337                         (*ipr).Message.serial( stored_addr );
00338                         if ( stored_addr == addr )
00339                         {
00340                                 // Found
00341                                 event = (*ipr).Event;
00342                                 nldebug( "MR: Connection attempt found at update %"NL_I64"u", (*ipr).UpdateCounter );
00343                                 _ConnectionAttempts.erase( ipr );
00344                                 return event;
00345                         }
00346                 }
00347         }
00348         
00349         // Seek in the preloaded records
00350         for ( ipr=_PreloadedRecords.begin(); ipr!=_PreloadedRecords.end(); ++ipr )
00351         {
00352                 event = (*ipr).Event;
00353                 if ( (event == Connecting) || (event == ConnFailing) )
00354                 {
00355                         CInetAddress stored_addr;
00356                         (*ipr).Message.serial( stored_addr );
00357                         if ( stored_addr == addr )
00358                         {
00359                                 // Found
00360                                 nldebug( "MR: Connection attempt found at update %"NL_I64"u", (*ipr).UpdateCounter );
00361                                 _PreloadedRecords.erase( ipr );
00362                                 return event;
00363                         }
00364                 }
00365         }
00366         if ( ipr==_PreloadedRecords.end() )
00367         {
00368                 // If not found, load next records until found !
00369                 TMessageRecord rec( true );
00370                 while ( loadNext( rec ) )
00371                 {
00372                         if ( ( rec.Event == Connecting ) || ( rec.Event == ConnFailing ) )
00373                         {
00374                                 CInetAddress stored_addr;
00375                                 rec.Message.serial( stored_addr );
00376                                 if ( stored_addr == addr )
00377                                 {
00378                                         // Found
00379                                         nldebug( "MR: Connection attempt found at update %"NL_I64"u", rec.UpdateCounter );
00380                                         return rec.Event;
00381                                 }
00382                                 else
00383                                 {
00384                                         _PreloadedRecords.push_back( rec );
00385                                 }
00386                         }
00387                         else
00388                         {
00389                                 _PreloadedRecords.push_back( rec );
00390                         }
00391                 }
00392                 // Not found
00393                 nldebug( "MR: Connection attempt not found" );          
00394                 return Error;
00395         }
00396         nlstop;
00397         return Error;
00398 }

void NLNET::CMessageRecorder::replayNextDataAvailable sint64  updatecounter  ) 
 

Push the received blocks for this counter into the receive queue.

Definition at line 276 of file message_recorder.cpp.

References _ConnectionAttempts, NLNET::Accepting, NLNET::Connecting, NLNET::ConnFailing, NLNET::Disconnecting, NLNET::TMessageRecord::Event, getNext(), nlstop, ReceivedMessages, NLNET::Receiving, NLNET::Sending, and sint64.

00277 {
00278         TMessageRecord rec( true ); // input message
00279 
00280         while ( getNext( rec, updatecounter ) )
00281         {
00282                 switch ( rec.Event )
00283                 {
00284                 case Receiving :
00285                 case Accepting :
00286                 case Disconnecting :
00287                         ReceivedMessages.push( rec );
00288                         break;
00289 
00290                 case Sending :
00291                         break;
00292 
00293                 case Connecting :
00294                 case ConnFailing :
00295                         _ConnectionAttempts.push_back( rec );
00296                         break;
00297                         
00298                 default :
00299                         nlstop;
00300                 }
00301         }
00302 }

bool NLNET::CMessageRecorder::startRecord const std::string &  filename,
bool  recordall = true
 

Start recording.

Definition at line 104 of file message_recorder.cpp.

References _File, _RecordAll, nldebug, and nlwarning.

00105 {
00106         _Filename = filename;
00107         _File.open( _Filename.c_str(), ios_base::out );
00108         _File << endl;
00109         _RecordAll = recordall;
00110         if ( _File.fail() )
00111         {
00112                 nlwarning( "MR: Record: Cannot open file %s", _Filename.c_str() );
00113                 return false;
00114         }
00115         else
00116         {
00117                 nldebug( "MR: Start recording into %s", _Filename.c_str() );
00118                 return true;
00119         }
00120 }

bool NLNET::CMessageRecorder::startReplay const std::string &  filename  ) 
 

Start replaying.

Definition at line 178 of file message_recorder.cpp.

References _File, nldebug, and nlerror.

00179 {
00180         _Filename = filename;
00181         _File.open( _Filename.c_str(), ios_base::in );
00182         if ( _File.fail() )
00183         {
00184                 nlerror( "MR: Replay: Cannot open file %s", _Filename.c_str() );
00185                 return false;
00186         }
00187         else
00188         {
00189                 nldebug( "MR: Start replaying from %s", _Filename.c_str() );
00190                 return true;
00191         }
00192 }

void NLNET::CMessageRecorder::stopRecord  ) 
 

Stop recording.

Definition at line 168 of file message_recorder.cpp.

References _File.

Referenced by ~CMessageRecorder().

00169 {
00170         _File.close();
00171         _Filename = "";
00172 }

void NLNET::CMessageRecorder::stopReplay  ) 
 

Stop playback.

Definition at line 404 of file message_recorder.cpp.

References _File.

Referenced by ~CMessageRecorder().

00405 {
00406         _File.close();
00407         _Filename = "";
00408 }


Field Documentation

std::deque<TMessageRecord> NLNET::CMessageRecorder::_ConnectionAttempts [private]
 

Definition at line 176 of file message_recorder.h.

Referenced by replayConnectionAttempt(), and replayNextDataAvailable().

std::fstream NLNET::CMessageRecorder::_File [private]
 

Definition at line 167 of file message_recorder.h.

Referenced by loadNext(), recordNext(), startRecord(), startReplay(), stopRecord(), and stopReplay().

std::string NLNET::CMessageRecorder::_Filename [private]
 

Definition at line 170 of file message_recorder.h.

std::deque<TMessageRecord> NLNET::CMessageRecorder::_PreloadedRecords [private]
 

Definition at line 173 of file message_recorder.h.

Referenced by getNext(), and replayConnectionAttempt().

bool NLNET::CMessageRecorder::_RecordAll [private]
 

Definition at line 179 of file message_recorder.h.

Referenced by recordNext(), and startRecord().

std::queue<NLNET::TMessageRecord> NLNET::CMessageRecorder::ReceivedMessages
 

Receive queue (corresponding to one update count). Use empty(), front(), pop().

Definition at line 154 of file message_recorder.h.

Referenced by replayNextDataAvailable().


The documentation for this class was generated from the following files:
Generated on Tue Mar 16 14:00:11 2004 for NeL by doxygen 1.3.6