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

AltStyle によって変換されたページ (->オリジナル) /