StringArray.cpp

00001 /*
00002  *  Copyright (C) 2010  Regents of the University of Michigan
00003  *
00004  *   This program is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   This program is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
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 
Generated on Wed Nov 17 15:38:29 2010 for StatGen Software by  doxygen 1.6.3