Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

String.cc

Go to the documentation of this file.
00001 /*
00002     File:           String.cc
00003 
00004     Function:       Implements string class
00005 
00006     Author:         Andrew Willmott
00007 
00008     Notes:
00009 */
00010 
00011 
00012 #include "cl/String.h"
00013 #include "cl/CLConfig.h"
00014 
00015 #include <stdio.h>
00016 #include <ctype.h>
00017 #include <stdlib.h>
00018 #include <stdarg.h>
00019 
00020 String::String(StrConst s) : Array<Char>(s.Length() + 1)
00021 {
00022     strcpy(item, s);
00023 }
00024 
00025 String &String::operator = (StrConst s)
00026 {
00027     Assert(!s.IsNull(), "(String::=) Can't assign null to a String");
00028     
00029     SetSize(s.Length() + 1);
00030     strcpy(item, s);
00031     
00032     return(SELF);
00033 }
00034 
00035 String &String::operator = (const Char *s)
00036 {
00037     Assert(s != 0, "(String::=) Can't assign null to a String");
00038     
00039     SetSize(strlen(s) + 1);
00040     strcpy(item, s);
00041     
00042     return(SELF);
00043 }
00044 
00045 String &String::Append(StrConst s)
00046 {
00047     Int start = Length();
00048     Add(s.Length());
00049     strcpy(item + start, s);
00050     return(SELF);
00051 }
00052 
00053 String &String::Insert(StrConst s, Int position)
00054 {
00055     Int len = s.Length();
00056     
00057     Array<Char>::Insert(position, len);
00058     memcpy(item + position, s, len);
00059     
00060     return(SELF);
00061 }
00062 
00063 String &String::Delete(Int start, Int length)
00064 {
00065     Array<Char>::Delete(start, length);     
00066     return(SELF);
00067 }
00068 
00069 // --- StrConst class ---------------------------------------------------------------
00070 
00071 Int StrConst::FindChar(Char c) const
00072 {
00073     Char *s = strchr(theString, c);
00074 
00075     if (s)
00076         return((s - theString));
00077     else
00078         return(-1);
00079 }
00080 
00081 Int StrConst::FindCharLast(Char c) const
00082 {
00083     Char *s = strrchr(theString, c);
00084 
00085     if (s)
00086         return((s - theString));
00087     else
00088         return(-1);
00089 }
00090 
00091 String StrConst::SubString(Int start, Int length)
00092 {
00093     String  result;
00094     Int     strLength = Length();
00095     
00096     if (length > 0)
00097     {
00098         if (start < 0)
00099             start = Max(0, Length() + start);
00100         else
00101             start = Min(strLength, start);
00102     
00103         length = Min(length, strLength - start);
00104 
00105         result.SetSize(length + 1);
00106         memcpy(result.item, theString + start, length);
00107         result.item[length] = 0;
00108     }
00109         
00110     return(result);
00111 }
00112 
00113 String StrConst::Prefix(Int length)
00114 {
00115     String  result;
00116     Int     strLength = Length();
00117     
00118     if (length < 0)
00119         length = Max(0, strLength + length);
00120     else
00121         length = Min(strLength, length);
00122 
00123     result.SetSize(length + 1);
00124     memcpy(result.item, theString, length);
00125     result.item[length] = 0;
00126     
00127     return(result);
00128 }
00129 
00130 String StrConst::Suffix(Int length)
00131 {
00132     String  result;
00133     Int     strLength = Length(), offset;
00134         
00135     if (length < 0)
00136         offset = Min(strLength, -length);
00137     else
00138         offset = Max(0, strLength - length);
00139 
00140     result = (theString + offset);
00141     
00142     return(result);
00143 }
00144 
00145 istream &String::ReadString(istream &s)
00146 {
00147     Char    c;
00148     
00149     //  Expected format: "... "
00150     
00151     while (isspace(s.peek()))           //  chomp white space
00152         s.get(c);
00153         
00154     if (s.peek() == '"')                        
00155     {
00156         s.get(c);
00157         Clear();
00158                 
00159         while (s.peek() != '"')
00160         {           
00161             s.get(c);
00162             
00163             if (!s)
00164             {
00165                 Expect(false, "Couldn't read array component");
00166                 return(s);
00167             }
00168             else
00169                 Array<Char>::Append(c);
00170         }           
00171         s.get(c);
00172     }
00173     else
00174     {
00175         s.clear(ios::failbit);
00176         Expect(false, "Error: Expected '\"' while reading string");
00177         return(s);
00178     }
00179     
00180     Array<Char>::Append(0);
00181 
00182     return(s);
00183 }
00184 
00185 istream &operator >> (istream &s, String &str)
00186 {
00187     // We default to reading a string. Use the other Read... methods to
00188     // read/parse other types of data.
00189 
00190     str.ReadString(s);
00191     return(s);
00192 }
00193 
00194 istream &String::ReadWord(istream &s)
00195 {
00196     Char    c;
00197     
00198     //  Expected format: "... "
00199     
00200     while (isspace(s.peek()))           //  chomp white space
00201         s.get(c);
00202         
00203     Clear();
00204                 
00205     while (!isspace(s.peek()))
00206     {           
00207         s.get(c);
00208         
00209         if (!s)
00210         {
00211             Expect(false, "Couldn't read word");
00212             return(s);
00213         }
00214         else
00215             Array<Char>::Append(c);
00216     }           
00217     
00218     Array<Char>::Append(0);
00219 
00220     return(s);
00221 }
00222 
00223 int iseol(int c)
00224 {
00225     return(c == 0x0a || c == 0x0d);
00226 }
00227 
00228 istream &String::ReadLine(istream &s)
00229 {
00230     Char    c;
00231                 
00232     Clear();
00233                 
00234     while (1)
00235     {           
00236         s.get(c);
00237         
00238         if (!s || iseol(c))
00239             break;
00240         else
00241             Array<Char>::Append(c);
00242     }           
00243     
00244     Array<Char>::Append(0);
00245 
00246     return(s);
00247 }
00248 
00249 
00250 String &String::Printf(const Char *format, ...)
00251 {
00252     static Char buffer[2048];
00253     Int         size;
00254     va_list     ap;
00255     
00256     va_start(ap, format);
00257 #ifdef CL_HAS_VSNPRINTF
00258     size = vsnprintf(buffer, 2048, format, ap);
00259 #else
00260     size = vsprintf(buffer, format, ap);
00261 #endif
00262 
00263     if (size >= 0)
00264     {
00265         SetSize(size + 1);
00266         strcpy(item, buffer);
00267     }
00268     else
00269         SELF = "<string too large>";
00270 
00271     va_end(ap);
00272 
00273     return(SELF);
00274 }
00275 
00276 // --- String utilities -------------------------------------------
00277 
00278 
00279 Bool IsEndOfLine(istream &s)
00280 {
00281     char c;
00282     
00283     while (isspace(s.peek()) && !iseol(s.peek()))
00284         s.get(c);
00285 
00286     return(iseol(s.peek()));
00287 }
00288 
00289 Void ChompWhiteSpace(istream &s)
00290 {
00291     char    c;
00292     
00293     while (isspace(s.peek()))               //  chomp white space
00294         s.get(c);
00295 }
00296 
00297 TempString SubstituteEnvVars(StrConst s)
00298 {
00299     StrConst        varStart, varSub, oldVarStart;
00300     String          var;
00301     TempString      result;
00302     Int             vlen;
00303     
00304     varStart = s;
00305     
00306     while (varStart)
00307     {
00308         oldVarStart = varStart;
00309         varStart = strchr(varStart, '$');
00310 
00311         if (varStart)
00312         {
00313             result += oldVarStart.Prefix((varStart - oldVarStart));
00314             vlen = strcspn(varStart, "/- \t}.,;\"'");
00315             var = varStart.SubString(1, vlen - 1);
00316             
00317             varStart = varStart + vlen;
00318             if (var[0] == '{' && varStart[0] == '}')
00319             {
00320                 varStart = varStart + 1;
00321                 var = var.Suffix(-1);
00322             }
00323             varSub = getenv(var.CString());
00324             if (varSub)
00325                 result += varSub;
00326             else
00327                 result += "<" + var + ">";
00328         }       
00329     }
00330     
00331     result += oldVarStart;
00332 
00333     return(result);
00334 }
00335 
00336 Void Split(StrConst line, StrConstArray &a, StrConst sep)
00337 // Splits 'line' into an array of tokens 'a', where each token is separated
00338 // by the characters in "sep" (default is white space).
00339 {
00340     static String   buffer;
00341     StrConst        s;
00342 
00343     buffer = line;
00344     a.Clear();
00345     s = strtok(buffer.CString(), sep);
00346     if (!s)
00347         return;
00348     a.Append(s);
00349     while (s = strtok(0, sep))
00350         a.Append(s);
00351 }
00352 
00353 #ifdef CL_TMPL_INST
00354 template class Array<Char>;
00355 #endif

Generated at Sat Aug 5 00:16:33 2000 for Class Library by doxygen 1.1.0 written by Dimitri van Heesch, © 1997-2000