ECharString.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. #ifndef ECHARSTRING_H
  2. #define ECHARSTRING_H
  3. //===========================================================================//
  4. // Copyright (C) Microsoft Corporation. All rights reserved. //
  5. //===========================================================================//
  6. // Notes essentially EString, except that it uses chars (not wchars) even when UNICODE is defined
  7. //
  8. //***************************************************************
  9. //***************************************************************
  10. /* just for this file, we want UNICODE, K_UNICODE and MBCS undefined */
  11. #ifdef UNICODE
  12. #define _UNICODE_WAS_PREVIOUSLY_DEFINED___ECHARSTRING_H
  13. #define _PREVIOUS_UNICODE___ECHARSTRING_H UNICODE
  14. #undef UNICODE
  15. #endif /* def UNICODE */
  16. #ifdef K_UNICODE
  17. #define _K_UNICODE_WAS_PREVIOUSLY_DEFINED___ECHARSTRING_H
  18. #define _PREVIOUS_K_UNICODE___ECHARSTRING_H UNICODE
  19. #undef K_UNICODE
  20. #endif /* def K_UNICODE */
  21. #ifdef MBCS
  22. #define _MBCS_WAS_PREVIOUSLY_DEFINED___ECHARSTRING_H
  23. #define _PREVIOUS_MBCS___ECHARSTRING_H MBCS
  24. #undef MBCS
  25. #endif /* def MBCS */
  26. //***************************************************************
  27. #ifdef UNICODE
  28. #define ECSChar unsigned short
  29. #else
  30. #define ECSChar char
  31. #endif
  32. #include <gameos.hpp>
  33. class ECharString
  34. {
  35. public:
  36. // ENUMERATIONS & CONSTANTS
  37. static const int INVALID_INDEX;
  38. // CONSTRUCTORS/DESTRUCTORS
  39. /*explicit*/ ECharString( const ECSChar* newString );
  40. ECharString( const ECharString& );
  41. /*explicit*/ ECharString( const ECSChar );
  42. ECharString();
  43. ~ECharString();
  44. // MANIPULATORS
  45. void Replace( int Start_Index, const ECharString& String );
  46. void Replace( int Start_Index, const ECSChar* );
  47. bool Remove( int Start_Index, int End_Index );
  48. bool Remove( ECharString& Sub_String );
  49. // puts this string in the middle of another string
  50. inline void Insert( int Start_Index, const ECharString& String );
  51. void Insert( int Start_Index, const ECSChar* String );
  52. void Swap( ECharString& );
  53. inline void Empty();
  54. void MakeUpper();
  55. void MakeLower();
  56. void Reverse();
  57. // works like sprintf with the destination buffer being
  58. // the this pointer
  59. void Format( const ECSChar*, ... );
  60. inline const ECharString& operator=( const ECSChar* );
  61. inline const ECharString& operator=( const ECharString& );
  62. inline const ECharString& operator=( ECSChar );
  63. inline const ECharString& operator+=( const ECSChar* );
  64. inline const ECharString& operator+=( const ECharString& );
  65. inline const ECharString& operator+=( ECSChar );
  66. friend ECharString operator+( const ECharString&, const ECharString& );
  67. friend ECharString operator+( const ECSChar*, const ECharString& );
  68. friend ECharString operator+( const ECharString& , const ECSChar* );
  69. friend ECharString operator+( const ECharString&, const ECSChar );
  70. friend ECharString operator+( const ECSChar, const ECharString& );
  71. // ACCESSORS
  72. // these are case sensitive, use Compare
  73. // if you don't want case senstitivity
  74. inline bool operator==( const ECharString& ) const;
  75. inline bool operator==( const ECSChar* ) const;
  76. inline friend bool operator==( const ECSChar*, const ECharString& );
  77. // these functions return -1 if "this" is less than the passed in string
  78. int Compare( const ECharString&, bool Case_Sensitive = false ) const;
  79. int Compare( const ECSChar*, bool Case_Sensitive = false ) const;
  80. bool operator!=( const ECharString& ) const;
  81. bool operator!=( const ECSChar*) const;
  82. friend bool operator!=( const ECSChar*, const ECharString& );
  83. inline ECSChar& operator[]( int Index );
  84. inline const ECSChar& operator[](int Index) const;
  85. inline bool operator<( const ECharString& ) const;
  86. inline bool operator<( const ECSChar* ) const;
  87. inline friend bool operator<( const ECSChar*, const ECharString& );
  88. inline bool operator<=( const ECharString& ) const;
  89. inline bool operator<=( const ECSChar*) const;
  90. inline friend bool operator<=( const ECSChar*, const ECharString&);
  91. inline bool operator>( const ECharString& ) const;
  92. inline bool operator>(const ECSChar*) const;
  93. inline friend bool operator>( const ECSChar*, const ECharString&);
  94. inline bool operator>=( const ECharString& ) const;
  95. inline bool operator>=( const ECSChar*) const;
  96. inline friend bool operator>=( const ECSChar*, const ECharString&);
  97. int Size() const; // number of bytes
  98. int Length() const; // number of characters
  99. // search functions
  100. int Find( ECSChar, int Start_Index = ECharString::INVALID_INDEX) const;
  101. int Find( const ECharString&, int Start_Index = ECharString::INVALID_INDEX) const;
  102. int Find( const ECSChar*, int Start_Index = ECharString::INVALID_INDEX) const;
  103. int ReverseFind ( ECSChar, int End_Index = ECharString::INVALID_INDEX) const;
  104. // we are going to treat this object as a TCHAR array, so we
  105. // don't have to worry about #of chars versus #of bytes
  106. ECharString SubString( int Start_Index, int End_Index ) const;
  107. inline ECharString Left( int Num_Chars) const;
  108. inline ECharString Right( int Num_Chars) const;
  109. inline bool IsEmpty() const;
  110. unsigned short* CreateUNICODE() const;
  111. char* CreateMBCS() const;
  112. inline const ECSChar* Data() const;
  113. // ALL UNICODE SPECIFIC AND
  114. #ifndef UNICODE
  115. int Find( unsigned short, int Start_Index = -1 ) const;
  116. #else // K_UNICODE
  117. // we'll convert string literals for you
  118. ECharString( const char* );
  119. friend ECharString operator+( const ECharString&, char* );
  120. friend ECharString operator+( char*, const ECharString& );
  121. friend ECharString operator+( char, const ECharString& );
  122. friend ECharString operator+( const ECharString&, char );
  123. const ECharString& operator+=( const char* );
  124. const ECharString& operator+=( char );
  125. const ECharString& operator=( char );
  126. bool operator==( const char* );
  127. friend bool operator==( const char*, const ECharString& );
  128. bool operator!=( const char*) const;
  129. friend bool operator!=( const char*, const ECharString& );
  130. bool operator<( const char* ) const;
  131. friend bool operator<( const char*, const ECharString& );
  132. bool operator>( const char* ) const;
  133. friend bool operator>( const char*, const ECharString& );
  134. bool operator<=( const char*) const;
  135. friend bool operator<=( const char*, const ECharString&);
  136. bool operator>=( const char*) const;
  137. friend bool operator>=( const char*, const ECharString&);
  138. void Format( const char*, ... );
  139. int Find( char, int Start_Index = ECharString::INVALID_INDEX) const;
  140. #endif // Unicode
  141. private:
  142. // helper functions
  143. // Allocates a specific amount
  144. void Alloc( int Min_Amount );
  145. // Reallocates if you want to make a change to a shared buffer
  146. inline void ChecEBuffer();
  147. void ChecEBufferDoRealloc();
  148. // sets the buffer, reallocs if necessary
  149. void Assign( const ECSChar* p_Str );
  150. static inline unsigned short* ToUnicode( unsigned short* Buffer, const unsigned char* p_Str, int Num_Chars );
  151. static inline int StrSize( const ECSChar* p_Str );
  152. struct EBuffer
  153. {
  154. int m_Ref_Count; // reference count
  155. int m_Data_Length; // Length of String
  156. int m_Alloc_Length; // Length of the Buffer
  157. inline ECSChar* Data();
  158. inline void Release();
  159. static EBuffer s_Empty_Buffer;
  160. static EBuffer* s_p_Empty_Buffer;
  161. };
  162. EBuffer* m_pBuffer;
  163. static const int s_Alloc_Allign;
  164. static const int s_Force_Ansi;
  165. static const int s_Force_Unicode;
  166. };
  167. //***************************************************************
  168. // inlines
  169. /////////////////////////////////////////////////////////////////
  170. inline void ECharString::ChecEBuffer()
  171. {
  172. if ( m_pBuffer->m_Ref_Count > 0 )
  173. {
  174. m_pBuffer->m_Ref_Count --;
  175. m_pBuffer = EBuffer::s_p_Empty_Buffer;
  176. }
  177. }
  178. /////////////////////////////////////////////////////////////////
  179. inline void ECharString::EBuffer::Release()
  180. {
  181. if ( this != s_p_Empty_Buffer )
  182. {
  183. m_Ref_Count --;
  184. if ( m_Ref_Count < 0 )
  185. {
  186. delete [] (char*)this;
  187. }
  188. }
  189. }
  190. /////////////////////////////////////////////////////////////////
  191. inline void ECharString::Empty()
  192. {
  193. m_pBuffer->Release();
  194. m_pBuffer = EBuffer::s_p_Empty_Buffer;
  195. }
  196. /////////////////////////////////////////////////////////////////
  197. inline void ECharString::Insert( int Start_Index, const ECharString& String )
  198. {
  199. Insert( Start_Index, String.m_pBuffer->Data() );
  200. }
  201. /////////////////////////////////////////////////////////////////
  202. inline const ECharString& ECharString::operator=( const ECSChar* p_String )
  203. {
  204. ChecEBuffer();
  205. Assign( p_String );
  206. return *this;
  207. }
  208. /////////////////////////////////////////////////////////////////
  209. inline const ECharString& ECharString::operator=( const ECharString& Src )
  210. {
  211. if ( &Src != this )
  212. {
  213. m_pBuffer->Release();
  214. m_pBuffer = Src.m_pBuffer;
  215. Src.m_pBuffer->m_Ref_Count ++;
  216. }
  217. return *this;
  218. }
  219. /////////////////////////////////////////////////////////////////
  220. inline const ECharString& ECharString::operator=( ECSChar Char )
  221. {
  222. ChecEBuffer();
  223. ECSChar Tmp[2];
  224. Tmp[0] = Char;
  225. Tmp[1] = 0;
  226. Assign( Tmp );
  227. return *this;
  228. }
  229. /////////////////////////////////////////////////////////////////
  230. inline const ECharString& ECharString::operator+=( const ECSChar* p_String )
  231. {
  232. Insert( m_pBuffer->m_Data_Length, p_String );
  233. return *this;
  234. }
  235. /////////////////////////////////////////////////////////////////
  236. inline const ECharString& ECharString::operator+=( const ECharString& String )
  237. {
  238. Insert( m_pBuffer->m_Data_Length, String );
  239. return *this;
  240. }
  241. /////////////////////////////////////////////////////////////////
  242. inline const ECharString& ECharString::operator+=( ECSChar Char )
  243. {
  244. ECSChar Tmp[2];
  245. Tmp[0] = Char;
  246. Tmp[1] = 0;
  247. Insert( m_pBuffer->m_Data_Length, Tmp );
  248. return *this;
  249. }
  250. /////////////////////////////////////////////////////////////////
  251. inline bool ECharString::operator!=( const ECharString& Str_To_Compare ) const
  252. {
  253. return !( operator==(Str_To_Compare) );
  254. }
  255. /////////////////////////////////////////////////////////////////
  256. inline bool ECharString::operator!=( const ECSChar* p_Str_To_Compare ) const
  257. {
  258. return !( operator==( p_Str_To_Compare ) );
  259. }
  260. /////////////////////////////////////////////////////////////////
  261. inline ECharString ECharString::Left( int Num_Chars) const
  262. {
  263. // Bill changed to Num_Chars - 1, this was always returning one character too many
  264. return SubString( 0, Num_Chars - 1 );
  265. }
  266. /////////////////////////////////////////////////////////////////
  267. inline ECharString ECharString::Right( int Num_Chars) const
  268. {
  269. return SubString( m_pBuffer->m_Data_Length - Num_Chars,
  270. m_pBuffer->m_Data_Length - 1 );
  271. }
  272. /////////////////////////////////////////////////////////////////
  273. inline bool ECharString::IsEmpty() const
  274. {
  275. return (m_pBuffer->m_Data_Length <= 0);
  276. }
  277. /////////////////////////////////////////////////////////////////
  278. inline const ECSChar* ECharString::Data() const
  279. {
  280. return ( m_pBuffer->Data() );
  281. }
  282. /////////////////////////////////////////////////////////////////
  283. inline ECSChar* ECharString::EBuffer::Data()
  284. {
  285. if ( !m_Alloc_Length )
  286. {
  287. return 0;
  288. }
  289. return (ECSChar*)(this + 1);
  290. }
  291. /////////////////////////////////////////////////////////////////
  292. inline bool ECharString::operator==( const ECharString& Str_To_Compare) const
  293. {
  294. return ( 0 == Compare( Str_To_Compare, true ) );
  295. }
  296. /////////////////////////////////////////////////////////////////
  297. inline bool ECharString::operator==( const ECSChar* p_String ) const
  298. {
  299. return ( 0 == Compare( p_String, true ) );
  300. }
  301. /////////////////////////////////////////////////////////////////
  302. inline bool operator==( const ECSChar* p_String, const ECharString& Str )
  303. {
  304. return ( 0 == Str.Compare( p_String ) );
  305. }
  306. /////////////////////////////////////////////////////////////////
  307. inline bool operator!=( const ECSChar* p_String, const ECharString& Str )
  308. {
  309. return !(Str == p_String );
  310. }
  311. /////////////////////////////////////////////////////////////////
  312. inline ECSChar& ECharString::operator[]( int Index )
  313. {
  314. ChecEBufferDoRealloc();
  315. gosASSERT( Index < m_pBuffer->m_Data_Length );
  316. return *(m_pBuffer->Data() + Index);
  317. }
  318. /////////////////////////////////////////////////////////////////
  319. inline const ECSChar& ECharString::operator[](int Index) const
  320. {
  321. gosASSERT( Index < m_pBuffer->m_Data_Length );
  322. return *(m_pBuffer->Data() + Index);
  323. }
  324. /////////////////////////////////////////////////////////////////
  325. inline bool ECharString::operator<( const ECharString& Greater_String ) const
  326. {
  327. return ( 0 > Compare( Greater_String, true));
  328. }
  329. /////////////////////////////////////////////////////////////////
  330. inline bool operator<( const ECSChar* p_Lesser_String,
  331. const ECharString& Greater_String )
  332. {
  333. return ( 0 < Greater_String.Compare( p_Lesser_String, true ) );
  334. }
  335. /////////////////////////////////////////////////////////////////
  336. inline bool ECharString::operator<( const ECSChar* p_Greater_String ) const
  337. {
  338. return ( 0 > Compare( p_Greater_String, true ) );
  339. }
  340. /////////////////////////////////////////////////////////////////
  341. inline bool ECharString::operator<=( const ECharString& Greater_String ) const
  342. {
  343. return ( 1 > Compare( Greater_String, true ) );
  344. }
  345. /////////////////////////////////////////////////////////////////
  346. inline bool operator<=( const ECSChar* p_Lesser_String,
  347. const ECharString& Greater_String )
  348. {
  349. return ( 0 < Greater_String.Compare( p_Lesser_String, true ) );
  350. }
  351. /////////////////////////////////////////////////////////////////
  352. inline bool ECharString::operator<=( const ECSChar* p_Greater_String ) const
  353. {
  354. return ( 1 > Compare( p_Greater_String, true ) );
  355. }
  356. /////////////////////////////////////////////////////////////////
  357. inline bool ECharString::operator>( const ECharString& Lesser_String ) const
  358. {
  359. return ( 0 < Compare( Lesser_String, true ) );
  360. }
  361. /////////////////////////////////////////////////////////////////
  362. inline bool operator>( const ECSChar* p_Greater_String,
  363. const ECharString& Lesser_String )
  364. {
  365. return ( 0 > Lesser_String.Compare( p_Greater_String, true ) );
  366. }
  367. /////////////////////////////////////////////////////////////////
  368. inline bool ECharString::operator>( const ECSChar* p_Lesser_String ) const
  369. {
  370. return ( 0 < Compare( p_Lesser_String, true ) );
  371. }
  372. /////////////////////////////////////////////////////////////////
  373. inline bool ECharString::operator>=( const ECharString& Lesser_String ) const
  374. {
  375. return ( -1 < Compare( Lesser_String, true ) );
  376. }
  377. /////////////////////////////////////////////////////////////////
  378. inline bool operator>=( const ECSChar* p_Greater_String,
  379. const ECharString& Lesser_String )
  380. {
  381. return ( 1 > Lesser_String.Compare( p_Greater_String, true ) );
  382. }
  383. /////////////////////////////////////////////////////////////////
  384. inline bool ECharString::operator>=( const ECSChar* p_Lesser_String ) const
  385. {
  386. return ( -1 < Compare( p_Lesser_String, true ) );
  387. }
  388. //***************************************************************
  389. /* restore UNICODE, K_UNICODE and MBCS to their previous state */
  390. #ifdef _UNICODE_WAS_PREVIOUSLY_DEFINED___ECHARSTRING_H
  391. #undef _UNICODE_WAS_PREVIOUSLY_DEFINED___ECHARSTRING_H
  392. #define UNICODE _PREVIOUS_UNICODE___ECHARSTRING_H
  393. #undef _PREVIOUS_UNICODE___ECHARSTRING_H
  394. #endif /* def _UNICODE_WAS_PREVIOUSLY_DEFINED___ECHARSTRING_H */
  395. #ifdef _K_UNICODE_WAS_PREVIOUSLY_DEFINED___ECHARSTRING_H
  396. #undef _K_UNICODE_WAS_PREVIOUSLY_DEFINED___ECHARSTRING_H
  397. #define K_UNICODE _PREVIOUS_K_UNICODE___ECHARSTRING_H
  398. #undef _PREVIOUS_K_UNICODE___ECHARSTRING_H
  399. #endif /* def _K_UNICODE_WAS_PREVIOUSLY_DEFINED___ECHARSTRING_H */
  400. #ifdef _MBCS_WAS_PREVIOUSLY_DEFINED___ECHARSTRING_H
  401. #undef _MBCS_WAS_PREVIOUSLY_DEFINED___ECHARSTRING_H
  402. #define MBCS _PREVIOUS_MBCS___ECHARSTRING_H
  403. #undef _PREVIOUS_MBCS___ECHARSTRING_H
  404. #endif /* def _MBCS_WAS_PREVIOUSLY_DEFINED___ECHARSTRING_H */
  405. //***************************************************************
  406. #endif //ECharString_H_