doom3-bfg/neo/idlib/DataQueue.h
2012-11-26 12:58:24 -06:00

83 lines
2.1 KiB
C++

#ifndef DATAQUEUE_H
#define DATAQUEUE_H
template< int maxItems, int maxBuffer >
class idDataQueue {
public:
idDataQueue() {
dataLength = 0;
}
bool Append( int sequence, const byte * b1, int b1Len, const byte * b2 = NULL, int b2Len = 0 );
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 ) ); }
private:
struct msgItem_t {
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 ) {
int length = 0;
while ( items.Num() > 0 && items[0].sequence < sequence ) {
length += items[0].length;
items.RemoveIndex( 0 );
}
if ( length >= dataLength ) {
assert( items.Num() == 0 );
assert( dataLength == length );
dataLength = 0;
} else if ( length > 0 ) {
memmove( data, data + length, dataLength - length );
dataLength -= length;
}
length = 0;
for ( int i = 0; i < items.Num(); i++ ) {
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() ) {
return false;
}
if ( dataLength + b1Len + b2Len >= maxBuffer ) {
return false;
}
msgItem_t & item = *items.Alloc();
item.length = b1Len + b2Len;
item.sequence = sequence;
item.dataOffset = dataLength;
memcpy( data + dataLength, b1, b1Len ); dataLength += b1Len;
memcpy( data + dataLength, b2, b2Len ); dataLength += b2Len;
return true;
}
#endif // DATAQUEUE_H