#include <ReassemblyBuffer.h>
Currently used in IPFragBuf and IPv6FragBuf.
Public Member Functions | |
ReassemblyBuffer () | |
~ReassemblyBuffer () | |
bool | addFragment (ushort beg, ushort end, bool islast) |
ushort | totalLength () const |
Protected Types | |
typedef std::vector< Region > | RegionVector |
Protected Member Functions | |
void | merge (ushort beg, ushort end, bool islast) |
void | mergeFragments () |
Protected Attributes | |
Region | main |
RegionVector * | fragments |
Classes | |
struct | Region |
typedef std::vector<Region> ReassemblyBuffer::RegionVector [protected] |
ReassemblyBuffer::ReassemblyBuffer | ( | ) |
ReassemblyBuffer::~ReassemblyBuffer | ( | ) |
00047 { 00048 if (main.end==beg) 00049 { 00050 // most typical case (<95%): new fragment follows last one 00051 main.end = end; 00052 if (islast) 00053 main.islast = true; 00054 if (fragments) 00055 mergeFragments(); 00056 } 00057 else if (main.beg==end) 00058 { 00059 // new fragment precedes what we already have 00060 main.beg = beg; 00061 if (fragments) 00062 mergeFragments(); 00063 } 00064 else if (main.end<beg || main.beg>end) 00065 { 00066 // disjoint fragment, store it until another fragment fills in the gap 00067 if (!fragments) 00068 fragments = new RegionVector(); 00069 Region r; 00070 r.beg = beg; 00071 r.end = end; 00072 r.islast = islast; 00073 fragments->push_back(r); 00074 } 00075 else 00076 { 00077 // overlapping is not possible; 00078 // fragment's range already contained in buffer (probably duplicate fragment) 00079 } 00080 }
void ReassemblyBuffer::mergeFragments | ( | ) | [protected] |
00083 { 00084 RegionVector& frags = *fragments; 00085 00086 bool oncemore; 00087 do 00088 { 00089 oncemore = false; 00090 for (RegionVector::iterator i=frags.begin(); i!=frags.end(); ) 00091 { 00092 bool deleteit = false; 00093 Region& frag = *i; 00094 if (main.end==frag.beg) 00095 { 00096 main.end = frag.end; 00097 if (frag.islast) 00098 main.islast = true; 00099 deleteit = true; 00100 } 00101 else if (main.beg==frag.end) 00102 { 00103 main.beg = frag.beg; 00104 deleteit = true; 00105 } 00106 else if (main.beg<=frag.beg && main.end>=frag.end) 00107 { 00108 // we already have this region (duplicate fragment), delete it 00109 deleteit = true; 00110 } 00111 00112 if (deleteit) 00113 { 00114 // deletion is tricky because erase() invalidates iterator 00115 int pos = i - frags.begin(); 00116 frags.erase(i); 00117 i = frags.begin() + pos; 00118 oncemore = true; 00119 } 00120 else 00121 { 00122 ++i; 00123 } 00124 } 00125 } 00126 while (oncemore); 00127 }
ushort ReassemblyBuffer::totalLength | ( | ) | const [inline] |
Returns the total (assembled) length of the datagram. Can only be called after addFragment() returned true.
RegionVector* ReassemblyBuffer::fragments [protected] |
Region ReassemblyBuffer::main [protected] |