00001 #ifndef __STRING_H__
00002 #define __STRING_H__
00003
00004 #include <string.h>
00005 #include "libRefCount.h"
00006 #include <stdarg.h>
00007
00008 #undef DEBUG
00009 #define DEBUG -1
00010 #include "libDebug.h"
00011
00012 #include "Stream.h"
00013 typedef StreamOf<char> StCh;
00014
00015 class String: public StCh
00016 {
00017 protected:
00018
00019 String(char* vch, int cch, bool bPrivate) :
00020 StCh(vch, cch, bPrivate)
00021 {
00022 }
00023
00024 public:
00025 String()__attribute__((always_inline))
00026 : StCh()
00027 {}
00028
00029 String(const String& s) __attribute__((always_inline))
00030 : StCh(s)
00031 {}
00032
00033 String(const char* vch) __attribute__((always_inline))
00034 : StCh(vch,strlen(vch)+1)
00035 {
00036 SetSizeUnsafe(C()-1);
00037 }
00038
00039 String(const int& n) __attribute__((always_inline))
00040 : StCh()
00041 {
00042 EnsureSpace(32);
00043 SetSize(min(31,snprintf(V(),32,"%d",n)));
00044 }
00045
00046 String(const Real& r) __attribute__((always_inline))
00047 : StCh()
00048 {
00049 EnsureSpace(32);
00050 SetSize(min(31,snprintf(V(),32,"%.4lf",r)));
00051 }
00052
00053 Real AsReal()
00054
00055 {
00056 Real r=0;
00057 sscanf(V(),SFMT_REAL,&r);
00058 return r;
00059 }
00060
00061 int AsInt()
00062
00063 {
00064 int z=0;
00065 sscanf(V(),"%d",&z);
00066 return z;
00067 }
00068
00069 bool operator ==(const String& s) const
00070 {
00071 return strcmp(V(),s.V())==0;
00072 }
00073 bool operator ==(const char *s) const
00074 {
00075 return strcmp(V(),s)==0;
00076 }
00077 bool operator !=(const char *s) const
00078 {
00079 return strcmp(V(),s)!=0;
00080 }
00081 bool operator >(const char *s) const
00082 {
00083 return strcmp(V(),s)>0;
00084 }
00085 bool operator <(const char *s) const
00086 {
00087 return strcmp(V(),s)<0;
00088 }
00089 bool operator >=(const char *s) const
00090 {
00091 return strcmp(V(),s)>=0;
00092 }
00093 bool operator <=(const char *s) const
00094 {
00095 return strcmp(V(),s)<=0;
00096 }
00097
00098 char* VCH()
00099 {
00100 return V();
00101 }
00102
00103 const char* VCH() const
00104 {
00105 return V();
00106 }
00107
00108 String operator + (const int& t) const
00109 {
00110
00111 return *this+String(t);
00112 }
00113 String operator + (const byte& t) const
00114 {
00115
00116 return *this+String(t);
00117 }
00118 String operator + (const short& t) const
00119 {
00120
00121 return *this+String(t);
00122 }
00123 String operator + (const double& t) const
00124 {
00125
00126 return *this+String(t);
00127 }
00128 String operator + (const float& t) const
00129 {
00130
00131 return *this+String(t);
00132 }
00133
00134 String operator + (char* const vch) const
00135 {
00136
00137
00138 int cch=strlen(vch);
00139
00140 int cchNew=cch+C();
00141
00142 String s;
00143 s.EnsureSpace(m_nStart+cchNew+1);
00144
00145 if (C() > 0)
00146 {
00147 memcpy(s.V(),V(),C());
00148 }
00149 if (cch > 0)
00150 {
00151 memcpy(&s[C()],vch,cch);
00152 }
00153 s[cchNew]=0;
00154 s.SetSizeUnsafe(m_nStart+cchNew);
00155
00156 return s;
00157 }
00158
00159 String operator + (const String& sIn) const
00160 {
00161
00162 int c=C();
00163 int cIn=sIn.C();
00164 int cNew=c+cIn;
00165
00166 String s;
00167 s.EnsureSpace(m_nStart+cNew+1);
00168
00169 if (c > 0)
00170 {
00171 memcpy(s.V(),V(),c);
00172 }
00173 if (cIn > 0)
00174 {
00175 memcpy(&s[c],sIn.V(),cIn);
00176 }
00177 s[cNew]=0;
00178 s.SetSizeUnsafe(m_nStart+cNew);
00179
00180 return s;
00181 }
00182
00183 int ReadInt()
00184 {
00185 ASSERT(C()>0);
00186 int c=0;
00187 int z=0;
00188 ASSERT(sscanf(V(),"%d%n",&z,&c)==1);
00189 m_nStart+=c;
00190 return z;
00191 }
00192
00193 Real ReadReal()
00194 {
00195 ASSERT(C()>0);
00196 int c=0;
00197 Real r=0;
00198 ASSERT(sscanf(V(),SFMT_REAL "%n",&r,&c)==1);
00199 m_nStart+=c;
00200 return r;
00201 }
00202
00203 String ReadString()
00204 {
00205 ASSERT(C()>0);
00206 int c=0;
00207 char sT[4096];
00208 ASSERT(sscanf(V(),"%4095s%n",sT,&c)==1);
00209 m_nStart+=c;
00210 return String(sT);
00211 }
00212
00213 void Skip(const char* vch)
00214 {
00215 ASSERT(C()>0);
00216 int c=strlen(vch);
00217 ASSERT(strncmp(V(),vch,c)==0);
00218 m_nStart+=c;
00219 }
00220
00221 String& operator += (const String &s)
00222 {
00223 Append(s.V(),s.C());
00224 EnsureSpace(m_nStart+C()+1);
00225 V()[C()]=0;
00226 return *this;
00227 }
00228
00229 static String Indent(int c)
00230 {
00231 return Repeat("\t",c);
00232 }
00233
00234 static String Repeat(const String& s,int c)
00235 {
00236 String sOut;
00237 sOut.EnsureSpace(s.C()*c+1);
00238 for (int n=0; n<c; n++)
00239 {
00240 sOut+=s;
00241 }
00242 sOut[sOut.C()]=0;
00243 return sOut;
00244 }
00245
00246 static String IndentRidgedly(const String& s, int c=1)
00247 {
00248 int cchOut=c;
00249 int cch=s.C();
00250
00251 for (int nch=0; nch<cch; nch++)
00252 {
00253 cchOut+=1;
00254 if (s[nch]=='\n' && nch!=cch-1)
00255 {
00256 cchOut+=c;
00257 }
00258 }
00259
00260 String sOut;
00261 sOut.EnsureSpace(cchOut+1);
00262 int nchOut=0;
00263 for (int n=0; n<c; n++)
00264 {
00265 sOut[nchOut]='\t';
00266 nchOut++;
00267 }
00268
00269 for (int nch=0; nch<cch; nch++)
00270 {
00271 sOut[nchOut]=s[nch];
00272 nchOut++;
00273 if (s[nch]=='\n' && nch!=cch-1)
00274 {
00275 for (int n=0; n<c; n++)
00276 {
00277 sOut[nchOut]='\t';
00278 nchOut++;
00279 }
00280 }
00281 }
00282 sOut[nchOut]=0;
00283 sOut.SetSizeUnsafe(cchOut);
00284 return sOut;
00285 }
00286 };
00287
00288 class StringIndent
00289 {
00290 int m_c;
00291
00292 friend String operator +(const StringIndent &s1, const char* &s2);
00293 friend String operator +(const StringIndent &s1, const String& s2);
00294
00295 public:
00296 StringIndent(int c)
00297 {
00298 m_c = c;
00299 }
00300 };
00301
00302 static const StringIndent _INDENT(1);
00303 static const StringIndent _INDENT2(2);
00304 static const String _LINE;
00305 static const String LINE_("\n");
00306 static const String INDENT("\t");
00307
00308 inline String operator +(const StringIndent &s1, const String& s2)
00309 {
00310 return String::IndentRidgedly(s2, s1.m_c);
00311 }
00312
00313 inline String operator +(const StringIndent &s1, const char* &s2)
00314 {
00315 return String::IndentRidgedly(String(s2), s1.m_c);
00316 }
00317
00318 inline String operator +(const char *s1, const String& s2)
00319 {
00320 return String(s1) + s2;
00321 }
00322
00323 inline String operator +(const String& s1, const char* s2)
00324 {
00325 return s1 + (char* const ) s2;
00326 }
00327
00328 inline String operator +(int z, const String& s2)
00329 {
00330 return String(z) + s2;
00331 }
00332
00333 inline String operator +(byte y, const String& s2)
00334 {
00335 return String(y) + s2;
00336 }
00337
00338 inline String operator +(short yy, const String& s2)
00339 {
00340 return String(yy) + s2;
00341 }
00342
00343 inline String operator +(double r, const String& s2)
00344 {
00345 return String(r) + s2;
00346 }
00347
00348 inline String operator +(float r, const String& s2)
00349 {
00350 return String(r) + s2;
00351 }
00352
00353 template<class T>
00354 inline String operator +(const T& t, const String& s2)
00355 {
00356 return t.Describe() + s2;
00357 }
00358
00359 template<class T>
00360 inline String operator +(const String& s1, const T& t)
00361 {
00362 return s1 + t.Describe();
00363 }
00364
00365 String StringF(const char* sFmt, ...);
00366
00367 #endif