Str.h 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #ifndef __STR_H__
  21. #define __STR_H__
  22. /*
  23. ===============================================================================
  24. Character string
  25. ===============================================================================
  26. */
  27. // these library functions should not be used for cross platform compatibility
  28. #define strcmp idStr::Cmp // use_idStr_Cmp
  29. #define strncmp use_idStr_Cmpn
  30. #if defined( StrCmpN )
  31. #undef StrCmpN
  32. #endif
  33. #define StrCmpN use_idStr_Cmpn
  34. #if defined( strcmpi )
  35. #undef strcmpi
  36. #endif
  37. #define strcmpi use_idStr_Icmp
  38. #if defined( StrCmpI )
  39. #undef StrCmpI
  40. #endif
  41. #define StrCmpI use_idStr_Icmp
  42. #if defined( StrCmpNI )
  43. #undef StrCmpNI
  44. #endif
  45. #define StrCmpNI use_idStr_Icmpn
  46. #define stricmp idStr::Icmp // use_idStr_Icmp
  47. #define _stricmp use_idStr_Icmp
  48. #define strcasecmp use_idStr_Icmp
  49. #define strnicmp use_idStr_Icmpn
  50. #define _strnicmp use_idStr_Icmpn
  51. #define _memicmp use_idStr_Icmpn
  52. #define snprintf use_idStr_snPrintf
  53. #define _snprintf use_idStr_snPrintf
  54. #define vsnprintf use_idStr_vsnPrintf
  55. #define _vsnprintf use_idStr_vsnPrintf
  56. class idVec4;
  57. #ifndef FILE_HASH_SIZE
  58. #define FILE_HASH_SIZE 1024
  59. #endif
  60. // color escape character
  61. const int C_COLOR_ESCAPE = '^';
  62. const int C_COLOR_DEFAULT = '0';
  63. const int C_COLOR_RED = '1';
  64. const int C_COLOR_GREEN = '2';
  65. const int C_COLOR_YELLOW = '3';
  66. const int C_COLOR_BLUE = '4';
  67. const int C_COLOR_CYAN = '5';
  68. const int C_COLOR_MAGENTA = '6';
  69. const int C_COLOR_WHITE = '7';
  70. const int C_COLOR_GRAY = '8';
  71. const int C_COLOR_BLACK = '9';
  72. // color escape string
  73. #define S_COLOR_DEFAULT "^0"
  74. #define S_COLOR_RED "^1"
  75. #define S_COLOR_GREEN "^2"
  76. #define S_COLOR_YELLOW "^3"
  77. #define S_COLOR_BLUE "^4"
  78. #define S_COLOR_CYAN "^5"
  79. #define S_COLOR_MAGENTA "^6"
  80. #define S_COLOR_WHITE "^7"
  81. #define S_COLOR_GRAY "^8"
  82. #define S_COLOR_BLACK "^9"
  83. // make idStr a multiple of 16 bytes long
  84. // don't make too large to keep memory requirements to a minimum
  85. const int STR_ALLOC_BASE = 20;
  86. const int STR_ALLOC_GRAN = 32;
  87. typedef enum {
  88. MEASURE_SIZE = 0,
  89. MEASURE_BANDWIDTH
  90. } Measure_t;
  91. class idStr {
  92. public:
  93. idStr( void );
  94. idStr( const idStr &text );
  95. idStr( const idStr &text, int start, int end );
  96. idStr( const char *text );
  97. idStr( const char *text, int start, int end );
  98. explicit idStr( const bool b );
  99. explicit idStr( const char c );
  100. explicit idStr( const int i );
  101. explicit idStr( const unsigned u );
  102. explicit idStr( const float f );
  103. ~idStr( void );
  104. size_t Size( void ) const;
  105. const char * c_str( void ) const;
  106. operator const char *( void ) const;
  107. operator const char *( void );
  108. char operator[]( int index ) const;
  109. char & operator[]( int index );
  110. void operator=( const idStr &text );
  111. void operator=( const char *text );
  112. friend idStr operator+( const idStr &a, const idStr &b );
  113. friend idStr operator+( const idStr &a, const char *b );
  114. friend idStr operator+( const char *a, const idStr &b );
  115. friend idStr operator+( const idStr &a, const float b );
  116. friend idStr operator+( const idStr &a, const int b );
  117. friend idStr operator+( const idStr &a, const unsigned b );
  118. friend idStr operator+( const idStr &a, const bool b );
  119. friend idStr operator+( const idStr &a, const char b );
  120. idStr & operator+=( const idStr &a );
  121. idStr & operator+=( const char *a );
  122. idStr & operator+=( const float a );
  123. idStr & operator+=( const char a );
  124. idStr & operator+=( const int a );
  125. idStr & operator+=( const unsigned a );
  126. idStr & operator+=( const bool a );
  127. // case sensitive compare
  128. friend bool operator==( const idStr &a, const idStr &b );
  129. friend bool operator==( const idStr &a, const char *b );
  130. friend bool operator==( const char *a, const idStr &b );
  131. // case sensitive compare
  132. friend bool operator!=( const idStr &a, const idStr &b );
  133. friend bool operator!=( const idStr &a, const char *b );
  134. friend bool operator!=( const char *a, const idStr &b );
  135. // case sensitive compare
  136. int Cmp( const char *text ) const;
  137. int Cmpn( const char *text, int n ) const;
  138. int CmpPrefix( const char *text ) const;
  139. // case insensitive compare
  140. int Icmp( const char *text ) const;
  141. int Icmpn( const char *text, int n ) const;
  142. int IcmpPrefix( const char *text ) const;
  143. // case insensitive compare ignoring color
  144. int IcmpNoColor( const char *text ) const;
  145. // compares paths and makes sure folders come first
  146. int IcmpPath( const char *text ) const;
  147. int IcmpnPath( const char *text, int n ) const;
  148. int IcmpPrefixPath( const char *text ) const;
  149. int Length( void ) const;
  150. int Allocated( void ) const;
  151. void Empty( void );
  152. bool IsEmpty( void ) const;
  153. void Clear( void );
  154. void Append( const char a );
  155. void Append( const idStr &text );
  156. void Append( const char *text );
  157. void Append( const char *text, int len );
  158. void Insert( const char a, int index );
  159. void Insert( const char *text, int index );
  160. void ToLower( void );
  161. void ToUpper( void );
  162. bool IsNumeric( void ) const;
  163. bool IsColor( void ) const;
  164. bool HasLower( void ) const;
  165. bool HasUpper( void ) const;
  166. int LengthWithoutColors( void ) const;
  167. idStr & RemoveColors( void );
  168. void CapLength( int );
  169. void Fill( const char ch, int newlen );
  170. int Find( const char c, int start = 0, int end = -1 ) const;
  171. int Find( const char *text, bool casesensitive = true, int start = 0, int end = -1 ) const;
  172. bool Filter( const char *filter, bool casesensitive ) const;
  173. int Last( const char c ) const; // return the index to the last occurance of 'c', returns -1 if not found
  174. const char * Left( int len, idStr &result ) const; // store the leftmost 'len' characters in the result
  175. const char * Right( int len, idStr &result ) const; // store the rightmost 'len' characters in the result
  176. const char * Mid( int start, int len, idStr &result ) const; // store 'len' characters starting at 'start' in result
  177. idStr Left( int len ) const; // return the leftmost 'len' characters
  178. idStr Right( int len ) const; // return the rightmost 'len' characters
  179. idStr Mid( int start, int len ) const; // return 'len' characters starting at 'start'
  180. void StripLeading( const char c ); // strip char from front as many times as the char occurs
  181. void StripLeading( const char *string ); // strip string from front as many times as the string occurs
  182. bool StripLeadingOnce( const char *string ); // strip string from front just once if it occurs
  183. void StripTrailing( const char c ); // strip char from end as many times as the char occurs
  184. void StripTrailing( const char *string ); // strip string from end as many times as the string occurs
  185. bool StripTrailingOnce( const char *string ); // strip string from end just once if it occurs
  186. void Strip( const char c ); // strip char from front and end as many times as the char occurs
  187. void Strip( const char *string ); // strip string from front and end as many times as the string occurs
  188. void StripTrailingWhitespace( void ); // strip trailing white space characters
  189. idStr & StripQuotes( void ); // strip quotes around string
  190. void Replace( const char *old, const char *nw );
  191. // file name methods
  192. int FileNameHash( void ) const; // hash key for the filename (skips extension)
  193. idStr & BackSlashesToSlashes( void ); // convert slashes
  194. idStr & SetFileExtension( const char *extension ); // set the given file extension
  195. idStr & StripFileExtension( void ); // remove any file extension
  196. idStr & StripAbsoluteFileExtension( void ); // remove any file extension looking from front (useful if there are multiple .'s)
  197. idStr & DefaultFileExtension( const char *extension ); // if there's no file extension use the default
  198. idStr & DefaultPath( const char *basepath ); // if there's no path use the default
  199. void AppendPath( const char *text ); // append a partial path
  200. idStr & StripFilename( void ); // remove the filename from a path
  201. idStr & StripPath( void ); // remove the path from the filename
  202. void ExtractFilePath( idStr &dest ) const; // copy the file path to another string
  203. void ExtractFileName( idStr &dest ) const; // copy the filename to another string
  204. void ExtractFileBase( idStr &dest ) const; // copy the filename minus the extension to another string
  205. void ExtractFileExtension( idStr &dest ) const; // copy the file extension to another string
  206. bool CheckExtension( const char *ext );
  207. // char * methods to replace library functions
  208. static int Length( const char *s );
  209. static char * ToLower( char *s );
  210. static char * ToUpper( char *s );
  211. static bool IsNumeric( const char *s );
  212. static bool IsColor( const char *s );
  213. static bool HasLower( const char *s );
  214. static bool HasUpper( const char *s );
  215. static int LengthWithoutColors( const char *s );
  216. static char * RemoveColors( char *s );
  217. static int Cmp( const char *s1, const char *s2 );
  218. static int Cmpn( const char *s1, const char *s2, int n );
  219. static int Icmp( const char *s1, const char *s2 );
  220. static int Icmpn( const char *s1, const char *s2, int n );
  221. static int IcmpNoColor( const char *s1, const char *s2 );
  222. static int IcmpPath( const char *s1, const char *s2 ); // compares paths and makes sure folders come first
  223. static int IcmpnPath( const char *s1, const char *s2, int n ); // compares paths and makes sure folders come first
  224. static void Append( char *dest, int size, const char *src );
  225. static void Copynz( char *dest, const char *src, int destsize );
  226. static int snPrintf( char *dest, int size, const char *fmt, ... ) id_attribute((format(printf,3,4)));
  227. static int vsnPrintf( char *dest, int size, const char *fmt, va_list argptr );
  228. static int FindChar( const char *str, const char c, int start = 0, int end = -1 );
  229. static int FindText( const char *str, const char *text, bool casesensitive = true, int start = 0, int end = -1 );
  230. static bool Filter( const char *filter, const char *name, bool casesensitive );
  231. static void StripMediaName( const char *name, idStr &mediaName );
  232. static bool CheckExtension( const char *name, const char *ext );
  233. static const char * FloatArrayToString( const float *array, const int length, const int precision );
  234. // hash keys
  235. static int Hash( const char *string );
  236. static int Hash( const char *string, int length );
  237. static int IHash( const char *string ); // case insensitive
  238. static int IHash( const char *string, int length ); // case insensitive
  239. // character methods
  240. static char ToLower( char c );
  241. static char ToUpper( char c );
  242. static bool CharIsPrintable( int c );
  243. static bool CharIsLower( int c );
  244. static bool CharIsUpper( int c );
  245. static bool CharIsAlpha( int c );
  246. static bool CharIsNumeric( int c );
  247. static bool CharIsNewLine( char c );
  248. static bool CharIsTab( char c );
  249. static int ColorIndex( int c );
  250. static idVec4 & ColorForIndex( int i );
  251. friend int sprintf( idStr &dest, const char *fmt, ... );
  252. friend int vsprintf( idStr &dest, const char *fmt, va_list ap );
  253. void ReAllocate( int amount, bool keepold ); // reallocate string data buffer
  254. void FreeData( void ); // free allocated string memory
  255. // format value in the given measurement with the best unit, returns the best unit
  256. int BestUnit( const char *format, float value, Measure_t measure );
  257. // format value in the requested unit and measurement
  258. void SetUnit( const char *format, float value, int unit, Measure_t measure );
  259. static void InitMemory( void );
  260. static void ShutdownMemory( void );
  261. static void PurgeMemory( void );
  262. static void ShowMemoryUsage_f( const idCmdArgs &args );
  263. int DynamicMemoryUsed() const;
  264. static idStr FormatNumber( int number );
  265. protected:
  266. int len;
  267. char * data;
  268. int alloced;
  269. char baseBuffer[ STR_ALLOC_BASE ];
  270. void Init( void ); // initialize string using base buffer
  271. void EnsureAlloced( int amount, bool keepold = true ); // ensure string data buffer is large anough
  272. };
  273. char * va( const char *fmt, ... ) id_attribute((format(printf,1,2)));
  274. ID_INLINE void idStr::EnsureAlloced( int amount, bool keepold ) {
  275. if ( amount > alloced ) {
  276. ReAllocate( amount, keepold );
  277. }
  278. }
  279. ID_INLINE void idStr::Init( void ) {
  280. len = 0;
  281. alloced = STR_ALLOC_BASE;
  282. data = baseBuffer;
  283. data[ 0 ] = '\0';
  284. #ifdef ID_DEBUG_UNINITIALIZED_MEMORY
  285. memset( baseBuffer, 0, sizeof( baseBuffer ) );
  286. #endif
  287. }
  288. ID_INLINE idStr::idStr( void ) {
  289. Init();
  290. }
  291. ID_INLINE idStr::idStr( const idStr &text ) {
  292. int l;
  293. Init();
  294. l = text.Length();
  295. EnsureAlloced( l + 1 );
  296. strcpy( data, text.data );
  297. len = l;
  298. }
  299. ID_INLINE idStr::idStr( const idStr &text, int start, int end ) {
  300. int i;
  301. int l;
  302. Init();
  303. if ( end > text.Length() ) {
  304. end = text.Length();
  305. }
  306. if ( start > text.Length() ) {
  307. start = text.Length();
  308. } else if ( start < 0 ) {
  309. start = 0;
  310. }
  311. l = end - start;
  312. if ( l < 0 ) {
  313. l = 0;
  314. }
  315. EnsureAlloced( l + 1 );
  316. for ( i = 0; i < l; i++ ) {
  317. data[ i ] = text[ start + i ];
  318. }
  319. data[ l ] = '\0';
  320. len = l;
  321. }
  322. ID_INLINE idStr::idStr( const char *text ) {
  323. int l;
  324. Init();
  325. if ( text ) {
  326. l = strlen( text );
  327. EnsureAlloced( l + 1 );
  328. strcpy( data, text );
  329. len = l;
  330. }
  331. }
  332. ID_INLINE idStr::idStr( const char *text, int start, int end ) {
  333. int i;
  334. int l = strlen( text );
  335. Init();
  336. if ( end > l ) {
  337. end = l;
  338. }
  339. if ( start > l ) {
  340. start = l;
  341. } else if ( start < 0 ) {
  342. start = 0;
  343. }
  344. l = end - start;
  345. if ( l < 0 ) {
  346. l = 0;
  347. }
  348. EnsureAlloced( l + 1 );
  349. for ( i = 0; i < l; i++ ) {
  350. data[ i ] = text[ start + i ];
  351. }
  352. data[ l ] = '\0';
  353. len = l;
  354. }
  355. ID_INLINE idStr::idStr( const bool b ) {
  356. Init();
  357. EnsureAlloced( 2 );
  358. data[ 0 ] = b ? '1' : '0';
  359. data[ 1 ] = '\0';
  360. len = 1;
  361. }
  362. ID_INLINE idStr::idStr( const char c ) {
  363. Init();
  364. EnsureAlloced( 2 );
  365. data[ 0 ] = c;
  366. data[ 1 ] = '\0';
  367. len = 1;
  368. }
  369. ID_INLINE idStr::idStr( const int i ) {
  370. char text[ 64 ];
  371. int l;
  372. Init();
  373. l = sprintf( text, "%d", i );
  374. EnsureAlloced( l + 1 );
  375. strcpy( data, text );
  376. len = l;
  377. }
  378. ID_INLINE idStr::idStr( const unsigned u ) {
  379. char text[ 64 ];
  380. int l;
  381. Init();
  382. l = sprintf( text, "%u", u );
  383. EnsureAlloced( l + 1 );
  384. strcpy( data, text );
  385. len = l;
  386. }
  387. ID_INLINE idStr::idStr( const float f ) {
  388. char text[ 64 ];
  389. int l;
  390. Init();
  391. l = idStr::snPrintf( text, sizeof( text ), "%f", f );
  392. while( l > 0 && text[l-1] == '0' ) text[--l] = '\0';
  393. while( l > 0 && text[l-1] == '.' ) text[--l] = '\0';
  394. EnsureAlloced( l + 1 );
  395. strcpy( data, text );
  396. len = l;
  397. }
  398. ID_INLINE idStr::~idStr( void ) {
  399. FreeData();
  400. }
  401. ID_INLINE size_t idStr::Size( void ) const {
  402. return sizeof( *this ) + Allocated();
  403. }
  404. ID_INLINE const char *idStr::c_str( void ) const {
  405. return data;
  406. }
  407. ID_INLINE idStr::operator const char *( void ) {
  408. return c_str();
  409. }
  410. ID_INLINE idStr::operator const char *( void ) const {
  411. return c_str();
  412. }
  413. ID_INLINE char idStr::operator[]( int index ) const {
  414. assert( ( index >= 0 ) && ( index <= len ) );
  415. return data[ index ];
  416. }
  417. ID_INLINE char &idStr::operator[]( int index ) {
  418. assert( ( index >= 0 ) && ( index <= len ) );
  419. return data[ index ];
  420. }
  421. ID_INLINE void idStr::operator=( const idStr &text ) {
  422. int l;
  423. l = text.Length();
  424. EnsureAlloced( l + 1, false );
  425. memcpy( data, text.data, l );
  426. data[l] = '\0';
  427. len = l;
  428. }
  429. ID_INLINE idStr operator+( const idStr &a, const idStr &b ) {
  430. idStr result( a );
  431. result.Append( b );
  432. return result;
  433. }
  434. ID_INLINE idStr operator+( const idStr &a, const char *b ) {
  435. idStr result( a );
  436. result.Append( b );
  437. return result;
  438. }
  439. ID_INLINE idStr operator+( const char *a, const idStr &b ) {
  440. idStr result( a );
  441. result.Append( b );
  442. return result;
  443. }
  444. ID_INLINE idStr operator+( const idStr &a, const bool b ) {
  445. idStr result( a );
  446. result.Append( b ? "true" : "false" );
  447. return result;
  448. }
  449. ID_INLINE idStr operator+( const idStr &a, const char b ) {
  450. idStr result( a );
  451. result.Append( b );
  452. return result;
  453. }
  454. ID_INLINE idStr operator+( const idStr &a, const float b ) {
  455. char text[ 64 ];
  456. idStr result( a );
  457. sprintf( text, "%f", b );
  458. result.Append( text );
  459. return result;
  460. }
  461. ID_INLINE idStr operator+( const idStr &a, const int b ) {
  462. char text[ 64 ];
  463. idStr result( a );
  464. sprintf( text, "%d", b );
  465. result.Append( text );
  466. return result;
  467. }
  468. ID_INLINE idStr operator+( const idStr &a, const unsigned b ) {
  469. char text[ 64 ];
  470. idStr result( a );
  471. sprintf( text, "%u", b );
  472. result.Append( text );
  473. return result;
  474. }
  475. ID_INLINE idStr &idStr::operator+=( const float a ) {
  476. char text[ 64 ];
  477. sprintf( text, "%f", a );
  478. Append( text );
  479. return *this;
  480. }
  481. ID_INLINE idStr &idStr::operator+=( const int a ) {
  482. char text[ 64 ];
  483. sprintf( text, "%d", a );
  484. Append( text );
  485. return *this;
  486. }
  487. ID_INLINE idStr &idStr::operator+=( const unsigned a ) {
  488. char text[ 64 ];
  489. sprintf( text, "%u", a );
  490. Append( text );
  491. return *this;
  492. }
  493. ID_INLINE idStr &idStr::operator+=( const idStr &a ) {
  494. Append( a );
  495. return *this;
  496. }
  497. ID_INLINE idStr &idStr::operator+=( const char *a ) {
  498. Append( a );
  499. return *this;
  500. }
  501. ID_INLINE idStr &idStr::operator+=( const char a ) {
  502. Append( a );
  503. return *this;
  504. }
  505. ID_INLINE idStr &idStr::operator+=( const bool a ) {
  506. Append( a ? "true" : "false" );
  507. return *this;
  508. }
  509. ID_INLINE bool operator==( const idStr &a, const idStr &b ) {
  510. return ( !idStr::Cmp( a.data, b.data ) );
  511. }
  512. ID_INLINE bool operator==( const idStr &a, const char *b ) {
  513. assert( b );
  514. return ( !idStr::Cmp( a.data, b ) );
  515. }
  516. ID_INLINE bool operator==( const char *a, const idStr &b ) {
  517. assert( a );
  518. return ( !idStr::Cmp( a, b.data ) );
  519. }
  520. ID_INLINE bool operator!=( const idStr &a, const idStr &b ) {
  521. return !( a == b );
  522. }
  523. ID_INLINE bool operator!=( const idStr &a, const char *b ) {
  524. return !( a == b );
  525. }
  526. ID_INLINE bool operator!=( const char *a, const idStr &b ) {
  527. return !( a == b );
  528. }
  529. ID_INLINE int idStr::Cmp( const char *text ) const {
  530. assert( text );
  531. return idStr::Cmp( data, text );
  532. }
  533. ID_INLINE int idStr::Cmpn( const char *text, int n ) const {
  534. assert( text );
  535. return idStr::Cmpn( data, text, n );
  536. }
  537. ID_INLINE int idStr::CmpPrefix( const char *text ) const {
  538. assert( text );
  539. return idStr::Cmpn( data, text, strlen( text ) );
  540. }
  541. ID_INLINE int idStr::Icmp( const char *text ) const {
  542. assert( text );
  543. return idStr::Icmp( data, text );
  544. }
  545. ID_INLINE int idStr::Icmpn( const char *text, int n ) const {
  546. assert( text );
  547. return idStr::Icmpn( data, text, n );
  548. }
  549. ID_INLINE int idStr::IcmpPrefix( const char *text ) const {
  550. assert( text );
  551. return idStr::Icmpn( data, text, strlen( text ) );
  552. }
  553. ID_INLINE int idStr::IcmpNoColor( const char *text ) const {
  554. assert( text );
  555. return idStr::IcmpNoColor( data, text );
  556. }
  557. ID_INLINE int idStr::IcmpPath( const char *text ) const {
  558. assert( text );
  559. return idStr::IcmpPath( data, text );
  560. }
  561. ID_INLINE int idStr::IcmpnPath( const char *text, int n ) const {
  562. assert( text );
  563. return idStr::IcmpnPath( data, text, n );
  564. }
  565. ID_INLINE int idStr::IcmpPrefixPath( const char *text ) const {
  566. assert( text );
  567. return idStr::IcmpnPath( data, text, strlen( text ) );
  568. }
  569. ID_INLINE int idStr::Length( void ) const {
  570. return len;
  571. }
  572. ID_INLINE int idStr::Allocated( void ) const {
  573. if ( data != baseBuffer ) {
  574. return alloced;
  575. } else {
  576. return 0;
  577. }
  578. }
  579. ID_INLINE void idStr::Empty( void ) {
  580. EnsureAlloced( 1 );
  581. data[ 0 ] = '\0';
  582. len = 0;
  583. }
  584. ID_INLINE bool idStr::IsEmpty( void ) const {
  585. return ( idStr::Cmp( data, "" ) == 0 );
  586. }
  587. ID_INLINE void idStr::Clear( void ) {
  588. FreeData();
  589. Init();
  590. }
  591. ID_INLINE void idStr::Append( const char a ) {
  592. EnsureAlloced( len + 2 );
  593. data[ len ] = a;
  594. len++;
  595. data[ len ] = '\0';
  596. }
  597. ID_INLINE void idStr::Append( const idStr &text ) {
  598. int newLen;
  599. int i;
  600. newLen = len + text.Length();
  601. EnsureAlloced( newLen + 1 );
  602. for ( i = 0; i < text.len; i++ ) {
  603. data[ len + i ] = text[ i ];
  604. }
  605. len = newLen;
  606. data[ len ] = '\0';
  607. }
  608. ID_INLINE void idStr::Append( const char *text ) {
  609. int newLen;
  610. int i;
  611. if ( text ) {
  612. newLen = len + strlen( text );
  613. EnsureAlloced( newLen + 1 );
  614. for ( i = 0; text[ i ]; i++ ) {
  615. data[ len + i ] = text[ i ];
  616. }
  617. len = newLen;
  618. data[ len ] = '\0';
  619. }
  620. }
  621. ID_INLINE void idStr::Append( const char *text, int l ) {
  622. int newLen;
  623. int i;
  624. if ( text && l ) {
  625. newLen = len + l;
  626. EnsureAlloced( newLen + 1 );
  627. for ( i = 0; text[ i ] && i < l; i++ ) {
  628. data[ len + i ] = text[ i ];
  629. }
  630. len = newLen;
  631. data[ len ] = '\0';
  632. }
  633. }
  634. ID_INLINE void idStr::Insert( const char a, int index ) {
  635. int i, l;
  636. if ( index < 0 ) {
  637. index = 0;
  638. } else if ( index > len ) {
  639. index = len;
  640. }
  641. l = 1;
  642. EnsureAlloced( len + l + 1 );
  643. for ( i = len; i >= index; i-- ) {
  644. data[i+l] = data[i];
  645. }
  646. data[index] = a;
  647. len++;
  648. }
  649. ID_INLINE void idStr::Insert( const char *text, int index ) {
  650. int i, l;
  651. if ( index < 0 ) {
  652. index = 0;
  653. } else if ( index > len ) {
  654. index = len;
  655. }
  656. l = strlen( text );
  657. EnsureAlloced( len + l + 1 );
  658. for ( i = len; i >= index; i-- ) {
  659. data[i+l] = data[i];
  660. }
  661. for ( i = 0; i < l; i++ ) {
  662. data[index+i] = text[i];
  663. }
  664. len += l;
  665. }
  666. ID_INLINE void idStr::ToLower( void ) {
  667. for (int i = 0; data[i]; i++ ) {
  668. if ( CharIsUpper( data[i] ) ) {
  669. data[i] += ( 'a' - 'A' );
  670. }
  671. }
  672. }
  673. ID_INLINE void idStr::ToUpper( void ) {
  674. for (int i = 0; data[i]; i++ ) {
  675. if ( CharIsLower( data[i] ) ) {
  676. data[i] -= ( 'a' - 'A' );
  677. }
  678. }
  679. }
  680. ID_INLINE bool idStr::IsNumeric( void ) const {
  681. return idStr::IsNumeric( data );
  682. }
  683. ID_INLINE bool idStr::IsColor( void ) const {
  684. return idStr::IsColor( data );
  685. }
  686. ID_INLINE bool idStr::HasLower( void ) const {
  687. return idStr::HasLower( data );
  688. }
  689. ID_INLINE bool idStr::HasUpper( void ) const {
  690. return idStr::HasUpper( data );
  691. }
  692. ID_INLINE idStr &idStr::RemoveColors( void ) {
  693. idStr::RemoveColors( data );
  694. len = Length( data );
  695. return *this;
  696. }
  697. ID_INLINE int idStr::LengthWithoutColors( void ) const {
  698. return idStr::LengthWithoutColors( data );
  699. }
  700. ID_INLINE void idStr::CapLength( int newlen ) {
  701. if ( len <= newlen ) {
  702. return;
  703. }
  704. data[ newlen ] = 0;
  705. len = newlen;
  706. }
  707. ID_INLINE void idStr::Fill( const char ch, int newlen ) {
  708. EnsureAlloced( newlen + 1 );
  709. len = newlen;
  710. memset( data, ch, len );
  711. data[ len ] = 0;
  712. }
  713. ID_INLINE int idStr::Find( const char c, int start, int end ) const {
  714. if ( end == -1 ) {
  715. end = len;
  716. }
  717. return idStr::FindChar( data, c, start, end );
  718. }
  719. ID_INLINE int idStr::Find( const char *text, bool casesensitive, int start, int end ) const {
  720. if ( end == -1 ) {
  721. end = len;
  722. }
  723. return idStr::FindText( data, text, casesensitive, start, end );
  724. }
  725. ID_INLINE bool idStr::Filter( const char *filter, bool casesensitive ) const {
  726. return idStr::Filter( filter, data, casesensitive );
  727. }
  728. ID_INLINE const char *idStr::Left( int len, idStr &result ) const {
  729. return Mid( 0, len, result );
  730. }
  731. ID_INLINE const char *idStr::Right( int len, idStr &result ) const {
  732. if ( len >= Length() ) {
  733. result = *this;
  734. return result;
  735. }
  736. return Mid( Length() - len, len, result );
  737. }
  738. ID_INLINE idStr idStr::Left( int len ) const {
  739. return Mid( 0, len );
  740. }
  741. ID_INLINE idStr idStr::Right( int len ) const {
  742. if ( len >= Length() ) {
  743. return *this;
  744. }
  745. return Mid( Length() - len, len );
  746. }
  747. ID_INLINE void idStr::Strip( const char c ) {
  748. StripLeading( c );
  749. StripTrailing( c );
  750. }
  751. ID_INLINE void idStr::Strip( const char *string ) {
  752. StripLeading( string );
  753. StripTrailing( string );
  754. }
  755. ID_INLINE bool idStr::CheckExtension( const char *ext ) {
  756. return idStr::CheckExtension( data, ext );
  757. }
  758. ID_INLINE int idStr::Length( const char *s ) {
  759. int i;
  760. for ( i = 0; s[i]; i++ ) {}
  761. return i;
  762. }
  763. ID_INLINE char *idStr::ToLower( char *s ) {
  764. for ( int i = 0; s[i]; i++ ) {
  765. if ( CharIsUpper( s[i] ) ) {
  766. s[i] += ( 'a' - 'A' );
  767. }
  768. }
  769. return s;
  770. }
  771. ID_INLINE char *idStr::ToUpper( char *s ) {
  772. for ( int i = 0; s[i]; i++ ) {
  773. if ( CharIsLower( s[i] ) ) {
  774. s[i] -= ( 'a' - 'A' );
  775. }
  776. }
  777. return s;
  778. }
  779. ID_INLINE int idStr::Hash( const char *string ) {
  780. int i, hash = 0;
  781. for ( i = 0; *string != '\0'; i++ ) {
  782. hash += ( *string++ ) * ( i + 119 );
  783. }
  784. return hash;
  785. }
  786. ID_INLINE int idStr::Hash( const char *string, int length ) {
  787. int i, hash = 0;
  788. for ( i = 0; i < length; i++ ) {
  789. hash += ( *string++ ) * ( i + 119 );
  790. }
  791. return hash;
  792. }
  793. ID_INLINE int idStr::IHash( const char *string ) {
  794. int i, hash = 0;
  795. for( i = 0; *string != '\0'; i++ ) {
  796. hash += ToLower( *string++ ) * ( i + 119 );
  797. }
  798. return hash;
  799. }
  800. ID_INLINE int idStr::IHash( const char *string, int length ) {
  801. int i, hash = 0;
  802. for ( i = 0; i < length; i++ ) {
  803. hash += ToLower( *string++ ) * ( i + 119 );
  804. }
  805. return hash;
  806. }
  807. ID_INLINE bool idStr::IsColor( const char *s ) {
  808. return ( s[0] == C_COLOR_ESCAPE && s[1] != '\0' && s[1] != ' ' );
  809. }
  810. ID_INLINE char idStr::ToLower( char c ) {
  811. if ( c <= 'Z' && c >= 'A' ) {
  812. return ( c + ( 'a' - 'A' ) );
  813. }
  814. return c;
  815. }
  816. ID_INLINE char idStr::ToUpper( char c ) {
  817. if ( c >= 'a' && c <= 'z' ) {
  818. return ( c - ( 'a' - 'A' ) );
  819. }
  820. return c;
  821. }
  822. ID_INLINE bool idStr::CharIsPrintable( int c ) {
  823. // test for regular ascii and western European high-ascii chars
  824. return ( c >= 0x20 && c <= 0x7E ) || ( c >= 0xA1 && c <= 0xFF );
  825. }
  826. ID_INLINE bool idStr::CharIsLower( int c ) {
  827. // test for regular ascii and western European high-ascii chars
  828. return ( c >= 'a' && c <= 'z' ) || ( c >= 0xE0 && c <= 0xFF );
  829. }
  830. ID_INLINE bool idStr::CharIsUpper( int c ) {
  831. // test for regular ascii and western European high-ascii chars
  832. return ( c <= 'Z' && c >= 'A' ) || ( c >= 0xC0 && c <= 0xDF );
  833. }
  834. ID_INLINE bool idStr::CharIsAlpha( int c ) {
  835. // test for regular ascii and western European high-ascii chars
  836. return ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) ||
  837. ( c >= 0xC0 && c <= 0xFF ) );
  838. }
  839. ID_INLINE bool idStr::CharIsNumeric( int c ) {
  840. return ( c <= '9' && c >= '0' );
  841. }
  842. ID_INLINE bool idStr::CharIsNewLine( char c ) {
  843. return ( c == '\n' || c == '\r' || c == '\v' );
  844. }
  845. ID_INLINE bool idStr::CharIsTab( char c ) {
  846. return ( c == '\t' );
  847. }
  848. ID_INLINE int idStr::ColorIndex( int c ) {
  849. return ( c & 15 );
  850. }
  851. ID_INLINE int idStr::DynamicMemoryUsed() const {
  852. return ( data == baseBuffer ) ? 0 : alloced;
  853. }
  854. #endif /* !__STR_H__ */