DataQueue.h 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #ifndef DATAQUEUE_H
  2. #define DATAQUEUE_H
  3. template< int maxItems, int maxBuffer >
  4. class idDataQueue {
  5. public:
  6. idDataQueue() {
  7. dataLength = 0;
  8. }
  9. bool Append( int sequence, const byte * b1, int b1Len, const byte * b2 = NULL, int b2Len = 0 );
  10. void RemoveOlderThan( int sequence );
  11. int GetDataLength() const { return dataLength; }
  12. int Num() const { return items.Num(); }
  13. int ItemSequence( int i ) const { return items[i].sequence; }
  14. int ItemLength( int i ) const { return items[i].length; }
  15. const byte * ItemData( int i ) const { return &data[items[i].dataOffset]; }
  16. void Clear() { dataLength = 0; items.Clear(); memset( data, 0, sizeof( data ) ); }
  17. private:
  18. struct msgItem_t {
  19. int sequence;
  20. int length;
  21. int dataOffset;
  22. };
  23. idStaticList<msgItem_t, maxItems > items;
  24. int dataLength;
  25. byte data[ maxBuffer ];
  26. };
  27. /*
  28. ========================
  29. idDataQueue::RemoveOlderThan
  30. ========================
  31. */
  32. template< int maxItems, int maxBuffer >
  33. void idDataQueue< maxItems, maxBuffer >::RemoveOlderThan( int sequence ) {
  34. int length = 0;
  35. while ( items.Num() > 0 && items[0].sequence < sequence ) {
  36. length += items[0].length;
  37. items.RemoveIndex( 0 );
  38. }
  39. if ( length >= dataLength ) {
  40. assert( items.Num() == 0 );
  41. assert( dataLength == length );
  42. dataLength = 0;
  43. } else if ( length > 0 ) {
  44. memmove( data, data + length, dataLength - length );
  45. dataLength -= length;
  46. }
  47. length = 0;
  48. for ( int i = 0; i < items.Num(); i++ ) {
  49. items[i].dataOffset = length;
  50. length += items[i].length;
  51. }
  52. assert( length == dataLength );
  53. }
  54. /*
  55. ========================
  56. idDataQueue::Append
  57. ========================
  58. */
  59. template< int maxItems, int maxBuffer >
  60. bool idDataQueue< maxItems, maxBuffer >::Append( int sequence, const byte * b1, int b1Len, const byte * b2, int b2Len ) {
  61. if ( items.Num() == items.Max() ) {
  62. return false;
  63. }
  64. if ( dataLength + b1Len + b2Len >= maxBuffer ) {
  65. return false;
  66. }
  67. msgItem_t & item = *items.Alloc();
  68. item.length = b1Len + b2Len;
  69. item.sequence = sequence;
  70. item.dataOffset = dataLength;
  71. memcpy( data + dataLength, b1, b1Len ); dataLength += b1Len;
  72. memcpy( data + dataLength, b2, b2Len ); dataLength += b2Len;
  73. return true;
  74. }
  75. #endif // DATAQUEUE_H