00001
00060 #ifndef INC_MI32_FIXEDSTR_H
00061 #define INC_MI32_FIXEDSTR_H
00062
00063 #ifndef INC_MI32_UCSTRING_H
00064 #include <mi32/ucstring.h>
00065 #endif
00066
00067 #ifndef INC_MI32_UCCHAR_H
00068 #include <mi32/ucchar.h>
00069 #endif
00070
00071 #ifndef INC_MI32_MEMBUF_H
00072 #include <mi32/membuf.h>
00073 #endif
00074
00075 #ifndef INC_MI32_INIBASE_H
00076 #include <mi32/inibase.h>
00077 #endif
00078
00079 #ifndef INC_MI32_MISTRING_H
00080 #include <mi32/mistring.h>
00081 #endif
00082
00083 #ifndef INC_MI32_DELEGATE_H
00084 #include <mi32/delegate.h>
00085 #endif
00086
00087 #ifndef INC_MEMORY_H
00088 #include <memory.h>
00089 #define INC_MEMORY_H
00090 #endif
00091
00092
00093 inline bool DftValidNameChar (
00094 MIUNICODE c
00095 ) { return (c =='_'||(c >='A'&& c <='Z')||( c >='a'&& c <='z')||( c >='0'&& c <='9')|| c >=160); }
00096
00097
00102 template <int _CT> class FIXEDSTRING {
00103 public:
00104
00106 FIXEDSTRING (
00107 ) { Clear(); }
00108
00110 FIXEDSTRING (
00111 const FIXEDSTRING& rhs
00112 ) { memcpy(m_String, rhs.m_String, sizeof(m_String)); }
00113
00115
00116
00117
00118
00119
00120
00121
00123 FIXEDSTRING (
00124 const MIUNICODE* string
00125 ) {
00126 Clear();
00127 if (string != 0) ucstrncpy(m_String, string, _CT - 1);
00128 }
00129
00131 FIXEDSTRING (
00132 const MISTRING& string
00133 ) {
00134 Clear();
00135 ucstrncpy(m_String, string, _CT - 1);
00136 }
00137
00139 FIXEDSTRING (
00140 TEXTID textid
00141 ) { Clear(); MISTRING str(textid); ucstrncpy(m_String,str,_CT-1); }
00142
00144 ~FIXEDSTRING (
00145 ) { m_String[0] = 0; }
00146
00148 FIXEDSTRING& operator= (
00149 const FIXEDSTRING& rhs
00150 ) {
00151 if (this != &rhs) {
00152 memcpy(m_String, rhs.m_String, sizeof(m_String));
00153 }
00154 return (*this);
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00167 FIXEDSTRING& operator= (
00168 const MIUNICODE* rhs
00169 ) {
00170 if (m_String != rhs) {
00171 Clear();
00172 if (rhs != 0) ucstrncpy(m_String, rhs, _CT - 1);
00173 }
00174 return (*this);
00175 }
00176
00178 FIXEDSTRING& operator= (
00179 const MISTRING& rhs
00180 ) {
00181 Clear();
00182 ucstrncpy(m_String, rhs, _CT - 1);
00183 return (*this);
00184 }
00185
00187 FIXEDSTRING& operator= (
00188 TEXTID textid
00189 ) { Clear(); MISTRING str(textid); ucstrncpy(m_String,str,_CT-1); return(*this); }
00190
00192
00193
00194
00195
00196
00197
00198
00199
00201 FIXEDSTRING& operator+= (
00202 const MIUNICODE* rhs
00203 ) {
00204 if (rhs != 0) ucstrncat(m_String, rhs, _CT - (ucstrlen(m_String) + 1));
00205 return (*this);
00206 }
00207
00209 operator const MIUNICODE* (
00210 ) const { return (m_String); }
00211
00213
00214
00215
00216
00218 bool operator== (
00219 const MIUNICODE *rhs
00220 ) const { return (Compare(rhs) == 0); }
00221
00223
00224
00225
00226
00228 bool operator!= (
00229 const MIUNICODE *rhs
00230 ) const { return (!(*this == rhs)); }
00231
00233
00234
00235
00236
00238 bool operator< (
00239 const MIUNICODE *rhs
00240 ) const { return (Compare(rhs) < 0); }
00241
00243
00244
00245
00246
00248 bool operator<= (
00249 const MIUNICODE *rhs
00250 ) const { return (Compare(rhs) <= 0); }
00251
00253
00254
00255
00256
00258 bool operator> (
00259 const MIUNICODE *rhs
00260 ) const { return (Compare(rhs) > 0); }
00261
00263
00264
00265
00266
00268 bool operator>= (
00269 const MIUNICODE *rhs
00270 ) const { return (Compare(rhs) >= 0); }
00271
00273 void Append (
00274 const char* name
00275 ) {
00276 MIUNICODE *p = ucstrchr(m_String, 0);
00277 strntouc(p, name, _CT - (p - m_String) - 1);
00278 return;
00279 }
00280
00282 void Assign (
00283 const char* name
00284 ) { strntouc(m_String, name, _CT - 1); }
00285
00287 void Assign (
00288 const char* name,
00289 int len
00290 ) { strntouc(m_String, name, MIN(_CT - 1, len)); }
00291
00293 void Assign (
00294 const char* name,
00295 CHAR_ENCODING encoding
00296 ) {
00297 if (encoding == CHAR_ENCODING_ASCII) {
00298 strtouc(m_String, name);
00299 }
00300 else {
00301 MISTRING mistr(name, encoding);
00302 Clear();
00303 ucstrncpy(m_String, mistr, _CT - 1);
00304 }
00305 }
00306
00308 void Assign (
00309 const MIUNICODE* name,
00310 int len
00311 ) { ucstrncpy(m_String, name, MIN(_CT - 1, len)); }
00312
00314 void Clear (
00315 ) { memset(m_String, 0, sizeof(m_String)); }
00316
00319
00320
00321
00322
00325 int Compare (
00326 const MIUNICODE *str
00327 ) const { return (ucstrcmp(m_String, str)); }
00328
00331
00332
00333
00334
00337 int CompareNoCase (
00338 const MIUNICODE *str
00339 ) const { return (ucstricmp(m_String, str)); }
00340
00342 class UNIQUENAMEFILTER {
00343 public:
00344 UNIQUENAMEFILTER () {}
00345
00348 int Filter (const FIXEDSTRING<_CT>& string) { return (v_Filter(string)); }
00349 private:
00350 virtual int v_Filter (const FIXEDSTRING<_CT>& string) = 0;
00351 };
00352
00354 ERRVALUE GenerateUniqueName (
00355 FastDelegate<int(const FIXEDSTRING<_CT>&)> delegate
00356 ) {
00357 ERRVALUE err;
00358 if ((err = delegate(m_String)) < 0) return (err);
00359 if (err > 0) return (0);
00360
00361
00362 int k = 0, len = GetLength();
00363 memset(&m_String[len], 0, (_CT - len) * sizeof(MIUNICODE));
00364 MIUNICODE* where = &m_String[len];
00365 if (len == (_CT-1)) where --;
00366 MIUNICODE* start = where;
00367 UINT8 count[_CT];
00368 memset(count, 0, _CT);
00369
00370 static const char *AddArray = "1234567890abcdefghijklmnopqrstuvwxyz_?";
00371 do {
00372 *where = static_cast<MIUNICODE>(AddArray[k++]);
00373 if (*where == static_cast<MIUNICODE>('?')) {
00374 k = 1;
00375 *where = static_cast<MIUNICODE>(AddArray[0]);
00376 MIUNICODE *p;
00377 for (p = where - 1;(p >= start);--p) {
00378 *p = static_cast<MIUNICODE>(AddArray[count[p-m_String]++]);
00379 if (*p == static_cast<MIUNICODE>('?')) {
00380 *p = static_cast<MIUNICODE>(AddArray[0]);
00381 count[p-m_String] = 0;
00382 }
00383 else break;
00384 }
00385 if (p < start) {
00386 ++where;
00387 if (where - start == 4) return (EProgramError);
00388 memset(count, 0, _CT);
00389 if (where - m_String == (_CT-1)) {
00390 start --;
00391 where = start;
00392 if (start < m_String) return (EProgramError);
00393 }
00394 for (p = where;(p >= start);--p) *p = static_cast<MIUNICODE>(AddArray[0]);
00395 }
00396 }
00397 err = delegate(m_String);
00398 } while (err == 0);
00399 if (err < 0) return (err);
00400 return (0);
00401 }
00402
00404 ERRVALUE GenerateUniqueName (
00405 UNIQUENAMEFILTER& FilterInst
00406 ) {
00407 FastDelegate<int(const FIXEDSTRING<_CT>&)> delegate = FastDelegate<int(const FIXEDSTRING<_CT>&)>(&FilterInst, &FIXEDSTRING<_CT>::UNIQUENAMEFILTER::Filter);
00408 return (GenerateUniqueName(delegate));
00409 }
00410
00413 void* GetEncoded (
00414 CHAR_ENCODING encoding
00415 ) const {
00416 MISTRING tstr(m_String);
00417 return (tstr.GetEncoded(encoding));
00418 }
00419
00421 int GetLength (
00422 ) const { return (ucstrlen(m_String)); }
00423
00425 static int GetMaxSize (
00426 ) { return (_CT-1); }
00427
00429 const MIUNICODE* GetReference (
00430 ) const { return (m_String); }
00431
00433 const MIUNICODE* GetTail (
00434 int maxlen
00435 ) const { int len = ucstrlen(m_String); return ((len <= maxlen) ? m_String : (m_String + (len - maxlen))); }
00436
00438 bool IsEmpty (
00439 ) const { return (m_String[0] == 0); }
00440
00443 bool IniRead (
00444 INIHANDLE inih,
00445 const char *group,
00446 const char*const field
00447 ) { return (_iniReadString(inih, group, field, INITYPE_Unicode, m_String, _CT * sizeof(MIUNICODE)) > 0); }
00448
00450 void IniWrite (
00451 INIHANDLE inih,
00452 const char *group,
00453 const char*const field
00454 ) const { _iniWriteString(inih, group, field, INITYPE_Unicode, m_String); }
00455
00456 bool IsValidName (
00457 FastDelegate<bool(MIUNICODE)> delegate = FastDelegate<bool(MIUNICODE)>(DftValidNameChar)
00458 ) const {
00459 const MIUNICODE* p = m_String;
00460 if (*p == 0 || (*p >= '0' && *p <= '9') || !delegate(*p)) return (false);
00461
00462 for (++p;(*p != 0);++p) {
00463 if (!delegate(*p)) return (false);
00464 }
00465 return (true);
00466 }
00467
00468 void MakeValidName (
00469 FastDelegate<bool(MIUNICODE)> delegate = FastDelegate<bool(MIUNICODE)>(DftValidNameChar)
00470 ) {
00471 if (IsEmpty()) {
00472 Assign("_1");
00473 return;
00474 }
00475 if (IsValidName(delegate)) return;
00476
00477
00478 MIUNICODE *p = ucstrchr(m_String, 0) - 1;
00479 memset(p+1, 0, ((_CT-1) - (p - m_String))*sizeof(MIUNICODE));
00480 while (p >= m_String && ucisspace(*p)) *p-- = 0;
00481
00482
00483 for (p = m_String;(*p != 0);++p) {
00484 if (!delegate(*p)) *p = '_';
00485 }
00486
00487
00488 if (m_String[0] >= '0' && m_String[0] <= '9') {
00489 for (p = ucstrchr(m_String, 0);(p != m_String);--p) *p = *(p-1);
00490 *p = (MIUNICODE)'_';
00491 m_String[_CT-1] = 0;
00492 }
00493 return;
00494 }
00495
00497 void PadToEnd (
00498 char item
00499 ) {
00500 for (int j = ucstrlen(m_String);(j < _CT-1);++j) m_String[j] = item;
00501 m_String[_CT-1] = 0;
00502 }
00503
00505 void SetLowerCase (
00506 ) { ucstrlwr(m_String); }
00507
00509 void SetUpperCase (
00510 ) { ucstrupr(m_String); }
00511
00513 void SwapBytes (
00514 ) { ::SwapBytes(m_String, _CT); }
00515
00517 void Terminate (
00518 ) { m_String[_CT - 1] = 0; }
00519
00521 void Truncate (
00522 int NewLength
00523 ) { if (NewLength < (_CT - 1)) m_String[NewLength] = 0; }
00524
00525 private:
00526 #ifndef GENERATING_DOXYGEN_OUTPUT
00527 MIUNICODE m_String[_CT];
00528 #endif // GENERATING_DOXYGEN_OUTPUT
00529 };
00530
00531 #endif // INC_MI32_FIXEDSTR_H