00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef _WIN32
00018 #include <spl/configwin32.h>
00019 #include <stdio.h>
00020 #else
00021 #include <spl/autoconf/config.h>
00022 #endif
00023 #include <stdio.h>
00024 #include <memory.h>
00025 #include <spl/Int32.h>
00026 #include <spl/text/StringBuffer.h>
00027
00028 void StringBuffer::Init(int size)
00029 {
00030 m_buf = new char[size];
00031 m_used = 0;
00032 m_len = size;
00033 m_buf[0] = '\0';
00034 }
00035
00036 StringBuffer::StringBuffer()
00037 {
00038 Init(20);
00039 }
00040
00041 StringBuffer::StringBuffer(const char *str)
00042 {
00043 Init((int)strlen(str) + 1);
00044 Append(str);
00045 }
00046
00047 StringBuffer::StringBuffer(int size)
00048 {
00049 Init(size);
00050 }
00051
00052 StringBuffer::StringBuffer(const StringBuffer& sb)
00053 {
00054 Init(sb.m_len + 1);
00055 Append(sb.m_buf);
00056 }
00057
00058 StringBuffer::~StringBuffer()
00059 {
00060 delete[] m_buf;
00061 }
00062
00063 #ifdef BSTR
00064 StringBuffer::StringBuffer(BSTR str)
00065 {
00066 m_len = SysStringLen(str) +1;
00067
00068 m_buf = new char[len];
00069 for (m_used = 0; m_used < m_len; m_used++)
00070 {
00071 buf[m_used] = (char)str[m_used];
00072 }
00073 m_buf[m_used] = '\0';
00074 }
00075 #endif
00076
00077 void StringBuffer::Trim()
00078 {
00079 ASSERT_MEM(m_buf, m_len);
00080 int x;
00081 for (x = m_used-1; x >= 0; x--)
00082 {
00083 if (m_buf[x] != ' ')
00084 {
00085 break;
00086 }
00087 m_buf[x] = '\0';
00088 }
00089 m_used = x + 1;
00090 if ( ' ' == m_buf[0] )
00091 {
00092 x = 1;
00093 while ( ' ' == m_buf[x] )
00094 {
00095 x++;
00096 }
00097 ASSERT(' ' != m_buf[x]);
00098 memcpy(&m_buf[0], &m_buf[x], m_used - x);
00099 m_used -= x;
00100 }
00101 m_buf[m_used] = '\0';
00102 }
00103
00104
00105
00106
00107
00108
00109 void StringBuffer::Append(const char *str)
00110 {
00111 ASSERT_MEM(m_buf, m_len);
00112
00113 int alen = (int)strlen(str);
00114
00115 while (alen + m_used + 1 > m_len)
00116 {
00117 Extend();
00118 }
00119 int x;
00120 for (x = 0; x < alen; x++)
00121 {
00122 m_buf[m_used + x] = str[x];
00123 }
00124 m_buf[m_used + x] = '\0';
00125 m_used += alen;
00126
00127 ASSERT(m_buf[m_used] == '\0');
00128 }
00129
00130 void StringBuffer::Fill(char ch, int len)
00131 {
00132 while ( len-- > 0 )
00133 {
00134 Append(ch);
00135 }
00136 }
00137
00142 void StringBuffer::Insert(int index, const char *str)
00143 {
00144 ASSERT(m_buf[m_used] == '\0');
00145 ASSERT_MEM(m_buf, m_len);
00146
00147 int x;
00148 int alen = (int)strlen(str);
00149
00150 ExtendTo(m_used + alen + 1);
00151 for ( x = (m_used-index)-1; x >= 0; x-- )
00152 {
00153 m_buf[index+alen+x] = m_buf[index+x];
00154 }
00155 for (x = 0; x < alen; x++)
00156 {
00157 m_buf[index+x] = str[x];
00158 }
00159 m_used = m_used + alen;
00160 ASSERT( m_used < m_len );
00161 m_buf[m_used] = '\0';
00162 ValidateMem();
00163 }
00164
00165 void StringBuffer::SetCharAt(const int index, char c)
00166 {
00167 ASSERT_MEM(m_buf, m_len);
00168 ASSERT(m_buf[m_used] == '\0');
00169
00170 ExtendTo(index);
00171 m_buf[index] = c;
00172
00173 if (index == m_used)
00174 {
00175 if (m_used == m_len)
00176 {
00177 Extend();
00178 }
00179 m_buf[index+1] = '\0';
00180 m_used++;
00181 }
00182 ASSERT(m_buf[m_used] == '\0');
00183 ASSERT_MEM(m_buf, m_len);
00184 }
00185
00186 void StringBuffer::RemoveCharAt( int idx )
00187 {
00188 ASSERT_MEM(m_buf, m_len);
00189 ASSERT(m_buf[m_used] == '\0');
00190
00191 if ( idx >= m_used || idx < 0 )
00192 {
00193 return;
00194 }
00195 memmove( &m_buf[idx], &m_buf[idx+1], m_used-idx );
00196 m_used--;
00197 }
00198
00199 StringBuffer& StringBuffer::operator =(const char *str)
00200 {
00201 ASSERT_MEM(m_buf, m_len);
00202 m_used = 0;
00203 Append(str);
00204
00205 return *this;
00206 }
00207
00208 StringBuffer& StringBuffer::operator =(const StringBuffer& sb )
00209 {
00210 ASSERT_MEM(m_buf, m_len);
00211 m_used = 0;
00212 Append(sb.m_buf);
00213
00214 return *this;
00215 }
00216
00217 bool StringBuffer::IsNumeric() const
00218 {
00219 bool sawdot = false;
00220 ASSERT(m_buf[m_used] == '\0');
00221 ASSERT_MEM(m_buf, m_len);
00222
00223 for (int x = 0; x < m_used; x++)
00224 {
00225 if (! isdigit(m_buf[x]))
00226 {
00227 if ( !sawdot && '.' == m_buf[x] )
00228 {
00229 sawdot = true;
00230 }
00231 else
00232 {
00233 return false;
00234 }
00235 }
00236 }
00237 return true;
00238 }
00239
00240 int StringBuffer::ToInt() const
00241 {
00242 return Int32::Parse(m_buf);
00243 }
00244
00245 void StringBuffer::ExtendTo(int index)
00246 {
00247 ASSERT_MEM(m_buf, m_len);
00248
00249 if (index > m_len)
00250 {
00251 char *newbuf;
00252
00253 if ((newbuf = new char[index + 1]) == NULL)
00254 {
00255 throw OutOfMemoryException();
00256 }
00257 memcpy(newbuf, m_buf, m_len);
00258 m_len = index+1;
00259 delete[] m_buf;
00260 m_buf = newbuf;
00261 ASSERT_MEM(m_buf, m_len);
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 ASSERT(m_buf[m_used] == '\0');
00273 ASSERT_MEM(m_buf, m_len);
00274 }
00275
00276 void StringBuffer::Extend()
00277 {
00278 ASSERT_MEM(m_buf, m_len);
00279
00280 int newlen = m_len*2;
00281 char *newbuf;
00282
00283 newbuf = new char[newlen];
00284
00285 memcpy(newbuf, m_buf, m_len);
00286 m_len = newlen;
00287 delete[] m_buf;
00288 m_buf = newbuf;
00289 ASSERT_MEM(m_buf, m_len);
00290 }
00291
00292 int StringBuffer::IndexOf( const char *cp, const int start ) const
00293 {
00294 for ( int pos = start; pos < m_len; pos++ )
00295 {
00296 int end;
00297 int cppos = 1;
00298
00299 if ( m_buf[pos] == cp[0] )
00300 {
00301 for( end = pos+1; end < m_len && cp[cppos] != '\0'; end++ )
00302 {
00303 if ( m_buf[end] != cp[cppos] )
00304 {
00305 break;
00306 }
00307 cppos++;
00308 }
00309 if ( cp[cppos] == '\0' )
00310 {
00311 return pos;
00312 }
00313 }
00314 }
00315 return -1;
00316 }
00317
00318 int StringBuffer::IndexOfIgnoreCase( const char *cp, const int start ) const
00319 {
00320 for ( int pos = start; pos < m_len; pos++ )
00321 {
00322 if ( tolower(m_buf[pos]) == tolower(cp[0]) )
00323 {
00324 int end;
00325 int cppos = 1;
00326 for( end = pos+1; end < m_len && cp[cppos] != '\0'; end++ )
00327 {
00328 if ( m_buf[end] != cp[cppos] && tolower(m_buf[end]) != tolower(cp[cppos]) )
00329 {
00330 break;
00331 }
00332 cppos++;
00333 }
00334 if ( cp[cppos] == '\0' )
00335 {
00336 return pos;
00337 }
00338 }
00339 }
00340 return -1;
00341 }
00342
00343 void StringBuffer::Replace( const char from, const char to )
00344 {
00345 for ( int x = 0; x < m_used; x++ )
00346 {
00347 if ( m_buf[x] == from )
00348 {
00349 m_buf[x] = to;
00350 }
00351 }
00352 }
00353
00354 void StringBuffer::ToLower()
00355 {
00356 for (int x = 0; x < m_used; x++)
00357 {
00358 m_buf[x] = tolower(m_buf[x]);
00359 }
00360 }
00361
00362 void StringBuffer::ToUpper()
00363 {
00364 for (int x = 0; x < m_used; x++)
00365 {
00366 m_buf[x] = toupper(m_buf[x]);
00367 }
00368 }
00369
00370 StringPtr StringBuffer::ToString() const
00371 {
00372 return StringPtr( new String(m_buf) );
00373 }
00374
00375 RefCountPtr<Array<byte> > StringBuffer::ToByteArray() const
00376 {
00377 return String(m_buf).ToByteArray();
00378 }
00379
00380 #if defined(DEBUG)
00381 void StringBuffer::CheckMem() const
00382 {
00383 DEBUG_NOTE_MEM_ALLOCATION(m_buf);
00384 }
00385
00386 void StringBuffer::ValidateMem() const
00387 {
00388 ASSERT_MEM(m_buf, m_len);
00389 }
00390 #endif
00391