#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 |
|
|
|
|
|
Ctor.
|
|
|
Dtor. 00034 {
00035 delete fragments;
00036 }
|
|
||||||||||||||||
|
Add a fragment, and returns true if reassembly has completed (i.e. we have everything from offset 0 to the last fragment). 00039 {
00040 merge(beg, end, islast);
00041
00042 // do we have the complete datagram?
00043 return main.beg==0 && main.islast;
00044 }
|
|
||||||||||||||||
|
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 }
|
|
|
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 }
|
|
|
Returns the total (assembled) length of the datagram. Can only be called after addFragment() returned true.
|
|
|
|
|
|
|
1.4.1