00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef __GNUG__
00026 # pragma implementation "UseTrackingVisitor.h"
00027 #endif
00028
00029 #include "StrMod/UseTrackingVisitor.h"
00030 #include "StrMod/StackSwapper.h"
00031
00032 namespace strmod {
00033 namespace strmod {
00034
00035 const STR_ClassIdent UseTrackingVisitor::identifier(47UL);
00036
00037
00038
00039
00040
00041
00042 UseTrackingVisitor::UseTrackingVisitor(bool ignorezeros)
00043 : curpos_(0), ignorezeros_(ignorezeros)
00044 {
00045 }
00046
00047 void UseTrackingVisitor::visitStrChunk(const StrChunkPtr &chunk)
00048 throw(halt_visitation)
00049 {
00050
00051 assert(chunk);
00052 if (ignorezeros_ && (curpos_ >= curext_.endOffset()))
00053 {
00054 return;
00055 }
00056 LinearExtent::length_t chunklen = chunk->Length();
00057 LinearExtent used = computeUsed(LinearExtent(0, chunklen));
00058 if ((used.Length() != 0) || !ignorezeros_)
00059 {
00060 use_visitStrChunk(chunk, used);
00061 }
00062 do_acceptVisitor(chunk, used);
00063 curpos_ += chunklen;
00064
00065 }
00066
00067 void UseTrackingVisitor::visitStrChunk(const StrChunkPtr &chunk,
00068 const LinearExtent &used)
00069 throw(halt_visitation)
00070 {
00071
00072 assert(chunk);
00073 if (ignorezeros_ && (curpos_ >= curext_.endOffset()))
00074 {
00075 return;
00076 }
00077 LinearExtent::length_t chunklen = chunk->Length();
00078 LinearExtent chnkused =
00079 computeUsed(LinearExtent(0, chunklen).SubExtent(used));
00080 if ((used.Length() > 0) || !ignorezeros_)
00081 {
00082 use_visitStrChunk(chunk, chnkused);
00083 }
00084 do_acceptVisitor(chunk, chnkused);
00085 curpos_ += used.Length();
00086
00087 }
00088
00089 void UseTrackingVisitor::visitDataBlock(const void *data, size_t len)
00090 throw(halt_visitation)
00091 {
00092
00093 assert(data != NULL);
00094 if (ignorezeros_ && (curpos_ >= curext_.endOffset()))
00095 {
00096 return;
00097 }
00098 LinearExtent used = computeUsed(LinearExtent(0, len));
00099 if ((used.Length() > 0) || !ignorezeros_)
00100 {
00101 if (used.Offset() != 0)
00102 {
00103
00104 use_visitDataBlock(static_cast<const unsigned char *>(data) +
00105 used.Offset(),
00106 used.Length(),
00107 data, len);
00108 }
00109 else
00110 {
00111
00112 use_visitDataBlock(data, used.Length(), data, len);
00113 }
00114 }
00115 curpos_ += len;
00116
00117 }
00118
00119 const LinearExtent UseTrackingVisitor::computeUsed(const LinearExtent &used)
00120 {
00121 LinearExtent chunkext(curpos_, used.Length());
00122 LinearExtent overlap = chunkext.intersection(curext_);
00123 chunkext = overlap;
00124 assert(chunkext.Offset() >= curpos_);
00125 chunkext.MoveLeft(curpos_);
00126 return used.SubExtent(chunkext);
00127 }
00128
00129 void UseTrackingVisitor::do_acceptVisitor(const StrChunkPtr &chunk,
00130 const LinearExtent &chunkext)
00131 throw(halt_visitation)
00132 {
00133
00134
00135 StackSwapper<StrChunkPtr> s1(curchnk_, chunk);
00136 StackSwapper<LinearExtent::off_t> s2(curpos_, 0);
00137 StackSwapper<LinearExtent> s3(curext_, chunkext);
00138 call_acceptVisitor(chunk);
00139 }
00140
00141 };
00142 };