Source code of Windows XP (NT5)
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.

815 lines
31 KiB

  1. /*****************************************************************/
  2. /** Microsoft Windows for Workgroups **/
  3. /** Copyright (C) Microsoft Corp., 1991-1992 **/
  4. /*****************************************************************/
  5. /*
  6. npstring.h
  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. RESOURCE_STR
  25. ISTR
  26. This file also contains the STACK_NLS_STR macro and the
  27. strcpy( CHAR *, const NLS_STR& ) prototype.
  28. FILE HISTORY:
  29. beng 10/21/90 Created from email memo of last week
  30. johnl 11/13/90 Removed references to EB_STRING
  31. johnl 11/28/90 Release fully functional version
  32. johnl 12/07/90 Numerous revisions after code review
  33. (Removed SZ_STR, ISTR must associate
  34. w/a string upon decl etc.)
  35. beng 02/05/91 Replaced PCH with CHAR * for
  36. const-placement
  37. beng 04/26/91 Expunged of CB, IB types; relocated
  38. inline functions to string/strmisc.cxx
  39. beng 07/23/91 Added more *_STR types
  40. gregj 03/22/93 Ported to Chicago environment.
  41. gregj 03/25/93 Added Party(), DonePartying()
  42. gregj 03/30/93 Allow assigning NLS_STR to ISTR
  43. gregj 04/02/93 Added NLS_STR::IsDBCSLeadByte()
  44. gregj 04/02/93 Added ISTR::operator int
  45. gregj 04/08/93 Added NLS_STR::strncpy()
  46. gregj 04/08/93 Added NLS_STR::GetPrivateProfileString()
  47. */
  48. #define WIN31 /* for certain string and NETLIB stuff */
  49. #ifndef _BASE_HXX_
  50. #include "base.h"
  51. #endif
  52. #ifndef _STRING_HXX_
  53. #define _STRING_HXX_
  54. extern HINSTANCE hInstance; // for NLS_STR::LoadString
  55. // String class doesn't allocate or deallocate memory
  56. // for STR_OWNERALLOC strings
  57. //
  58. #define STR_OWNERALLOC 0x8000
  59. // Same as owner alloc only the string is initialized with the null string.
  60. //
  61. #define STR_OWNERALLOC_CLEAR 0x8001
  62. // Maximum resource string size, owner alloced strings must be at least
  63. // MAX_RES_STR_LEN, otherwise an error will occur.
  64. //
  65. #define MAX_RES_STR_LEN 255
  66. // The maximum number of insert parameters the InsertParams method can
  67. // handle
  68. //
  69. #define MAX_INSERT_PARAMS 9
  70. /*************************************************************************
  71. NAME: ISTR
  72. SYNOPSIS: String index object, used in conjunction with NLS_STR
  73. INTERFACE:
  74. ISTR() - this ISTR gets associated with
  75. the passed string and can only be used
  76. on this string (NOTE: on non-debug
  77. versions this turns into a nop, can still
  78. be useful for decl. clarity however).
  79. ISTR() - Initialize to passed ISTR;
  80. this ISTR will be associated with
  81. the same string that the passed ISTR
  82. is associated with.
  83. operator=() - Copy passed ISTR (see prev.)
  84. operator=() - Associate ISTR with a new NLS_STR.
  85. operator-() - Returns CB diff. between *this & Param.
  86. (must both belong to the same string)
  87. operator++() - Advance the ISTR to the next logical
  88. character (use only where absolutely
  89. necessary). Stops at end of string
  90. operator+=() - Advance the ISTR to the ith logical
  91. character (call operator++ i times)
  92. Stops at end of string.
  93. operator==() - Returns TRUE if the two ISTRs point to
  94. the same position in the string (causes
  95. an assertion failure if the two ISTRs
  96. don't point to the same string).
  97. operator>() - Returns true of *this is greater then
  98. the passed ISTR (i.e., further along
  99. in the string).
  100. operator<() - Same as operator>, only less then.
  101. Reset() - Resets ISTR to beginning of string and
  102. updates the ISTR version number with the
  103. string's current version number
  104. private:
  105. QueryIB() - Returns the index in bytes
  106. QueryPNLS() - Returns the pointer to the NLS_STR this ISTR
  107. references
  108. SetPNLS() - Sets the pointer to point to the NLS_STR
  109. this ISTR references
  110. DEBUG ONLY:
  111. QueryVersion() - Gets the version number of
  112. the string this ISTR is associated with
  113. SetVersion() - Sets the version number of this ISTR.
  114. USES:
  115. CAVEATS: Each NLS_STR has a version number associated with it. When
  116. an operation is performed that modifies the string, the
  117. version number is updated. It is invalid to use an ISTR
  118. after its associated NLS_STR has been modified (can use
  119. Reset to resync it with the NLS_STR, the index gets reset
  120. to zero).
  121. You must associate an NLS_STR with an ISTR at the
  122. declaration of the ISTR.
  123. NOTES: The version checking and string association checking goes
  124. away in the non-debug version.
  125. HISTORY:
  126. johnl 11/16/90 Created
  127. johnl 12/07/90 Modified after code review
  128. gregj 03/30/93 Allow assigning NLS_STR to ISTR
  129. **************************************************************************/
  130. class ISTR
  131. {
  132. friend class NLS_STR;
  133. public:
  134. ISTR( const ISTR& istr );
  135. ISTR( const NLS_STR& nls );
  136. ISTR& operator=( const ISTR& istr );
  137. ISTR& operator=( const NLS_STR& nls );
  138. INT operator-( const ISTR& istr ) const;
  139. ISTR& operator++();
  140. VOID operator+=( INT iChars );
  141. BOOL operator==( const ISTR& istr ) const;
  142. BOOL operator>( const ISTR& istr ) const;
  143. BOOL operator<( const ISTR& istr ) const;
  144. operator INT() const { return QueryIB(); }
  145. VOID Reset();
  146. private:
  147. INT _ibString; // Index (in bytes) into an NLS_STR
  148. NLS_STR *_pnls; // Pointer to "owner" NLS
  149. INT QueryIB() const
  150. { return _ibString; }
  151. VOID SetIB( INT ib )
  152. { _ibString = ib; }
  153. const NLS_STR* QueryPNLS() const
  154. { return _pnls; }
  155. VOID SetPNLS( const NLS_STR * pnls )
  156. { _pnls = (NLS_STR*)pnls; }
  157. #ifdef DEBUG
  158. // Version number of NLS_STR this ISTR is associated with
  159. //
  160. USHORT _usVersion;
  161. USHORT QueryVersion() const { return _usVersion; }
  162. VOID SetVersion( USHORT usVers ) { _usVersion = usVers; }
  163. #endif
  164. };
  165. /*************************************************************************
  166. NAME: NLS_STR (nls)
  167. SYNOPSIS: Provide a better string abstraction than the standard ASCIIZ
  168. representation offered by C (and C++). The abstraction is
  169. better mainly because it handles double-byte characters
  170. (DBCS) in the string and makes intelligent use of operator
  171. overloading.
  172. INTERFACE: NLS_STR() Construct a NLS_STR (initialized to a CHAR *,
  173. NLS_STR or NULL). Reports errors via BASE.
  174. ~NLS_STR() Destructor
  175. operator=() Assign one NLS_STR (or CHAR *) value
  176. to another (old string is deleted, new
  177. string is allocated and copies source)
  178. operator+=() Concatenate with assignment (equivalent to
  179. strcat - see strcat).
  180. operator==() Compare two NLS_STRs for equality
  181. operator!=() Compare two NLS_STRs for inequality
  182. QueryPch() Access operator, returning a "char *"
  183. aliased to the string. DO NOT MODIFY
  184. THE STRING USING THIS METHOD (or pass
  185. it to procedures that might modify it).
  186. Synonym: operator const CHAR *().
  187. operator[]() Same as QueryPch, except the string
  188. is offset by ISTR characters
  189. IsDBCSLeadByte() Returns whether a byte is a lead byte,
  190. according to the ANSI- or OEM-ness of the
  191. string.
  192. C-runtime-style methods.
  193. strlen() Return the length of the string in bytes,
  194. less terminator. Provided only for crt
  195. compatibility; please use a Query method
  196. if possible.
  197. strcat() Append an NLS_STR. Will cause *this to be
  198. reallocated if the appended string is larger
  199. then this->QueryCb() and this is not an
  200. STR_OWNERALLOC string
  201. strncpy() Copy a non-null-terminated string into an
  202. NLS_STR. DBCS-safe. For similar functionality
  203. with an NLS_STR as the source, use the sub-
  204. string members.
  205. strcmp() Compare two NLS_STRs
  206. stricmp() "
  207. strncmp() Compare a portion of two NLS_STRs
  208. strnicmp() "
  209. strcspn() Find first char in *this that is
  210. a char in arg
  211. strspn() Find first char in *this that is
  212. not a char in arg
  213. strtok() Returns a token from the string
  214. strstr() Search for a NLS_STR.
  215. strchr() Search for a CHAR from beginning.
  216. Returns offset.
  217. strrchr() Search for a CHAR from end.
  218. strupr() Convert NLS_STR to upper case.
  219. atoi() Returns integer numeric value
  220. atol() Returns long value
  221. realloc() Resize string preserving its contents
  222. Other methods.
  223. QueryAllocSize() Returns total # of bytes allocated (i.e.,
  224. number new was called with, or size of
  225. memory block if STR_OWNERALLOC
  226. IsOwnerAlloc() Returns TRUE if this string is an owner
  227. allocated string
  228. QuerySubStr() Return a substring
  229. InsertStr() Insert a NLS_STR at given index.
  230. DelSubStr() Delete a substring
  231. ReplSubStr() Replace a substring (given start and
  232. NLS_STR)
  233. InsertParams() Replace %1-%9 params in *this with the
  234. corresponding NLS_STRs contained in the
  235. array of pointers
  236. LoadString() Load the string associated with the passed
  237. resource into *this (OWNER_ALLOC strings must
  238. be at least MAX_RES_STR_LEN). Optionally
  239. calls InsertParams with a passed array of
  240. nls pointers.
  241. GetPrivateProfileString() Loads a string from an INI file.
  242. Reset() After an operation fails (due to memory
  243. failure), it is invalid to use the string
  244. until Reset has been called. If the object
  245. wasn't successfully constructed, Reset will
  246. fail.
  247. QueryTextLength() Returns the number of CHARS, less
  248. terminator.
  249. QueryTextSize() Returns the number of bytes, including
  250. terminator. Denotes amount of storage
  251. needed to dup string into a bytevector.
  252. QueryNumChar() Returns total number of logical characters
  253. within the string. Rarely needed.
  254. Append() Appends a string to the current string,
  255. like strcat.
  256. AppendChar() Appends a single character.
  257. Compare() As strcmp().
  258. CopyFrom() As operator=(), but returns an APIERR.
  259. ToOEM() Convert string to OEM character set.
  260. ToAnsi() Convert string to ANSI character set.
  261. Party() Obtain read-write access to the buffer.
  262. DonePartying() Release read-write access.
  263. PARENT: BASE
  264. USES: ISTR
  265. CAVEATS: A NLS_STR object can enter an error state for various
  266. reasons - typically a memory allocation failure. Using
  267. an object in such a state is theoretically an error.
  268. Since string operations frequently occur in groups,
  269. we define operations on an erroneous string as no-op,
  270. so that the check for an error may be postponed until
  271. the end of the complex operation. Most member functions
  272. which calculate a value will treat an erroneous string
  273. as having zero length; however, clients should not depend
  274. on this.
  275. Attempting to use an ISTR that is registered with another
  276. string will cause an assertion failure.
  277. Each NLS_STR has a version/modification flag that is also
  278. stored in the the ISTR. An attempt to use an ISTR on an
  279. NLS_STR that has been modified (by calling one of the methods
  280. listed below) will cause an assertion failure. To use the
  281. ISTR after a modifying method, you must first call ISTR::Reset
  282. which will update the version in the ISTR. See the
  283. method definition for more detail.
  284. List of modifying methods:
  285. All NLS::operator= methods
  286. NLS::DelSubStr
  287. NLS::ReplSubStr
  288. NLS::InsertSubStr
  289. NOTE: The ISTR used as a starting index on the
  290. Substring methods remains valid after the call.
  291. Party() and DonePartying() can be used when you need to
  292. do something that the standard NLS_STR methods don't
  293. cover. For example, you might want to tweak the first
  294. couple of characters in a pathname; if you know they're
  295. definitely not double-byte characters, this is safe to
  296. do with ordinary character assignments.
  297. Calling Party() returns a pointer to the string buffer,
  298. and places the NLS_STR in an error state to prevent the
  299. standard methods from operating on it (and thereby getting
  300. confused by the possibly incorrect cached length). You
  301. can still call QueryAllocSize() to find out the maximum
  302. size of the buffer. When you've finished, call DonePartying()
  303. to switch the NLS_STR back to "normal" mode. There are two
  304. overloaded forms of DonePartying(). If you know what the
  305. length of the string is, you can pass it in, and NLS_STR
  306. will just use that. Otherwise, it will use strlenf() to
  307. find out what the new length is. If you don't plan to
  308. change the length, call strlen() on the string before you
  309. Party(), save that length, and pass it to DonePartying().
  310. The initial strlen() is fast because it's cached.
  311. If you find yourself constantly Party()ing in order to
  312. accomplish a particular function, that function should
  313. be formally added to the NLS_STR definition.
  314. NOTES: The lack of a strlwr() method comes from a shortcoming
  315. in the casemap tables. Sorry.
  316. STR_OWNERALLOC strings are a special type of NLS_STR
  317. You mark a string as STR_OWNERALLOC on
  318. construction by passing the flag STR_OWNERALLOC and a pointer
  319. to your memory space where you want the string to reside
  320. plus the size of the memory block.
  321. THE POINTER MUST POINT TO A VALID NULL TERMINATED STRING.
  322. You are guaranteed this pointer will never be
  323. resized or deleted. Note that no checking is performed for
  324. writing beyond the end of the string. Valid uses include
  325. static strings, severe optimization, owner controlled
  326. memory allocation or stack controlled memory allocation.
  327. CODEWORK: Owner-alloc strings should be a distinct
  328. class from these normal strings.
  329. CODEWORK: Should add a fReadOnly flag.
  330. CODEWORK: Should clean up this mess, and make the
  331. owner-alloc constructor protected.
  332. I wish I could clean up this mess...
  333. HISTORY:
  334. johnl 11/28/90 First fully functioning version
  335. johnl 12/07/90 Incorporated code review changes
  336. terryk 04/05/91 add QueryNumChar method
  337. beng 07/22/91 Added more methods; separated fOwnerAlloc
  338. from cbData
  339. gregj 05/22/92 Added ToOEM, ToAnsi methods
  340. gregj 03/22/93 Ported to Chicago environment
  341. gregj 04/02/93 Added IsDBCSLeadByte()
  342. gregj 04/08/93 Added strncpy()
  343. **************************************************************************/
  344. class NLS_STR : public BASE
  345. {
  346. friend class ISTR; // Allow access to CheckIstr
  347. public:
  348. // Default constructor, creating an empty string.
  349. //
  350. NLS_STR();
  351. // Initialize to "cchInitLen" characters, each "chInit",
  352. // plus trailing NUL.
  353. //
  354. NLS_STR( INT cchInitLen );
  355. // Initialize from a NUL-terminated character vector.
  356. //
  357. NLS_STR( const CHAR *pchInit );
  358. // Initialize an NLS_STR to memory position passed in achInit
  359. // No memory allocation of any type will be performed on this string
  360. // cbSize should be the total memory size of the buffer, if cbSize == -1
  361. // then the size of the buffer will assumed to be strlen(achInit)+1
  362. //
  363. NLS_STR( unsigned stralloc, CHAR *pchInit, INT cbSize = -1 );
  364. // Initialize from an existing x_STRING.
  365. //
  366. NLS_STR( const NLS_STR& nlsInit );
  367. ~NLS_STR();
  368. // Number of bytes the string uses (not including terminator)
  369. // Cf. QueryTextLength and QueryTextSize.
  370. //
  371. inline INT strlen() const;
  372. // Return a read-only CHAR vector, for the APIs.
  373. //
  374. const CHAR *QueryPch() const
  375. #ifdef DEBUG
  376. ;
  377. #else
  378. { return _pchData; }
  379. #endif
  380. const CHAR *QueryPch( const ISTR& istr ) const
  381. #ifdef DEBUG
  382. ;
  383. #else
  384. { return _pchData + istr.QueryIB(); }
  385. #endif
  386. WCHAR QueryChar( const ISTR& istr ) const
  387. #ifdef DEBUG
  388. ;
  389. #else
  390. { return *(_pchData+istr.QueryIB()); }
  391. #endif
  392. operator const CHAR *() const
  393. { return QueryPch(); }
  394. const CHAR *operator[]( const ISTR& istr ) const
  395. { return QueryPch(istr); }
  396. BOOL IsDBCSLeadByte( CHAR ch ) const;
  397. // Total allocated storage
  398. //
  399. inline INT QueryAllocSize() const;
  400. inline BOOL IsOwnerAlloc() const;
  401. // Increase the size of a string preserving its contents.
  402. // Returns TRUE if successful, false otherwise (illegal to
  403. // call for an owner alloced string). If you ask for a string smaller
  404. // then the currently allocated one, the request will be ignored and TRUE
  405. // will be returned.
  406. //
  407. BOOL realloc( INT cbNew );
  408. // Returns TRUE if error was successfully cleared (string is now in valid
  409. // state), FALSE otherwise.
  410. //
  411. BOOL Reset();
  412. NLS_STR& operator=( const NLS_STR& nlsSource );
  413. NLS_STR& operator=( const CHAR *achSource );
  414. NLS_STR& operator+=( WCHAR wch ); // NEW, replaces AppendChar
  415. NLS_STR& operator+=( const NLS_STR& nls ) { return strcat(nls); }
  416. NLS_STR& operator+=( LPCSTR psz ) { return strcat(psz); }
  417. NLS_STR& strncpy( const CHAR *pchSource, UINT cbSource );
  418. NLS_STR& strcat( const NLS_STR& nls );
  419. NLS_STR& strcat( LPCSTR psz );
  420. BOOL operator== ( const NLS_STR& nls ) const;
  421. BOOL operator!= ( const NLS_STR& nls ) const;
  422. INT strcmp( const NLS_STR& nls ) const;
  423. INT strcmp( const NLS_STR& nls, const ISTR& istrThis ) const;
  424. INT strcmp( const NLS_STR& nls, const ISTR& istrThis,
  425. const ISTR& istrStart2 ) const;
  426. INT stricmp( const NLS_STR& nls ) const;
  427. INT stricmp( const NLS_STR& nls, const ISTR& istrThis ) const;
  428. INT stricmp( const NLS_STR& nls, const ISTR& istrThis,
  429. const ISTR& istrStart2 ) const;
  430. INT strncmp( const NLS_STR& nls, const ISTR& istrLen ) const;
  431. INT strncmp( const NLS_STR& nls, const ISTR& istrLen,
  432. const ISTR& istrThis ) const;
  433. INT strncmp( const NLS_STR& nls, const ISTR& istrLen,
  434. const ISTR& istrThis, const ISTR& istrStart2 ) const;
  435. INT strnicmp( const NLS_STR& nls, const ISTR& istrLen ) const;
  436. INT strnicmp( const NLS_STR& nls, const ISTR& istrLen,
  437. const ISTR& istrThis ) const;
  438. INT strnicmp( const NLS_STR& nls, const ISTR& istrLen,
  439. const ISTR& istrThis, const ISTR& istrStart2 ) const;
  440. // The following str* functions return TRUE if successful (istrPos has
  441. // meaningful data), false otherwise.
  442. //
  443. BOOL strcspn( ISTR *istrPos, const NLS_STR& nls ) const;
  444. BOOL strcspn( ISTR *istrPos, const NLS_STR& nls, const ISTR& istrStart ) const;
  445. BOOL strspn( ISTR *istrPos, const NLS_STR& nls ) const;
  446. BOOL strspn( ISTR *istrPos, const NLS_STR& nls, const ISTR& istrStart ) const;
  447. BOOL strstr( ISTR *istrPos, const NLS_STR& nls ) const;
  448. BOOL strstr( ISTR *istrPos, const NLS_STR& nls, const ISTR& istrStart ) const;
  449. BOOL stristr( ISTR *istrPos, const NLS_STR& nls ) const;
  450. BOOL stristr( ISTR *istrPos, const NLS_STR& nls, const ISTR& istrStart ) const;
  451. BOOL strchr( ISTR *istrPos, const CHAR ch ) const;
  452. BOOL strchr( ISTR *istrPos, const CHAR ch, const ISTR& istrStart ) const;
  453. BOOL strrchr( ISTR *istrPos, const CHAR ch ) const;
  454. BOOL strrchr( ISTR *istrPos, const CHAR ch, const ISTR& istrStart ) const;
  455. BOOL strtok( ISTR *istrPos, const NLS_STR& nlsBreak, BOOL fFirst = FALSE );
  456. LONG atol() const;
  457. LONG atol( const ISTR& istrStart ) const;
  458. INT atoi() const;
  459. INT atoi( const ISTR& istrStart ) const;
  460. NLS_STR& strupr();
  461. // Return a pointer to a new NLS_STR that contains the contents
  462. // of *this from istrStart to:
  463. // End of string if no istrEnd is passed
  464. // istrStart + istrEnd
  465. //
  466. NLS_STR *QuerySubStr( const ISTR& istrStart ) const;
  467. NLS_STR *QuerySubStr( const ISTR& istrStart, const ISTR& istrEnd ) const;
  468. // Collapse the string by removing the characters from istrStart to:
  469. // End of string
  470. // istrStart + istrEnd
  471. // The string is not reallocated
  472. //
  473. VOID DelSubStr( ISTR& istrStart );
  474. VOID DelSubStr( ISTR& istrStart, const ISTR& istrEnd );
  475. BOOL InsertStr( const NLS_STR& nlsIns, ISTR& istrStart );
  476. // Replace till End of string of either *this or replacement string
  477. // (or istrEnd in the 2nd form) starting at istrStart
  478. //
  479. VOID ReplSubStr( const NLS_STR& nlsRepl, ISTR& istrStart );
  480. VOID ReplSubStr( const NLS_STR& nlsRepl, ISTR& istrStart,
  481. const ISTR& istrEnd );
  482. // Replace %1-%9 in *this with corresponding index from apnlsParamStrings
  483. // Ex. if *this="Error %1" and apnlsParamStrings[0]="Foo" the resultant
  484. // string would be "Error Foo"
  485. //
  486. USHORT InsertParams( const NLS_STR *apnlsParamStrings[] );
  487. // Load a message from a resource file into *this (if string is an
  488. // OWNER_ALLOC string, then must be at least MAX_RES_STR_LEN. Heap
  489. // NLS_STRs will be reallocated if necessary
  490. //
  491. USHORT LoadString( USHORT usMsgID );
  492. // Combines functionality of InsertParams & LoadString. *this gets loaded
  493. // with the string from the resource file corresponding to usMsgID.
  494. //
  495. USHORT LoadString( USHORT usMsgID, const NLS_STR *apnlsParamStrings[] );
  496. VOID GetPrivateProfileString( const CHAR *pszFile, const CHAR *pszSection,
  497. const CHAR *pszKey, const CHAR *pszDefault = NULL );
  498. VOID ToOEM(); // convert ANSI to OEM
  499. VOID ToAnsi(); // convert OEM to ANSI
  500. VOID SetOEM(); // declare that string was constructed as OEM
  501. VOID SetAnsi(); // declare that string was constructed as ANSI
  502. inline BOOL IsOEM() const;
  503. CHAR *Party(); // get read-write access
  504. VOID DonePartying( VOID ); // if you don't have the length handy
  505. VOID DonePartying( INT cchNew ); // if you do
  506. #ifdef EXTENDED_STRINGS
  507. // Initialize from a NUL-terminated character vector
  508. // and allocate a minimum of: cbTotalLen+1 bytes or strlen(achInit)+1
  509. //
  510. NLS_STR( const CHAR *pchInit, INT iTotalLen );
  511. // Similar to prev. except the string pointed at by pchInit is copied
  512. // to pchBuff. The address of pchBuff is used as the string storage.
  513. // cbSize is required. stralloc can only be STR_OWNERALLOC (it makes
  514. // no sense to use STR_OWNERALLOC_CLEAR).
  515. //
  516. NLS_STR( unsigned stralloc, CHAR *pchBuff, INT cbSize,
  517. const CHAR *pchInit );
  518. // return the number of logical characters within the string
  519. //
  520. INT QueryNumChar() const;
  521. // Return the number of printing CHARs in the string.
  522. // This number does not include the termination character.
  523. //
  524. // Cf. QueryNumChar, which returns a count of glyphs.
  525. //
  526. INT QueryTextLength() const;
  527. // Return the number of BYTES occupied by the string's representation.
  528. // Cf. QueryAllocSize, which returns the total amount alloc'd.
  529. //
  530. INT QueryTextSize() const;
  531. APIERR Append( const NLS_STR& nls );
  532. APIERR AppendChar( WCHAR wch );
  533. APIERR CopyFrom( const NLS_STR& nlsSource );
  534. APIERR CopyFrom( const CHAR *achSource );
  535. INT Compare( const NLS_STR *nls ) const { return strcmp(*nls); }
  536. #endif
  537. private:
  538. UINT _fsFlags; // owner-alloc, character set flags
  539. #define SF_OWNERALLOC 0x1
  540. #define SF_OEM 0x2
  541. INT _cchLen; // Number of bytes string uses (strlen)
  542. INT _cbData; // Total storage allocated
  543. CHAR *_pchData; // Pointer to Storage
  544. #ifdef DEBUG
  545. USHORT _usVersion; // Version count (inc. after each change)
  546. #endif
  547. // The following substring functions are used internally (can't be
  548. // exposed since they take an INT cbLen parameter for an index).
  549. //
  550. VOID DelSubStr( ISTR&istrStart, INT cbLen );
  551. NLS_STR *QuerySubStr( const ISTR& istrStart, INT cbLen ) const;
  552. VOID ReplSubStr( const NLS_STR& nlsRepl, ISTR& istrStart, INT cbLen );
  553. BOOL Alloc( INT cchLen ); // Allocate memory for a string
  554. #ifdef DEBUG // DEBUG is new for these
  555. // CheckIstr checks whether istr is associated with this, asserts out
  556. // if it is not. Also checks version numbers in debug version.
  557. //
  558. VOID CheckIstr( const ISTR& istr ) const;
  559. // UpdateIstr syncs the version number between *this and the passed
  560. // ISTR. This is for operations that cause an update to the string
  561. // but the ISTR that was passed in is still valid (see InsertSubSt).
  562. //
  563. VOID UpdateIstr( ISTR *pistr ) const;
  564. // IncVers adds one to this strings version number because the previous
  565. // operation caused the contents to change thus possibly rendering
  566. // ISTRs on this string as invalid.
  567. //
  568. VOID IncVers();
  569. // InitializeVers sets the version number to 0
  570. //
  571. VOID InitializeVers();
  572. // QueryVersion returns the current version number of this string
  573. //
  574. USHORT QueryVersion() const;
  575. #else // DEBUG
  576. VOID CheckIstr( const ISTR& istr ) const { }
  577. VOID UpdateIstr( ISTR *pistr ) const { }
  578. VOID IncVers() { }
  579. VOID InitializeVers() { }
  580. USHORT QueryVersion() const { return 0; }
  581. #endif
  582. };
  583. /***********************************************************************/
  584. /***********************************************************************
  585. *
  586. * Macro STACK_NLS_STR(name, len )
  587. *
  588. * Define an NLS string on the stack with the name of "name" and the
  589. * length of "len". The strlen will be 0 and the first character will
  590. * be '\0'. One byte is added for the NULL terminator. Usage:
  591. * STACK_NLS_STR( UncPath, UNCLEN );
  592. *
  593. * Macro ISTACK_NLS_STR(name, len, pchInitString )
  594. *
  595. * Same as STACK_NLS_STR except ISTACK_NLS_STR takes an initializer.
  596. **********************************************************************/
  597. #define STACK_NLS_STR( name, len ) \
  598. CHAR _tmp##name[ len+1 ] ; \
  599. *_tmp##name = '\0' ; \
  600. NLS_STR name( STR_OWNERALLOC, _tmp##name, len+1 );
  601. #define ISTACK_NLS_STR( name, len, pchInitString ) \
  602. STACK_NLS_STR( name, len ) ; \
  603. name = pchInitString;
  604. /***********************************************************************/
  605. BOOL NLS_STR::IsOwnerAlloc() const
  606. {
  607. return _fsFlags & SF_OWNERALLOC;
  608. }
  609. BOOL NLS_STR::IsOEM() const
  610. {
  611. return _fsFlags & SF_OEM;
  612. }
  613. INT NLS_STR::strlen() const
  614. {
  615. return _cchLen;
  616. }
  617. INT NLS_STR::QueryAllocSize() const
  618. {
  619. return _cbData;
  620. }
  621. #endif // _STRING_HXX_