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
00026
00027
00028
00029 #ifdef __GNUG__
00030 # pragma implementation "CharChopper.h"
00031 #endif
00032
00033 #include <StrMod/CharChopper.h>
00034 #include <StrMod/StrChunk.h>
00035 #include <StrMod/ChunkIterator.h>
00036 #include <StrMod/StrChunkPtrT.h>
00037 #include <StrMod/GroupChunk.h>
00038 #include <StrMod/StrSubChunk.h>
00039 #include <StrMod/PreAllocBuffer.h>
00040 #include <StrMod/DynamicBuffer.h>
00041 #include <algorithm>
00042 #include <cassert>
00043
00044 namespace strmod {
00045 namespace strmod {
00046
00047 const STR_ClassIdent CharChopper::identifier(26UL);
00048
00049 void CharChopper::addChunk(const StrChunkPtr &chnk)
00050 {
00051 bool iscurdata = false;
00052
00053 if (chnk.GetPtr() == curdata_.GetPtr())
00054 {
00055 curdata_->resize(usedsize_);
00056 iscurdata = true;
00057 }
00058 else if (curdata_)
00059 {
00060 addChunk(curdata_);
00061 }
00062 if (outgoing_)
00063 {
00064 if (!groupdata_)
00065 {
00066 if (outgoing_->AreYouA(GroupChunk::identifier))
00067 {
00068 groupdata_ = static_cast<GroupChunk *>(outgoing_.GetPtr());
00069 }
00070 else
00071 {
00072 groupdata_ = new GroupChunk;
00073 groupdata_->push_back(outgoing_);
00074 outgoing_ = groupdata_;
00075 }
00076 groupdata_->push_back(chnk);
00077 }
00078 else
00079 {
00080 assert(outgoing_.GetPtr() == groupdata_.GetPtr());
00081 groupdata_->push_back(chnk);
00082 }
00083 }
00084 else
00085 {
00086 if (groupdata_)
00087 {
00088 groupdata_.ReleasePtr();
00089 }
00090 outgoing_ = chnk;
00091 }
00092 if (iscurdata)
00093 {
00094 curdata_.ReleasePtr();
00095 }
00096 }
00097
00098 void CharChopper::processIncoming()
00099 {
00100 assert(incoming_);
00101 assert(!outgoing_ready_);
00102 checkIncoming();
00103 assert(incoming_is_bc_ != INMaybe);
00104
00105 unsigned int inlen = incoming_->Length();
00106
00107 if (inlen <= 0)
00108 {
00109 addChunk(incoming_);
00110 zeroIncoming();
00111 }
00112 else
00113 {
00114 char buf[16];
00115 size_t count = 0;
00116 bool foundchar = false;
00117
00118 {
00119 StrChunk::const_iterator end = incoming_->end();
00120 for (StrChunk::const_iterator i = incoming_->begin();
00121 !foundchar && i != end; ++i)
00122 {
00123 if (count < 16)
00124 {
00125 buf[count] = *i;
00126 }
00127 count++;
00128 if (*i == chopchar_)
00129 {
00130 foundchar = true;
00131 }
00132 }
00133 }
00134 assert((count >= inlen) || foundchar);
00135 if ((incoming_is_bc_ == INYes) && (count <= 16))
00136 {
00137 if (!curdata_)
00138 {
00139 if (foundchar)
00140 {
00141 curdata_ = new PreAllocBuffer<16>;
00142 curdata_->resize(count);
00143 }
00144 else
00145 {
00146 curdata_ = new DynamicBuffer(32);
00147 }
00148 memcpy(curdata_->getVoidP(), buf, count);
00149 usedsize_ = count;
00150 }
00151 else
00152 {
00153 unsigned int curlen = curdata_->Length();
00154 size_t usedshadow = usedsize_;
00155 if (curlen < (usedshadow + count))
00156 {
00157 if (foundchar)
00158 {
00159 curlen = usedshadow + count;
00160 }
00161 else
00162 {
00163 curlen = std::max(usedshadow + usedshadow / 2, usedshadow + count);
00164 }
00165 curdata_->resize(curlen);
00166 }
00167 memcpy(curdata_->getCharP() + usedshadow, buf, count);
00168 usedsize_ = usedshadow = (usedshadow + count);
00169 }
00170 }
00171 else
00172 {
00173 if (count >= inlen)
00174 {
00175 addChunk(incoming_);
00176 }
00177 else
00178 {
00179 addChunk(new StrSubChunk(incoming_, LinearExtent(0, count)));
00180 }
00181 }
00182 if (count >= inlen)
00183 {
00184 zeroIncoming();
00185 }
00186 else
00187 {
00188 replaceIncoming(new StrSubChunk(incoming_,
00189 LinearExtent(count, inlen)));
00190 }
00191 if (foundchar && curdata_)
00192 {
00193 addChunk(curdata_);
00194 }
00195 outgoing_ready_ = foundchar;
00196 }
00197 }
00198
00199 };
00200 };