doom3-bfg/neo/idlib/DataQueue.h

118 lines
2.2 KiB
C
Raw Normal View History

2012-11-26 18:58:24 +00:00
#ifndef DATAQUEUE_H
#define DATAQUEUE_H
template< int maxItems, int maxBuffer >
class idDataQueue
{
2012-11-26 18:58:24 +00:00
public:
idDataQueue()
{
2012-11-26 18:58:24 +00:00
dataLength = 0;
}
bool Append( int sequence, const byte* b1, int b1Len, const byte* b2 = NULL, int b2Len = 0 );
2012-11-26 18:58:24 +00:00
void RemoveOlderThan( int sequence );
int GetDataLength() const
{
return dataLength;
}
int Num() const
{
return items.Num();
}
int ItemSequence( int i ) const
{
return items[i].sequence;
}
int ItemLength( int i ) const
{
return items[i].length;
}
const byte* ItemData( int i ) const
{
return &data[items[i].dataOffset];
}
void Clear()
{
dataLength = 0;
items.Clear();
memset( data, 0, sizeof( data ) );
}
2012-11-26 18:58:24 +00:00
private:
struct msgItem_t
{
2012-11-26 18:58:24 +00:00
int sequence;
int length;
int dataOffset;
};
idStaticList<msgItem_t, maxItems > items;
int dataLength;
byte data[ maxBuffer ];
};
/*
========================
idDataQueue::RemoveOlderThan
========================
*/
template< int maxItems, int maxBuffer >
void idDataQueue< maxItems, maxBuffer >::RemoveOlderThan( int sequence )
{
2012-11-26 18:58:24 +00:00
int length = 0;
while( items.Num() > 0 && items[0].sequence < sequence )
{
2012-11-26 18:58:24 +00:00
length += items[0].length;
items.RemoveIndex( 0 );
}
if( length >= dataLength )
{
2012-11-26 18:58:24 +00:00
assert( items.Num() == 0 );
assert( dataLength == length );
dataLength = 0;
}
else if( length > 0 )
{
2012-11-26 18:58:24 +00:00
memmove( data, data + length, dataLength - length );
dataLength -= length;
}
length = 0;
for( int i = 0; i < items.Num(); i++ )
{
2012-11-26 18:58:24 +00:00
items[i].dataOffset = length;
length += items[i].length;
}
assert( length == dataLength );
}
/*
========================
idDataQueue::Append
========================
*/
template< int maxItems, int maxBuffer >
bool idDataQueue< maxItems, maxBuffer >::Append( int sequence, const byte* b1, int b1Len, const byte* b2, int b2Len )
{
if( items.Num() == items.Max() )
{
2012-11-26 18:58:24 +00:00
return false;
}
if( dataLength + b1Len + b2Len >= maxBuffer )
{
2012-11-26 18:58:24 +00:00
return false;
}
msgItem_t& item = *items.Alloc();
2012-11-26 18:58:24 +00:00
item.length = b1Len + b2Len;
item.sequence = sequence;
item.dataOffset = dataLength;
memcpy( data + dataLength, b1, b1Len );
dataLength += b1Len;
memcpy( data + dataLength, b2, b2Len );
dataLength += b2Len;
2012-11-26 18:58:24 +00:00
return true;
}
#endif // DATAQUEUE_H