From 271a22f148e4241d563d4130a38fe04659f712dc Mon Sep 17 00:00:00 2001 From: Jordan Cristiano Date: Sun, 3 May 2015 22:40:41 -0400 Subject: [PATCH] Code cleanup --- demboyz/demboyz.cpp | 112 +++++++++++------------ demboyz/demofile.cpp | 212 +++++++++++++++++++++++++------------------ demboyz/demofile.h | 43 ++++++--- 3 files changed, 205 insertions(+), 162 deletions(-) diff --git a/demboyz/demboyz.cpp b/demboyz/demboyz.cpp index ea85e26..88c30db 100644 --- a/demboyz/demboyz.cpp +++ b/demboyz/demboyz.cpp @@ -8,31 +8,63 @@ void ParsePacket(const std::vector& packet) { assert(packet.size() <= NET_MAX_PAYLOAD); - CBitRead bitBuf(packet.data(), packet.size()); - while (bitBuf.GetNumBitsLeft() >= NETMSG_TYPE_BITS) + CBitRead bitbuf(packet.data(), packet.size()); + while (bitbuf.GetNumBitsLeft() >= NETMSG_TYPE_BITS) { - uint32 typeId = bitBuf.ReadUBitLong(NETMSG_TYPE_BITS); + uint32 typeId = bitbuf.ReadUBitLong(NETMSG_TYPE_BITS); printf("%i\n", typeId); - ProcessNetMsg(typeId, bitBuf); + ProcessNetMsg(typeId, bitbuf); } } -void ParseSignonData(const std::vector& signonData) +void ParseDemoSequence(const std::vector& sequenceData) { - CBitRead bitbuf(signonData.data(), signonData.size()); - const char cmd = bitbuf.ReadChar(); - assert(cmd == dem_signon); - const int32 tick = bitbuf.ReadLong(); - bitbuf.SeekRelative(sizeof(democmdinfo_t) * 8); - const int32 seq1 = bitbuf.ReadLong(); - const int32 seq2 = bitbuf.ReadLong(); - assert(seq1 == seq2); + unsigned char cmd; + int32 tick; + int32 sequenceInfo1; + int32 sequenceInfo2; + democmdinfo_t cmdInfo; + std::vector buffer; - const int32 numBytes = bitbuf.ReadLong(); - std::vector packet; - packet.resize(numBytes); - bitbuf.ReadBytes(&packet[0], numBytes); - ParsePacket(packet); + DemoSequenceReader reader(sequenceData); + for (;;) + { + reader.ReadCmdHeader(cmd, tick); + switch (cmd) + { + case dem_signon: + case dem_packet: + reader.ReadCmdInfo(cmdInfo); + reader.ReadSequenceInfo(sequenceInfo1, sequenceInfo2); + assert(sequenceInfo1 == sequenceInfo2); + reader.ReadRawData(buffer); + ParsePacket(buffer); + break; + case dem_synctick: + // nothing + break; + case dem_consolecmd: + break; + case dem_usercmd: + reader.ReadUserCmd(buffer); + break; + case dem_datatables: + // TODO: datatables + reader.ReadRawData(nullptr, 0); + break; + case dem_stop: + // TODO assert frame and tick numbers + break; + case dem_customdata: + reader.ReadRawData(nullptr, 0); + break; + case dem_stringtables: + break; + default: + assert(false); + break; + } + } } int main(const int argc, const char* argv[]) @@ -49,48 +81,8 @@ int main(const int argc, const char* argv[]) } auto demoHeader = demoFile.GetDemoHeader(); - - ParseSignonData(demoFile.GetSignOnData()); - - unsigned char cmd; - int32 tick; - int32 sequenceInfo1; - int32 sequenceInfo2; - democmdinfo_t cmdInfo; - std::vector packet; - demoFile.ReadCmdHeader(cmd, tick); - - assert(cmd == dem_synctick && tick == 0); - - const int numFrames = demoHeader->playback_frames; - const int numTicks = demoHeader->playback_ticks; - for (int i = 0; i <= numFrames; ++i) - { - demoFile.ReadCmdHeader(cmd, tick); - //printf("tick: %i\n", tick); - switch (cmd) - { - case dem_packet: - demoFile.ReadCmdInfo(cmdInfo); - demoFile.ReadSequenceInfo(sequenceInfo1, sequenceInfo2); - assert(sequenceInfo1 == sequenceInfo2); - demoFile.ReadRawData(packet); - ParsePacket(packet); - break; - case dem_stop: - assert(i == numFrames && tick == numTicks); - break; - case dem_synctick: - case dem_consolecmd: - case dem_usercmd: - case dem_datatables: - default: - assert(false); - break; - } - } - + ParseDemoSequence(demoFile.GetSignOnData()); + ParseDemoSequence(demoFile.GetDemoData()); demoFile.Close(); - return 0; } diff --git a/demboyz/demofile.cpp b/demboyz/demofile.cpp index 3866ee0..4f3d8b5 100644 --- a/demboyz/demofile.cpp +++ b/demboyz/demofile.cpp @@ -27,129 +27,169 @@ #include #include "demofile.h" -CDemoFile::CDemoFile(): - m_DemoHeader(), - m_fileBufferPos(0) +DemoSequenceReader::DemoSequenceReader(const std::vector& sequenceData): + m_sequenceData(sequenceData), + m_dataReadOffset(0) { } -CDemoFile::~CDemoFile() +int32 DemoSequenceReader::ReadRawData(char *buffer, int32 length) { - Close(); -} - -void CDemoFile::ReadSequenceInfo( int32 &nSeqNrIn, int32 &nSeqNrOut ) -{ - if ( !m_fileBuffer.size() ) - return; - - nSeqNrIn = *( int32 * )( &m_fileBuffer[ m_fileBufferPos ] ); - m_fileBufferPos += sizeof( int32 ); - nSeqNrOut = *( int32 * )( &m_fileBuffer[ m_fileBufferPos ] ); - m_fileBufferPos += sizeof( int32 ); -} - -void CDemoFile::ReadCmdInfo( democmdinfo_t& info ) -{ - if ( !m_fileBuffer.size() ) - return; - - memcpy( &info, &m_fileBuffer[ m_fileBufferPos ], sizeof( democmdinfo_t ) ); - m_fileBufferPos += sizeof( democmdinfo_t ); -} - -void CDemoFile::ReadCmdHeader( unsigned char& cmd, int32& tick ) -{ - if ( !m_fileBuffer.size() ) - return; - - // Read the command - cmd = *( unsigned char * )( &m_fileBuffer[ m_fileBufferPos ] ); - m_fileBufferPos += sizeof( unsigned char ); - - if ( cmd <=0 ) + if (m_sequenceData.empty()) { - fprintf( stderr, "CDemoFile::ReadCmdHeader: Missing end tag in demo file.\n"); - cmd = dem_stop; - return; + return 0; } - assert( cmd >= 1 && cmd <= dem_lastcmd ); - - // Read the timestamp - tick = *( int32 * )( &m_fileBuffer[ m_fileBufferPos ] ); - m_fileBufferPos += sizeof( int32 ); -} - -int32 CDemoFile::ReadUserCmd( char *buffer, int32 &size ) -{ - if ( !m_fileBuffer.size() ) - return 0; - - int32 outgoing_sequence = *( int32 * )( &m_fileBuffer[ m_fileBufferPos ] ); - m_fileBufferPos += sizeof( int32 ); - - size = ReadRawData( buffer, size ); - - return outgoing_sequence; -} - -int32 CDemoFile::ReadRawData( char *buffer, int32 length ) -{ - if ( !m_fileBuffer.size() ) - return 0; + const unsigned char* sequenceData = m_sequenceData.data(); + size_t currentReadOffset = m_dataReadOffset; // read length of data block - int32 size = *( int32 * )( &m_fileBuffer[ m_fileBufferPos ] ); - m_fileBufferPos += sizeof( int32 ); - - if ( buffer && (length < size) ) + const int32 size = *reinterpret_cast(sequenceData + currentReadOffset); + currentReadOffset += sizeof(int32); + + if (buffer && (length < size)) { - fprintf( stderr, "CDemoFile::ReadRawData: buffer overflow (%i).\n", size ); + fprintf(stderr, "CDemoFile::ReadRawData: buffer overflow (%i).\n", size); return -1; } - if ( buffer ) + if (buffer) { // read data into buffer - memcpy( buffer, &m_fileBuffer[ m_fileBufferPos ], size ); - m_fileBufferPos += size; - } - else - { - // just skip it - m_fileBufferPos += size; + memcpy(buffer, sequenceData + currentReadOffset, size); } + currentReadOffset += size; + m_dataReadOffset = currentReadOffset; return size; } -bool CDemoFile::ReadRawData(std::vector& buf) +bool DemoSequenceReader::ReadRawData(std::vector& buf, + const int32 maxReadSize /*= MAX_READ_SIZE*/) { - if (!m_fileBuffer.size()) + if (m_sequenceData.empty()) { return false; } + const unsigned char* sequenceData = m_sequenceData.data(); + size_t currentReadOffset = m_dataReadOffset; + // read length of data block - int32 size = *(int32 *)(&m_fileBuffer[m_fileBufferPos]); - m_fileBufferPos += sizeof(int32); + const int32 size = *reinterpret_cast(sequenceData + currentReadOffset); + currentReadOffset += sizeof(int32); if (size < 0) { - fprintf(stderr, "CDemoFile::ReadRawData: invalid size (%i).\n", size); + fprintf(stderr, "DemoSequenceReader::ReadRawData: invalid size (%i).\n", size); + return false; + } + if (maxReadSize < 0 || size > maxReadSize) + { + fprintf(stderr, "DemoSequenceReader::ReadRawData: invalid size (%i) with max (%i).\n", size, maxReadSize); return false; } buf.resize(size); // read data into buffer - memcpy(&buf[0], &m_fileBuffer[m_fileBufferPos], size); - m_fileBufferPos += size; + memcpy(buf.data(), sequenceData + currentReadOffset, size); + currentReadOffset += size; + m_dataReadOffset = currentReadOffset; return true; } +void DemoSequenceReader::ReadSequenceInfo(int32 &nSeqNrIn, int32 &nSeqNrOut) +{ + if (m_sequenceData.empty()) + { + return; + } + + const unsigned char* sequenceData = m_sequenceData.data(); + size_t currentReadOffset = m_dataReadOffset; + + nSeqNrIn = *reinterpret_cast(sequenceData + currentReadOffset); + currentReadOffset += sizeof(int32); + nSeqNrOut = *reinterpret_cast(sequenceData + currentReadOffset); + currentReadOffset += sizeof(int32); + + m_dataReadOffset = currentReadOffset; +} + +void DemoSequenceReader::ReadCmdInfo(democmdinfo_t& info) +{ + if (m_sequenceData.empty()) + { + return; + } + + size_t currentReadOffset = m_dataReadOffset; + + memcpy(&info, m_sequenceData.data() + currentReadOffset, sizeof(democmdinfo_t)); + currentReadOffset += sizeof(democmdinfo_t); + + m_dataReadOffset = currentReadOffset; +} + +void DemoSequenceReader::ReadCmdHeader(unsigned char& cmd, int32& tick) +{ + if (m_sequenceData.empty()) + { + return; + } + + const unsigned char* sequenceData = m_sequenceData.data(); + size_t currentReadOffset = m_dataReadOffset; + + // Read the command + cmd = sequenceData[currentReadOffset]; + currentReadOffset += sizeof(unsigned char); + + if (cmd > 0) + { + assert(cmd <= dem_lastcmd); + + // Read the timestamp + tick = *reinterpret_cast(sequenceData + currentReadOffset); + currentReadOffset += sizeof(int32); + } + else + { + fprintf(stderr, "CDemoFile::ReadCmdHeader: Missing end tag in demo file.\n"); + cmd = dem_stop; + } + m_dataReadOffset = currentReadOffset; +} + +int32 DemoSequenceReader::ReadUserCmd(std::vector& buf) +{ + if (m_sequenceData.empty()) + { + return 0; + } + + const int32 outgoing_sequence = *reinterpret_cast(m_sequenceData.data() + m_dataReadOffset); + m_dataReadOffset += sizeof(int32); + + if (!ReadRawData(buf)) + { + return 0; + } + return outgoing_sequence; +} + +CDemoFile::CDemoFile(): + m_DemoHeader() +{ +} + +CDemoFile::~CDemoFile() +{ + Close(); +} + bool CDemoFile::Open( const char *name ) { Close(); @@ -209,8 +249,6 @@ bool CDemoFile::Open( const char *name ) Close(); return false; } - - m_fileBufferPos = 0; return true; } @@ -218,6 +256,4 @@ void CDemoFile::Close() { m_signOnData.clear(); m_fileBuffer.clear(); - - m_fileBufferPos = 0; } diff --git a/demboyz/demofile.h b/demboyz/demofile.h index 47adf85..6bdc400 100644 --- a/demboyz/demofile.h +++ b/demboyz/demofile.h @@ -218,6 +218,29 @@ struct democmdinfo_t Split_t u[ MAX_SPLITSCREEN_CLIENTS ]; }; +class DemoSequenceReader +{ + static const int32 MAX_READ_SIZE = 1024 * 1024; +public: + DemoSequenceReader(const std::vector& sequenceData); + + int32 ReadRawData(char *buffer, int32 length); + + bool ReadRawData(std::vector& buf, const int32 maxReadSize = MAX_READ_SIZE); + + void ReadSequenceInfo(int32 &nSeqNrIn, int32 &nSeqNrOutAck); + + void ReadCmdInfo(democmdinfo_t& info); + + void ReadCmdHeader(unsigned char &cmd, int32 &tick); + + int32 ReadUserCmd(std::vector& buf); + +private: + const std::vector& m_sequenceData; + size_t m_dataReadOffset; +}; + class CDemoFile { public: @@ -227,29 +250,16 @@ public: bool Open( const char *name ); void Close(); - int32 ReadRawData( char *buffer, int32 length ); - - bool ReadRawData(std::vector& buf); - - void ReadSequenceInfo( int32 &nSeqNrIn, int32 &nSeqNrOutAck ); - - void ReadCmdInfo( democmdinfo_t& info ); - - void ReadCmdHeader( unsigned char &cmd, int32 &tick ); - - int32 ReadUserCmd( char *buffer, int32 &size ); - const demoheader_t *GetDemoHeader() const; const std::vector& GetSignOnData() const; + const std::vector& GetDemoData() const; private: demoheader_t m_DemoHeader; //general demo info std::vector m_signOnData; std::vector m_fileBuffer; - - size_t m_fileBufferPos; }; inline const demoheader_t *CDemoFile::GetDemoHeader() const @@ -262,4 +272,9 @@ inline const std::vector& CDemoFile::GetSignOnData() const return m_signOnData; } +inline const std::vector& CDemoFile::GetDemoData() const +{ + return m_fileBuffer; +} + #endif // DEMOFILE_H