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.

694 lines
21 KiB

  1. #include <stdafx.h>
  2. #include <afx.h>
  3. #include <ole2.h>
  4. #include <basetyps.h>
  5. #include <atlbase.h>
  6. //+-------------------------------------------------------------------------
  7. //
  8. // Microsoft Windows
  9. //
  10. // Copyright (C) Microsoft Corporation, 1999 - 1999
  11. //
  12. // File: cstr.h
  13. //
  14. //--------------------------------------------------------------------------
  15. #ifndef __STR_H__
  16. #define __STR_H__
  17. #include <tchar.h>
  18. #define STRAPI __stdcall
  19. struct _STR_DOUBLE { BYTE doubleBits[sizeof(double)]; };
  20. BOOL STRAPI IsValidString(LPCSTR lpsz, int nLength);
  21. BOOL STRAPI IsValidString(LPCWSTR lpsz, int nLength);
  22. BOOL STRAPI IsValidAddressz(const void* lp, UINT nBytes, BOOL bReadWrite=TRUE);
  23. int STRAPI StrLoadString(HINSTANCE hInst, UINT nID, LPTSTR lpszBuf);
  24. class CStr
  25. {
  26. public:
  27. // Constructors
  28. CStr();
  29. CStr(const CStr& stringSrc);
  30. CStr(TCHAR ch, int nRepeat = 1);
  31. CStr(LPCSTR lpsz);
  32. CStr(LPCWSTR lpsz);
  33. CStr(LPCTSTR lpch, int nLength);
  34. CStr(const unsigned char* psz);
  35. // Attributes & Operations
  36. // as an array of characters
  37. int GetLength() const;
  38. BOOL IsEmpty() const;
  39. void Empty(); // free up the data
  40. TCHAR GetAt(int nIndex) const; // 0 based
  41. TCHAR operator[](int nIndex) const; // same as GetAt
  42. void SetAt(int nIndex, TCHAR ch);
  43. operator LPCTSTR() const; // as a C string
  44. // overloaded assignment
  45. const CStr& operator=(const CStr& stringSrc);
  46. const CStr& operator=(TCHAR ch);
  47. #ifdef UNICODE
  48. const CStr& operator=(char ch);
  49. #endif
  50. const CStr& operator=(LPCSTR lpsz);
  51. const CStr& operator=(LPCWSTR lpsz);
  52. const CStr& operator=(const unsigned char* psz);
  53. // string concatenation
  54. const CStr& operator+=(const CStr& string);
  55. const CStr& operator+=(TCHAR ch);
  56. #ifdef UNICODE
  57. const CStr& operator+=(char ch);
  58. #endif
  59. const CStr& operator+=(LPCTSTR lpsz);
  60. friend CStr STRAPI operator+(const CStr& string1,
  61. const CStr& string2);
  62. friend CStr STRAPI operator+(const CStr& string, TCHAR ch);
  63. friend CStr STRAPI operator+(TCHAR ch, const CStr& string);
  64. #ifdef UNICODE
  65. friend CStr STRAPI operator+(const CStr& string, char ch);
  66. friend CStr STRAPI operator+(char ch, const CStr& string);
  67. #endif
  68. friend CStr STRAPI operator+(const CStr& string, LPCTSTR lpsz);
  69. friend CStr STRAPI operator+(LPCTSTR lpsz, const CStr& string);
  70. // string comparison
  71. int Compare(LPCTSTR lpsz) const; // straight character
  72. int CompareNoCase(LPCTSTR lpsz) const; // ignore case
  73. int Collate(LPCTSTR lpsz) const; // NLS aware
  74. // simple sub-string extraction
  75. CStr Mid(int nFirst, int nCount) const;
  76. CStr Mid(int nFirst) const;
  77. CStr Left(int nCount) const;
  78. CStr Right(int nCount) const;
  79. CStr SpanIncluding(LPCTSTR lpszCharSet) const;
  80. CStr SpanExcluding(LPCTSTR lpszCharSet) const;
  81. // upper/lower/reverse conversion
  82. void MakeUpper();
  83. void MakeLower();
  84. void MakeReverse();
  85. // trimming whitespace (either side)
  86. void TrimRight();
  87. void TrimLeft();
  88. // searching (return starting index, or -1 if not found)
  89. // look for a single character match
  90. int Find(TCHAR ch) const; // like "C" strchr
  91. int ReverseFind(TCHAR ch) const;
  92. int FindOneOf(LPCTSTR lpszCharSet) const;
  93. // look for a specific sub-string
  94. int Find(LPCTSTR lpszSub) const; // like "C" strstr
  95. // simple formatting
  96. void Format(LPCTSTR lpszFormat, ...);
  97. #ifndef _MAC
  98. // formatting for localization (uses FormatMessage API)
  99. void __cdecl FormatMessage(LPCTSTR lpszFormat, ...);
  100. void __cdecl FormatMessage(UINT nFormatID, ...);
  101. #endif
  102. // Windows support
  103. BOOL LoadString(HINSTANCE hInst, UINT nID); // load from string resource
  104. // 255 chars max
  105. #ifndef UNICODE
  106. // ANSI <-> OEM support (convert string in place)
  107. void AnsiToOem();
  108. void OemToAnsi();
  109. #endif
  110. BSTR AllocSysString();
  111. BSTR SetSysString(BSTR* pbstr);
  112. // Access to string implementation buffer as "C" character array
  113. LPTSTR GetBuffer(int nMinBufLength);
  114. void ReleaseBuffer(int nNewLength = -1);
  115. LPTSTR GetBufferSetLength(int nNewLength);
  116. void FreeExtra();
  117. // Implementation
  118. public:
  119. ~CStr();
  120. int GetAllocLength() const;
  121. protected:
  122. // lengths/sizes in characters
  123. // (note: an extra character is always allocated)
  124. LPTSTR m_pchData; // actual string (zero terminated)
  125. int m_nDataLength; // does not include terminating 0
  126. int m_nAllocLength; // does not include terminating 0
  127. // implementation helpers
  128. void Init();
  129. void AllocCopy(CStr& dest, int nCopyLen, int nCopyIndex, int nExtraLen) const;
  130. void AllocBuffer(int nLen);
  131. void AssignCopy(int nSrcLen, LPCTSTR lpszSrcData);
  132. void ConcatCopy(int nSrc1Len, LPCTSTR lpszSrc1Data, int nSrc2Len, LPCTSTR lpszSrc2Data);
  133. void ConcatInPlace(int nSrcLen, LPCTSTR lpszSrcData);
  134. static void SafeDelete(LPTSTR lpch);
  135. static int SafeStrlen(LPCTSTR lpsz);
  136. };
  137. // Compare helpers
  138. BOOL STRAPI operator==(const CStr& s1, const CStr& s2);
  139. BOOL STRAPI operator==(const CStr& s1, LPCTSTR s2);
  140. BOOL STRAPI operator==(LPCTSTR s1, const CStr& s2);
  141. BOOL STRAPI operator!=(const CStr& s1, const CStr& s2);
  142. BOOL STRAPI operator!=(const CStr& s1, LPCTSTR s2);
  143. BOOL STRAPI operator!=(LPCTSTR s1, const CStr& s2);
  144. BOOL STRAPI operator<(const CStr& s1, const CStr& s2);
  145. BOOL STRAPI operator<(const CStr& s1, LPCTSTR s2);
  146. BOOL STRAPI operator<(LPCTSTR s1, const CStr& s2);
  147. BOOL STRAPI operator>(const CStr& s1, const CStr& s2);
  148. BOOL STRAPI operator>(const CStr& s1, LPCTSTR s2);
  149. BOOL STRAPI operator>(LPCTSTR s1, const CStr& s2);
  150. BOOL STRAPI operator<=(const CStr& s1, const CStr& s2);
  151. BOOL STRAPI operator<=(const CStr& s1, LPCTSTR s2);
  152. BOOL STRAPI operator<=(LPCTSTR s1, const CStr& s2);
  153. BOOL STRAPI operator>=(const CStr& s1, const CStr& s2);
  154. BOOL STRAPI operator>=(const CStr& s1, LPCTSTR s2);
  155. BOOL STRAPI operator>=(LPCTSTR s1, const CStr& s2);
  156. // conversion helpers
  157. int mmc_wcstombsz(char* mbstr, const wchar_t* wcstr, size_t count);
  158. int mmc_mbstowcsz(wchar_t* wcstr, const char* mbstr, size_t count);
  159. // Globals
  160. extern const CStr strEmptyString;
  161. extern TCHAR strChNil;
  162. // Compiler doesn't inline for DBG
  163. /////////////////////////////////////////////////////////////////////////////
  164. // Inline function declarations
  165. inline int CStr::SafeStrlen(LPCTSTR lpsz)
  166. { return (lpsz == NULL) ? NULL : _tcslen(lpsz); }
  167. inline CStr::CStr(const unsigned char* lpsz)
  168. { Init(); *this = (LPCSTR)lpsz; }
  169. inline const CStr& CStr::operator=(const unsigned char* lpsz)
  170. { *this = (LPCSTR)lpsz; return *this; }
  171. #ifdef _UNICODE
  172. inline const CStr& CStr::operator+=(char ch)
  173. { *this += (TCHAR)ch; return *this; }
  174. inline const CStr& CStr::operator=(char ch)
  175. { *this = (TCHAR)ch; return *this; }
  176. inline CStr STRAPI operator+(const CStr& string, char ch)
  177. { return string + (TCHAR)ch; }
  178. inline CStr STRAPI operator+(char ch, const CStr& string)
  179. { return (TCHAR)ch + string; }
  180. #endif
  181. inline int CStr::GetLength() const
  182. { return m_nDataLength; }
  183. inline int CStr::GetAllocLength() const
  184. { return m_nAllocLength; }
  185. inline BOOL CStr::IsEmpty() const
  186. { return m_nDataLength == 0; }
  187. inline CStr::operator LPCTSTR() const
  188. { return (LPCTSTR)m_pchData; }
  189. // String support (windows specific)
  190. inline int CStr::Compare(LPCTSTR lpsz) const
  191. { return _tcscmp(m_pchData, lpsz); } // MBCS/Unicode aware
  192. inline int CStr::CompareNoCase(LPCTSTR lpsz) const
  193. { return _tcsicmp(m_pchData, lpsz); } // MBCS/Unicode aware
  194. // CStr::Collate is often slower than Compare but is MBSC/Unicode
  195. // aware as well as locale-sensitive with respect to sort order.
  196. inline int CStr::Collate(LPCTSTR lpsz) const
  197. { return _tcscoll(m_pchData, lpsz); } // locale sensitive
  198. inline void CStr::MakeUpper()
  199. { ::CharUpper(m_pchData); }
  200. inline void CStr::MakeLower()
  201. { ::CharLower(m_pchData); }
  202. inline void CStr::MakeReverse()
  203. { _tcsrev(m_pchData); }
  204. inline TCHAR CStr::GetAt(int nIndex) const
  205. {
  206. ASSERT(nIndex >= 0);
  207. ASSERT(nIndex < m_nDataLength);
  208. return m_pchData[nIndex];
  209. }
  210. inline TCHAR CStr::operator[](int nIndex) const
  211. {
  212. // same as GetAt
  213. ASSERT(nIndex >= 0);
  214. ASSERT(nIndex < m_nDataLength);
  215. return m_pchData[nIndex];
  216. }
  217. inline void CStr::SetAt(int nIndex, TCHAR ch)
  218. {
  219. ASSERT(nIndex >= 0);
  220. ASSERT(nIndex < m_nDataLength);
  221. ASSERT(ch != 0);
  222. m_pchData[nIndex] = ch;
  223. }
  224. inline BOOL STRAPI operator==(const CStr& s1, const CStr& s2)
  225. { return s1.Compare(s2) == 0; }
  226. inline BOOL STRAPI operator==(const CStr& s1, LPCTSTR s2)
  227. { return s1.Compare(s2) == 0; }
  228. inline BOOL STRAPI operator==(LPCTSTR s1, const CStr& s2)
  229. { return s2.Compare(s1) == 0; }
  230. inline BOOL STRAPI operator!=(const CStr& s1, const CStr& s2)
  231. { return s1.Compare(s2) != 0; }
  232. inline BOOL STRAPI operator!=(const CStr& s1, LPCTSTR s2)
  233. { return s1.Compare(s2) != 0; }
  234. inline BOOL STRAPI operator!=(LPCTSTR s1, const CStr& s2)
  235. { return s2.Compare(s1) != 0; }
  236. inline BOOL STRAPI operator<(const CStr& s1, const CStr& s2)
  237. { return s1.Compare(s2) < 0; }
  238. inline BOOL STRAPI operator<(const CStr& s1, LPCTSTR s2)
  239. { return s1.Compare(s2) < 0; }
  240. inline BOOL STRAPI operator<(LPCTSTR s1, const CStr& s2)
  241. { return s2.Compare(s1) > 0; }
  242. inline BOOL STRAPI operator>(const CStr& s1, const CStr& s2)
  243. { return s1.Compare(s2) > 0; }
  244. inline BOOL STRAPI operator>(const CStr& s1, LPCTSTR s2)
  245. { return s1.Compare(s2) > 0; }
  246. inline BOOL STRAPI operator>(LPCTSTR s1, const CStr& s2)
  247. { return s2.Compare(s1) < 0; }
  248. inline BOOL STRAPI operator<=(const CStr& s1, const CStr& s2)
  249. { return s1.Compare(s2) <= 0; }
  250. inline BOOL STRAPI operator<=(const CStr& s1, LPCTSTR s2)
  251. { return s1.Compare(s2) <= 0; }
  252. inline BOOL STRAPI operator<=(LPCTSTR s1, const CStr& s2)
  253. { return s2.Compare(s1) >= 0; }
  254. inline BOOL STRAPI operator>=(const CStr& s1, const CStr& s2)
  255. { return s1.Compare(s2) >= 0; }
  256. inline BOOL STRAPI operator>=(const CStr& s1, LPCTSTR s2)
  257. { return s1.Compare(s2) >= 0; }
  258. inline BOOL STRAPI operator>=(LPCTSTR s1, const CStr& s2)
  259. { return s2.Compare(s1) <= 0; }
  260. #ifndef UNICODE
  261. inline void CStr::AnsiToOem()
  262. { ::AnsiToOem(m_pchData, m_pchData); }
  263. inline void CStr::OemToAnsi()
  264. { ::OemToAnsi(m_pchData, m_pchData); }
  265. #endif // UNICODE
  266. // General Exception for memory
  267. class MemoryException
  268. {
  269. public:
  270. MemoryException(){}
  271. void DisplayMessage()
  272. {
  273. ::MessageBox(NULL, _T("Memory Exception"), _T("System Out of Memory"), MB_OK|MB_ICONSTOP);
  274. }
  275. };
  276. // General Exception for memory
  277. class ResourceException
  278. {
  279. public:
  280. ResourceException()
  281. {
  282. ::MessageBox(NULL, _T("Resource Exception"), _T("Unable to Load Resource"), MB_OK|MB_ICONSTOP);
  283. }
  284. };
  285. #endif // __STR_H__
  286. /////////////////////////////////////////////////////////////////////////////
  287. //____________________________________________________________________________
  288. //
  289. // Microsoft Windows
  290. // Copyright (C) Microsoft Corporation, 1995 - 1999
  291. //
  292. // File: macros.h
  293. //
  294. // Contents: Useful macros
  295. //
  296. // Macros: ARRAYLEN
  297. //
  298. // BREAK_ON_FAIL(hresult)
  299. // BREAK_ON_FAIL(hresult)
  300. //
  301. // DECLARE_IUNKNOWN_METHODS
  302. // DECLARE_STANDARD_IUNKNOWN
  303. // IMPLEMENT_STANDARD_IUNKNOWN
  304. //
  305. // SAFE_RELEASE
  306. //
  307. // DECLARE_SAFE_INTERFACE_PTR_MEMBERS
  308. //
  309. // History: 6/3/1996 RaviR Created
  310. // 7/23/1996 JonN Added exception handling macros
  311. //
  312. //____________________________________________________________________________
  313. #ifndef _MACROS_H_
  314. #define _MACROS_H_
  315. //____________________________________________________________________________
  316. //
  317. // Macro: ARRAYLEN
  318. //
  319. // Purpose: To determine the length of an array.
  320. //____________________________________________________________________________
  321. //
  322. #define ARRAYLEN(a) (sizeof(a) / sizeof((a)[0]))
  323. //____________________________________________________________________________
  324. //
  325. // Macros: BREAK_ON_FAIL(hresult), BREAK_ON_ERROR(lastError)
  326. //
  327. // Purpose: To break out of a loop on error.
  328. //____________________________________________________________________________
  329. //
  330. #define BREAK_ON_FAIL(hr) if (FAILED(hr)) { break; } else 1;
  331. #define BREAK_ON_ERROR(lr) if (lr != ERROR_SUCCESS) { break; } else 1;
  332. #define RETURN_ON_FAIL(hr) if (FAILED(hr)) { return(hr); } else 1;
  333. #define THROW_ON_FAIL(hr) if (FAILED(hr)) { _com_issue_error(hr); } else 1;
  334. //____________________________________________________________________________
  335. //
  336. // Macros: DwordAlign(n)
  337. //____________________________________________________________________________
  338. //
  339. #define DwordAlign(n) (((n) + 3) & ~3)
  340. //____________________________________________________________________________
  341. //
  342. // Macros: SAFE_RELEASE
  343. //____________________________________________________________________________
  344. //
  345. #ifndef SAFE_RELEASE
  346. #define SAFE_RELEASE(punk) \
  347. if (punk != NULL) \
  348. { \
  349. punk##->Release(); \
  350. punk = NULL; \
  351. } \
  352. else \
  353. { \
  354. TRACE(_T("Release called on NULL interface ptr")); \
  355. }
  356. #endif // SAFE_RELEASE
  357. //____________________________________________________________________________
  358. //
  359. // Macros: IF_NULL_RETURN_INVALIDARG
  360. //____________________________________________________________________________
  361. //
  362. #define IF_NULL_RETURN_INVALIDARG(x) \
  363. { \
  364. ASSERT((x) != NULL); \
  365. if ((x) == NULL) \
  366. return E_INVALIDARG; \
  367. }
  368. #define IF_NULL_RETURN_INVALIDARG2(x, y) \
  369. IF_NULL_RETURN_INVALIDARG(x) \
  370. IF_NULL_RETURN_INVALIDARG(y)
  371. #define IF_NULL_RETURN_INVALIDARG3(x, y, z) \
  372. IF_NULL_RETURN_INVALIDARG(x) \
  373. IF_NULL_RETURN_INVALIDARG(y) \
  374. IF_NULL_RETURN_INVALIDARG(z)
  375. #endif // _MACROS_H_
  376. HRESULT ExtractString( IDataObject* piDataObject,
  377. CLIPFORMAT cfClipFormat,
  378. CStr* pstr, // OUT: Pointer to CStr to store data
  379. DWORD cchMaxLength)
  380. {
  381. IF_NULL_RETURN_INVALIDARG2( piDataObject, pstr );
  382. ASSERT( cchMaxLength > 0 );
  383. HRESULT hr = S_OK;
  384. FORMATETC formatetc = {cfClipFormat, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  385. STGMEDIUM stgmedium = {TYMED_HGLOBAL, NULL};
  386. stgmedium.hGlobal = ::GlobalAlloc(GPTR, sizeof(WCHAR)*cchMaxLength);
  387. do // false loop
  388. {
  389. if (NULL == stgmedium.hGlobal)
  390. {
  391. ASSERT(FALSE);
  392. ////AfxThrowMemoryException();
  393. hr = E_OUTOFMEMORY;
  394. break;
  395. }
  396. hr = piDataObject->GetDataHere( &formatetc, &stgmedium );
  397. if ( FAILED(hr) )
  398. {
  399. // This failure happens when 'searching' for
  400. // clipboard format supported by the IDataObject.
  401. // t-danmo (24-Oct-96)
  402. // Skipping ASSERT( FALSE );
  403. break;
  404. }
  405. LPWSTR pszNewData = reinterpret_cast<LPWSTR>(stgmedium.hGlobal);
  406. if (NULL == pszNewData)
  407. {
  408. ASSERT(FALSE);
  409. hr = E_UNEXPECTED;
  410. break;
  411. }
  412. pszNewData[cchMaxLength-1] = L'\0'; // just to be safe
  413. USES_CONVERSION;
  414. *pstr = OLE2T(pszNewData);
  415. } while (FALSE); // false loop
  416. if (NULL != stgmedium.hGlobal)
  417. {
  418. #if (_MSC_VER >= 1200)
  419. #pragma warning (push)
  420. #endif
  421. #pragma warning(disable: 4553) // "==" operator has no effect
  422. VERIFY( NULL == ::GlobalFree(stgmedium.hGlobal) );
  423. #if (_MSC_VER >= 1200)
  424. #pragma warning (pop)
  425. #endif
  426. }
  427. return hr;
  428. } // ExtractString()
  429. TCHAR strChNil = '\0';
  430. void CStr::Init()
  431. {
  432. m_nDataLength = m_nAllocLength = 0;
  433. m_pchData = (LPTSTR)&strChNil;
  434. }
  435. // declared static
  436. void CStr::SafeDelete(LPTSTR lpch)
  437. {
  438. if (lpch != (LPTSTR)&strChNil)
  439. delete[] lpch;
  440. }
  441. //////////////////////////////////////////////////////////////////////////////
  442. // Construction/Destruction
  443. // begin_extractstring
  444. CStr::CStr()
  445. {
  446. Init();
  447. }
  448. CStr::CStr(const CStr& stringSrc)
  449. {
  450. // if constructing a String from another String, we make a copy of the
  451. // original string data to enforce value semantics (i.e. each string
  452. // gets a copy of its own
  453. stringSrc.AllocCopy(*this, stringSrc.m_nDataLength, 0, 0);
  454. }
  455. void CStr::AllocBuffer(int nLen)
  456. // always allocate one extra character for '\0' termination
  457. // assumes [optimistically] that data length will equal allocation length
  458. {
  459. ASSERT(nLen >= 0);
  460. if (nLen == 0)
  461. {
  462. Init();
  463. }
  464. else
  465. {
  466. m_pchData = new TCHAR[nLen+1]; //REVIEW may throw an exception
  467. m_pchData[nLen] = '\0';
  468. m_nDataLength = nLen;
  469. m_nAllocLength = nLen;
  470. }
  471. }
  472. void CStr::Empty()
  473. {
  474. SafeDelete(m_pchData);
  475. Init();
  476. ASSERT(m_nDataLength == 0);
  477. ASSERT(m_nAllocLength == 0);
  478. }
  479. CStr::~CStr()
  480. // free any attached data
  481. {
  482. SafeDelete(m_pchData);
  483. }
  484. //////////////////////////////////////////////////////////////////////////////
  485. // Helpers for the rest of the implementation
  486. static inline int SafeStrlen(LPCTSTR lpsz)
  487. {
  488. ASSERT(lpsz == NULL || IsValidString(lpsz, FALSE));
  489. return (lpsz == NULL) ? 0 : lstrlen(lpsz);
  490. }
  491. void CStr::AllocCopy(CStr& dest, int nCopyLen, int nCopyIndex,
  492. int nExtraLen) const
  493. {
  494. // will clone the data attached to this string
  495. // allocating 'nExtraLen' characters
  496. // Places results in uninitialized string 'dest'
  497. // Will copy the part or all of original data to start of new string
  498. int nNewLen = nCopyLen + nExtraLen;
  499. if (nNewLen == 0)
  500. {
  501. dest.Init();
  502. }
  503. else
  504. {
  505. dest.AllocBuffer(nNewLen);
  506. memcpy(dest.m_pchData, &m_pchData[nCopyIndex], nCopyLen*sizeof(TCHAR));
  507. }
  508. }
  509. //////////////////////////////////////////////////////////////////////////////
  510. // More sophisticated construction
  511. CStr::CStr(LPCTSTR lpsz)
  512. {
  513. if (lpsz != NULL && (DWORD_PTR)lpsz <= 0xffff)
  514. {
  515. Init();
  516. UINT nID = LOWORD((DWORD_PTR)lpsz);
  517. // REVIEW hInstance for LoadString(hInst, nID);
  518. }
  519. else
  520. {
  521. int nLen;
  522. if ((nLen = SafeStrlen(lpsz)) == 0)
  523. Init();
  524. else
  525. {
  526. AllocBuffer(nLen);
  527. memcpy(m_pchData, lpsz, nLen*sizeof(TCHAR));
  528. }
  529. }
  530. }
  531. //////////////////////////////////////////////////////////////////////////////
  532. // Assignment operators
  533. // All assign a new value to the string
  534. // (a) first see if the buffer is big enough
  535. // (b) if enough room, copy on top of old buffer, set size and type
  536. // (c) otherwise free old string data, and create a new one
  537. //
  538. // All routines return the new string (but as a 'const CStr&' so that
  539. // assigning it again will cause a copy, eg: s1 = s2 = "hi there".
  540. //
  541. void CStr::AssignCopy(int nSrcLen, LPCTSTR lpszSrcData)
  542. {
  543. // check if it will fit
  544. if (nSrcLen > m_nAllocLength)
  545. {
  546. // it won't fit, allocate another one
  547. Empty();
  548. AllocBuffer(nSrcLen);
  549. }
  550. if (nSrcLen != 0)
  551. memcpy(m_pchData, lpszSrcData, nSrcLen*sizeof(TCHAR));
  552. m_nDataLength = nSrcLen;
  553. m_pchData[nSrcLen] = '\0';
  554. }
  555. const CStr& CStr::operator=(const CStr& stringSrc)
  556. {
  557. AssignCopy(stringSrc.m_nDataLength, stringSrc.m_pchData);
  558. return *this;
  559. }
  560. const CStr& CStr::operator=(LPCTSTR lpsz)
  561. {
  562. ASSERT(lpsz == NULL || IsValidString(lpsz, FALSE));
  563. AssignCopy(SafeStrlen(lpsz), lpsz);
  564. return *this;
  565. }
  566. HRESULT ExtractString( IDataObject* piDataObject,
  567. CLIPFORMAT cfClipFormat,
  568. CString* pstr, // OUT: Pointer to CStr to store data
  569. DWORD cchMaxLength)
  570. {
  571. if (pstr == NULL)
  572. return E_POINTER;
  573. CStr cstr(*pstr);
  574. HRESULT hr = ExtractString(piDataObject, cfClipFormat, &cstr, cchMaxLength);
  575. *pstr = cstr;
  576. return hr;
  577. }
  578. BOOL STRAPI IsValidString(LPCSTR lpsz, int nLength)
  579. {
  580. if (lpsz == NULL)
  581. return FALSE;
  582. return ::IsBadStringPtrA(lpsz, nLength) == 0;
  583. }
  584. BOOL STRAPI IsValidString(LPCWSTR lpsz, int nLength)
  585. {
  586. if (lpsz == NULL)
  587. return FALSE;
  588. return ::IsBadStringPtrW(lpsz, nLength) == 0;
  589. }