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.

478 lines
9.0 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (c) 1998-1999 Microsoft Corporation
  6. //
  7. // File: str.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. //
  11. // string.cpp
  12. #include "str.h"
  13. WORD String::sm_wBlockSize = 16;
  14. String::String()
  15. {
  16. m_wAllocated = 0;
  17. m_pBuf = NULL;
  18. m_wLength = 0;
  19. }
  20. String::String( const String& str )
  21. {
  22. m_wLength = str.m_wLength;
  23. if (m_wLength == 0)
  24. {
  25. m_wAllocated = 0;
  26. m_pBuf = NULL;
  27. }
  28. else
  29. {
  30. m_wAllocated = figureblocksize( m_wLength );
  31. m_pBuf = new WCHAR[m_wAllocated];
  32. if( m_pBuf != NULL )
  33. {
  34. wcscpy( m_pBuf, str.m_pBuf );
  35. }
  36. else
  37. {
  38. m_wLength = 0;
  39. m_wAllocated = 0;
  40. }
  41. }
  42. }
  43. String::String( LPCSTR pszStr )
  44. {
  45. if( pszStr != NULL && pszStr[0] != '\0' )
  46. {
  47. m_wLength = static_cast<WORD>( MultiByteToWideChar( CP_ACP, 0, pszStr, -1, NULL, 0 ) );
  48. m_wAllocated = figureblocksize( m_wLength );
  49. m_pBuf = new WCHAR[m_wAllocated];
  50. if( m_pBuf != NULL )
  51. {
  52. MultiByteToWideChar( CP_ACP, 0, pszStr, -1, m_pBuf, m_wAllocated );
  53. }
  54. else
  55. {
  56. m_wLength = 0;
  57. m_wAllocated = 0;
  58. }
  59. }
  60. else
  61. {
  62. m_wLength = 0;
  63. m_wAllocated = 0;
  64. m_pBuf = NULL;
  65. }
  66. }
  67. String::String( LPCWSTR pszWstr )
  68. {
  69. if( pszWstr != NULL && pszWstr[0] != L'\0')
  70. {
  71. m_wLength = static_cast<WORD>( wcslen(pszWstr) );
  72. m_wAllocated = figureblocksize( m_wLength );
  73. m_pBuf = new WCHAR[m_wAllocated];
  74. if( m_pBuf != NULL )
  75. {
  76. wcscpy(m_pBuf, pszWstr);
  77. }
  78. else
  79. {
  80. m_wLength = 0;
  81. m_wAllocated = 0;
  82. }
  83. }
  84. else
  85. {
  86. m_wLength = 0;
  87. m_wAllocated = 0;
  88. m_pBuf = NULL;
  89. }
  90. }
  91. String::~String()
  92. {
  93. if (m_pBuf) delete[] m_pBuf;
  94. }
  95. String& String::operator=( const String& str )
  96. {
  97. WORD wBlockSize;
  98. if( m_pBuf != str.m_pBuf )
  99. {
  100. if (!str.m_pBuf)
  101. {
  102. if (m_pBuf)
  103. {
  104. m_pBuf[0] = L'\0';
  105. }
  106. m_wLength = 0;
  107. }
  108. else
  109. {
  110. wBlockSize = figureblocksize( str.m_wLength );
  111. if( wBlockSize <= m_wAllocated )
  112. {
  113. m_wLength = str.m_wLength;
  114. wcscpy( m_pBuf, str.m_pBuf );
  115. }
  116. else
  117. {
  118. if (m_pBuf) delete [] m_pBuf;
  119. m_wLength = str.m_wLength;
  120. m_wAllocated = wBlockSize;
  121. m_pBuf = new WCHAR[m_wAllocated];
  122. if( m_pBuf != NULL )
  123. {
  124. wcscpy( m_pBuf, str.m_pBuf );
  125. }
  126. else
  127. {
  128. m_wLength = 0;
  129. m_wAllocated = 0;
  130. }
  131. }
  132. }
  133. }
  134. return *this;
  135. }
  136. String& String::operator=( LPCSTR pszStr )
  137. {
  138. WORD wLength;
  139. WORD wBlockSize;
  140. if( pszStr == NULL )
  141. {
  142. m_wLength = 0;
  143. return *this;
  144. }
  145. wLength = static_cast<WORD>( MultiByteToWideChar( CP_ACP, 0, pszStr, -1, NULL, 0 ) );
  146. wBlockSize = figureblocksize( wLength );
  147. if( wBlockSize <= m_wAllocated )
  148. {
  149. m_wLength = wLength;
  150. MultiByteToWideChar( CP_ACP, 0, pszStr, -1, m_pBuf, m_wAllocated );
  151. }
  152. else
  153. {
  154. if (m_pBuf) delete[] m_pBuf;
  155. m_wLength = wLength;
  156. m_wAllocated = wBlockSize;
  157. m_pBuf = new WCHAR[m_wAllocated];
  158. if( m_pBuf != NULL )
  159. {
  160. MultiByteToWideChar( CP_ACP, 0, pszStr, -1, m_pBuf, m_wAllocated );
  161. }
  162. else
  163. {
  164. m_wLength = 0;
  165. m_wAllocated = 0;
  166. }
  167. }
  168. return *this;
  169. }
  170. String& String::operator=( LPCWSTR pszWstr )
  171. {
  172. WORD wLength;
  173. WORD wBlockSize;
  174. if( pszWstr == NULL )
  175. {
  176. m_wLength = 0;
  177. return *this;
  178. }
  179. wLength = static_cast<WORD>( wcslen( pszWstr ) );
  180. wBlockSize = figureblocksize( wLength );
  181. if( wBlockSize <= m_wAllocated )
  182. {
  183. m_wLength = wLength;
  184. wcscpy(m_pBuf, pszWstr);
  185. }
  186. else
  187. {
  188. if (m_pBuf) delete[] m_pBuf;
  189. m_wLength = wLength;
  190. m_wAllocated = wBlockSize;
  191. m_pBuf = new WCHAR[m_wAllocated];
  192. if( m_pBuf != NULL )
  193. {
  194. wcscpy(m_pBuf, pszWstr);
  195. }
  196. else
  197. {
  198. m_wLength = 0;
  199. m_wAllocated = 0;
  200. }
  201. }
  202. return *this;
  203. }
  204. /*
  205. #ifndef _MAC
  206. BOOL String::LoadString( UINT nID, HINSTANCE hInstance )
  207. {
  208. char szBuf[256]; // this is safe since resource strings
  209. // are limited to 255 characters
  210. if( ::LoadString( hInstance, nID, szBuf, sizeof( szBuf ) ) == 0 )
  211. {
  212. return FALSE;
  213. }
  214. delete[] m_pBuf;
  215. m_wLength = static_cast<WORD>( ::lstrlen( szBuf ) );
  216. m_wAllocated = figureblocksize( m_wLength );
  217. m_pBuf = new WCHAR[m_wAllocated];
  218. if( m_pBuf == NULL )
  219. {
  220. m_wLength = 0;
  221. return FALSE;
  222. }
  223. ::lstrcpy( m_pBuf, szBuf );
  224. m_pBuf[m_wLength] = '\0';
  225. return TRUE;
  226. }
  227. #endif
  228. */
  229. void String::TrimTrailingSpaces()
  230. {
  231. while( m_wLength > 0 && m_pBuf[m_wLength - 1] == ' ' )
  232. {
  233. m_pBuf[m_wLength - 1] = '\0';
  234. --m_wLength;
  235. }
  236. }
  237. void String::Concat( const String& str )
  238. {
  239. if( ( str.m_wLength + m_wLength + 1 ) < m_wAllocated )
  240. {
  241. m_wLength = static_cast<WORD>( m_wLength + str.m_wLength );
  242. wcscat( m_pBuf, str.m_pBuf );
  243. }
  244. else
  245. {
  246. WCHAR* p;
  247. m_wLength = static_cast<WORD>( m_wLength + str.m_wLength );
  248. m_wAllocated = figureblocksize( m_wLength );
  249. p = new WCHAR[m_wAllocated];
  250. if( p != NULL )
  251. {
  252. wcscpy( p, m_pBuf );
  253. wcscat( p, str.m_pBuf );
  254. if (m_pBuf) delete[] m_pBuf;
  255. m_pBuf = p;
  256. }
  257. }
  258. }
  259. void String::Concat( LPCWSTR lpwzStr )
  260. {
  261. int len;
  262. len = wcslen( lpwzStr );
  263. if( ( len + m_wLength + 1 ) < m_wAllocated )
  264. {
  265. m_wLength = static_cast<WORD>( m_wLength + len );
  266. wcscat( m_pBuf, lpwzStr );
  267. }
  268. else
  269. {
  270. WCHAR* p;
  271. m_wLength = static_cast<WORD>( m_wLength + len );
  272. m_wAllocated = figureblocksize( m_wLength );
  273. p = new WCHAR[m_wAllocated];
  274. if( p != NULL )
  275. {
  276. wcscpy( p, m_pBuf );
  277. wcscat( p, lpwzStr );
  278. if (m_pBuf) delete[] m_pBuf;
  279. m_pBuf = p;
  280. }
  281. }
  282. }
  283. void String::Concat( WCHAR wch )
  284. {
  285. WCHAR buf[2];
  286. buf[0] = wch;
  287. buf[1] = '\0';
  288. if( ( 1 + m_wLength + 1 ) < m_wAllocated )
  289. {
  290. m_wLength += 1;
  291. wcscat( m_pBuf, buf );
  292. }
  293. else
  294. {
  295. WCHAR* p;
  296. m_wLength += 1;
  297. m_wAllocated = figureblocksize( m_wLength );
  298. p = new WCHAR[m_wAllocated];
  299. if( p != NULL )
  300. {
  301. wcscpy( p, m_pBuf );
  302. wcscat( p, buf );
  303. if (m_pBuf) delete[] m_pBuf;
  304. m_pBuf = p;
  305. }
  306. }
  307. }
  308. HRESULT String::ReadWCS( LPSTREAM pStream, DWORD cSize )
  309. {
  310. HRESULT hr = S_OK;
  311. WCHAR* wstrText = NULL;
  312. DWORD cb;
  313. WORD wBlockSize;
  314. wstrText = new WCHAR[cSize / sizeof( WCHAR )];
  315. if( NULL == wstrText )
  316. {
  317. hr = E_OUTOFMEMORY;
  318. goto ON_ERR;
  319. }
  320. hr = pStream->Read( reinterpret_cast<LPWSTR>( wstrText ), cSize, &cb );
  321. if( FAILED( hr ) || cb != cSize )
  322. {
  323. hr = E_FAIL;
  324. goto ON_ERR;
  325. }
  326. cSize = wcslen(wstrText);
  327. if (cSize == 0)
  328. {
  329. if (m_pBuf)
  330. {
  331. m_pBuf[0] = L'\0';
  332. }
  333. m_wLength = 0;
  334. goto ON_ERR;
  335. }
  336. wBlockSize = figureblocksize( static_cast<WORD>( cSize ) );
  337. m_wLength = static_cast<WORD>( cSize );
  338. if( wBlockSize <= m_wAllocated )
  339. {
  340. wcscpy( m_pBuf, wstrText );
  341. }
  342. else
  343. {
  344. if (m_pBuf) delete[] m_pBuf;
  345. m_wAllocated = wBlockSize;
  346. m_pBuf = new WCHAR[m_wAllocated];
  347. if( m_pBuf != NULL )
  348. {
  349. wcscpy( m_pBuf, wstrText );
  350. }
  351. else
  352. {
  353. hr = E_OUTOFMEMORY;
  354. m_wLength = 0;
  355. m_wAllocated = 0;
  356. }
  357. }
  358. ON_ERR:
  359. if( wstrText != NULL )
  360. {
  361. delete [] wstrText;
  362. }
  363. return hr;
  364. }
  365. /*
  366. HRESULT String::WriteWCS( LPSTREAM pStream )
  367. {
  368. HRESULT hr;
  369. wchar_t* wstrText;
  370. DWORD cb;
  371. DWORD cSize;
  372. cSize = MultiByteToWideChar( CP_ACP, 0, m_pBuf, -1, NULL, 0 ); // get number of wide characters required
  373. wstrText = new wchar_t[cSize];
  374. if( wstrText == NULL )
  375. {
  376. hr = E_OUTOFMEMORY;
  377. }
  378. else
  379. {
  380. MultiByteToWideChar( CP_ACP, 0, m_pBuf, -1, wstrText, cSize );
  381. hr = pStream->Write( reinterpret_cast<LPSTR>( wstrText ), cSize * sizeof( wchar_t ), &cb );
  382. if( FAILED( hr ) || cb != ( cSize * sizeof( wchar_t ) ) )
  383. {
  384. hr = E_FAIL;
  385. }
  386. else
  387. {
  388. hr = S_OK;
  389. }
  390. delete [] wstrText;
  391. }
  392. return hr;
  393. }
  394. */
  395. String operator+( const String& str1, const String& str2 )
  396. {
  397. String str;
  398. str = str1;
  399. str.Concat( str2 );
  400. return str;
  401. }
  402. String operator+( const String& str1, LPCSTR lpszStr )
  403. {
  404. String str;
  405. str = str1;
  406. str.Concat( lpszStr );
  407. return str;
  408. }
  409. String operator+( LPCSTR lpszStr, const String& str1 )
  410. {
  411. String str;
  412. str = lpszStr;
  413. str.Concat( str1 );
  414. return str;
  415. }
  416. String operator+( const String& str1, char ch )
  417. {
  418. String str;
  419. str = str1;
  420. str.Concat( ch );
  421. return str;
  422. }
  423. String operator+( char ch, const String& str1 )
  424. {
  425. String str;
  426. str.Concat( ch );
  427. str.Concat( str1 );
  428. return str;
  429. }