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.

232 lines
5.3 KiB

  1. /*++
  2. Copyright (C) 1992-2001 Microsoft Corporation
  3. Module Name:
  4. STREX.CPP
  5. Abstract:
  6. History:
  7. --*/
  8. // This is a part of the Microsoft Foundation Classes C++ library.
  9. // Copyright (C) 1992-1993 Microsoft Corporation
  10. // All rights reserved.
  11. //
  12. // This source code is only intended as a supplement to the
  13. // Microsoft Foundation Classes Reference and Microsoft
  14. // QuickHelp and/or WinHelp documentation provided with the library.
  15. // See these sources for detailed information regarding the
  16. // Microsoft Foundation Classes product.
  17. #include "precomp.h"
  18. #define ASSERT(x)
  19. #define ASSERT_VALID(x)
  20. //////////////////////////////////////////////////////////////////////////////
  21. // More sophisticated construction
  22. CString::CString(char ch, int nLength)
  23. {
  24. ASSERT(!_AfxIsDBCSLeadByte(ch)); // can't create a lead byte string
  25. if (nLength < 1)
  26. // return empty string if invalid repeat count
  27. Init();
  28. else
  29. {
  30. AllocBuffer(nLength);
  31. memset(m_pchData, ch, nLength);
  32. }
  33. }
  34. CString::CString(const char* pch, int nLength)
  35. {
  36. if (nLength == 0)
  37. Init();
  38. else
  39. {
  40. ASSERT(pch != NULL);
  41. AllocBuffer(nLength);
  42. memcpy(m_pchData, pch, nLength);
  43. }
  44. }
  45. //////////////////////////////////////////////////////////////////////////////
  46. // Additional constructors for far string data
  47. #ifdef _NEARDATA
  48. CString::CString(LPCSTR lpch, int nLen)
  49. {
  50. if (nLen == 0)
  51. Init();
  52. else
  53. {
  54. AllocBuffer(nLen);
  55. _fmemcpy(m_pchData, lpch, nLen);
  56. }
  57. }
  58. #endif //_NEARDATA
  59. //////////////////////////////////////////////////////////////////////////////
  60. // Assignment operators
  61. const CString& CString::operator =(char ch)
  62. {
  63. ASSERT(!_AfxIsDBCSLeadByte(ch)); // can't set single lead byte
  64. AssignCopy(1, &ch);
  65. return *this;
  66. }
  67. //////////////////////////////////////////////////////////////////////////////
  68. // less common string expressions
  69. CString operator +(const CString& string1, char ch)
  70. {
  71. CString s;
  72. s.ConcatCopy(string1.m_nDataLength, string1.m_pchData, 1, &ch);
  73. return s;
  74. }
  75. CString operator +(char ch, const CString& string)
  76. {
  77. CString s;
  78. s.ConcatCopy(1, &ch, string.m_nDataLength, string.m_pchData);
  79. return s;
  80. }
  81. //////////////////////////////////////////////////////////////////////////////
  82. // Very simple sub-string extraction
  83. CString CString::Mid(int nFirst) const
  84. {
  85. return Mid(nFirst, m_nDataLength - nFirst);
  86. }
  87. CString CString::Mid(int nFirst, int nCount) const
  88. {
  89. ASSERT(nFirst >= 0);
  90. ASSERT(nCount >= 0);
  91. // out-of-bounds requests return sensible things
  92. if (nFirst + nCount > m_nDataLength)
  93. nCount = m_nDataLength - nFirst;
  94. if (nFirst > m_nDataLength)
  95. nCount = 0;
  96. CString dest;
  97. AllocCopy(dest, nCount, nFirst, 0);
  98. return dest;
  99. }
  100. CString CString::Right(int nCount) const
  101. {
  102. ASSERT(nCount >= 0);
  103. if (nCount > m_nDataLength)
  104. nCount = m_nDataLength;
  105. CString dest;
  106. AllocCopy(dest, nCount, m_nDataLength-nCount, 0);
  107. return dest;
  108. }
  109. CString CString::Left(int nCount) const
  110. {
  111. ASSERT(nCount >= 0);
  112. if (nCount > m_nDataLength)
  113. nCount = m_nDataLength;
  114. CString dest;
  115. AllocCopy(dest, nCount, 0, 0);
  116. return dest;
  117. }
  118. // strspn equivalent
  119. CString CString::SpanIncluding(const char* pszCharSet) const
  120. {
  121. ASSERT(pszCharSet != NULL);
  122. return Left(strspn(m_pchData, pszCharSet));
  123. }
  124. // strcspn equivalent
  125. CString CString::SpanExcluding(const char* pszCharSet) const
  126. {
  127. ASSERT(pszCharSet != NULL);
  128. return Left(strcspn(m_pchData, pszCharSet));
  129. }
  130. //////////////////////////////////////////////////////////////////////////////
  131. // Finding
  132. int CString::ReverseFind(char ch) const
  133. {
  134. char* psz;
  135. #ifdef _WINDOWS
  136. if (afxData.bDBCS)
  137. {
  138. // compare forward remembering the last match
  139. char* pszLast = NULL;
  140. psz = m_pchData;
  141. while (*psz != '\0')
  142. {
  143. if (*psz == ch)
  144. pszLast = psz;
  145. psz = _AfxAnsiNext(psz);
  146. }
  147. psz = pszLast;
  148. }
  149. else
  150. #endif
  151. psz = (char*)strrchr(m_pchData, ch);
  152. return (psz == NULL) ? -1 : (int)(psz - m_pchData);
  153. }
  154. // find a sub-string (like strstr)
  155. int CString::Find(const char* pszSub) const
  156. {
  157. ASSERT(pszSub != NULL);
  158. char* psz;
  159. #ifdef _WINDOWS
  160. if (afxData.bDBCS)
  161. {
  162. for (psz = m_pchData; TRUE; psz = _AfxAnsiNext(psz))
  163. {
  164. // stop looking if at end of string
  165. if (*psz == '\0')
  166. {
  167. psz = NULL;
  168. break;
  169. }
  170. // compare the substring against current position
  171. const char* psz1 = psz;
  172. const char* psz2 = pszSub;
  173. while (*psz2 == *psz1 && *psz2 != '\0')
  174. ++psz1, ++psz2;
  175. // continue looking unless there was a match
  176. if (*psz2 == '\0')
  177. break;
  178. }
  179. }
  180. else
  181. #endif
  182. psz = (char*)strstr(m_pchData, pszSub);
  183. // return -1 for not found, distance from beginning otherwise
  184. return (psz == NULL) ? -1 : (int)(psz - m_pchData);
  185. }
  186. ///////////////////////////////////////////////////////////////////////////////