wwstring.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program 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. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : WWSaveLoad *
  23. * *
  24. * $Archive:: /Commando/Code/wwlib/wwstring.h $*
  25. * *
  26. * Author:: Patrick Smith *
  27. * *
  28. * $Modtime:: 12/13/01 5:11p $*
  29. * *
  30. * $Revision:: 37 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #if defined(_MSC_VER)
  36. #pragma once
  37. #endif
  38. #ifndef __WWSTRING_H
  39. #define __WWSTRING_H
  40. #include "always.h"
  41. #include "mutex.h"
  42. #include "win.h"
  43. #include <string.h>
  44. #include <stdarg.h>
  45. #include <tchar.h>
  46. #include "trim.h"
  47. #include "wwdebug.h"
  48. #ifdef _UNIX
  49. #include "osdep.h"
  50. #endif
  51. //////////////////////////////////////////////////////////////////////
  52. //
  53. // StringClass
  54. //
  55. // Note: This class is UNICODE friendly. That means it can be
  56. // compiled using either single-byte or double-byte strings. There
  57. // are no assumptions made as to the size of a character.
  58. //
  59. // Any method that takes a parameter with the word 'len' or 'length'
  60. // in it refers to a count of characters. If the name contains 'byte'
  61. // it is talking about the memory size.
  62. //
  63. //////////////////////////////////////////////////////////////////////
  64. class StringClass
  65. {
  66. public:
  67. ////////////////////////////////////////////////////////////
  68. // Public constructors/destructors
  69. ////////////////////////////////////////////////////////////
  70. StringClass (bool hint_temporary);
  71. StringClass (int initial_len = 0, bool hint_temporary = false);
  72. StringClass (const StringClass &string, bool hint_temporary = false);
  73. StringClass (const TCHAR *string, bool hint_temporary = false);
  74. StringClass (TCHAR ch, bool hint_temporary = false);
  75. StringClass (const WCHAR *string, bool hint_temporary = false);
  76. ~StringClass (void);
  77. ////////////////////////////////////////////////////////////
  78. // Public operators
  79. ////////////////////////////////////////////////////////////
  80. bool operator== (const TCHAR *rvalue) const;
  81. bool operator!= (const TCHAR *rvalue) const;
  82. inline const StringClass &operator= (const StringClass &string);
  83. inline const StringClass &operator= (const TCHAR *string);
  84. inline const StringClass &operator= (TCHAR ch);
  85. inline const StringClass &operator= (const WCHAR *string);
  86. const StringClass &operator+= (const StringClass &string);
  87. const StringClass &operator+= (const TCHAR *string);
  88. const StringClass &operator+= (TCHAR ch);
  89. friend StringClass operator+ (const StringClass &string1, const StringClass &string2);
  90. friend StringClass operator+ (const TCHAR *string1, const StringClass &string2);
  91. friend StringClass operator+ (const StringClass &string1, const TCHAR *string2);
  92. bool operator < (const TCHAR *string) const;
  93. bool operator <= (const TCHAR *string) const;
  94. bool operator > (const TCHAR *string) const;
  95. bool operator >= (const TCHAR *string) const;
  96. const TCHAR & operator[] (int index) const;
  97. TCHAR & operator[] (int index);
  98. inline operator const TCHAR * (void) const;
  99. ////////////////////////////////////////////////////////////
  100. // Public methods
  101. ////////////////////////////////////////////////////////////
  102. int Compare (const TCHAR *string) const;
  103. int Compare_No_Case (const TCHAR *string) const;
  104. inline int Get_Length (void) const;
  105. bool Is_Empty (void) const;
  106. void Erase (int start_index, int char_count);
  107. int _cdecl Format (const TCHAR *format, ...);
  108. int _cdecl Format_Args (const TCHAR *format, const va_list & arg_list );
  109. // Trim leading and trailing whitespace characters (values <= 32)
  110. void Trim(void);
  111. TCHAR * Get_Buffer (int new_length);
  112. TCHAR * Peek_Buffer (void);
  113. const TCHAR * Peek_Buffer (void) const;
  114. bool Copy_Wide (const WCHAR *source);
  115. ////////////////////////////////////////////////////////////
  116. // Static methods
  117. ////////////////////////////////////////////////////////////
  118. static void Release_Resources (void);
  119. private:
  120. ////////////////////////////////////////////////////////////
  121. // Private structures
  122. ////////////////////////////////////////////////////////////
  123. typedef struct _HEADER
  124. {
  125. int allocated_length;
  126. int length;
  127. } HEADER;
  128. ////////////////////////////////////////////////////////////
  129. // Private constants
  130. ////////////////////////////////////////////////////////////
  131. // Note: Don't change these enums without withs checking the Get_String() and Free_String() function!
  132. enum
  133. {
  134. MAX_TEMP_STRING = 8,
  135. MAX_TEMP_LEN = 256-sizeof(_HEADER),
  136. MAX_TEMP_BYTES = (MAX_TEMP_LEN * sizeof (TCHAR)) + sizeof (HEADER),
  137. ALL_TEMP_STRINGS_USED_MASK = 0xff
  138. };
  139. ////////////////////////////////////////////////////////////
  140. // Private methods
  141. ////////////////////////////////////////////////////////////
  142. void Get_String (int length, bool is_temp);
  143. TCHAR * Allocate_Buffer (int length);
  144. void Resize (int size);
  145. void Uninitialised_Grow (int length);
  146. void Free_String (void);
  147. inline void Store_Length (int length);
  148. inline void Store_Allocated_Length (int allocated_length);
  149. inline HEADER * Get_Header (void) const;
  150. int Get_Allocated_Length (void) const;
  151. void Set_Buffer_And_Allocated_Length (TCHAR *buffer, int length);
  152. ////////////////////////////////////////////////////////////
  153. // Private member data
  154. ////////////////////////////////////////////////////////////
  155. TCHAR * m_Buffer;
  156. ////////////////////////////////////////////////////////////
  157. // Static member data
  158. ////////////////////////////////////////////////////////////
  159. static unsigned ReservedMask;
  160. static char m_TempStrings[];
  161. static FastCriticalSectionClass m_Mutex;
  162. static TCHAR m_NullChar;
  163. static TCHAR * m_EmptyString;
  164. };
  165. ///////////////////////////////////////////////////////////////////
  166. // operator=
  167. ///////////////////////////////////////////////////////////////////
  168. inline const StringClass &
  169. StringClass::operator= (const StringClass &string)
  170. {
  171. int len = string.Get_Length();
  172. Uninitialised_Grow(len+1);
  173. Store_Length(len);
  174. ::memcpy (m_Buffer, string.m_Buffer, (len+1) * sizeof (TCHAR));
  175. return (*this);
  176. }
  177. ///////////////////////////////////////////////////////////////////
  178. // operator=
  179. ///////////////////////////////////////////////////////////////////
  180. inline const StringClass &
  181. StringClass::operator= (const TCHAR *string)
  182. {
  183. if (string != 0) {
  184. int len = _tcslen (string);
  185. Uninitialised_Grow (len+1);
  186. Store_Length (len);
  187. ::memcpy (m_Buffer, string, (len + 1) * sizeof (TCHAR));
  188. }
  189. return (*this);
  190. }
  191. ///////////////////////////////////////////////////////////////////
  192. // operator=
  193. ///////////////////////////////////////////////////////////////////
  194. inline const StringClass &
  195. StringClass::operator= (const WCHAR *string)
  196. {
  197. if (string != 0) {
  198. Copy_Wide (string);
  199. }
  200. return (*this);
  201. }
  202. ///////////////////////////////////////////////////////////////////
  203. // operator=
  204. ///////////////////////////////////////////////////////////////////
  205. inline const StringClass &
  206. StringClass::operator= (TCHAR ch)
  207. {
  208. Uninitialised_Grow (2);
  209. m_Buffer[0] = ch;
  210. m_Buffer[1] = m_NullChar;
  211. Store_Length (1);
  212. return (*this);
  213. }
  214. ///////////////////////////////////////////////////////////////////
  215. // StringClass
  216. ///////////////////////////////////////////////////////////////////
  217. inline
  218. StringClass::StringClass (bool hint_temporary)
  219. : m_Buffer (m_EmptyString)
  220. {
  221. Get_String (MAX_TEMP_LEN, hint_temporary);
  222. m_Buffer[0] = m_NullChar;
  223. return ;
  224. }
  225. ///////////////////////////////////////////////////////////////////
  226. // StringClass
  227. ///////////////////////////////////////////////////////////////////
  228. inline
  229. StringClass::StringClass (int initial_len, bool hint_temporary)
  230. : m_Buffer (m_EmptyString)
  231. {
  232. Get_String (initial_len, hint_temporary);
  233. m_Buffer[0] = m_NullChar;
  234. return ;
  235. }
  236. ///////////////////////////////////////////////////////////////////
  237. // StringClass
  238. ///////////////////////////////////////////////////////////////////
  239. inline
  240. StringClass::StringClass (TCHAR ch, bool hint_temporary)
  241. : m_Buffer (m_EmptyString)
  242. {
  243. Get_String (2, hint_temporary);
  244. (*this) = ch;
  245. return ;
  246. }
  247. ///////////////////////////////////////////////////////////////////
  248. // StringClass
  249. ///////////////////////////////////////////////////////////////////
  250. inline
  251. StringClass::StringClass (const StringClass &string, bool hint_temporary)
  252. : m_Buffer (m_EmptyString)
  253. {
  254. if (hint_temporary || (string.Get_Length()>0)) {
  255. Get_String (string.Get_Length()+1, hint_temporary);
  256. }
  257. (*this) = string;
  258. return ;
  259. }
  260. ///////////////////////////////////////////////////////////////////
  261. // StringClass
  262. ///////////////////////////////////////////////////////////////////
  263. inline
  264. StringClass::StringClass (const TCHAR *string, bool hint_temporary)
  265. : m_Buffer (m_EmptyString)
  266. {
  267. int len=string ? _tcsclen(string) : 0;
  268. if (hint_temporary || len>0) {
  269. Get_String (len+1, hint_temporary);
  270. }
  271. (*this) = string;
  272. return ;
  273. }
  274. ///////////////////////////////////////////////////////////////////
  275. // StringClass
  276. ///////////////////////////////////////////////////////////////////
  277. inline
  278. StringClass::StringClass (const WCHAR *string, bool hint_temporary)
  279. : m_Buffer (m_EmptyString)
  280. {
  281. int len = string ? wcslen (string) : 0;
  282. if (hint_temporary || len > 0) {
  283. Get_String (len + 1, hint_temporary);
  284. }
  285. (*this) = string;
  286. return ;
  287. }
  288. ///////////////////////////////////////////////////////////////////
  289. // ~StringClass
  290. ///////////////////////////////////////////////////////////////////
  291. inline
  292. StringClass::~StringClass (void)
  293. {
  294. Free_String ();
  295. return ;
  296. }
  297. ///////////////////////////////////////////////////////////////////
  298. // Is_Empty
  299. ///////////////////////////////////////////////////////////////////
  300. inline bool
  301. StringClass::Is_Empty (void) const
  302. {
  303. return (m_Buffer[0] == m_NullChar);
  304. }
  305. ///////////////////////////////////////////////////////////////////
  306. // Compare
  307. ///////////////////////////////////////////////////////////////////
  308. inline int
  309. StringClass::Compare (const TCHAR *string) const
  310. {
  311. return _tcscmp (m_Buffer, string);
  312. }
  313. ///////////////////////////////////////////////////////////////////
  314. // Compare_No_Case
  315. ///////////////////////////////////////////////////////////////////
  316. inline int
  317. StringClass::Compare_No_Case (const TCHAR *string) const
  318. {
  319. return _tcsicmp (m_Buffer, string);
  320. }
  321. ///////////////////////////////////////////////////////////////////
  322. // operator[]
  323. ///////////////////////////////////////////////////////////////////
  324. inline const TCHAR &
  325. StringClass::operator[] (int index) const
  326. {
  327. WWASSERT (index >= 0 && index < Get_Length ());
  328. return m_Buffer[index];
  329. }
  330. ///////////////////////////////////////////////////////////////////
  331. // operator[]
  332. ///////////////////////////////////////////////////////////////////
  333. inline TCHAR &
  334. StringClass::operator[] (int index)
  335. {
  336. WWASSERT (index >= 0 && index < Get_Length ());
  337. return m_Buffer[index];
  338. }
  339. ///////////////////////////////////////////////////////////////////
  340. // operator const TCHAR *
  341. ///////////////////////////////////////////////////////////////////
  342. inline
  343. StringClass::operator const TCHAR * (void) const
  344. {
  345. return m_Buffer;
  346. }
  347. ///////////////////////////////////////////////////////////////////
  348. // operator==
  349. ///////////////////////////////////////////////////////////////////
  350. inline bool
  351. StringClass::operator== (const TCHAR *rvalue) const
  352. {
  353. return (Compare (rvalue) == 0);
  354. }
  355. ///////////////////////////////////////////////////////////////////
  356. // operator!=
  357. ///////////////////////////////////////////////////////////////////
  358. inline bool
  359. StringClass::operator!= (const TCHAR *rvalue) const
  360. {
  361. return (Compare (rvalue) != 0);
  362. }
  363. ///////////////////////////////////////////////////////////////////
  364. // operator <
  365. ///////////////////////////////////////////////////////////////////
  366. inline bool
  367. StringClass::operator < (const TCHAR *string) const
  368. {
  369. return (_tcscmp (m_Buffer, string) < 0);
  370. }
  371. ///////////////////////////////////////////////////////////////////
  372. // operator <=
  373. ///////////////////////////////////////////////////////////////////
  374. inline bool
  375. StringClass::operator <= (const TCHAR *string) const
  376. {
  377. return (_tcscmp (m_Buffer, string) <= 0);
  378. }
  379. ///////////////////////////////////////////////////////////////////
  380. // operator >
  381. ///////////////////////////////////////////////////////////////////
  382. inline bool
  383. StringClass::operator > (const TCHAR *string) const
  384. {
  385. return (_tcscmp (m_Buffer, string) > 0);
  386. }
  387. ///////////////////////////////////////////////////////////////////
  388. // operator >=
  389. ///////////////////////////////////////////////////////////////////
  390. inline bool
  391. StringClass::operator >= (const TCHAR *string) const
  392. {
  393. return (_tcscmp (m_Buffer, string) >= 0);
  394. }
  395. ///////////////////////////////////////////////////////////////////
  396. // Erase
  397. ///////////////////////////////////////////////////////////////////
  398. inline void
  399. StringClass::Erase (int start_index, int char_count)
  400. {
  401. int len = Get_Length ();
  402. if (start_index < len) {
  403. if (start_index + char_count > len) {
  404. char_count = len - start_index;
  405. }
  406. ::memmove ( &m_Buffer[start_index],
  407. &m_Buffer[start_index + char_count],
  408. (len - (start_index + char_count) + 1) * sizeof (TCHAR));
  409. Store_Length( len - char_count );
  410. }
  411. return ;
  412. }
  413. ///////////////////////////////////////////////////////////////////
  414. // Trim leading and trailing whitespace characters (values <= 32)
  415. ///////////////////////////////////////////////////////////////////
  416. inline void StringClass::Trim(void)
  417. {
  418. strtrim(m_Buffer);
  419. }
  420. ///////////////////////////////////////////////////////////////////
  421. // operator+=
  422. ///////////////////////////////////////////////////////////////////
  423. inline const StringClass &
  424. StringClass::operator+= (const TCHAR *string)
  425. {
  426. WWASSERT (string != NULL);
  427. int cur_len = Get_Length ();
  428. int src_len = _tcslen (string);
  429. int new_len = cur_len + src_len;
  430. //
  431. // Make sure our buffer is large enough to hold the new string
  432. //
  433. Resize (new_len + 1);
  434. Store_Length (new_len);
  435. //
  436. // Copy the new string onto our the end of our existing buffer
  437. //
  438. ::memcpy (&m_Buffer[cur_len], string, (src_len + 1) * sizeof (TCHAR));
  439. return (*this);
  440. }
  441. ///////////////////////////////////////////////////////////////////
  442. // operator+=
  443. ///////////////////////////////////////////////////////////////////
  444. inline const StringClass &
  445. StringClass::operator+= (TCHAR ch)
  446. {
  447. int cur_len = Get_Length ();
  448. Resize (cur_len + 2);
  449. m_Buffer[cur_len] = ch;
  450. m_Buffer[cur_len + 1] = m_NullChar;
  451. if (ch != m_NullChar) {
  452. Store_Length (cur_len + 1);
  453. }
  454. return (*this);
  455. }
  456. ///////////////////////////////////////////////////////////////////
  457. // Get_Buffer
  458. ///////////////////////////////////////////////////////////////////
  459. inline TCHAR *
  460. StringClass::Get_Buffer (int new_length)
  461. {
  462. Uninitialised_Grow (new_length);
  463. return m_Buffer;
  464. }
  465. ///////////////////////////////////////////////////////////////////
  466. // Peek_Buffer
  467. ///////////////////////////////////////////////////////////////////
  468. inline TCHAR *
  469. StringClass::Peek_Buffer (void)
  470. {
  471. return m_Buffer;
  472. }
  473. ///////////////////////////////////////////////////////////////////
  474. // Peek_Buffer
  475. ///////////////////////////////////////////////////////////////////
  476. inline const TCHAR *
  477. StringClass::Peek_Buffer (void) const
  478. {
  479. return m_Buffer;
  480. }
  481. ///////////////////////////////////////////////////////////////////
  482. // operator+=
  483. ///////////////////////////////////////////////////////////////////
  484. inline const StringClass &
  485. StringClass::operator+= (const StringClass &string)
  486. {
  487. int src_len = string.Get_Length();
  488. if (src_len > 0) {
  489. int cur_len = Get_Length ();
  490. int new_len = cur_len + src_len;
  491. //
  492. // Make sure our buffer is large enough to hold the new string
  493. //
  494. Resize (new_len + 1);
  495. Store_Length (new_len);
  496. //
  497. // Copy the new string onto our the end of our existing buffer
  498. //
  499. ::memcpy (&m_Buffer[cur_len], (const TCHAR *)string, (src_len + 1) * sizeof (TCHAR));
  500. }
  501. return (*this);
  502. }
  503. ///////////////////////////////////////////////////////////////////
  504. // operator+=
  505. ///////////////////////////////////////////////////////////////////
  506. inline StringClass
  507. operator+ (const StringClass &string1, const StringClass &string2)
  508. {
  509. StringClass new_string(string1, true);
  510. new_string += string2;
  511. return new_string;
  512. }
  513. ///////////////////////////////////////////////////////////////////
  514. // operator+=
  515. ///////////////////////////////////////////////////////////////////
  516. inline StringClass
  517. operator+ (const TCHAR *string1, const StringClass &string2)
  518. {
  519. StringClass new_string(string1, true);
  520. new_string += string2;
  521. return new_string;
  522. }
  523. ///////////////////////////////////////////////////////////////////
  524. // operator+=
  525. ///////////////////////////////////////////////////////////////////
  526. inline StringClass
  527. operator+ (const StringClass &string1, const TCHAR *string2)
  528. {
  529. StringClass new_string(string1, true);
  530. StringClass new_string2(string2, true);
  531. new_string += new_string2;
  532. return new_string;
  533. }
  534. ///////////////////////////////////////////////////////////////////
  535. // Get_Allocated_Length
  536. //
  537. // Return allocated size of the string buffer
  538. ///////////////////////////////////////////////////////////////////
  539. inline int
  540. StringClass::Get_Allocated_Length (void) const
  541. {
  542. int allocated_length = 0;
  543. //
  544. // Read the allocated length from the header
  545. //
  546. if (m_Buffer != m_EmptyString) {
  547. HEADER *header = Get_Header ();
  548. allocated_length = header->allocated_length;
  549. }
  550. return allocated_length;
  551. }
  552. ///////////////////////////////////////////////////////////////////
  553. // Get_Length
  554. //
  555. // Return text legth. If length is not known calculate it, otherwise
  556. // just return the previously stored value (strlen tends to take
  557. // quite a lot cpu time if a lot of string combining operations are
  558. // performed.
  559. ///////////////////////////////////////////////////////////////////
  560. inline int
  561. StringClass::Get_Length (void) const
  562. {
  563. int length = 0;
  564. if (m_Buffer != m_EmptyString) {
  565. //
  566. // Read the length from the header
  567. //
  568. HEADER *header = Get_Header ();
  569. length = header->length;
  570. //
  571. // Hmmm, a zero length was stored in the header,
  572. // we better manually get the string length.
  573. //
  574. if (length == 0) {
  575. length = _tcslen (m_Buffer);
  576. ((StringClass *)this)->Store_Length (length);
  577. }
  578. }
  579. return length;
  580. }
  581. ///////////////////////////////////////////////////////////////////
  582. // Set_Buffer_And_Allocated_Length
  583. //
  584. // Set buffer pointer and init size variable. Length is set to 0
  585. // as the contents of the new buffer are not necessarily defined.
  586. ///////////////////////////////////////////////////////////////////
  587. inline void
  588. StringClass::Set_Buffer_And_Allocated_Length (TCHAR *buffer, int length)
  589. {
  590. Free_String ();
  591. m_Buffer = buffer;
  592. //
  593. // Update the header (if necessary)
  594. //
  595. if (m_Buffer != m_EmptyString) {
  596. Store_Allocated_Length (length);
  597. Store_Length (0);
  598. } else {
  599. WWASSERT (length == 0);
  600. }
  601. return ;
  602. }
  603. ///////////////////////////////////////////////////////////////////
  604. // Allocate_Buffer
  605. ///////////////////////////////////////////////////////////////////
  606. inline TCHAR *
  607. StringClass::Allocate_Buffer (int length)
  608. {
  609. //
  610. // Allocate a buffer that is 'length' characters long, plus the
  611. // bytes required to hold the header.
  612. //
  613. char *buffer = new char[(sizeof (TCHAR) * length) + sizeof (StringClass::_HEADER)];
  614. //
  615. // Fill in the fields of the header
  616. //
  617. HEADER *header = reinterpret_cast<HEADER *>(buffer);
  618. header->length = 0;
  619. header->allocated_length = length;
  620. //
  621. // Return the buffer as if it was a TCHAR pointer
  622. //
  623. return reinterpret_cast<TCHAR *>(buffer + sizeof (StringClass::_HEADER));
  624. }
  625. ///////////////////////////////////////////////////////////////////
  626. // Get_Header
  627. ///////////////////////////////////////////////////////////////////
  628. inline StringClass::HEADER *
  629. StringClass::Get_Header (void) const
  630. {
  631. return reinterpret_cast<HEADER *>(((char *)m_Buffer) - sizeof (StringClass::_HEADER));
  632. }
  633. ///////////////////////////////////////////////////////////////////
  634. // Store_Allocated_Length
  635. ///////////////////////////////////////////////////////////////////
  636. inline void
  637. StringClass::Store_Allocated_Length (int allocated_length)
  638. {
  639. if (m_Buffer != m_EmptyString) {
  640. HEADER *header = Get_Header ();
  641. header->allocated_length = allocated_length;
  642. } else {
  643. WWASSERT (allocated_length == 0);
  644. }
  645. return ;
  646. }
  647. ///////////////////////////////////////////////////////////////////
  648. // Store_Length
  649. //
  650. // Set length... The caller of this (private) function better
  651. // be sure that the len is correct.
  652. ///////////////////////////////////////////////////////////////////
  653. inline void
  654. StringClass::Store_Length (int length)
  655. {
  656. if (m_Buffer != m_EmptyString) {
  657. HEADER *header = Get_Header ();
  658. header->length = length;
  659. } else {
  660. WWASSERT (length == 0);
  661. }
  662. return ;
  663. }
  664. #endif //__WWSTRING_H