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 #include "DcBuffer.h"
00026
00027 CdcBuffer::CdcBuffer()
00028 : aBuffer (NULL), nSize (0), nGrow (DEFAULT_SIZE), nDataSize (0),
00029 pRefCount (new int (1)), pMutex (new CdcMutex ())
00030 { }
00031
00032
00033 CdcBuffer::CdcBuffer (unsigned int size, int grow) throw (CdcException)
00034 : aBuffer (NULL), nSize (0), nGrow (grow), nDataSize (0),
00035 pRefCount (new int (1)), pMutex (new CdcMutex ())
00036 {
00037 PreperRoom (size);
00038 }
00039
00040
00041 void CdcBuffer::PreperRoom (int size) throw (CdcException)
00042 {
00043 bool ref_copy = false;
00044 bool increase_space = false;
00045
00046 pMutex->Lock ();
00047
00048 if (*pRefCount > 1)
00049 {
00050 --(*pRefCount);
00051 pRefCount = new int (1);
00052 ref_copy = true;
00053 }
00054
00055 if (nSize < nDataSize + size)
00056 {
00057 increase_space = true;
00058
00059 if (nGrow < 1) nGrow = DEFAULT_SIZE;
00060 int factor = (((nDataSize + size) - nSize) / nGrow) + 1;
00061 nSize += factor * nGrow;
00062 }
00063
00064 if (increase_space || ref_copy)
00065 {
00066
00067 t_buff_unit* temp = new t_buff_unit [nSize];
00068 if (temp == NULL)
00069 {
00070 pMutex->Unlock ();
00071 if (ref_copy == true)
00072 {
00073 aBuffer = NULL;
00074 pMutex = NULL;
00075 }
00076 throw (CdcException ("Out of memory!"));
00077 }
00078
00079 memcpy (temp, aBuffer, nDataSize);
00080
00081 if (!ref_copy && aBuffer != NULL)
00082 delete aBuffer;
00083
00084 aBuffer = temp;
00085 }
00086
00087 pMutex->Unlock ();
00088 if (ref_copy)
00089 pMutex = new CdcMutex ();
00090 }
00091
00092
00093 void CdcBuffer::Attach (const CdcBuffer& buff)
00094 {
00095
00096 buff.pMutex->Lock ();
00097
00098 aBuffer = buff.aBuffer;
00099 pRefCount = buff.pRefCount;
00100 nDataSize = buff.nDataSize;
00101 nSize = buff.nSize;
00102 nGrow = buff.nGrow;
00103 pMutex = buff.pMutex;
00104
00105 (*pRefCount)++;
00106
00107 buff.pMutex->Unlock ();
00108 }
00109
00110
00111 void CdcBuffer::Detach ()
00112 {
00113
00114 pMutex->Lock ();
00115
00116 if (--(*pRefCount) == 0)
00117 {
00118 if (aBuffer != NULL)
00119 {
00120 delete aBuffer;
00121 aBuffer = NULL;
00122 }
00123 if (pRefCount != NULL)
00124 {
00125 delete pRefCount;
00126 pRefCount = NULL;
00127 }
00128
00129 delete pMutex;
00130 }
00131 else
00132 pMutex->Unlock ();
00133 }
00134
00135
00136 const CdcBuffer& CdcBuffer::operator = (const CdcBuffer& buff)
00137 {
00138 if (aBuffer != buff.aBuffer)
00139 {
00140 Detach ();
00141 Attach (buff);
00142 }
00143
00144 return *this;
00145 }
00146
00147
00148 t_buff_unit CdcBuffer::operator[] (int index) const throw (CdcException)
00149 {
00150 if (index < 0 || index >= nDataSize)
00151 throw (CdcException ("Index out of bounds!"));
00152
00153 return aBuffer [index];
00154 }
00155
00156
00157 CdcBuffer& CdcBuffer::Append (const t_buff_unit data) throw (CdcException)
00158 {
00159 PreperRoom (1);
00160 aBuffer [nDataSize++] = data;
00161 return *this;
00162 }
00163
00164 CdcBuffer& CdcBuffer::Append (CdcString& data) throw (CdcException)
00165 {
00166 PreperRoom (data.GetLength ());
00167 memcpy (aBuffer + nDataSize, data.GetBuffer (),
00168 data.GetLength ());
00169 nDataSize += data.GetLength ();
00170 return *this;
00171 }
00172
00173 CdcBuffer& CdcBuffer::Append (const CdcBuffer& data) throw (CdcException)
00174 {
00175 PreperRoom (data.nDataSize);
00176 memcpy (aBuffer + nDataSize, data.aBuffer, data.nDataSize);
00177 nDataSize += data.nDataSize;
00178 return *this;
00179 }
00180
00181 CdcBuffer& CdcBuffer::Append (int data) throw (CdcException)
00182 {
00183 char temp [15];
00184 sprintf (temp, "%d", data);
00185 Append (temp);
00186 return *this;
00187 }
00188
00189 CdcBuffer& CdcBuffer::Append (const t_buff_unit* data,
00190 int length) throw (CdcException)
00191 {
00192 if (length < 0)
00193 length = strlen (data);
00194
00195 PreperRoom (length);
00196 memcpy (aBuffer + nDataSize, data, length);
00197 nDataSize += length;
00198 return *this;
00199 }
00200
00201
00202 int CdcBuffer::GetSize () const
00203 {
00204 return nSize;
00205 }
00206
00207 int CdcBuffer::GetDataSize () const
00208 {
00209 return nDataSize;
00210 }
00211
00212 t_buff_unit* CdcBuffer::GetPointer () const
00213 {
00214 return aBuffer;
00215 }
00216
00217
00218 int CdcBuffer::Find (const char* str, int start, int stop) const
00219 {
00220 if (str == NULL) return -1;
00221 if (start >= nDataSize) return -1;
00222 if (stop == 0) stop = nDataSize;
00223 char* pbuf = aBuffer + start;
00224 int str_leng = strlen (str), i;
00225
00226 while (pbuf - aBuffer <= stop - str_leng)
00227 {
00228 i = 0;
00229 while (pbuf[i] == str[i])
00230 if (++i == str_leng)
00231 return pbuf - aBuffer;
00232 pbuf++;
00233 }
00234
00235 return -1;
00236 }
00237
00238
00239 int CdcBuffer::Find (char chr, int start, int stop) const
00240 {
00241 if (start >= nDataSize) return -1;
00242 if (stop == 0) stop = nDataSize;
00243 char* pbuf = aBuffer + start;
00244
00245 while (pbuf - aBuffer < stop)
00246 if (*pbuf == chr)
00247 return pbuf - aBuffer;
00248 else
00249 ++pbuf;
00250
00251 return -1;
00252 }
00253
00254
00255 int CdcBuffer::ReplaceAll (const char* strold, const char* strnew,
00256 int stroldlen, int strnewlen,
00257 int start, int stop)
00258 {
00259 if (strold == NULL) return 0;
00260 int count = 1;
00261 int list [100];
00262
00263 if (stroldlen < 0)
00264 stroldlen = strlen (strold);
00265 if (strnewlen < 0)
00266 strnewlen = strlen (strnew);
00267
00268 CdcString temp (strold, stroldlen);
00269 list[0] = Find (temp, start, stop);
00270 if (list[0] == -1) return 0;
00271 while ((list[count] = Find (temp, list [count - 1] + 1, stop)) != -1)
00272 {
00273 ++count;
00274 if (count == 100) return 0;
00275 }
00276
00277
00278 int i, size_gap = (strnewlen - stroldlen);
00279 PreperRoom (size_gap * count);
00280
00281 for (i = 0; i < count; ++i)
00282 memmove (aBuffer + list[i] + (size_gap * i) + strnewlen,
00283 aBuffer + list[i] + (size_gap * i) + stroldlen,
00284 nDataSize - (list[i] + stroldlen));
00285
00286 for (i = 0; i < count; ++i)
00287 memcpy (aBuffer + list[i] + (size_gap * i),
00288 strnew, strnewlen);
00289
00290 nDataSize += (size_gap * count);
00291 return count;
00292 }
00293
00294
00295 int CdcBuffer::ReplaceAll (char old_chr, char new_chr)
00296 {
00297
00298 PreperRoom (0);
00299 int place = -1, count = 0;
00300
00301 while ((place = Find (old_chr, place + 1)) != -1)
00302 {
00303 aBuffer [place] = new_chr;
00304 ++ count;
00305 }
00306
00307 return count;
00308 }
00309
00310
00311 bool CdcBuffer::IsWhiteSpaces (int start, int stop)
00312 {
00313 if (start >= nDataSize) return false;
00314 if (stop == 0) stop = nDataSize;
00315 if (stop < start) return false;
00316
00317 for (int i = start; i < stop; ++i)
00318 if (isspace (aBuffer[i]) == false)
00319 return false;
00320 return true;
00321 }