StringArray.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "StringArray.h"
00019 #include "InputFile.h"
00020 #include "Sort.h"
00021 #include "Error.h"
00022
00023 #include <string.h>
00024
00025 int StringArray::alloc = 32;
00026 bool StringArray::lazyMemoryManagement = false;
00027
00028 StringArray::StringArray(int startsize)
00029 {
00030 count = startsize;
00031 size = (startsize + alloc) / alloc * alloc;
00032 strings = new String * [size];
00033 for (int i = 0; i < count; i++)
00034 strings[i] = new String;
00035 for (int i = count; i < size; i++)
00036 strings[i] = NULL;
00037 };
00038
00039 StringArray::StringArray(StringArray & rhs)
00040 {
00041 count = rhs.count;
00042 size = (rhs.count + alloc) / alloc * alloc;
00043 strings = new String * [size];
00044
00045 for (int i = 0; i < count; i++)
00046 strings[i] = new String(rhs[i]);;
00047 for (int i = count; i < size; i++)
00048 strings[i] = NULL;
00049 }
00050
00051 StringArray::~StringArray()
00052 {
00053 for (int i = 0; i < size; i++)
00054 if (strings[i] != NULL)
00055 delete strings[i];
00056 else
00057 break;
00058
00059 delete [] strings;
00060 }
00061
00062 int StringArray::CharLength()
00063 {
00064 int charlen = 0;
00065 for (int i = 0; i < count; i++)
00066 charlen += strings[i]->Length();
00067 return charlen;
00068 }
00069
00070 void StringArray::Read(const char * filename)
00071 {
00072 IFILE f = ifopen(filename, "rb");
00073 if (f == NULL) return;
00074 Read(f);
00075 ifclose(f);
00076 }
00077
00078 void StringArray::Write(const char * filename)
00079 {
00080 FILE * f = fopen(filename, "wt");
00081 if (f == NULL) return;
00082 Write(f);
00083 fclose(f);
00084 }
00085
00086 void StringArray::WriteLine(const char * filename)
00087 {
00088 FILE * f = fopen(filename, "wt");
00089 if (f == NULL) return;
00090 WriteLine(f);
00091 fclose(f);
00092 }
00093
00094 void StringArray::Read(FILE * f)
00095 {
00096 while (!feof(f))
00097 {
00098 Grow(count + 1);
00099 if (strings[count] == NULL)
00100 strings[count] = new String;
00101 strings[count]->ReadLine(f);
00102 count++;
00103 }
00104 }
00105
00106 void StringArray::Write(FILE * f)
00107 {
00108 for (int i = 0; i < count; i++)
00109 strings[i]->WriteLine(f);
00110 }
00111
00112 void StringArray::WriteLine(FILE * f)
00113 {
00114 for (int i = 0; i < count; i++)
00115 fprintf(f, "%s%c", (const char *)(*strings[i]), i == count-1 ? '\n' : '\t');
00116 }
00117
00118 #ifdef __ZLIB_AVAILABLE__
00119 void StringArray::Read(IFILE & f)
00120 {
00121 while (!ifeof(f))
00122 {
00123 Grow(count + 1);
00124 if (strings[count] == NULL)
00125 strings[count] = new String;
00126 strings[count]->ReadLine(f);
00127 if (ifeof(f) && strings[count]->Length()==0)
00128 {
00129 return;
00130 }
00131 count++;
00132 }
00133 }
00134 #endif
00135
00136 void StringArray::Grow(int newsize)
00137 {
00138 if (newsize >= size)
00139 {
00140 int oldsize = size;
00141
00142 if ((newsize >> 1) >= size)
00143 size = (newsize + alloc) / alloc * alloc;
00144 else
00145 {
00146 size = alloc;
00147 while (size <= newsize)
00148 size *= 2;
00149 }
00150 String ** tmp = new String * [size];
00151 for (int i = 0; i < oldsize; i++)
00152 tmp[i] = strings[i];
00153 for (int i = oldsize; i < size; i++)
00154 tmp[i] = NULL;
00155 delete [] strings;
00156 strings = tmp;
00157 }
00158 }
00159
00160 void StringArray::Clear()
00161 {
00162 if (!lazyMemoryManagement)
00163 {
00164 for (int i = 0; i < size; i++)
00165 {
00166 if (strings[i] != NULL)
00167 {
00168 delete strings[i];
00169 strings[i] = NULL;
00170 }
00171 else
00172 {
00173 break;
00174 }
00175 }
00176 }
00177 count = 0;
00178 }
00179
00180 int StringArray::AddColumns(const String & s, char ch)
00181 {
00182 if (s.Length() > 0)
00183 for (int pos = 0; pos <= s.Length(); pos++)
00184 {
00185 int oldpos = pos;
00186 pos = s.FindChar(ch, pos);
00187 if (pos == -1) pos = s.Length();
00188 Grow(count + 1);
00189
00190 if (strings[count] == NULL)
00191 {
00192 strings[count] = new String(pos - oldpos);
00193 }
00194 strings[count]->SetLength(pos - oldpos);
00195 memcpy((char *) *strings[count++], ((const char *) s) + oldpos, pos - oldpos);
00196 }
00197
00198 return count;
00199 }
00200
00201 int StringArray::AddColumns(const String & s, char ch, int maxColumns)
00202 {
00203 maxColumns += count;
00204
00205 if (s.Length() > 0)
00206 for (int pos = 0; pos <= s.Length() && maxColumns != count; pos++)
00207 {
00208 int oldpos = pos;
00209 pos = s.FindChar(ch, pos);
00210 if (pos == -1) pos = s.Length();
00211 Grow(count + 1);
00212
00213 if (strings[count] == NULL)
00214 strings[count] = new String(pos - oldpos);
00215 strings[count]->SetLength(pos - oldpos);
00216 memcpy((char *) *strings[count++], ((const char *) s) + oldpos, pos - oldpos);
00217 };
00218
00219 return count;
00220 }
00221
00222 int StringArray::AddTokens(const String & s, char ch)
00223 {
00224 for (int pos = 0; pos < s.Length(); pos++)
00225 {
00226 while (pos < s.Length() && s[pos] == ch) pos++;
00227 int oldpos = pos;
00228
00229 while (pos < s.Length() && s[pos] != ch) pos++;
00230
00231 if (oldpos < s.Length())
00232 {
00233 Grow(count + 1);
00234 if (strings[count] == NULL)
00235 {
00236 strings[count] = new String(pos - oldpos);
00237 }
00238 strings[count]->SetLength(pos - oldpos);
00239 memcpy((char *) *strings[count++], (const char *) s + oldpos, pos - oldpos);
00240 }
00241 }
00242
00243 return count;
00244 }
00245
00246 int StringArray::AddTokens(const String & s, const String & separators)
00247 {
00248 for (int pos = 0; pos < s.Length(); pos++)
00249 {
00250 while (pos < s.Length() && separators.FindChar(s[pos]) != -1) pos++;
00251 int oldpos = pos;
00252
00253 while (pos < s.Length() && separators.FindChar(s[pos]) == -1) pos++;
00254
00255 if (oldpos < s.Length())
00256 {
00257 Grow(count + 1);
00258 if (strings[count] == NULL)
00259 strings[count] = new String(pos - oldpos);
00260 strings[count]->SetLength(pos - oldpos);
00261 memcpy((char *) *strings[count++], ((const char *) s) + oldpos, pos - oldpos);
00262 }
00263 }
00264
00265 return count;
00266 }
00267
00268 int StringArray::Dimension(int newcount)
00269 {
00270 if (newcount > count)
00271 {
00272 Grow(newcount);
00273 for (int i = count; i < newcount; i++)
00274 {
00275 if (strings[i] == NULL)
00276 strings[i] = new String;
00277 else
00278 strings[i]->Clear();
00279 }
00280 count = newcount;
00281 }
00282 else if (newcount < count)
00283 {
00284 if (!lazyMemoryManagement)
00285 {
00286 for (int i = newcount; i < size; i++)
00287 {
00288 if (strings[i] != NULL)
00289 {
00290 delete strings[i];
00291 strings[i] = NULL;
00292 }
00293 else
00294 {
00295 break;
00296 }
00297 }
00298 }
00299 count = newcount;
00300 }
00301
00302 return count;
00303 }
00304
00305 int StringArray::Find(const String & s) const
00306 {
00307 for (int i = 0; i < count; i++)
00308 if (*(strings[i]) == s)
00309 return i;
00310 return -1;
00311 }
00312
00313 int StringArray::FastFind(const String & s) const
00314 {
00315 for (int i = 0; i < count; i++)
00316 if (strings[i]->FastCompare(s) == 0)
00317 return i;
00318 return -1;
00319 }
00320
00321 int StringArray::SlowFind(const String & s) const
00322 {
00323 for (int i = 0; i < count; i++)
00324 if (strings[i]->SlowCompare(s) == 0)
00325 return i;
00326 return -1;
00327 }
00328
00329 int StringArray::Add(const String & s)
00330 {
00331 Grow(count + 1);
00332 if (strings[count] == NULL)
00333 {
00334 strings[count] = new String(s);
00335 }
00336 else
00337 {
00338 *strings[count] = s;
00339 }
00340 return ++count;
00341 }
00342
00343 void StringArray::InsertAt(int position, const String & s)
00344 {
00345 Grow(count + 1);
00346
00347 String * newString = strings[count];
00348 if (newString == NULL)
00349 newString = new String(s);
00350 else
00351 *newString = s;
00352
00353 for (int i = count; i > position; i--)
00354 strings[i] = strings[i - 1];
00355 strings[position] = newString;
00356 count++;
00357 }
00358
00359 String & StringArray::Last() const
00360 {
00361 if (!count) error("StringArray: Null String Access");
00362 return *(strings[count - 1]);
00363 }
00364
00365 void StringArray::Delete(int index)
00366 {
00367 String * oldString = strings[index];
00368
00369 count--;
00370 for (; index < count; index++)
00371 strings[index] = strings[index + 1];
00372 strings[count] = oldString;
00373 }
00374
00375 StringArray & StringArray::operator = (const StringArray & rhs)
00376 {
00377 Dimension(rhs.count);
00378 for (int i = 0; i < rhs.count; i++)
00379 *strings[i] = *rhs.strings[i];
00380 return *this;
00381 }
00382
00383 bool StringArray::operator == (const StringArray & rhs)
00384 {
00385 if (count != rhs.count) return false;
00386 for (int i = 0; i < rhs.count; i++)
00387 if (*strings[i] != *rhs.strings[i])
00388 return false;
00389 return true;
00390 }
00391
00392 void StringArray::Sort()
00393 {
00394 QuickSort(strings, count, sizeof(String *), ComparisonForSort);
00395 }
00396
00397 int StringArray::ComparisonForSort(const void * a, const void * b)
00398 {
00399 String * string1 = *(String **) a;
00400 String * string2 = *(String **) b;
00401
00402 return Compare(*string1, *string2);
00403 }
00404
00405 String StringArray::Pop()
00406 {
00407 String result = *(strings[count - 1]);
00408
00409 Dimension(count - 1);
00410
00411 return result;
00412 }
00413
00414 void StringArray::Trim()
00415 {
00416 for (int i = 0; i < count; i++)
00417 strings[i]->Trim();
00418 }
00419
00420 void StringArray::Print()
00421 {
00422 Print(stdout);
00423 }
00424
00425 void StringArray::Print(FILE * output)
00426 {
00427 for (int i = 0; i < count; i++)
00428 fprintf(output, "%s\n", (const char *)(*strings[i]));
00429 }
00430
00431 void StringArray::PrintLine()
00432 {
00433 PrintLine(stdout);
00434 }
00435
00436 void StringArray::PrintLine(FILE * output)
00437 {
00438 for (int i = 0; i < count; i++)
00439 fprintf(output, "%s%c", (const char *)(*strings[i]), i == count - 1 ? '\n' : '\t');
00440 }
00441
00442 void StringArray::Swap(StringArray & s)
00443 {
00444 String ** temp = s.strings;
00445 s.strings = strings;
00446 strings = temp;
00447
00448 int swap = s.size;
00449 s.size = size;
00450 size = swap;
00451
00452 swap = s.count;
00453 s.count = count;
00454 count = swap;
00455 }
00456