Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

UseTrackingVisitor.cxx

00001 /* -*-c-file-style: "hopper";-*- */
00002 
00003 /*
00004  * Copyright 2000 by Eric M. Hopper <hopper@omnifarious.mn.org>
00005  * 
00006  *     This program is free software; you can redistribute it and/or modify it
00007  *     under the terms of the GNU Lesser General Public License as published
00008  *     by the Free Software Foundation; either version 2 of the License, or
00009  *     (at your option) any later version.
00010  * 
00011  *     This program is distributed in the hope that it will be useful, but
00012  *     WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  *     Lesser General Public License for more details.
00015  * 
00016  *     You should have received a copy of the GNU Lesser General Public
00017  *     License along with this program; if not, write to the Free Software
00018  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 /* $Header: /home/hopper/src/cvs/C++/StrMod/UseTrackingVisitor.cxx,v 1.6 2001/09/23 22:40:42 hopper Exp $ */
00022 
00023 // For a log, see ChangeLog
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  * @param ignorezeros Should the use_* Template Methods be called for
00039  * StrChunks that have no used bytes or data sections that have no
00040  * used bytes?
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 //   cerr << "visitStrChunk 1: Visiting " << chunk.GetPtr() << " && curpos_ == " << curpos_ << "\n";
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 //   cerr << "visitStrChunk 1: Leaving " << chunk.GetPtr() << " && curpos_ == " << curpos_ << "\n";
00065 }
00066 
00067 void UseTrackingVisitor::visitStrChunk(const StrChunkPtr &chunk,
00068                                         const LinearExtent &used)
00069    throw(halt_visitation)
00070 {
00071 //   cerr << "visitStrChunk 2: Visiting " << chunk.GetPtr() << " && curpos_ == " << curpos_ << "\n";
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 //   cerr << "visitStrChunk 2: Leaving " << chunk.GetPtr() << " && curpos_ == " << curpos_ << "\n";
00087 }
00088 
00089 void UseTrackingVisitor::visitDataBlock(const void *data, size_t len)
00090    throw(halt_visitation)
00091 {
00092 //   cerr << "visitDataBlock: Visiting " << data << " && curpos_ == " << curpos_ << "\n";
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 //         cerr << "used.Offset() == " << used.Offset() << " && used.Length() == " << used.Length() << "\n";
00104          use_visitDataBlock(static_cast<const unsigned char *>(data) +
00105                             used.Offset(),
00106                             used.Length(),
00107                             data, len);
00108       }
00109       else
00110       {
00111 //         cerr << "used.Length() == " << used.Length() << "\n";
00112          use_visitDataBlock(data, used.Length(), data, len);
00113       }
00114    }
00115    curpos_ += len;
00116 //   cerr << "visitDataBlock: Leaving " << data << " && curpos_ == " << curpos_ << "\n";
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    // curchnk_ is chunk for duration of function.  Automatically set back to
00134    // old value when function exits for any reason.
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 };  // End namespace strmod
00142 };  // End namespace strmod

Generated on Wed Jan 29 00:32:45 2003 for libNet by doxygen1.3-rc1