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.

354 lines
6.6 KiB

  1. /*****************************************************************/
  2. /** Microsoft Windows for Workgroups **/
  3. /** Copyright (C) Microsoft Corp., 1991-1992 **/
  4. /*****************************************************************/
  5. /*
  6. string.cxx
  7. NLS/DBCS-aware string class: essential core methods
  8. This file contains those routines which every client of
  9. the string classes will always need.
  10. Most of the implementation has been exploded into other files,
  11. so that an app linking to string doesn't end up dragging the
  12. entire string runtime library along with it.
  13. FILE HISTORY:
  14. beng 10/23/90 Created
  15. johnl 12/11/90 Remodeled beyond all recognizable form
  16. beng 01/18/91 Most methods relocated into other files
  17. beng 02/07/91 Uses lmui.hxx
  18. beng 07/26/91 Replaced min with local inline
  19. gregj 03/30/93 Removed ISTR to separate module
  20. */
  21. #include "npcommon.h"
  22. extern "C"
  23. {
  24. #include <netlib.h>
  25. }
  26. #if defined(DEBUG)
  27. static const CHAR szFileName[] = __FILE__;
  28. #define _FILENAME_DEFINED_ONCE szFileName
  29. #endif
  30. #include <npassert.h>
  31. #include <npstring.h>
  32. /*******************************************************************
  33. NAME: NLS_STR::NLS_STR
  34. SYNOPSIS: Constructor for NLS_STR
  35. ENTRY: NLS_STR takes many (too many) ctor forms.
  36. EXIT: String constructed
  37. NOTES:
  38. The default constructor creates an empty string.
  39. HISTORY:
  40. beng 10/23/90 Created
  41. beng 04/26/91 Replaced 'CB' and USHORT with INT
  42. beng 07/22/91 Uses member-init ctor forms
  43. ********************************************************************/
  44. NLS_STR::NLS_STR()
  45. : _pchData(0),
  46. _cbData(0),
  47. _cchLen(0),
  48. _fsFlags(0)
  49. {
  50. if ( !Alloc(1) )
  51. return;
  52. *_pchData = '\0';
  53. InitializeVers();
  54. }
  55. NLS_STR::NLS_STR( INT cchInitLen )
  56. : _pchData(0),
  57. _cbData(0),
  58. _cchLen(0),
  59. _fsFlags(0)
  60. {
  61. if (!Alloc(cchInitLen+1))
  62. return;
  63. ::memsetf( _pchData, '\0', cchInitLen );
  64. _cchLen = 0;
  65. InitializeVers();
  66. }
  67. NLS_STR::NLS_STR( const CHAR * pchInit )
  68. : _pchData(0),
  69. _cbData(0),
  70. _cchLen(0),
  71. _fsFlags(0)
  72. {
  73. if (pchInit == NULL)
  74. {
  75. if (!Alloc(1))
  76. ReportError( WN_OUT_OF_MEMORY );
  77. else
  78. {
  79. *_pchData = '\0';
  80. }
  81. return;
  82. }
  83. INT iSourceLen = ::strlenf( pchInit );
  84. if ( !Alloc( iSourceLen + 1 ) )
  85. return;
  86. ::strcpyf( _pchData, pchInit );
  87. _cchLen = iSourceLen;
  88. InitializeVers();
  89. }
  90. NLS_STR::NLS_STR( const NLS_STR & nlsInit )
  91. : _pchData(0),
  92. _cbData(0),
  93. _cchLen(0),
  94. _fsFlags(0)
  95. {
  96. UIASSERT( !nlsInit.QueryError() );
  97. if (!Alloc( nlsInit.strlen()+1 ) )
  98. return;
  99. ::memcpyf( _pchData, nlsInit.QueryPch(), nlsInit.strlen()+1 );
  100. _cchLen = nlsInit.strlen();
  101. InitializeVers();
  102. }
  103. #ifdef EXTENDED_STRINGS
  104. NLS_STR::NLS_STR( const CHAR * pchInit, INT iTotalLen )
  105. : _pchData(0),
  106. _cbData(0),
  107. _cchLen(0),
  108. _fsFlags(0)
  109. {
  110. if (pchInit == NULL)
  111. {
  112. if (!Alloc( 1 + iTotalLen ))
  113. return;
  114. *_pchData = '\0';
  115. }
  116. else
  117. {
  118. _cchLen = ::strlenf( pchInit );
  119. if ( _cchLen > iTotalLen )
  120. {
  121. _cchLen = 0;
  122. ReportError( WN_OUT_OF_MEMORY );
  123. return;
  124. }
  125. if ( !Alloc( iTotalLen ) )
  126. {
  127. _cchLen = 0;
  128. return;
  129. }
  130. ::memcpyf( _pchData, pchInit, _cchLen+1 );
  131. }
  132. InitializeVers();
  133. }
  134. #endif // EXTENDED_STRINGS
  135. NLS_STR::NLS_STR( unsigned stralloc, CHAR *pchInit, INT cbSize )
  136. : _pchData(0),
  137. _cbData(0),
  138. _cchLen(0),
  139. _fsFlags(SF_OWNERALLOC)
  140. {
  141. UIASSERT( stralloc == STR_OWNERALLOC || stralloc == STR_OWNERALLOC_CLEAR);
  142. UIASSERT( pchInit != NULL );
  143. if ( stralloc == STR_OWNERALLOC_CLEAR )
  144. {
  145. UIASSERT( cbSize > 0 );
  146. *(_pchData = pchInit ) = '\0';
  147. _cchLen = 0;
  148. }
  149. else
  150. {
  151. _pchData = pchInit;
  152. _cchLen = ::strlenf( pchInit );
  153. }
  154. if ( cbSize == -1 )
  155. _cbData = _cchLen + 1;
  156. else
  157. _cbData = cbSize;
  158. InitializeVers();
  159. }
  160. #ifdef EXTENDED_STRINGS
  161. NLS_STR::NLS_STR( unsigned stralloc, CHAR *pchBuff, INT cbSize,
  162. const CHAR *pchInit )
  163. : _pchData(0),
  164. _cbData(0),
  165. _cchLen(0),
  166. _fsFlags(SF_OWNERALLOC)
  167. {
  168. UIASSERT( stralloc == STR_OWNERALLOC );
  169. UIASSERT( stralloc != STR_OWNERALLOC_CLEAR );
  170. UIASSERT( pchBuff != NULL || pchInit != NULL );
  171. UIASSERT( cbSize > 0 && ::strlenf( pchInit ) <= cbSize );
  172. UNREFERENCED( stralloc );
  173. _pchData = pchBuff;
  174. INT cbToCopy = min( ::strlenf( pchInit ), cbSize - 1 );
  175. ::memcpyf( _pchData, pchInit, cbToCopy );
  176. *(_pchData + cbToCopy) = '\0';
  177. _cchLen = cbToCopy;
  178. _cbData = cbSize;
  179. InitializeVers();
  180. }
  181. #endif
  182. /*******************************************************************
  183. NAME: NLS_STR::~NLS_STR
  184. SYNOPSIS: Destructor for NLS_STR
  185. ENTRY:
  186. EXIT: Storage deallocated, if not owner-alloc
  187. HISTORY:
  188. beng 10/23/90 Created
  189. beng 07/22/91 Zeroes only in debug version
  190. ********************************************************************/
  191. NLS_STR::~NLS_STR()
  192. {
  193. if ( !IsOwnerAlloc() )
  194. delete _pchData;
  195. #if defined(DEBUG)
  196. _pchData = NULL;
  197. _cchLen = 0;
  198. _cbData = 0;
  199. #endif
  200. }
  201. /*******************************************************************
  202. NAME: NLS_STR::Alloc
  203. SYNOPSIS: Common code for constructors.
  204. ENTRY:
  205. cb - number of bytes desired in string storage
  206. EXIT:
  207. Returns TRUE if successful:
  208. _pchData points to allocated storage of "cb" bytes.
  209. _cbData set to cb.
  210. Allocated storage set to 0xF2 in debug version
  211. Returns FALSE upon allocation failure.
  212. NOTES:
  213. HISTORY:
  214. beng 10/23/90 Created
  215. johnl 12/11/90 Updated as per code review
  216. beng 04/26/91 Changed USHORT parm to INT
  217. ********************************************************************/
  218. BOOL NLS_STR::Alloc( INT cb )
  219. {
  220. UIASSERT( cb != 0 );
  221. _pchData = new CHAR[cb];
  222. if (_pchData == NULL)
  223. {
  224. // For now, assume not enough memory.
  225. //
  226. ReportError(WN_OUT_OF_MEMORY);
  227. return FALSE;
  228. }
  229. #ifdef DEBUG
  230. ::memsetf(_pchData, 0xf2, cb);
  231. #endif
  232. _cbData = cb;
  233. return TRUE;
  234. }
  235. /*******************************************************************
  236. NAME: NLS_STR::Reset
  237. SYNOPSIS: Attempts to clear the error state of the string
  238. ENTRY: String is in error state
  239. EXIT: If recoverable, string is correct again
  240. RETURNS: TRUE if successful; FALSE otherwise
  241. NOTES:
  242. An operation on a string may fail, if this occurs, the error
  243. flag is set and you can't use the string until the flag
  244. is cleared. By calling Reset, you can clear the flag,
  245. thus allowing you to get access to the string again. The
  246. string will be in a consistent state. Reset will return
  247. FALSE if the string couldn't be restored (for example, after
  248. construction failure).
  249. HISTORY:
  250. Johnl 12/12/90 Created
  251. ********************************************************************/
  252. BOOL NLS_STR::Reset()
  253. {
  254. UIASSERT( QueryError() ) ; // Make sure an error exists
  255. if ( QueryError() == WN_OUT_OF_MEMORY && _pchData != NULL )
  256. {
  257. ReportError( WN_SUCCESS );
  258. return TRUE;
  259. }
  260. return FALSE;
  261. }