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 "Sort.h"
00020 #include "Error.h"
00021
00022 int StringArray::alloc = 32;
00023
00024 StringArray::StringArray(int startsize)
00025 {
00026 count = startsize;
00027 size = (startsize + alloc) / alloc * alloc;
00028 strings = new String * [size];
00029 for (int i = 0; i < count; i++)
00030 strings[i] = new String;
00031 };
00032
00033 StringArray::StringArray(StringArray & rhs)
00034 {
00035 count = rhs.count;
00036 size = (rhs.count + alloc) / alloc * alloc;
00037 strings = new String * [size];
00038
00039 for (int i = 0; i < count; i++)
00040 strings[i] = new String(rhs[i]);;
00041 }
00042
00043 StringArray::~StringArray()
00044 {
00045 for (int i = 0; i < count; i++)
00046 delete strings[i];
00047 delete [] strings;
00048 }
00049
00050 int StringArray::CharLength()
00051 {
00052 int charlen = 0;
00053 for (int i = 0; i < count; i++)
00054 charlen += strings[i]->Length();
00055 return charlen;
00056 }
00057
00058 void StringArray::Read(const char * filename)
00059 {
00060 IFILE f = ifopen(filename, "rb");
00061 if (f == NULL) return;
00062 Read(f);
00063 ifclose(f);
00064 }
00065
00066 void StringArray::Write(const char * filename)
00067 {
00068 FILE * f = fopen(filename, "wt");
00069 if (f == NULL) return;
00070 Write(f);
00071 fclose(f);
00072 }
00073
00074 void StringArray::WriteLine(const char * filename)
00075 {
00076 FILE * f = fopen(filename, "wt");
00077 if (f == NULL) return;
00078 WriteLine(f);
00079 fclose(f);
00080 }
00081
00082 void StringArray::Read(FILE * f)
00083 {
00084 while (!feof(f))
00085 {
00086 Grow(count + 1);
00087 strings[count] = new String;
00088 strings[count]->ReadLine(f);
00089 count++;
00090 }
00091 }
00092
00093 void StringArray::Write(FILE * f)
00094 {
00095 for (int i = 0; i < count; i++)
00096 strings[i]->WriteLine(f);
00097 }
00098
00099 void StringArray::WriteLine(FILE * f)
00100 {
00101 for (int i = 0; i < count; i++)
00102 fprintf(f, "%s%c", (const char *)(*strings[i]), i == count-1 ? '\n' : '\t');
00103 }
00104
00105 #ifdef __ZLIB_AVAILABLE__
00106 void StringArray::Read(IFILE & f)
00107 {
00108 while (!ifeof(f))
00109 {
00110 Grow(count + 1);
00111 strings[count] = new String;
00112 strings[count]->ReadLine(f);
00113 if (ifeof(f) && strings[count]->Length()==0)
00114 {
00115 delete strings[count];
00116 break;
00117 }
00118 count++;
00119 }
00120 }
00121 #endif
00122
00123 void StringArray::Grow(int newsize)
00124 {
00125 if (newsize >= size)
00126 {
00127 if ((newsize >> 1) >= size)
00128 size = (newsize + alloc) / alloc * alloc;
00129 else
00130 {
00131 size = alloc;
00132 while (size <= newsize)
00133 size *= 2;
00134 }
00135 String ** tmp = new String * [size];
00136 for (int i = 0; i < count; i++) tmp[i] = strings[i];
00137 delete [] strings;
00138 strings = tmp;
00139 }
00140 }
00141
00142 void StringArray::Clear()
00143 {
00144 for (int i = 0; i < count; i++)
00145 delete strings[i];
00146 count = 0;
00147 }
00148
00149 int StringArray::AddColumns(const String & s, char ch)
00150 {
00151 if (s.Length() > 0)
00152 for (int pos = 0; pos <= s.Length(); pos++)
00153 {
00154 int oldpos = pos;
00155 pos = s.FindChar(ch, pos);
00156 if (pos == -1) pos = s.Length();
00157 Grow(count + 1);
00158 strings[count++] = new String(s.Mid(oldpos, pos - 1));
00159 };
00160
00161 return count;
00162 }
00163
00164 int StringArray::AddTokens(const String & s, char ch)
00165 {
00166 for (int pos = 0; pos < s.Length(); pos++)
00167 {
00168 while (pos < s.Length() && s[pos] == ch) pos++;
00169 int oldpos = pos;
00170
00171 while (pos < s.Length() && s[pos] != ch) pos++;
00172
00173 if (oldpos < s.Length())
00174 {
00175 Grow(count + 1);
00176 strings[count++] = new String(s.Mid(oldpos, pos - 1));
00177 }
00178 }
00179
00180 return count;
00181 }
00182
00183 int StringArray::AddTokens(const String & s, const String & separators)
00184 {
00185 for (int pos = 0; pos < s.Length(); pos++)
00186 {
00187 while (pos < s.Length() && separators.FindChar(s[pos]) != -1) pos++;
00188 int oldpos = pos;
00189
00190 while (pos < s.Length() && separators.FindChar(s[pos]) == -1) pos++;
00191
00192 if (oldpos < s.Length())
00193 {
00194 Grow(count + 1);
00195 strings[count++] = new String(s.Mid(oldpos, pos - 1));
00196 }
00197 }
00198
00199 return count;
00200 }
00201
00202 int StringArray::Dimension(int newcount)
00203 {
00204 if (newcount > count)
00205 {
00206 Grow(newcount);
00207 for (int i = count; i < newcount; i++)
00208 strings[i] = new String;
00209 count = newcount;
00210 }
00211 else if (newcount < count)
00212 {
00213 for (int i = newcount; i < count; i++)
00214 delete strings[i];
00215 count = newcount;
00216 }
00217
00218 return count;
00219 }
00220
00221 int StringArray::Find(const String & s) const
00222 {
00223 for (int i = 0; i < count; i++)
00224 if (*(strings[i]) == s)
00225 return i;
00226 return -1;
00227 }
00228
00229 int StringArray::FastFind(const String & s) const
00230 {
00231 for (int i = 0; i < count; i++)
00232 if (strings[i]->FastCompare(s) == 0)
00233 return i;
00234 return -1;
00235 }
00236
00237 int StringArray::SlowFind(const String & s) const
00238 {
00239 for (int i = 0; i < count; i++)
00240 if (strings[i]->SlowCompare(s) == 0)
00241 return i;
00242 return -1;
00243 }
00244
00245 int StringArray::Add(const String & s)
00246 {
00247 Grow(count + 1);
00248 strings[count] = new String(s);
00249 return ++count;
00250 }
00251
00252 void StringArray::InsertAt(int position, const String & s)
00253 {
00254 Grow(count + 1);
00255 for (int i = count; i > position; i--)
00256 strings[i] = strings[i - 1];
00257 strings[position] = new String(s);
00258 count++;
00259 }
00260
00261 String & StringArray::Last() const
00262 {
00263 if (!count) error("StringArray: Null String Access");
00264 return *(strings[count - 1]);
00265 }
00266
00267 void StringArray::Delete(int index)
00268 {
00269 delete strings[index];
00270 count--;
00271 for (; index < count; index++)
00272 strings[index] = strings[index + 1];
00273 }
00274
00275 StringArray & StringArray::operator = (const StringArray & rhs)
00276 {
00277 Clear();
00278 for (int i = 0; i < rhs.count; i++)
00279 Push(*rhs.strings[i]);
00280 return *this;
00281 }
00282
00283 bool StringArray::operator == (const StringArray & rhs)
00284 {
00285 if (count != rhs.count) return false;
00286 for (int i = 0; i < rhs.count; i++)
00287 if (*strings[i] != *rhs.strings[i])
00288 return false;
00289 return true;
00290 }
00291
00292 void StringArray::Sort()
00293 {
00294 QuickSort(strings, count, sizeof(String *), ComparisonForSort);
00295 }
00296
00297 int StringArray::ComparisonForSort(const void * a, const void * b)
00298 {
00299 String * string1 = *(String **) a;
00300 String * string2 = *(String **) b;
00301
00302 return Compare(*string1, *string2);
00303 }
00304
00305 String StringArray::Pop()
00306 {
00307 String result = *(strings[count - 1]);
00308
00309 Dimension(count - 1);
00310
00311 return result;
00312 }
00313
00314 void StringArray::Trim()
00315 {
00316 for (int i = 0; i < count; i++)
00317 strings[i]->Trim();
00318 }
00319
00320 void StringArray::Print()
00321 {
00322 for (int i = 0; i < count; i++)
00323 printf("%s\n", (const char *)(*strings[i]));
00324 }
00325
00326 void StringArray::PrintLine()
00327 {
00328 for (int i = 0; i < count; i++)
00329 printf("%s%c", (const char *)(*strings[i]), i == count - 1 ? '\n' : '\t');
00330 }
00331
00332 void StringArray::Swap(StringArray & s)
00333 {
00334 String ** temp = s.strings;
00335 s.strings = strings;
00336 strings = temp;
00337
00338 int swap = s.size;
00339 s.size = size;
00340 size = swap;
00341
00342 swap = s.count;
00343 s.count = count;
00344 count = swap;
00345 }
00346