00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <limits>
00013
00014 #ifdef WIN32
00015 #include <float.h>
00016 #endif
00017
00018 #ifndef SAFE_DELETE_ARRAY
00019 #define SAFE_DELETE_ARRAY(ptr) if (ptr != NULL) { delete [] ptr; ptr = NULL; }
00020 #endif
00021
00022 template <class Char, class SPrintF>
00023 FUStringBuilderT<Char,SPrintF>::FUStringBuilderT(const String& sz)
00024 {
00025 this->buffer = NULL;
00026 this->size = 0;
00027 this->reserved = 0;
00028
00029 reserve(sz.size() + 32);
00030 append(sz.c_str());
00031 }
00032
00033 template <class Char, class SPrintF>
00034 FUStringBuilderT<Char,SPrintF>::FUStringBuilderT(const Char* sz)
00035 {
00036 this->buffer = NULL;
00037 this->size = 0;
00038 this->reserved = 0;
00039
00040 SPrintF s;
00041 reserve(s.StrLen(sz) + 32);
00042 append(sz);
00043 }
00044
00045 template <class Char, class SPrintF>
00046 FUStringBuilderT<Char,SPrintF>::FUStringBuilderT(Char ch, size_t count)
00047 {
00048 this->buffer = NULL;
00049 this->size = 0;
00050 this->reserved = 0;
00051
00052 reserve(count + 32);
00053 for (size_t i = 0; i < count; ++i) buffer[size++] = ch;
00054 }
00055
00056 template <class Char, class SPrintF>
00057 FUStringBuilderT<Char,SPrintF>::FUStringBuilderT(size_t reservation)
00058 {
00059 this->buffer = NULL;
00060 this->size = 0;
00061 this->reserved = 0;
00062
00063 reserve(reservation);
00064 }
00065
00066 template <class Char, class SPrintF>
00067 FUStringBuilderT<Char,SPrintF>::FUStringBuilderT()
00068 {
00069 this->buffer = NULL;
00070 this->size = 0;
00071 this->reserved = 0;
00072
00073 #ifndef _DEBUG
00074 reserve(32);
00075 #endif
00076 }
00077
00078 template <class Char, class SPrintF>
00079 FUStringBuilderT<Char,SPrintF>::~FUStringBuilderT()
00080 {
00081 reserve(0);
00082 }
00083
00084 template <class Char, class SPrintF>
00085 void FUStringBuilderT<Char,SPrintF>::enlarge(size_t minimum)
00086 {
00087 reserve(max(reserved + minimum + 32, 2 * reserved + 32));
00088 }
00089
00090 template <class Char, class SPrintF>
00091 void FUStringBuilderT<Char,SPrintF>::clear()
00092 {
00093 size = 0;
00094 }
00095
00096 template <class Char, class SPrintF>
00097 void FUStringBuilderT<Char,SPrintF>::reserve(size_t _length)
00098 {
00099 FUAssert(size <= reserved, );
00100 if (_length > reserved)
00101 {
00102 Char* b = new Char[_length];
00103 memcpy(b, buffer, size * sizeof(Char));
00104 SAFE_DELETE_ARRAY(buffer);
00105 buffer = b;
00106 reserved = _length;
00107 }
00108 else if (_length == 0)
00109 {
00110 SAFE_DELETE_ARRAY(buffer);
00111 size = reserved = 0;
00112 }
00113 else if (_length < reserved)
00114 {
00115 size_t realSize = min(size, _length);
00116 Char* b = new Char[_length];
00117 memcpy(b, buffer, realSize * sizeof(Char));
00118 SAFE_DELETE_ARRAY(buffer);
00119 buffer = b;
00120 reserved = _length;
00121 size = realSize;
00122 }
00123 }
00124
00125 template <class Char, class SPrintF>
00126 void FUStringBuilderT<Char,SPrintF>::append(Char c)
00127 {
00128 if (size + 1 >= reserved) enlarge(2);
00129
00130 buffer[size++] = c;
00131 }
00132
00133 template <class Char, class SPrintF>
00134 void FUStringBuilderT<Char,SPrintF>::append(const String& sz) { append(sz.c_str()); }
00135 template <class Char, class SPrintF>
00136 void FUStringBuilderT<Char,SPrintF>::append(const Char* sz)
00137 {
00138
00139 for (; *sz != 0; ++sz)
00140 {
00141 if (size >= reserved) enlarge(64);
00142 buffer[size++] = *sz;
00143 }
00144 }
00145 template <class Char, class SPrintF>
00146 void FUStringBuilderT<Char,SPrintF>::append(const FUStringBuilderT& b)
00147 {
00148 if (size + b.size >= reserved) enlarge(64 + size + b.size - reserved);
00149 memcpy(buffer + size, b.buffer, b.size * sizeof(Char));
00150 size += b.size;
00151 }
00152
00153 template <class Char, class SPrintF>
00154 void FUStringBuilderT<Char,SPrintF>::append(uint32 i)
00155 {
00156 Char sz[128];
00157 SPrintF writer; writer.PrintUInt32(sz, 128, i);
00158 append(sz);
00159 }
00160
00161 template <class Char, class SPrintF>
00162 void FUStringBuilderT<Char,SPrintF>::append(uint64 i)
00163 {
00164 Char sz[128];
00165 SPrintF writer; writer.PrintUInt64(sz, 128, i);
00166 append(sz);
00167 }
00168
00169 template <class Char, class SPrintF>
00170 void FUStringBuilderT<Char,SPrintF>::append(int32 i)
00171 {
00172 Char sz[128];
00173 SPrintF writer; writer.PrintInt32(sz, 128, i);
00174 append(sz);
00175 }
00176
00177 template <class Char, class SPrintF>
00178 void FUStringBuilderT<Char,SPrintF>::append(float f)
00179 {
00180 if (f != std::numeric_limits<float>::infinity() && f != -std::numeric_limits<float>::infinity() && f != std::numeric_limits<float>::quiet_NaN() && f != std::numeric_limits<float>::signaling_NaN())
00181 {
00182 if (IsEquivalent(f, 0.0f, std::numeric_limits<float>::epsilon())) append('0');
00183 else
00184 {
00185 Char sz[128];
00186 SPrintF writer; writer.PrintFloat(sz, 128, f);
00187 append(sz);
00188 }
00189 }
00190 else if (f == std::numeric_limits<float>::infinity())
00191 { append('I'); append('N'); append('F'); }
00192 else if (f == -std::numeric_limits<float>::infinity())
00193 { append('-'); append('I'); append('N'); append('F'); }
00194 else
00195 { append('N'); append('a'); append('N'); }
00196 }
00197
00198 template <class Char, class SPrintF>
00199 void FUStringBuilderT<Char,SPrintF>::append(double f)
00200 {
00201 if (f != std::numeric_limits<double>::infinity() && f != -std::numeric_limits<double>::infinity() && f != std::numeric_limits<double>::quiet_NaN() && f != std::numeric_limits<double>::signaling_NaN())
00202 {
00203 if (IsEquivalent(f, 0.0, std::numeric_limits<double>::epsilon())) append('0');
00204 else
00205 {
00206 Char sz[128];
00207 SPrintF writer; writer.PrintFloat(sz, 128, f);
00208 append(sz);
00209 }
00210 }
00211 else if (f == std::numeric_limits<double>::infinity())
00212 { append('I'); append('N'); append('F'); }
00213 else if (f == -std::numeric_limits<double>::infinity())
00214 { append('-'); append('I'); append('N'); append('F'); }
00215 else
00216 { append('N'); append('a'); append('N'); }
00217 }
00218
00219 template <class Char, class SPrintF>
00220 void FUStringBuilderT<Char,SPrintF>::appendLine(const Char* sz)
00221 {
00222 append(sz);
00223 append("\n");
00224 }
00225
00226 template <class Char, class SPrintF>
00227 void FUStringBuilderT<Char,SPrintF>::remove(int32 start)
00228 {
00229 if ((int32)size > start && start >= 0) size = start;
00230 }
00231
00232 template <class Char, class SPrintF>
00233 void FUStringBuilderT<Char,SPrintF>::remove(int32 start, int32 end)
00234 {
00235 int32 diff = end - start;
00236 if ((int32)size >= end && start >= 0 && diff > 0)
00237 {
00238 const Char* stop = buffer + size - diff;
00239 for (Char* p = buffer + start; p != stop; ++p)
00240 {
00241 *p = *(p + diff);
00242 }
00243 size -= diff;
00244 }
00245 }
00246
00247 template <class Char, class SPrintF>
00248 typename FUStringBuilderT<Char,SPrintF>::String FUStringBuilderT<Char,SPrintF>::ToString()
00249 {
00250 return String((const Char*)*this);
00251 }
00252
00253 template <class Char, class SPrintF>
00254 const Char* FUStringBuilderT<Char,SPrintF>::ToCharPtr()
00255 {
00256 if (size + 1 > reserved) enlarge(1);
00257 buffer[size] = 0;
00258 return buffer;
00259 }
00260
00261 template <class Char, class SPrintF>
00262 int32 FUStringBuilderT<Char,SPrintF>::index(Char c)
00263 {
00264 if (buffer != NULL && size > 0)
00265 {
00266 const Char* end = buffer + size + 1;
00267 for (const Char* p = buffer; p != end; ++p)
00268 {
00269 if (*p == c) return (int32)(p - buffer);
00270 }
00271 }
00272 return -1;
00273 }
00274
00275 template <class Char, class SPrintF>
00276 int32 FUStringBuilderT<Char,SPrintF>::rindex(Char c)
00277 {
00278 if (buffer != NULL && size > 0)
00279 {
00280 for (const Char* p = buffer + size - 1; p != buffer; --p)
00281 {
00282 if (*p == c) return (int32)(p - buffer);
00283 }
00284 }
00285 return -1;
00286 }