Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1098 lines
38 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corp., 1991 **/
  4. /**********************************************************************/
  5. /*
  6. string.hxx
  7. String classes: definition
  8. This file contains the basic string classes for the Thor UI.
  9. Its requirements are:
  10. - provide a modestly object-oriented interface to string
  11. manipulation, the better to work with the rest of our code;
  12. - encapsulate NLS and DBCS support as much as possible;
  13. - ensure that apps get correct form of library support,
  14. particularly with possible interference from intrinsics;
  15. The current solution consists of two classes: NLS_STR, and ISTR.
  16. class NLS_STR: use wherever NLS/DBCS support is needed.
  17. Most strings (in the UI, anyway) should be
  18. of this class.
  19. class ISTR: Indexes an NLS_STR in a DBCS safe manner. All
  20. positioning within an NLS_STR is done with ISTRs
  21. The class hierarchy looks like:
  22. BASE
  23. NLS_STR
  24. ALLOC_STR
  25. ALIAS_STR
  26. RESOURCE_STR
  27. ISTR
  28. This file also contains the STACK_NLS_STR macro and the
  29. strcpy( TCHAR *, const NLS_STR& ) prototype.
  30. FILE HISTORY:
  31. beng 21-Oct-1990 Created from email memo of last week
  32. johnl 13-Nov-1990 Removed references to EB_STRING
  33. johnl 28-Nov-1990 Release fully functional version
  34. johnl 7-Dec-1990 Numerous revisions after code review
  35. (Removed SZ_STR, ISTR must associate
  36. w/a string upon decl etc.)
  37. beng 05-Feb-1991 Replaced PCH with TCHAR * for
  38. const-placement
  39. beng 26-Apr-1991 Expunged of CB, IB types; relocated
  40. inline functions to string/strmisc.cxx
  41. beng 23-Jul-1991 Added more *_STR types
  42. KeithMo 09-Oct-1991 Win32 Conversion.
  43. beng 22-Oct-1991 Patch for NT C runtimes
  44. KeithMo 23-Oct-1991 Added forward references.
  45. beng 14-Nov-1991 Fixed CT_NLS_STR
  46. beng 21-Nov-1991 Removed STR_OWNERALLOC opcodes
  47. terryk 17-Apr-1992 Added atoul
  48. beng 24-Apr-1992 Added CBNLSMAGIC
  49. beng 28-Jul-1992 MAX_RES_STR_LEN is now advisory only;
  50. update MAX_INSERT_PARAMS
  51. KeithMo 24-Aug-1992 Added <string.h> for very bizarre reasons.
  52. KeithMo 16-Nov-1992 Performance tuning.
  53. */
  54. #ifndef _STRING_HXX_
  55. #define _STRING_HXX_
  56. #include "base.hxx"
  57. //
  58. // We *MUST* include string.h here!
  59. //
  60. // Why you ask? Simple. The "standard" string.h #defines a number of
  61. // nonstandard string functions, such as:
  62. //
  63. // #define strupr _strupr
  64. //
  65. // This keeps the "real" _strupr out of the normal app namespace.
  66. //
  67. // Unfortunately, the C preprocess phase applies this #define to
  68. // NLS_STR's member functions. So, if you include <string.h> *after*
  69. // you include <string.hxx>, you won't be able to access any of the
  70. // members with nonstandard names (such as strupr).
  71. //
  72. #include <string.h>
  73. //
  74. // CODEWORK: IS_LEAD_BYTE was ripped out of our hacked
  75. // string.h. We need a more proper definition,
  76. // especially for DBCS builds (such as Win32s).
  77. //
  78. #define IS_LEAD_BYTE(x) FALSE
  79. // Maximum resource string size. At one time, owneralloc strings had be at
  80. // least MAX_RES_STR_LEN characters long. While this is no longer the
  81. // case, it's easier to keep the symbol than to change all the client code.
  82. //
  83. #define MAX_RES_STR_LEN 255
  84. // The maximum number of parameters the InsertParams method can handle
  85. //
  86. #define MAX_INSERT_PARAMS 99
  87. /* Magic number used for overloading cbCopy member functions */
  88. #define CBNLSMAGIC ((UINT)-1)
  89. // A token for "use the default base DLL HMODULE" for resource lookup.
  90. #define NLS_BASE_DLL_HMOD 0
  91. //
  92. // Forward references.
  93. //
  94. DLL_CLASS NLS_STR;
  95. DLL_CLASS ISTR;
  96. DLL_CLASS RESOURCE_STR;
  97. DLL_CLASS ALLOC_STR;
  98. DLL_CLASS ALIAS_STR;
  99. //
  100. // Special debugging manifest for string class
  101. //
  102. // #define NLS_DEBUG
  103. //
  104. /*************************************************************************
  105. NAME: ISTR
  106. SYNOPSIS: String index object, used in conjunction with NLS_STR
  107. INTERFACE:
  108. ISTR() - this ISTR gets associated with
  109. the passed string and can only be used
  110. on this string (NOTE: on non-debug
  111. versions this turns into a nop, can still
  112. be useful for decl. clarity however).
  113. ISTR() - Initialize to passed ISTR;
  114. this ISTR will be associated with
  115. the same string that the passed ISTR
  116. is associated with.
  117. operator=() - Copy passed ISTR (see prev.)
  118. operator-() - Returns Cch diff. between *this & Param.
  119. (must both belong to the same string)
  120. operator++() - Advance the ISTR to the next logical
  121. character (use only where absolutely
  122. necessary). Stops at end of string
  123. operator+=() - Advance the ISTR to the ith logical
  124. character (call operator++ i times)
  125. Stops at end of string.
  126. operator==() - Returns TRUE if the two ISTRs point to
  127. the same position in the string (causes
  128. an assertion failure if the two ISTRs
  129. don't point to the same string).
  130. operator>() - Returns true of *this is greater then
  131. the passed ISTR (i.e., further along
  132. in the string).
  133. operator<() - Same as operator>, only less then.
  134. Reset() - Resets ISTR to beginning of string and
  135. updates the ISTR version number with the
  136. string's current version number
  137. IsLastPos() - TRUE if istr indexes last character in
  138. its string. (This would seem to belong
  139. more properly as NLS_STR::QueryLastPos;
  140. however, it's more efficient under DBCS
  141. as a property of ISTR.)
  142. USES:
  143. CAVEATS:
  144. Each NLS_STR has a version number associated with it. When
  145. an operation is performed that modifies the string, the
  146. version number is updated. It is invalid to use an ISTR
  147. after its associated NLS_STR has been modified (can use
  148. Reset to resync it with the NLS_STR, the index gets reset
  149. to zero).
  150. You must associate an NLS_STR with an ISTR at the
  151. declaration of the ISTR.
  152. Subtraction returns a signed difference, where it should probably
  153. return an unsigned difference.
  154. NOTES:
  155. The version checking and string association checking goes
  156. away in the non-debug version.
  157. HISTORY:
  158. johnl 16-Nov-1990 Created
  159. johnl 7-Dec-1990 Modified after code review
  160. yi-hsins 14-Oct-1991 Added IsLastPos
  161. beng 19-Nov-1991 Unicode fixes
  162. anirudhs 22-Apr-1995 Added operator INT, as in Win95
  163. **************************************************************************/
  164. DLL_CLASS ISTR
  165. {
  166. friend class NLS_STR;
  167. public:
  168. ISTR( const ISTR& istr );
  169. ISTR( const NLS_STR& nls );
  170. ISTR& operator=( const ISTR& istr );
  171. INT operator-( const ISTR& istr ) const;
  172. ISTR& operator++();
  173. VOID operator+=( INT iChars );
  174. BOOL operator==( const ISTR& istr ) const;
  175. BOOL operator>( const ISTR& istr ) const;
  176. BOOL operator<( const ISTR& istr ) const;
  177. operator INT() const
  178. { return _ichString; }
  179. VOID Reset();
  180. BOOL IsLastPos() const;
  181. private:
  182. INT _ichString; // Index (in TCHAR) into an NLS_STR
  183. const NLS_STR *_pnls; // Pointer to "owner" NLS
  184. INT QueryIch() const
  185. { return _ichString; }
  186. VOID SetIch( INT ich )
  187. { _ichString = ich; }
  188. const NLS_STR* QueryString() const
  189. { return _pnls; }
  190. VOID SetString( const NLS_STR * pnls )
  191. { _pnls = (NLS_STR*)pnls; }
  192. #ifdef NLS_DEBUG
  193. // Version number of NLS_STR this ISTR is associated with
  194. //
  195. UINT _nVersion;
  196. UINT QueryVersion() const { return _nVersion; }
  197. VOID SetVersion( UINT nVers ) { _nVersion = nVers; }
  198. #endif
  199. // This constructor does not exist, it is intended to make certain that
  200. // no one tries to construct an ISTR like this. JonN 1/11/96
  201. ISTR( LPTSTR str );
  202. };
  203. /*************************************************************************
  204. NAME: NLS_STR (nls)
  205. SYNOPSIS: Provide a better string abstraction than the standard ASCIIZ
  206. representation offered by C (and C++). The abstraction is
  207. better mainly because it handles double-byte characters
  208. (DBCS) in the string and makes intelligent use of operator
  209. overloading.
  210. INTERFACE:
  211. NLS_STR() Construct a NLS_STR (initialized to a TCHAR *,
  212. NLS_STR or NULL). Reports errors via BASE.
  213. ~NLS_STR() Destructor
  214. operator=() Assign one NLS_STR (or TCHAR *) value
  215. to another (old string is deleted, new
  216. string is allocated and copies source).
  217. See also NLS_STR::CopyFrom().
  218. operator+=() Concatenate with assignment (equivalent to
  219. strcat - see strcat).
  220. operator==() Compare two NLS_STRs for equality
  221. operator!=() Compare two NLS_STRs for inequality
  222. QueryPch() Access operator, returning a "const TCHAR *"
  223. aliased to the string. DO NOT MODIFY
  224. THE STRING USING THIS METHOD (or pass
  225. it to procedures that might modify it).
  226. Synonym: operator const TCHAR *().
  227. C-runtime-style methods.
  228. strlen() Return the length of the string in bytes,
  229. less terminator. Provided only for crt
  230. compatibility; please use a Query method
  231. (QueryTextLength()
  232. strcat() Append an NLS_STR. Will cause *this to be
  233. reallocated if the appended string is larger
  234. then this->QueryCb() and this is not an
  235. STR_OWNERALLOC string
  236. strcmp() Compare two NLS_STRs
  237. stricmp()
  238. strncmp() Compare a portion of two NLS_STRs
  239. strnicmp()
  240. strcspn() Find first char in *this that is in arg
  241. strspn() Find first char in *this that is NOT in arg
  242. strtok() Returns a token from the string
  243. strstr() Search for a NLS_STR.
  244. strchr() Search for a TCHAR from beginning.
  245. Returns offset.
  246. strrchr() Search for a TCHAR from end.
  247. strupr() Convert NLS_STR to upper case.
  248. RtlOemUpcase() Convert to upper case using
  249. RplUpcaseUnicodeStringToOemString
  250. atoi() Returns integer numeric value
  251. atol() Returns long value
  252. atoul() Returns unsigned long value
  253. Other methods.
  254. QueryTextLength() Returns the number of TCHAR, less
  255. terminator.
  256. QueryTextSize() Returns the number of bytes, including
  257. terminator. Denotes amount of storage
  258. needed to dup string into a bytevector.
  259. QueryNumChar() Returns total number of logical characters
  260. within the string. Rarely needed.
  261. QueryAllocSize() Returns total # of bytes allocated (i.e.,
  262. number new was called with, or size of
  263. memory block if STR_OWNERALLOC
  264. IsOwnerAlloc() Returns TRUE if this string is an owner
  265. allocated string
  266. QuerySubStr() Return a substring
  267. InsertStr() Insert a NLS_STR at given index.
  268. DelSubStr() Delete a substring
  269. ReplSubStr() Replace a substring (given start and
  270. NLS_STR)
  271. InsertParams() Replace %1-%9 params in *this with the
  272. corresponding NLS_STRs contained in the
  273. array of pointers
  274. Load() Load the string associated with the passed
  275. resource into *this (OWNER_ALLOC strings must
  276. be at least MAX_RES_STR_LEN).
  277. Reset() After an operation fails (due to memory
  278. failure), it is invalid to use the string
  279. until Reset has been called. If the object
  280. wasn't successfully constructed, Reset will
  281. fail.
  282. Append() Appends a string to the current string,
  283. like strcat.
  284. AppendChar() Appends a single character.
  285. Compare() As strcmp(). Used by collection classes.
  286. CopyFrom() As operator=(), but returns an APIERR.
  287. CopyTo() Similar to strcpy, returning an APIERR.
  288. MapCopyFrom() As CopyFrom(), but does Unicode/MBCS conversion
  289. as appropriate to argument type and host env.
  290. MapCopyTo() As MapCopyFrom(), but the other way around.
  291. PARENT: BASE
  292. USES: ISTR
  293. CAVEATS:
  294. A NLS_STR object can enter an error state for various
  295. reasons - typically a memory allocation failure. Using
  296. an object in such a state is theoretically an error.
  297. Since string operations frequently occur in groups,
  298. we define operations on an erroneous string as no-op,
  299. so that the check for an error may be postponed until
  300. the end of the complex operation. Most member functions
  301. which calculate a value will treat an erroneous string
  302. as having zero length; however, clients should not depend
  303. on this.
  304. Attempting to use an ISTR that is registered with another
  305. string will cause an assertion failure.
  306. Each NLS_STR has a version/modification flag that is also
  307. stored in the the ISTR. An attempt to use an ISTR on an
  308. NLS_STR that has been modified (by calling one of the methods
  309. listed below) will cause an assertion failure. To use the
  310. ISTR after a modifying method, you must first call ISTR::Reset
  311. which will update the version in the ISTR. See the
  312. method definition for more detail.
  313. List of modifying methods:
  314. All NLS::operator= methods
  315. NLS::DelSubStr
  316. NLS::ReplSubStr
  317. NLS::InsertSubStr
  318. N.b. The ISTR used as a starting index on the Substring
  319. methods remains valid after the call.
  320. NOTES:
  321. The lack of a strlwr() method comes from a shortcoming
  322. in the casemap tables. Sorry.
  323. "Owner-alloc" strings are a special type of NLS_STR, available
  324. only through certain derived classes. The client must supply
  325. a buffer where the string data will reside, plus the size of
  326. that block. NLS_STR will never resize or delete this buffer,
  327. and performs no checking for writing beyond the end of the
  328. string.
  329. Valid uses of owner-alloc strings include static strings,
  330. severe optimization, owner controlled memory allocation
  331. or stack controlled memory allocation.
  332. CODEWORK: Should add a fReadOnly flag.
  333. HISTORY:
  334. johnl 28-Nov-1990 First fully functioning version
  335. johnl 7-Dec-1990 Incorporated code review changes
  336. terryk 05-Apr-1991 add QueryNumChar method
  337. beng 22-Jul-1991 Added more methods; separated fOwnerAlloc
  338. from cbData
  339. beng 07-Oct-1991 LoadString takes MSGID and uses APIERR
  340. beng 18-Oct-1991 Renamed LoadString to Load (for Win32)
  341. beng 14-Nov-1991 Unicode fixes
  342. beng 21-Nov-1991 Withdrew stristr member function, some ctors;
  343. made owner-alloc ctor protected
  344. beng 27-Feb-1992 Create protected members for manipulation
  345. of buffer by derived classes; add additional
  346. InsertParams forms; withdrew Load+Insert
  347. comb. form
  348. beng 02-Mar-1992 Added MapCopy fcns, CopyTo
  349. beng 28-Mar-1992 Withdrew strtok member from Unicode; give
  350. {Map}CopyFrom an optional cbCopy param
  351. beng 24-Apr-1992 Changed MapCopyTo magic cbCopy value
  352. beng 05-Aug-1992 Added LoadSystem
  353. jonn 04-Sep-1992 Compare() must be _CRTAPI1
  354. **************************************************************************/
  355. DLL_CLASS NLS_STR : public BASE
  356. {
  357. // Istr needs access to CheckIstr.
  358. //
  359. friend class ISTR;
  360. // Alias-string op= needs r/w access to all ivars.
  361. //
  362. friend class ALIAS_STR;
  363. public:
  364. // Default constructor, creating an empty string.
  365. //
  366. NLS_STR();
  367. // Create an empty string, but preallocated to accomodate "cchInitLen"
  368. // characters, plus trailing NUL.
  369. //
  370. NLS_STR( UINT cchInit );
  371. // Initialize from a NUL-terminated character vector.
  372. //
  373. NLS_STR( const TCHAR * pchInit );
  374. // Initialize from an existing x_STRING.
  375. //
  376. NLS_STR( const NLS_STR & nlsInit );
  377. #ifdef UNICODE
  378. // Initialize from a non-NULL-terminated UNICODE character vector.
  379. //
  380. NLS_STR( const WCHAR * pchInit, USHORT cchInit );
  381. #endif
  382. ~NLS_STR();
  383. // Number of bytes the string uses (not including terminator)
  384. // Cf. QueryTextLength and QueryTextSize.
  385. //
  386. UINT strlen() const;
  387. // Number of logical characters within the string
  388. //
  389. UINT QueryNumChar() const;
  390. // Number of printing TCHAR in the string.
  391. // This number does not include the termination character.
  392. //
  393. // Cf. QueryNumChar, which returns a count of glyphs.
  394. //
  395. UINT _QueryTextLength() const;
  396. UINT QueryTextLength() const
  397. #if defined(DEBUG)
  398. { return _QueryTextLength(); }
  399. #else // !DEBUG
  400. { return _cchLen; }
  401. #endif // DEBUG
  402. // Number of BYTES occupied by the string's representation.
  403. // Cf. QueryAllocSize, which returns the total amount alloc'd.
  404. //
  405. UINT QueryTextSize() const;
  406. #if defined(UNICODE) && defined(FE_SB)
  407. // Number of bytes required for buffer.
  408. // (just calling nls function)
  409. //
  410. UINT QueryAnsiTextLength() const;
  411. #endif
  412. // Return a read-only TCHAR vector, for the APIs.
  413. //
  414. const TCHAR * QueryPch( const ISTR & istr ) const;
  415. const TCHAR * _QueryPch() const;
  416. const TCHAR * QueryPch() const
  417. #if defined(DEBUG)
  418. { return _QueryPch(); }
  419. #else // !DEBUG
  420. { return _pchData; }
  421. #endif // DEBUG
  422. WCHAR QueryChar( const ISTR & istr ) const;
  423. operator const TCHAR *() const
  424. #if defined(DEBUG)
  425. { return _QueryPch(); }
  426. #else // !DEBUG
  427. { return _pchData; }
  428. #endif // DEBUG
  429. const TCHAR * operator[]( const ISTR & istr ) const
  430. { return QueryPch(istr); }
  431. APIERR Append( const NLS_STR & nls );
  432. APIERR AppendChar( WCHAR wch );
  433. // Total allocated storage
  434. //
  435. UINT _QueryAllocSize() const;
  436. UINT QueryAllocSize() const
  437. #if defined(DEBUG)
  438. { return _QueryAllocSize(); }
  439. #else // !DEBUG
  440. { return _cbData; }
  441. #endif // DEBUG
  442. BOOL _IsOwnerAlloc() const;
  443. BOOL IsOwnerAlloc() const
  444. #if defined(DEBUG)
  445. { return _IsOwnerAlloc(); }
  446. #else // !DEBUG
  447. { return _fOwnerAlloc; }
  448. #endif // DEBUG
  449. // Returns TRUE if error was successfully cleared (string is
  450. // now in valid state), FALSE otherwise.
  451. //
  452. BOOL Reset();
  453. NLS_STR & operator = ( const NLS_STR & nlsSource );
  454. NLS_STR & operator = ( const TCHAR * achSource );
  455. APIERR CopyFrom( const NLS_STR & nlsSource );
  456. APIERR CopyFrom( const TCHAR * achSource, UINT cbCopy = CBNLSMAGIC );
  457. APIERR CopyTo( TCHAR * pchDest, UINT cbAvailable ) const;
  458. NLS_STR & operator += ( const NLS_STR & nls );
  459. NLS_STR & strcat( const NLS_STR & nls );
  460. BOOL operator == ( const NLS_STR & nls ) const;
  461. BOOL operator != ( const NLS_STR & nls ) const;
  462. INT strcmp( const NLS_STR & nls ) const;
  463. INT strcmp( const NLS_STR & nls,
  464. const ISTR & istrThis ) const;
  465. INT strcmp( const NLS_STR & nls,
  466. const ISTR & istrThis,
  467. const ISTR & istrStart2 ) const;
  468. INT _stricmp( const NLS_STR & nls ) const;
  469. INT _stricmp( const NLS_STR & nls,
  470. const ISTR & istrThis ) const;
  471. INT _stricmp( const NLS_STR & nls,
  472. const ISTR & istrThis,
  473. const ISTR & istrStart2 ) const;
  474. INT strncmp( const NLS_STR & nls,
  475. const ISTR & istrLen ) const;
  476. INT strncmp( const NLS_STR & nls,
  477. const ISTR & istrLen,
  478. const ISTR & istrThis ) const;
  479. INT strncmp( const NLS_STR & nls,
  480. const ISTR & istrLen,
  481. const ISTR & istrThis ,
  482. const ISTR & istrStart2 ) const;
  483. INT _strnicmp( const NLS_STR & nls,
  484. const ISTR & istrLen ) const;
  485. INT _strnicmp( const NLS_STR & nls,
  486. const ISTR & istrLen,
  487. const ISTR & istrThis ) const;
  488. INT _strnicmp( const NLS_STR & nls,
  489. const ISTR & istrLen,
  490. const ISTR & istrThis ,
  491. const ISTR & istrStart2 ) const;
  492. // The following str* functions return TRUE if successful (istrPos has
  493. // meaningful data), false otherwise.
  494. //
  495. BOOL strcspn( ISTR * istrPos,
  496. const NLS_STR & nls ) const;
  497. BOOL strcspn( ISTR * istrPos,
  498. const NLS_STR & nls,
  499. const ISTR & istrStart ) const;
  500. BOOL strspn( ISTR * istrPos,
  501. const NLS_STR & nls ) const;
  502. BOOL strspn( ISTR * istrPos,
  503. const NLS_STR & nls,
  504. const ISTR & istrStart ) const;
  505. BOOL strstr( ISTR * istrPos,
  506. const NLS_STR & nls ) const;
  507. BOOL strstr( ISTR * istrPos,
  508. const NLS_STR & nls,
  509. const ISTR & istrStart ) const;
  510. BOOL strchr( ISTR * istrPos,
  511. const TCHAR ch ) const;
  512. BOOL strchr( ISTR * istrPos,
  513. const TCHAR ch,
  514. const ISTR & istrStart ) const;
  515. BOOL strrchr( ISTR * istrPos,
  516. const TCHAR ch ) const;
  517. BOOL strrchr( ISTR * istrPos,
  518. const TCHAR ch,
  519. const ISTR & istrStart ) const;
  520. #if !defined(UNICODE)
  521. // Runtime support currently not available
  522. BOOL strtok( ISTR * istrPos,
  523. const NLS_STR & nlsBreak,
  524. BOOL fFirst = FALSE );
  525. #endif
  526. LONG atol() const;
  527. LONG atol( const ISTR &istrStart ) const;
  528. ULONG atoul() const;
  529. ULONG atoul( const ISTR &istrStart ) const;
  530. INT atoi() const;
  531. INT atoi( const ISTR &istrStart ) const;
  532. NLS_STR& _strupr();
  533. // Upcase the string using RtlUpcaseUnicodeStringToOemString and
  534. // then converting back to Unicode. This method of uppercasing
  535. // works better than strupr() when the string is sent to a client
  536. // which wants OEM.
  537. //
  538. APIERR RtlOemUpcase();
  539. // Return a pointer to a new NLS_STR that contains the contents
  540. // of *this from istrStart to:
  541. // End of string if no istrEnd is passed
  542. // istrStart + istrEnd
  543. //
  544. NLS_STR *QuerySubStr( const ISTR & istrStart ) const;
  545. NLS_STR *QuerySubStr( const ISTR & istrStart,
  546. const ISTR & istrEnd ) const;
  547. // Collapse the string by removing the characters from istrStart to:
  548. // End of string
  549. // istrStart + istrEnd
  550. // The string is not reallocated
  551. //
  552. VOID DelSubStr( ISTR & istrStart );
  553. VOID DelSubStr( ISTR & istrStart,
  554. const ISTR & istrEnd );
  555. BOOL InsertStr( const NLS_STR & nlsIns,
  556. ISTR & istrStart );
  557. // Replace till End of string of either *this or replacement string
  558. // (or istrEnd in the 2nd form) starting at istrStart
  559. //
  560. VOID ReplSubStr( const NLS_STR & nlsRepl,
  561. ISTR & istrStart );
  562. VOID ReplSubStr( const NLS_STR & nlsRepl,
  563. ISTR & istrStart,
  564. const ISTR & istrEnd );
  565. // Replace %1-%9 in *this with corresponding index from apnlsParams
  566. // Ex. if *this="Error %1" and apnlsParams[0]="Foo" the resultant
  567. // string would be "Error Foo"
  568. //
  569. APIERR InsertParams( const NLS_STR ** apnlsParams );
  570. // Use varargs on stack instead of vector of pointers
  571. //
  572. APIERR InsertParams( UINT cpnlsArgs, const NLS_STR * arg1, ... );
  573. // Other forms of InsertParams
  574. //
  575. APIERR InsertParams( const NLS_STR & arg )
  576. { return InsertParams( 1, &arg ); }
  577. APIERR InsertParams( const NLS_STR & arg1, const NLS_STR & arg2 )
  578. { return InsertParams( 2, &arg1, &arg2 ); }
  579. APIERR InsertParams( const NLS_STR & arg1, const NLS_STR & arg2,
  580. const NLS_STR & arg3 )
  581. { return InsertParams( 3, &arg1, &arg2, &arg3 ); }
  582. APIERR InsertParams( const NLS_STR & arg1, const NLS_STR & arg2,
  583. const NLS_STR & arg3, const NLS_STR & arg4 )
  584. { return InsertParams( 4, &arg1, &arg2, &arg3, &arg4 ); }
  585. APIERR InsertParams( const NLS_STR & arg1, const NLS_STR & arg2,
  586. const NLS_STR & arg3, const NLS_STR & arg4,
  587. const NLS_STR & arg5 )
  588. { return InsertParams( 5, &arg1, &arg2, &arg3, &arg4, &arg5 ); }
  589. // Load a message from a resource file into *this. If string is an
  590. // OWNER_ALLOC string, then must be at least MAX_RES_STR_LEN. Heap
  591. // NLS_STRs will be reallocated as necessary.
  592. //
  593. APIERR Load( MSGID msgid );
  594. #if defined(WIN32)
  595. APIERR LoadSystem( MSGID msgid );
  596. #endif
  597. // Load a message from the given resource file. If NULL, the base
  598. // NETUI DLL's HMODULE is used.
  599. APIERR Load( MSGID msgid, HMODULE hmod );
  600. // Used by collection classes
  601. //
  602. INT __cdecl Compare( const NLS_STR * pnls ) const;
  603. #if defined(WIN32)
  604. // Functions for MBCS/Unicode conversion (Win32 environment only).
  605. // Note that these explicitly reference CHAR and WCHAR instead of the
  606. // transmutable TCHAR type.
  607. //
  608. APIERR MapCopyFrom( const WCHAR * pwszSource, UINT cbCopy = CBNLSMAGIC );
  609. APIERR MapCopyFrom( const CHAR * pszSource, UINT cbCopy = CBNLSMAGIC );
  610. APIERR MapCopyTo( WCHAR * pwchDest, UINT cb ) const;
  611. APIERR MapCopyTo( CHAR * pchDest, UINT cb ) const;
  612. #endif
  613. protected:
  614. // The "owner-alloc" form:
  615. // Initialize an NLS_STR to memory position passed as achInit.
  616. // No memory allocation of any type will be performed on this string.
  617. // cbSize should be the total memory size of the buffer. Set fClear
  618. // to reset the buffer to the empty string.
  619. //
  620. NLS_STR( TCHAR * pchInit, UINT cbSize, BOOL fClear );
  621. // (more protected members follow the "private" section)
  622. private:
  623. BOOL _fOwnerAlloc; // Set if owner-alloc string
  624. UINT _cchLen; // Number of TCHAR string uses, less terminator
  625. UINT _cbData; // Total storage allocated, in bytes
  626. TCHAR * _pchData; // Pointer to Storage
  627. #ifdef NLS_DEBUG
  628. UINT _nVersion; // Version count (inc. after each change)
  629. #endif
  630. // The following substring functions are used internally (can't be
  631. // exposed since they take an INT cchLen parameter,
  632. // possibly referencing half a double-byte character).
  633. //
  634. VOID DelSubStr( ISTR & istrStart,
  635. UINT cchLen );
  636. NLS_STR *QuerySubStr( const ISTR & istrStart,
  637. UINT cchLen ) const;
  638. VOID ReplSubStr( const NLS_STR & nlsRepl,
  639. ISTR & istrStart,
  640. UINT cchLen );
  641. // Helper function for InsertParams
  642. //
  643. APIERR InsertParamsAux( const NLS_STR ** apnlsParams,
  644. UINT cParams, BOOL fDoReplace,
  645. UINT * pcchRequired );
  646. // Allocate memory for a string
  647. //
  648. BOOL Alloc( UINT cchRequested );
  649. // Increase the size of a string preserving its contents.
  650. // Returns TRUE if successful, false otherwise.
  651. //
  652. // Reallocations to a smaller size always succeed (no-op).
  653. // Reallocations to a larger size hit the allocator; even in failure,
  654. // the contents of the string remain.
  655. //
  656. // If called on an owner-alloc string, the request must not exceed the
  657. // original allocation.
  658. //
  659. BOOL Realloc( UINT cchRequested );
  660. // CheckIstr checks whether istr is associated with this, asserts out
  661. // if it is not. Also checks version numbers in debug version.
  662. //
  663. VOID CheckIstr( const ISTR& istr ) const;
  664. // UpdateIstr syncs the version number between *this and the passed
  665. // ISTR. This is for operations that cause an update to the string
  666. // but the ISTR that was passed in is still valid (see InsertSubStr).
  667. //
  668. VOID UpdateIstr( ISTR *pistr ) const
  669. #ifdef NLS_DEBUG
  670. { pistr->SetVersion( QueryVersion() ); }
  671. #else
  672. { UNREFERENCED(pistr); }
  673. #endif
  674. // QueryVersion returns the current version number of this string
  675. //
  676. UINT QueryVersion() const
  677. #ifdef NLS_DEBUG
  678. { return _nVersion; }
  679. #else
  680. { return 0xBAD0; }
  681. #endif
  682. protected:
  683. // These let derived strings manipulate the buffer directly.
  684. // On their own head be it if they overwrite end-of-buffer.
  685. //
  686. TCHAR * QueryData() const
  687. { return _pchData; }
  688. VOID SetTextLength( UINT cch )
  689. { _cchLen = cch; }
  690. // IncVers adds one to this strings version number because the previous
  691. // operation caused the contents to change thus possibly rendering
  692. // ISTRs on this string as invalid.
  693. //
  694. VOID IncVers()
  695. #ifdef NLS_DEBUG
  696. { _nVersion++; }
  697. #else
  698. { ; }
  699. #endif
  700. // InitializeVers sets the version number to 0
  701. //
  702. VOID InitializeVers()
  703. #ifdef NLS_DEBUG
  704. { _nVersion = 0; }
  705. #else
  706. { ; }
  707. #endif
  708. private:
  709. //
  710. // All "empty" strings will initially contain this pointer.
  711. //
  712. static TCHAR * _pszEmptyString;
  713. };
  714. /********************************************************************
  715. strcpy( TCHAR *, const NLS_STR & )
  716. Copies the contents of a string into a char buffer.
  717. Returns the destination string.
  718. *********************************************************************/
  719. DLL_BASED
  720. TCHAR * strcpy( TCHAR * pchDest, const NLS_STR& nls );
  721. /*************************************************************************
  722. NAME: RESOURCE_STR
  723. SYNOPSIS: String loaded from a resourcefile
  724. INTERFACE: RESOURCE_STR() - ctor, taking only the resource ID.
  725. PARENT: NLS_STR
  726. CAVEATS:
  727. These strings may not be owner-alloc. Clients who
  728. desire an owner-alloc string - say, perhaps where the
  729. string will be locked down for a very long time and
  730. might fragment the heap - should create the RESOURCE_STR,
  731. then cons up a new ALLOC_STR and copy this into that.
  732. That way the client doesn't have to fool with
  733. MAX_RES_STR_LEN.
  734. HISTORY:
  735. beng 22-Jul-1991 Created
  736. beng 07-Oct-1991 Uses MSGID
  737. beng 13-Nov-1991 Added op=
  738. **************************************************************************/
  739. DLL_CLASS RESOURCE_STR: public NLS_STR
  740. {
  741. public:
  742. RESOURCE_STR( MSGID idResource );
  743. RESOURCE_STR( MSGID idResource, HMODULE hmod );
  744. RESOURCE_STR & operator=( const TCHAR * pszSource )
  745. { return (RESOURCE_STR&) NLS_STR::operator=( pszSource ); }
  746. };
  747. /*************************************************************************
  748. NAME: ALLOC_STR
  749. SYNOPSIS: String w/ storage allocated by client.
  750. Such a string has fixed maximum length, of course.
  751. INTERFACE: ALLOC_STR() - ctor
  752. PARENT: NLS_STR
  753. NOTES:
  754. This class replaces the public STR_OWNERALLOC constructors
  755. of NLS_STR.
  756. CAVEATS:
  757. The forms which take a byte-count always clear their
  758. string to empty.
  759. HISTORY:
  760. beng 22-Jul-1991 Separated from NLS_STR
  761. beng 13-Nov-1991 Added op=
  762. beng 21-Nov-1991 Removed STR_OWNERALLOC
  763. **************************************************************************/
  764. DLL_CLASS ALLOC_STR: public NLS_STR
  765. {
  766. public:
  767. ALLOC_STR( TCHAR * pszBuffer )
  768. : NLS_STR( pszBuffer, 0, FALSE ) { }
  769. ALLOC_STR( TCHAR * pchBuffer, UINT cbBuffer )
  770. : NLS_STR(pchBuffer, cbBuffer, TRUE) { }
  771. ALLOC_STR( TCHAR * pchBuffer, UINT cbBuffer, const TCHAR * pchInit );
  772. // (implementation moved outline)
  773. ALLOC_STR & operator=( const TCHAR * pszSource )
  774. { return (ALLOC_STR&) NLS_STR::operator=( pszSource ); }
  775. };
  776. /*************************************************************************
  777. NAME: ALIAS_STR
  778. SYNOPSIS: A NLS_STR alias to a static, readonly string.
  779. INTERFACE: ALIAS_STR() - constructor, taking the string to
  780. alias as its sole parameter
  781. PARENT: NLS_STR
  782. CAVEATS:
  783. All instances of this class should be created "const."
  784. NOTES:
  785. This class replaces STR_OWNERALLOC et al.
  786. HISTORY:
  787. beng 23-Jul-1991 Created
  788. beng 13-Nov-1991 Added op=
  789. beng 21-Nov-1991 Removed STR_OWNERALLOC
  790. **************************************************************************/
  791. DLL_CLASS ALIAS_STR: public NLS_STR
  792. {
  793. friend class NLS_STR ; // BUGBUG: Why does STRCAT.CXX require this?
  794. public:
  795. ALIAS_STR( const TCHAR * pszSource )
  796. : NLS_STR( (TCHAR*)pszSource, 0, FALSE ) { }
  797. // Assignment to an alias string sets it to alias the new argument.
  798. //
  799. const ALIAS_STR & operator=( const TCHAR * pszSource );
  800. // If you assign a nlsstr to an aliasstr, that nlsstr must have been
  801. // owner-alloc (i.e. an allocstr or another aliasstr), in which case
  802. // it will alias that string's data.
  803. //
  804. const ALIAS_STR & operator=( const NLS_STR & nlsSource );
  805. };
  806. /********************************************************************
  807. Macros with which to define owner-alloc strings on the stack.
  808. STACK_NLS_STR(name, cchLen): define a string on the stack with
  809. the given name and available length in characters. It will
  810. be initialized to empty.
  811. E.g.: STACK_NLS_STR(nlsUnc, MAX_PATH)
  812. ISTACK_NLS_STR(name, cchLen, pszInit): same as STACK_NLS_STR,
  813. except it takes an initializer.
  814. *********************************************************************/
  815. #define STACK_NLS_STR( name, len ) \
  816. TCHAR _tmp##name[ len+1 ] ; \
  817. ALLOC_STR name( _tmp##name, sizeof(_tmp##name) );
  818. #define ISTACK_NLS_STR( name, len, pszInit ) \
  819. TCHAR _tmp##name[ len+1 ] ; \
  820. ALLOC_STR name( _tmp##name, sizeof(_tmp##name), pszInit ); \
  821. /********************************************************************
  822. Macros with which to define owner-alloc strings within a class
  823. definition.
  824. DECL_CLASS_NLS_STR( name, cchLen ): creates a string as part of
  825. the declaration's class. Creates a suitable character buffer
  826. as well.
  827. CT_NLS_STR( name ): member constructor for a string declared
  828. with DECL_CLASS_NLS_STR.
  829. CT_INIT_NLS_STR( name, pszInit ): same as CT_NLS_STR, except it
  830. takes an initializer.
  831. E.g.:
  832. class FOO
  833. {
  834. public:
  835. FOO();
  836. private:
  837. DECL_CLASS_NLS_STR( nlsComment, MAX_COMMENT_SIZE );
  838. ...
  839. };
  840. FOO::FOO() : CT_NLS_STR( nlsComment )
  841. {
  842. ....
  843. }
  844. *********************************************************************/
  845. #define DECL_CLASS_NLS_STR( name, len ) \
  846. TCHAR __sz_##name[len+1] ; \
  847. ALLOC_STR name
  848. #define CT_NLS_STR( name ) \
  849. name( __sz_##name, sizeof( __sz_##name ) )
  850. #define CT_INIT_NLS_STR( name, pszInit ) \
  851. name( __sz_##name, sizeof( __sz_##name ), pszInit )
  852. #endif // _STRING_HXX_