Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef __RANGE_LIST_H
00011 #define __RANGE_LIST_H
00012
00013 #include "DS_OrderedList.h"
00014 #include "BitStream.h"
00015 #include "RakMemoryOverride.h"
00016 #include "RakAssert.h"
00017
00018 namespace DataStructures
00019 {
00020 template <class range_type>
00021 struct RangeNode
00022 {
00023 RangeNode() {}
00024 ~RangeNode() {}
00025 RangeNode(range_type min, range_type max) {minIndex=min; maxIndex=max;}
00026 range_type minIndex;
00027 range_type maxIndex;
00028 };
00029
00030
00031 template <class range_type>
00032 int RangeNodeComp(const range_type &a, const RangeNode<range_type> &b)
00033 {
00034 if (a<b.minIndex)
00035 return -1;
00036 if (a==b.minIndex)
00037 return 0;
00038 return 1;
00039 }
00040
00041 template <class range_type>
00042 class RAK_DLL_EXPORT RangeList
00043 {
00044 public:
00045 RangeList();
00046 ~RangeList();
00047 void Insert(range_type index);
00048 void Clear(void);
00049 unsigned Size(void) const;
00050 unsigned RangeSum(void) const;
00051 BitSize_t Serialize(RakNet::BitStream *in, BitSize_t maxBits, bool clearSerialized);
00052 bool Deserialize(RakNet::BitStream *out);
00053
00054 DataStructures::OrderedList<range_type, RangeNode<range_type> , RangeNodeComp<range_type> > ranges;
00055 };
00056
00057 template <class range_type>
00058 BitSize_t RangeList<range_type>::Serialize(RakNet::BitStream *in, BitSize_t maxBits, bool clearSerialized)
00059 {
00060 RakAssert(ranges.Size() < (unsigned short)-1);
00061 RakNet::BitStream tempBS;
00062 BitSize_t bitsWritten;
00063 unsigned short countWritten;
00064 unsigned i;
00065 countWritten=0;
00066 bitsWritten=0;
00067 for (i=0; i < ranges.Size(); i++)
00068 {
00069 if ((int)sizeof(unsigned short)*8+bitsWritten+(int)sizeof(range_type)*8*2+1>maxBits)
00070 break;
00071 unsigned char minEqualsMax;
00072 if (ranges[i].minIndex==ranges[i].maxIndex)
00073 minEqualsMax=1;
00074 else
00075 minEqualsMax=0;
00076 tempBS.Write(minEqualsMax);
00077 tempBS.Write(ranges[i].minIndex);
00078 bitsWritten+=sizeof(range_type)*8+8;
00079 if (ranges[i].minIndex!=ranges[i].maxIndex)
00080 {
00081 tempBS.Write(ranges[i].maxIndex);
00082 bitsWritten+=sizeof(range_type)*8;
00083 }
00084 countWritten++;
00085 }
00086
00087 in->AlignWriteToByteBoundary();
00088 BitSize_t before=in->GetWriteOffset();
00089 in->Write(countWritten);
00090 bitsWritten+=in->GetWriteOffset()-before;
00091
00092 in->Write(&tempBS, tempBS.GetNumberOfBitsUsed());
00093
00094
00095 if (clearSerialized && countWritten)
00096 {
00097 unsigned rangeSize=ranges.Size();
00098 for (i=0; i < rangeSize-countWritten; i++)
00099 {
00100 ranges[i]=ranges[i+countWritten];
00101 }
00102 ranges.RemoveFromEnd(countWritten);
00103 }
00104
00105 return bitsWritten;
00106 }
00107 template <class range_type>
00108 bool RangeList<range_type>::Deserialize(RakNet::BitStream *out)
00109 {
00110 ranges.Clear(true, __FILE__, __LINE__);
00111 unsigned short count;
00112 out->AlignReadToByteBoundary();
00113 out->Read(count);
00114 unsigned short i;
00115 range_type min,max;
00116 unsigned char maxEqualToMin=0;
00117
00118 for (i=0; i < count; i++)
00119 {
00120 out->Read(maxEqualToMin);
00121 if (out->Read(min)==false)
00122 return false;
00123 if (maxEqualToMin==false)
00124 {
00125 if (out->Read(max)==false)
00126 return false;
00127 if (max<min)
00128 return false;
00129 }
00130 else
00131 max=min;
00132
00133
00134 ranges.InsertAtEnd(RangeNode<range_type>(min,max), __FILE__,__LINE__);
00135 }
00136 return true;
00137 }
00138
00139 template <class range_type>
00140 RangeList<range_type>::RangeList()
00141 {
00142 RangeNodeComp<range_type>(0, RangeNode<range_type>());
00143 }
00144
00145 template <class range_type>
00146 RangeList<range_type>::~RangeList()
00147 {
00148 Clear();
00149 }
00150
00151 template <class range_type>
00152 void RangeList<range_type>::Insert(range_type index)
00153 {
00154 if (ranges.Size()==0)
00155 {
00156 ranges.Insert(index, RangeNode<range_type>(index, index), true, __FILE__,__LINE__);
00157 return;
00158 }
00159
00160 bool objectExists;
00161 unsigned insertionIndex=ranges.GetIndexFromKey(index, &objectExists);
00162 if (insertionIndex==ranges.Size())
00163 {
00164 if (index == ranges[insertionIndex-1].maxIndex+(range_type)1)
00165 ranges[insertionIndex-1].maxIndex++;
00166 else if (index > ranges[insertionIndex-1].maxIndex+(range_type)1)
00167 {
00168
00169 ranges.Insert(index, RangeNode<range_type>(index, index), true, __FILE__,__LINE__);
00170 }
00171
00172 return;
00173 }
00174
00175 if (index < ranges[insertionIndex].minIndex-(range_type)1)
00176 {
00177
00178 ranges.InsertAtIndex(RangeNode<range_type>(index, index), insertionIndex, __FILE__,__LINE__);
00179
00180 return;
00181 }
00182 else if (index == ranges[insertionIndex].minIndex-(range_type)1)
00183 {
00184
00185 ranges[insertionIndex].minIndex--;
00186 if (insertionIndex>0 && ranges[insertionIndex-1].maxIndex+(range_type)1==ranges[insertionIndex].minIndex)
00187 {
00188 ranges[insertionIndex-1].maxIndex=ranges[insertionIndex].maxIndex;
00189 ranges.RemoveAtIndex(insertionIndex);
00190 }
00191
00192 return;
00193 }
00194 else if (index >= ranges[insertionIndex].minIndex && index <= ranges[insertionIndex].maxIndex)
00195 {
00196
00197 return;
00198 }
00199 else if (index == ranges[insertionIndex].maxIndex+(range_type)1)
00200 {
00201
00202 ranges[insertionIndex].maxIndex++;
00203 if (insertionIndex<ranges.Size()-1 && ranges[insertionIndex+(range_type)1].minIndex==ranges[insertionIndex].maxIndex+(range_type)1)
00204 {
00205 ranges[insertionIndex+1].minIndex=ranges[insertionIndex].minIndex;
00206 ranges.RemoveAtIndex(insertionIndex);
00207 }
00208
00209 return;
00210 }
00211 }
00212
00213 template <class range_type>
00214 void RangeList<range_type>::Clear(void)
00215 {
00216 ranges.Clear(true, __FILE__, __LINE__);
00217 }
00218
00219 template <class range_type>
00220 unsigned RangeList<range_type>::Size(void) const
00221 {
00222 return ranges.Size();
00223 }
00224
00225 template <class range_type>
00226 unsigned RangeList<range_type>::RangeSum(void) const
00227 {
00228 unsigned sum=0,i;
00229 for (i=0; i < ranges.Size(); i++)
00230 sum+=ranges[i].maxIndex-ranges[i].minIndex+1;
00231 return sum;
00232 }
00233
00234 }
00235
00236 #endif