#ifndef __RANGE_LIST_H #define __RANGE_LIST_H #include "DS_OrderedList.h" #include "BitStream.h" #include "RakMemoryOverride.h" #include namespace DataStructures { template struct RangeNode : public RakNet::RakMemoryOverride { RangeNode() {} ~RangeNode() {} RangeNode(range_type min, range_type max) {minIndex=min; maxIndex=max;} range_type minIndex; range_type maxIndex; }; template int RangeNodeComp(const range_type &a, const RangeNode &b) { if (a class RAK_DLL_EXPORT RangeList : public RakNet::RakMemoryOverride { public: RangeList(); ~RangeList(); void Insert(range_type index); void Clear(void); unsigned Size(void) const; unsigned RangeSum(void) const; BitSize_t Serialize(RakNet::BitStream *in, BitSize_t maxBits, bool clearSerialized); bool Deserialize(RakNet::BitStream *out); DataStructures::OrderedList , RangeNodeComp > ranges; }; template BitSize_t RangeList::Serialize(RakNet::BitStream *in, BitSize_t maxBits, bool clearSerialized) { assert(ranges.Size() < (unsigned short)-1); RakNet::BitStream tempBS; BitSize_t bitsWritten; unsigned short countWritten; unsigned i; countWritten=0; bitsWritten=0; for (i=0; i < ranges.Size(); i++) { if ((int)sizeof(unsigned short)*8+bitsWritten+(int)sizeof(range_type)*8*2+1>maxBits) break; tempBS.Write(ranges[i].minIndex==ranges[i].maxIndex); tempBS.Write(ranges[i].minIndex); bitsWritten+=sizeof(range_type)*8+1; if (ranges[i].minIndex!=ranges[i].maxIndex) { tempBS.Write(ranges[i].maxIndex); bitsWritten+=sizeof(range_type)*8; } countWritten++; } BitSize_t before=in->GetWriteOffset(); in->WriteCompressed(countWritten); bitsWritten+=in->GetWriteOffset()-before; // printf("%i ", in->GetNumberOfBitsUsed()); in->Write(&tempBS, tempBS.GetNumberOfBitsUsed()); // printf("%i %i \n", tempBS.GetNumberOfBitsUsed(),in->GetNumberOfBitsUsed()); if (clearSerialized && countWritten) { unsigned rangeSize=ranges.Size(); for (i=0; i < rangeSize-countWritten; i++) { ranges[i]=ranges[i+countWritten]; } ranges.RemoveFromEnd(countWritten); } return bitsWritten; } template bool RangeList::Deserialize(RakNet::BitStream *out) { ranges.Clear(); unsigned short count; out->ReadCompressed(count); unsigned short i; range_type min,max; bool maxEqualToMin=false; for (i=0; i < count; i++) { out->Read(maxEqualToMin); if (out->Read(min)==false) return false; if (maxEqualToMin==false) { if (out->Read(max)==false) return false; if (max(min,max)); } return true; } template RangeList::RangeList() { RangeNodeComp(0, RangeNode()); } template RangeList::~RangeList() { Clear(); } template void RangeList::Insert(range_type index) { if (ranges.Size()==0) { ranges.Insert(index, RangeNode(index, index), true); return; } bool objectExists; unsigned insertionIndex=ranges.GetIndexFromKey(index, &objectExists); if (insertionIndex==ranges.Size()) { if (index == ranges[insertionIndex-1].maxIndex+1) ranges[insertionIndex-1].maxIndex++; else if (index > ranges[insertionIndex-1].maxIndex+1) { // Insert at end ranges.Insert(index, RangeNode(index, index), true); } return; } if (index < ranges[insertionIndex].minIndex-1) { // Insert here ranges.InsertAtIndex(RangeNode(index, index), insertionIndex); return; } else if (index == ranges[insertionIndex].minIndex-1) { // Decrease minIndex and join left ranges[insertionIndex].minIndex--; if (insertionIndex>0 && ranges[insertionIndex-1].maxIndex+1==ranges[insertionIndex].minIndex) { ranges[insertionIndex-1].maxIndex=ranges[insertionIndex].maxIndex; ranges.RemoveAtIndex(insertionIndex); } return; } else if (index >= ranges[insertionIndex].minIndex && index <= ranges[insertionIndex].maxIndex) { // Already exists return; } else if (index == ranges[insertionIndex].maxIndex+1) { // Increase maxIndex and join right ranges[insertionIndex].maxIndex++; if (insertionIndex void RangeList::Clear(void) { ranges.Clear(); } template unsigned RangeList::Size(void) const { return ranges.Size(); } template unsigned RangeList::RangeSum(void) const { unsigned sum=0,i; for (i=0; i < ranges.Size(); i++) sum+=ranges[i].maxIndex-ranges[i].minIndex+1; return sum; } } #endif