Bstring.cpp 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109
  1. #include "stdafx.h"
  2. #include "Bstring.h"
  3. #include "string.h"
  4. //typedef char TCHAR;
  5. //typedef const TCHAR FAR * LPCTSTR;
  6. BYTE afxChNil = '\0';
  7. int _afxInitData[] = { -1, 0, 0, 0 }; //初始化BStringData的地址
  8. BStringData* _afxDataNil = (BStringData*)&_afxInitData; //地址转化为BStringData*
  9. LPBTSTR _afxPchNil = (LPBTSTR)(((BYTE*)&_afxInitData)+sizeof(BStringData));
  10. const BString& AfxGetEmptyString() //建立一个空的BString
  11. {
  12. return *(BString*)&_afxPchNil;
  13. }
  14. BOOL AfxIsValidString(LPBTSTR lpsz, int nLength /* = -1 */)
  15. {
  16. if (lpsz == NULL)
  17. return FALSE;
  18. return ::IsBadStringPtr(reinterpret_cast<LPCTSTR>(lpsz), nLength) == 0;
  19. }
  20. BOOL AfxIsValidAddress(const void* lp, UINT nBytes,BOOL bReadWrite /* = TRUE */)
  21. {
  22. return (lp != NULL && !IsBadReadPtr(lp, nBytes) && (!bReadWrite !IsBadWritePtr((LPVOID)lp, nBytes)));
  23. }
  24. void BString::Init()
  25. {
  26. m_pchData=AfxGetEmptyString().m_pchData;
  27. }
  28. BString::BString()
  29. {
  30. Init();
  31. }
  32. int BString::GetLength() const
  33. {
  34. return GetData()->nDataLength;
  35. }
  36. int BString::GetAllocLength() const
  37. {
  38. return GetData()->nAllocLength;
  39. }
  40. BOOL BString::IsEmpty() const
  41. {
  42. return GetData()->nDataLength == 0;
  43. }
  44. BStringData* BString::GetData() const
  45. {
  46. assert(m_pchData != NULL);
  47. return ((BStringData*)m_pchData)-1;
  48. }
  49. BString::operator LPBTSTR() const
  50. {
  51. return m_pchData;
  52. }
  53. int BString::SafeStrlen(LPBTSTR lpsz)
  54. {
  55. return (lpsz == NULL) ? 0 : lstrlen(reinterpret_cast<LPCTSTR>(lpsz));
  56. }
  57. void BString::AllocBuffer(int nLen)
  58. {
  59. assert(nLen >= 0);
  60. assert(nLen <= 2147483647-1); // (signed) int 的最大值
  61. if (nLen == 0)
  62. Init();
  63. else
  64. {
  65. BStringData* pData;
  66. {
  67. pData = (BStringData*)
  68. new BYTE[sizeof(BStringData) + (nLen+1)*sizeof(TCHAR)];
  69. pData->nAllocLength = nLen;
  70. }
  71. pData->nRefs = 1;
  72. pData->data()[nLen] = '\0';
  73. pData->nDataLength = nLen;
  74. m_pchData = pData->data();
  75. }
  76. }
  77. void BString::FreeData(BStringData* pData)
  78. {
  79. delete[] (BYTE*)pData;
  80. }
  81. void BString::CopyBeforeWrite()
  82. {
  83. if (GetData()->nRefs > 1)
  84. {
  85. BStringData* pData = GetData();
  86. Release();
  87. AllocBuffer(pData->nDataLength);
  88. memcpy(m_pchData, pData->data(), (pData->nDataLength+1)*sizeof(BYTE));
  89. }
  90. assert(GetData()->nRefs <= 1);
  91. }
  92. void BString::AllocBeforeWrite(int nLen)
  93. {
  94. if (GetData()->nRefs > 1 && nLen > GetData()->nAllocLength)
  95. {
  96. Release();
  97. AllocBuffer(nLen);
  98. }
  99. assert(GetData()->nRefs <= 1);
  100. }
  101. void BString::AssignCopy(int nSrcLen, LPBTSTR lpszSrcData)
  102. {
  103. AllocBeforeWrite(nSrcLen);
  104. memcpy(m_pchData, lpszSrcData, nSrcLen*sizeof(BYTE));
  105. GetData()->nDataLength = nSrcLen;
  106. m_pchData[nSrcLen] = '\0';
  107. }
  108. void BString::AllocCopy(BString& dest, int nCopyLen, int nCopyIndex,
  109. int nExtraLen) const
  110. {
  111. int nNewLen = nCopyLen + nExtraLen;
  112. if (nNewLen == 0)
  113. {
  114. dest.Init();
  115. }
  116. else
  117. {
  118. dest.AllocBuffer(nNewLen);
  119. memcpy(dest.m_pchData, m_pchData+nCopyIndex, nCopyLen*sizeof(BYTE));
  120. }
  121. }
  122. BString::~BString()
  123. {
  124. if (GetData() != _afxDataNil)
  125. {
  126. if (InterlockedDecrement(&GetData()->nRefs) <= 0)
  127. FreeData(GetData());
  128. }
  129. }
  130. BString::BString(const BString& stringSrc)
  131. {
  132. assert(stringSrc.GetData()->nRefs != 0);
  133. if (stringSrc.GetData()->nRefs >= 0)
  134. {
  135. assert(stringSrc.GetData() != _afxDataNil);
  136. m_pchData = stringSrc.m_pchData;
  137. InterlockedIncrement(&GetData()->nRefs);
  138. }
  139. else
  140. {
  141. Init();
  142. *this = stringSrc.m_pchData;
  143. }
  144. }
  145. BString::BString(LPBTSTR lpsz)
  146. {
  147. Init();
  148. int nLen = SafeStrlen(lpsz);
  149. if (nLen != 0)
  150. {
  151. AllocBuffer(nLen);
  152. memcpy(m_pchData, lpsz, nLen*sizeof(BYTE));
  153. }
  154. }
  155. BString::BString(LPBTSTR lpch, int nLength)
  156. {
  157. Init();
  158. if (nLength != 0)
  159. {
  160. assert(AfxIsValidAddress(lpch, nLength, FALSE));
  161. AllocBuffer(nLength);
  162. memcpy(m_pchData, lpch, nLength*sizeof(BYTE));
  163. }
  164. }
  165. void BString::Release()
  166. {
  167. if (GetData() != _afxDataNil)
  168. {
  169. assert(GetData()->nRefs != 0);
  170. if (InterlockedDecrement(&GetData()->nRefs) <= 0)
  171. FreeData(GetData());
  172. Init();
  173. }
  174. }
  175. void BString::Release(BStringData* pData)
  176. {
  177. if (pData != _afxDataNil)
  178. {
  179. assert(pData->nRefs != 0);
  180. if (InterlockedDecrement(&pData->nRefs) <= 0)
  181. FreeData(pData);
  182. }
  183. }
  184. void BString::Empty()
  185. {
  186. if (GetData()->nDataLength == 0)
  187. return;
  188. if (GetData()->nRefs >= 0)
  189. Release();
  190. else
  191. *this = &afxChNil;
  192. assert(GetData()->nDataLength == 0);
  193. assert(GetData()->nRefs < 0 GetData()->nAllocLength == 0);
  194. }
  195. const BString& BString::operator=(const BString& stringSrc)
  196. {
  197. if (m_pchData != stringSrc.m_pchData)
  198. {
  199. if ((GetData()->nRefs < 0 && GetData() != _afxDataNil) && stringSrc.GetData()->nRefs < 0)
  200. {
  201. //新建一快数据
  202. AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData);
  203. }
  204. else
  205. {
  206. //只拷贝指针
  207. Release();
  208. assert(stringSrc.GetData() != _afxDataNil);
  209. m_pchData = stringSrc.m_pchData;
  210. InterlockedIncrement(&GetData()->nRefs);
  211. }
  212. }
  213. return *this;
  214. }
  215. const BString& BString::operator=(LPBTSTR lpsz)
  216. {
  217. assert(lpsz == NULL AfxIsValidString(lpsz));
  218. AssignCopy(SafeStrlen(lpsz), lpsz);
  219. return *this;
  220. }
  221. const BString& BString::operator=(BYTE ch)
  222. {
  223. AssignCopy(1, &ch);
  224. return *this;
  225. }
  226. int BString::Delete(int nIndex, int nCount /* = 1 */)
  227. {
  228. if (nIndex < 0)
  229. nIndex = 0;
  230. int nNewLength = GetData()->nDataLength;
  231. if (nCount > 0 && nIndex < nNewLength)
  232. {
  233. CopyBeforeWrite(); //脱离共享数据块,
  234. int nBytesToCopy = nNewLength - (nIndex + nCount) + 1;
  235. //移动数据
  236. memcpy(m_pchData + nIndex,
  237. m_pchData + nIndex + nCount, nBytesToCopy * sizeof(BYTE));
  238. GetData()->nDataLength = nNewLength - nCount;
  239. }
  240. return nNewLength;
  241. }
  242. int BString::Insert(int nIndex, BYTE ch)
  243. {
  244. CopyBeforeWrite(); //脱离共享数据
  245. if (nIndex < 0)
  246. nIndex = 0;
  247. int nNewLength = GetData()->nDataLength;
  248. if (nIndex > nNewLength)
  249. nIndex = nNewLength;
  250. nNewLength++;
  251. if (GetData()->nAllocLength < nNewLength)
  252. { //动态分配内存,并拷贝原来的数据
  253. BStringData* pOldData = GetData();
  254. BYTE* pstr = m_pchData;
  255. AllocBuffer(nNewLength);
  256. memcpy(m_pchData, pstr, (pOldData->nDataLength+1)*sizeof(BYTE));
  257. BString::Release(pOldData);
  258. }
  259. //插入数据
  260. memcpy(m_pchData + nIndex + 1,
  261. m_pchData + nIndex, (nNewLength-nIndex)*sizeof(BYTE));
  262. m_pchData[nIndex] = ch;
  263. GetData()->nDataLength = nNewLength;
  264. return nNewLength;
  265. }
  266. int BString::Insert(int nIndex, LPBTSTR pstr)
  267. {
  268. if (nIndex < 0)
  269. nIndex = 0;
  270. int nInsertLength = SafeStrlen(pstr);
  271. int nNewLength = GetData()->nDataLength;
  272. if (nInsertLength > 0)
  273. {
  274. CopyBeforeWrite(); //脱离共享数据
  275. if (nIndex > nNewLength)
  276. nIndex = nNewLength;
  277. nNewLength += nInsertLength;
  278. if (GetData()->nAllocLength < nNewLength)
  279. { //动态分配内存,并拷贝原来的数据
  280. BStringData* pOldData = GetData();
  281. BYTE* pstr = m_pchData;
  282. AllocBuffer(nNewLength);
  283. memcpy(m_pchData, pstr, (pOldData->nDataLength+1)*sizeof(BYTE));
  284. BString::Release(pOldData);
  285. }
  286. //移动数据,留出插入的位酒move也可以
  287. memcpy(m_pchData + nIndex + nInsertLength,
  288. m_pchData + nIndex,
  289. (nNewLength-nIndex-nInsertLength+1)*sizeof(BYTE));
  290. //插入数据
  291. memcpy(m_pchData + nIndex,
  292. pstr, nInsertLength*sizeof(BYTE));
  293. GetData()->nDataLength = nNewLength;
  294. }
  295. return nNewLength;
  296. }
  297. int BString::Replace(BYTE chOld, BYTE chNew)
  298. {
  299. int nCount = 0;
  300. if (chOld != chNew) //替换的不能相同
  301. {
  302. CopyBeforeWrite();
  303. BYTE* psz = m_pchData;
  304. BYTE* pszEnd = psz + GetData()->nDataLength;
  305. while (psz < pszEnd)
  306. {
  307. if (*psz == chOld) //替换
  308. {
  309. *psz = chNew;
  310. nCount++;
  311. }
  312. psz = _tcsinc(psz); //相当于++psz,考虑要UNICODE下版本才用的
  313. }
  314. }
  315. return nCount;
  316. }
  317. int BString::Replace(LPBTSTR lpszOld, LPBTSTR lpszNew)
  318. {
  319. int nSourceLen = SafeStrlen(lpszOld);
  320. if (nSourceLen == 0) //要替换的不能为空
  321. return 0;
  322. int nReplacementLen = SafeStrlen(lpszNew);
  323. int nCount = 0;
  324. LPTSTR lpszStart = m_pchData;
  325. LPTSTR lpszEnd = m_pchData + GetData()->nDataLength;
  326. LPTSTR lpszTarget;
  327. while (lpszStart < lpszEnd) //检索要替换的个数
  328. {
  329. while ((lpszTarget = _tcsstr(reinterpret_cast<LPCTSTR>(lpszStart), reinterpret_cast<LPCTSTR>(lpszOld))) != NULL)
  330. {
  331. nCount++;
  332. lpszStart = lpszTarget + nSourceLen;
  333. }
  334. lpszStart += lstrlen(lpszStart) + 1;
  335. }
  336. if (nCount > 0)
  337. {
  338. CopyBeforeWrite();
  339. int nOldLength = GetData()->nDataLength;
  340. int nNewLength = nOldLength + (nReplacementLen-nSourceLen)*nCount; //替换以后的长度
  341. if (GetData()->nAllocLength < nNewLength GetData()->nRefs > 1)
  342. { //超出原来的内存长度动态分配
  343. BStringData* pOldData = GetData();
  344. LPTSTR pstr = m_pchData;
  345. AllocBuffer(nNewLength);
  346. memcpy(m_pchData, pstr, pOldData->nDataLength*sizeof(BYTE));
  347. BString::Release(pOldData);
  348. }
  349. lpszStart = m_pchData;
  350. lpszEnd = m_pchData + GetData()->nDataLength;
  351. while (lpszStart < lpszEnd) //这个循环好象没什么用
  352. {
  353. while ( (lpszTarget = _tcsstr(lpszStart, lpszOld)) != NULL) //开始替换
  354. {
  355. int nBalance = nOldLength - (lpszTarget - m_pchData + nSourceLen); //要往后移的长度
  356. //移动数据,留出插入的位酒
  357. memmove(lpszTarget + nReplacementLen, lpszTarget + nSourceLen,
  358. nBalance * sizeof(BYTE));
  359. //插入替换数据
  360. memcpy(lpszTarget, lpszNew, nReplacementLen*sizeof(BYTE));
  361. lpszStart = lpszTarget + nReplacementLen;
  362. lpszStart[nBalance] = '\0';
  363. nOldLength += (nReplacementLen - nSourceLen); //现有数据长度
  364. }
  365. lpszStart += lstrlen(lpszStart) + 1;
  366. }
  367. assert(m_pchData[nNewLength] == '\0');
  368. GetData()->nDataLength = nNewLength;
  369. }
  370. return nCount;
  371. }
  372. int BString::Remove(BYTE chRemove)
  373. {
  374. CopyBeforeWrite();
  375. LPTSTR pstrSource = m_pchData;
  376. LPTSTR pstrDest = m_pchData;
  377. LPTSTR pstrEnd = m_pchData + GetData()->nDataLength;
  378. while (pstrSource < pstrEnd)
  379. {
  380. if (*pstrSource != chRemove)
  381. {
  382. *pstrDest = *pstrSource; //把不移除的数据拷贝
  383. pstrDest = _tcsinc(pstrDest);
  384. }
  385. pstrSource = _tcsinc(pstrSource);//++pstrSource
  386. }
  387. *pstrDest = '\0';
  388. int nCount = pstrSource - pstrDest; //比较变态的计算替换个数,
  389. GetData()->nDataLength -= nCount;
  390. return nCount;
  391. }
  392. BString BString::Mid(int nFirst) const
  393. {
  394. return Mid(nFirst, GetData()->nDataLength - nFirst);
  395. }
  396. BString BString::Mid(int nFirst, int nCount) const
  397. {
  398. if (nFirst < 0)
  399. nFirst = 0;
  400. if (nCount < 0)
  401. nCount = 0;
  402. if (nFirst + nCount > GetData()->nDataLength)
  403. nCount = GetData()->nDataLength - nFirst;
  404. if (nFirst > GetData()->nDataLength)
  405. nCount = 0;
  406. assert(nFirst >= 0);
  407. assert(nFirst + nCount <= GetData()->nDataLength);
  408. //取去整个数据
  409. if (nFirst == 0 && nFirst + nCount == GetData()->nDataLength)
  410. return *this;
  411. BString dest;
  412. AllocCopy(dest, nCount, nFirst, 0);
  413. return dest;
  414. }
  415. BString BString::Right(int nCount) const
  416. {
  417. if (nCount < 0)
  418. nCount = 0;
  419. if (nCount >= GetData()->nDataLength)
  420. return *this;
  421. BString dest;
  422. AllocCopy(dest, nCount, GetData()->nDataLength-nCount, 0);
  423. return dest;
  424. }
  425. BString BString::Left(int nCount) const
  426. {
  427. if (nCount < 0)
  428. nCount = 0;
  429. if (nCount >= GetData()->nDataLength)
  430. return *this;
  431. BString dest;
  432. AllocCopy(dest, nCount, 0, 0);
  433. return dest;
  434. }
  435. int BString::ReverseFind(BYTE ch) const
  436. {
  437. //从最后查找
  438. LPTSTR lpsz = _tcsrchr(m_pchData, (_TUCHAR) ch);
  439. return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
  440. }
  441. int BString::Find(BYTE ch) const
  442. {
  443. return Find(ch, 0);
  444. }
  445. int BString::Find(BYTE ch, int nStart) const
  446. {
  447. int nLength = GetData()->nDataLength;
  448. if (nStart >= nLength)
  449. return -1;
  450. LPTSTR lpsz = _tcschr(m_pchData + nStart, (_TUCHAR)ch);
  451. return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
  452. }
  453. int BString::Find(LPBTSTR lpszSub) const
  454. {
  455. return Find(lpszSub, 0);
  456. }
  457. int BString::Find(LPBTSTR lpszSub, int nStart) const
  458. {
  459. assert(AfxIsValidString(lpszSub));
  460. int nLength = GetData()->nDataLength;
  461. if (nStart > nLength)
  462. return -1;
  463. LPTSTR lpsz = _tcsstr(m_pchData + nStart, lpszSub);
  464. return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
  465. }
  466. int BString::FindOneOf(LPBTSTR lpszCharSet) const
  467. {
  468. assert(AfxIsValidString(lpszCharSet));
  469. LPTSTR lpsz = _tcspbrk(m_pchData, lpszCharSet);
  470. return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
  471. }
  472. void BString::MakeUpper()
  473. {
  474. CopyBeforeWrite();
  475. _tcsupr(m_pchData);
  476. }
  477. void BString::MakeLower()
  478. {
  479. CopyBeforeWrite();
  480. _tcslwr(m_pchData);
  481. }
  482. void BString::MakeReverse()
  483. {
  484. CopyBeforeWrite();
  485. _tcsrev(m_pchData);
  486. }
  487. void BString::SetAt(int nIndex, BYTE ch)
  488. {
  489. assert(nIndex >= 0);
  490. assert(nIndex < GetData()->nDataLength);
  491. CopyBeforeWrite();
  492. m_pchData[nIndex] = ch;
  493. }
  494. void BString::TrimRight(LPBTSTR lpszTargetList)
  495. {
  496. CopyBeforeWrite();
  497. LPTSTR lpsz = m_pchData;
  498. LPTSTR lpszLast = NULL;
  499. while (*lpsz != '\0')
  500. {
  501. if (_tcschr(lpszTargetList, *lpsz) != NULL)
  502. {
  503. if (lpszLast == NULL)
  504. lpszLast = lpsz;
  505. }
  506. else
  507. lpszLast = NULL;
  508. lpsz = _tcsinc(lpsz);
  509. }
  510. if (lpszLast != NULL)
  511. {
  512. *lpszLast = '\0';
  513. GetData()->nDataLength = lpszLast - m_pchData;
  514. }
  515. }
  516. void BString::TrimRight(BYTE chTarget)
  517. {
  518. CopyBeforeWrite();
  519. LPTSTR lpsz = m_pchData;
  520. LPTSTR lpszLast = NULL;
  521. while (*lpsz != '\0')
  522. {
  523. if (*lpsz == chTarget)
  524. {
  525. if (lpszLast == NULL)
  526. lpszLast = lpsz;
  527. }
  528. else
  529. lpszLast = NULL;
  530. lpsz = _tcsinc(lpsz);
  531. }
  532. if (lpszLast != NULL)
  533. {
  534. *lpszLast = '\0';
  535. GetData()->nDataLength = lpszLast - m_pchData;
  536. }
  537. }
  538. void BString::TrimRight()
  539. {
  540. CopyBeforeWrite();
  541. LPTSTR lpsz = m_pchData;
  542. LPTSTR lpszLast = NULL;
  543. while (*lpsz != '\0')
  544. {
  545. if (_istspace(*lpsz))
  546. {
  547. if (lpszLast == NULL)
  548. lpszLast = lpsz;
  549. }
  550. else
  551. lpszLast = NULL;
  552. lpsz = _tcsinc(lpsz);
  553. }
  554. if (lpszLast != NULL)
  555. {
  556. // truncate at trailing space start
  557. *lpszLast = '\0';
  558. GetData()->nDataLength = lpszLast - m_pchData;
  559. }
  560. }
  561. void BString::TrimLeft(LPBTSTR lpszTargets)
  562. {
  563. // if we're not trimming anything, we're not doing any work
  564. if (SafeStrlen(lpszTargets) == 0)
  565. return;
  566. CopyBeforeWrite();
  567. LPBTSTR lpsz = m_pchData;
  568. while (*lpsz != '\0')
  569. {
  570. if (_tcschr(lpszTargets, *lpsz) == NULL)
  571. break;
  572. lpsz = _tcsinc(lpsz);
  573. }
  574. if (lpsz != m_pchData)
  575. {
  576. // fix up data and length
  577. int nDataLength = GetData()->nDataLength - (lpsz - m_pchData);
  578. memmove(m_pchData, lpsz, (nDataLength+1)*sizeof(BYTE));
  579. GetData()->nDataLength = nDataLength;
  580. }
  581. }
  582. void BString::TrimLeft(BYTE chTarget)
  583. {
  584. CopyBeforeWrite();
  585. LPBTSTR lpsz = m_pchData;
  586. while (chTarget == *lpsz)
  587. lpsz = _tcsinc(lpsz);
  588. if (lpsz != m_pchData)
  589. {
  590. int nDataLength = GetData()->nDataLength - (lpsz - m_pchData);
  591. memmove(m_pchData, lpsz, (nDataLength+1)*sizeof(BYTE));
  592. GetData()->nDataLength = nDataLength;
  593. }
  594. }
  595. void BString::TrimLeft()
  596. {
  597. CopyBeforeWrite();
  598. LPBTSTR lpsz = m_pchData;
  599. while (_istspace(*lpsz))
  600. lpsz = _tcsinc(lpsz);
  601. if (lpsz != m_pchData)
  602. {
  603. int nDataLength = GetData()->nDataLength - (lpsz - m_pchData);
  604. memmove(m_pchData, lpsz, (nDataLength+1)*sizeof(BYTE));
  605. GetData()->nDataLength = nDataLength;
  606. }
  607. }
  608. #define TCHAR_ARG TCHAR
  609. #define WCHAR_ARG WCHAR
  610. #define CHAR_ARG char
  611. struct _AFX_DOUBLE { BYTE doubleBits[sizeof(double)]; };
  612. #ifdef _X86_
  613. #define DOUBLE_ARG _AFX_DOUBLE
  614. #else
  615. #define DOUBLE_ARG double
  616. #endif
  617. #define FORCE_ANSI 0x10000
  618. #define FORCE_UNICODE 0x20000
  619. #define FORCE_INT64 0x40000
  620. void BString::FormatV(LPBTSTR lpszFormat, va_list argList)
  621. {
  622. assert(AfxIsValidString(lpszFormat));
  623. va_list argListSave = argList;
  624. // make a guess at the maximum length of the resulting string
  625. int nMaxLen = 0;
  626. for (LPBTSTR lpsz = lpszFormat; *lpsz != '\0'; lpsz = _tcsinc(lpsz))
  627. {
  628. //查找%,对%%不在查找范围
  629. if (*lpsz != '%' *(lpsz = _tcsinc(lpsz)) == '%')
  630. {
  631. nMaxLen += _tclen(lpsz);
  632. continue;
  633. }
  634. int nItemLen = 0;
  635. //%后面的格式判断
  636. int nWidth = 0;
  637. for (; *lpsz != '\0'; lpsz = _tcsinc(lpsz))
  638. {
  639. if (*lpsz == '#')
  640. nMaxLen += 2; // 16进制 '0x'
  641. else if (*lpsz == '*')
  642. nWidth = va_arg(argList, int);
  643. else if (*lpsz == '-' *lpsz == '+' *lpsz == '0'
  644. *lpsz == ' ')
  645. ;
  646. else // hit non-flag character
  647. break;
  648. }
  649. // get width and skip it
  650. if (nWidth == 0)
  651. {
  652. // width indicated by
  653. nWidth = _ttoi(lpsz);
  654. for (; *lpsz != '\0' && _istdigit(*lpsz); lpsz = _tcsinc(lpsz))
  655. ;
  656. }
  657. assert(nWidth >= 0);
  658. int nPrecision = 0;
  659. if (*lpsz == '.')
  660. {
  661. // skip past '.' separator (width.precision)
  662. lpsz = _tcsinc(lpsz);
  663. // get precision and skip it
  664. if (*lpsz == '*')
  665. {
  666. nPrecision = va_arg(argList, int);
  667. lpsz = _tcsinc(lpsz);
  668. }
  669. else
  670. {
  671. nPrecision = _ttoi(lpsz);
  672. for (; *lpsz != '\0' && _istdigit(*lpsz); lpsz = _tcsinc(lpsz))
  673. ;
  674. }
  675. assert(nPrecision >= 0);
  676. }
  677. // should be on type modifier or specifier
  678. int nModifier = 0;
  679. if (_tcsncmp(lpsz, _T("I64"), 3) == 0)
  680. {
  681. lpsz += 3;
  682. nModifier = FORCE_INT64;
  683. #if !defined(_X86_) && !defined(_ALPHA_)
  684. // __int64 is only available on X86 and ALPHA platforms
  685. ASSERT(FALSE);
  686. #endif
  687. }
  688. else
  689. {
  690. switch (*lpsz)
  691. {
  692. // modifiers that affect size
  693. case 'h':
  694. nModifier = FORCE_ANSI;
  695. lpsz = _tcsinc(lpsz);
  696. break;
  697. case 'l':
  698. nModifier = FORCE_UNICODE;
  699. lpsz = _tcsinc(lpsz);
  700. break;
  701. // modifiers that do not affect size
  702. case 'F':
  703. case 'N':
  704. case 'L':
  705. lpsz = _tcsinc(lpsz);
  706. break;
  707. }
  708. }
  709. // now should be on specifier
  710. switch (*lpsz | nModifier)
  711. {
  712. // single characters
  713. case 'c':
  714. case 'C':
  715. nItemLen = 2;
  716. va_arg(argList, TCHAR_ARG);
  717. break;
  718. case 'c'|FORCE_ANSI:
  719. case 'C'|FORCE_ANSI:
  720. nItemLen = 2;
  721. va_arg(argList, CHAR_ARG);
  722. break;
  723. case 'c'|FORCE_UNICODE:
  724. case 'C'|FORCE_UNICODE:
  725. nItemLen = 2;
  726. va_arg(argList, WCHAR_ARG);
  727. break;
  728. // strings
  729. case 's':
  730. {
  731. LPBTSTR pstrNextArg = va_arg(argList, LPBTSTR);
  732. if (pstrNextArg == NULL)
  733. nItemLen = 6; // "(null)"
  734. else
  735. {
  736. nItemLen = lstrlen(pstrNextArg);
  737. nItemLen = max(1, nItemLen);
  738. }
  739. }
  740. break;
  741. case 'S':
  742. {
  743. #ifndef _UNICODE
  744. LPWSTR pstrNextArg = va_arg(argList, LPWSTR);
  745. if (pstrNextArg == NULL)
  746. nItemLen = 6; // "(null)"
  747. else
  748. {
  749. nItemLen = wcslen(pstrNextArg);
  750. nItemLen = max(1, nItemLen);
  751. }
  752. #else
  753. LPCSTR pstrNextArg = va_arg(argList, LPCSTR);
  754. if (pstrNextArg == NULL)
  755. nItemLen = 6; // "(null)"
  756. else
  757. {
  758. nItemLen = lstrlenA(pstrNextArg);
  759. nItemLen = max(1, nItemLen);
  760. }
  761. #endif
  762. }
  763. break;
  764. case 's'|FORCE_ANSI:
  765. case 'S'|FORCE_ANSI:
  766. {
  767. LPCSTR pstrNextArg = va_arg(argList, LPCSTR);
  768. if (pstrNextArg == NULL)
  769. nItemLen = 6; // "(null)"
  770. else
  771. {
  772. nItemLen = lstrlenA(pstrNextArg);
  773. nItemLen = max(1, nItemLen);
  774. }
  775. }
  776. break;
  777. case 's'|FORCE_UNICODE:
  778. case 'S'|FORCE_UNICODE:
  779. {
  780. LPWSTR pstrNextArg = va_arg(argList, LPWSTR);
  781. if (pstrNextArg == NULL)
  782. nItemLen = 6; // "(null)"
  783. else
  784. {
  785. nItemLen = wcslen(pstrNextArg);
  786. nItemLen = max(1, nItemLen);
  787. }
  788. }
  789. break;
  790. }
  791. // adjust nItemLen for strings
  792. if (nItemLen != 0)
  793. {
  794. if (nPrecision != 0)
  795. nItemLen = min(nItemLen, nPrecision);
  796. nItemLen = max(nItemLen, nWidth);
  797. }
  798. else
  799. {
  800. switch (*lpsz)
  801. {
  802. // integers
  803. case 'd':
  804. case 'i':
  805. case 'u':
  806. case 'x':
  807. case 'X':
  808. case 'o':
  809. if (nModifier & FORCE_INT64)
  810. va_arg(argList, __int64);
  811. else
  812. va_arg(argList, int);
  813. nItemLen = 32;
  814. nItemLen = max(nItemLen, nWidth+nPrecision);
  815. break;
  816. case 'e':
  817. case 'g':
  818. case 'G':
  819. va_arg(argList, DOUBLE_ARG);
  820. nItemLen = 128;
  821. nItemLen = max(nItemLen, nWidth+nPrecision);
  822. break;
  823. case 'f':
  824. {
  825. double f;
  826. LPTSTR pszTemp;
  827. // 312 == strlen("-1+(309 zeroes).")
  828. // 309 zeroes == max precision of a double
  829. // 6 == adjustment in case precision is not specified,
  830. // which means that the precision defaults to 6
  831. pszTemp = (LPTSTR)_alloca(max(nWidth, 312+nPrecision+6));
  832. f = va_arg(argList, double);
  833. _stprintf( pszTemp, _T( "%*.*f" ), nWidth, nPrecision+6, f );
  834. nItemLen = _tcslen(pszTemp);
  835. }
  836. break;
  837. case 'p':
  838. va_arg(argList, void*);
  839. nItemLen = 32;
  840. nItemLen = max(nItemLen, nWidth+nPrecision);
  841. break;
  842. // no output
  843. case 'n':
  844. va_arg(argList, int*);
  845. break;
  846. default:
  847. assert(FALSE); // unknown formatting option
  848. }
  849. }
  850. // adjust nMaxLen for output nItemLen
  851. nMaxLen += nItemLen;
  852. }
  853. GetBuffer(nMaxLen);
  854. //VERIFY(_vstprintf(m_pchData, lpszFormat, argListSave) <= GetAllocLength());
  855. _vstprintf(m_pchData, lpszFormat, argListSave);
  856. ReleaseBuffer();
  857. va_end(argListSave);
  858. }
  859. void BString::Format(LPBTSTR lpszFormat, ...)
  860. {
  861. assert(AfxIsValidString(lpszFormat));
  862. va_list argList;
  863. va_start(argList, lpszFormat);
  864. FormatV(lpszFormat, argList);
  865. va_end(argList);
  866. }
  867. void BString::ConcatCopy(int nSrc1Len, LPBTSTR lpszSrc1Data,int nSrc2Len, LPBTSTR lpszSrc2Data)
  868. {
  869. int nNewLen = nSrc1Len + nSrc2Len;
  870. if (nNewLen != 0)
  871. {
  872. AllocBuffer(nNewLen);
  873. memcpy(m_pchData, lpszSrc1Data, nSrc1Len*sizeof(BYTE));
  874. memcpy(m_pchData+nSrc1Len, lpszSrc2Data, nSrc2Len*sizeof(BYTE));
  875. }
  876. }
  877. void BString::ConcatInPlace(int nSrcLen, LPBTSTR lpszSrcData)
  878. {
  879. if (nSrcLen == 0)
  880. return;
  881. if (GetData()->nRefs > 1 GetData()->nDataLength + nSrcLen > GetData()->nAllocLength)
  882. {//动态分配
  883. BStringData* pOldData = GetData();
  884. ConcatCopy(GetData()->nDataLength, m_pchData, nSrcLen, lpszSrcData);
  885. assert(pOldData != NULL);
  886. BString::Release(pOldData);
  887. }
  888. else
  889. {//直接往后添加
  890. memcpy(m_pchData+GetData()->nDataLength, lpszSrcData, nSrcLen*sizeof(BYTE));
  891. GetData()->nDataLength += nSrcLen;
  892. assert(GetData()->nDataLength <= GetData()->nAllocLength);
  893. m_pchData[GetData()->nDataLength] = '\0';
  894. }
  895. }
  896. const BString& BString::operator+=(LPBTSTR lpsz)
  897. {
  898. assert(lpsz == NULL AfxIsValidString(lpsz));
  899. ConcatInPlace(SafeStrlen(lpsz), lpsz);
  900. return *this;
  901. }
  902. const BString& BString::operator+=(BYTE ch)
  903. {
  904. ConcatInPlace(1, &ch);
  905. return *this;
  906. }
  907. const BString& BString::operator+=(const BString& string)
  908. {
  909. ConcatInPlace(string.GetData()->nDataLength, string.m_pchData);
  910. return *this;
  911. }
  912. LPTSTR BString::GetBuffer(int nMinBufLength)
  913. {
  914. assert(nMinBufLength >= 0);
  915. if (GetData()->nRefs > 1 nMinBufLength > GetData()->nAllocLength)
  916. { //重新动态分配
  917. BStringData* pOldData = GetData();
  918. int nOldLen = GetData()->nDataLength; // AllocBuffer will tromp it
  919. if (nMinBufLength < nOldLen)
  920. nMinBufLength = nOldLen;
  921. AllocBuffer(nMinBufLength);
  922. memcpy(m_pchData, pOldData->data(), (nOldLen+1)*sizeof(BYTE));
  923. GetData()->nDataLength = nOldLen;
  924. BString::Release(pOldData);
  925. }
  926. assert(GetData()->nRefs <= 1);
  927. assert(m_pchData != NULL);
  928. return m_pchData;
  929. }
  930. void BString::ReleaseBuffer(int nNewLength)
  931. {
  932. CopyBeforeWrite(); //脱离共享数据块,
  933. if (nNewLength == -1)
  934. nNewLength = lstrlen(m_pchData); // zero terminated
  935. assert(nNewLength <= GetData()->nAllocLength);
  936. GetData()->nDataLength = nNewLength;
  937. m_pchData[nNewLength] = '\0';
  938. }
  939. LPTSTR BString::GetBufferSetLength(int nNewLength)
  940. {
  941. assert(nNewLength >= 0);
  942. GetBuffer(nNewLength);
  943. GetData()->nDataLength = nNewLength;
  944. m_pchData[nNewLength] = '\0';
  945. return m_pchData;
  946. }
  947. void BString::FreeExtra()
  948. {
  949. assert(GetData()->nDataLength <= GetData()->nAllocLength);
  950. if (GetData()->nDataLength != GetData()->nAllocLength)
  951. {
  952. BStringData* pOldData = GetData();
  953. AllocBuffer(GetData()->nDataLength);
  954. memcpy(m_pchData, pOldData->data(), pOldData->nDataLength*sizeof(BYTE));
  955. assert(m_pchData[GetData()->nDataLength] == '\0');
  956. BString::Release(pOldData);
  957. }
  958. assert(GetData() != NULL);
  959. }
  960. LPTSTR BString::LockBuffer()
  961. {
  962. LPTSTR lpsz = GetBuffer(0);
  963. GetData()->nRefs = -1;
  964. return lpsz;
  965. }
  966. void BString::UnlockBuffer()
  967. {
  968. assert(GetData()->nRefs == -1);
  969. if (GetData() != _afxDataNil)
  970. GetData()->nRefs = 1;
  971. }
  972. int BString::Compare(LPBTSTR lpsz) const
  973. {
  974. assert(AfxIsValidString(lpsz));
  975. return _tcscmp(m_pchData, lpsz);
  976. }
  977. int BString::CompareNoCase(LPBTSTR lpsz) const
  978. {
  979. assert(AfxIsValidString(lpsz));
  980. return _tcsicmp(m_pchData, lpsz);
  981. }
  982. // BString::Collate is often slower than Compare but is MBSC/Unicode
  983. // aware as well as locale-sensitive with respect to sort order.
  984. int BString::Collate(LPBTSTR lpsz) const
  985. {
  986. assert(AfxIsValidString(lpsz));
  987. return _tcscoll(m_pchData, lpsz);
  988. }
  989. int BString::CollateNoCase(LPBTSTR lpsz) const
  990. {
  991. assert(AfxIsValidString(lpsz));
  992. return _tcsicoll(m_pchData, lpsz);
  993. }
  994. TCHAR BString::GetAt(int nIndex) const
  995. {
  996. assert(nIndex >= 0);
  997. assert(nIndex < GetData()->nDataLength);
  998. return m_pchData[nIndex];
  999. }
  1000. TCHAR BString::operator[](int nIndex) const
  1001. {
  1002. assert(nIndex >= 0);
  1003. assert(nIndex < GetData()->nDataLength);
  1004. return m_pchData[nIndex];
  1005. }
  1006. ////////////////////////////////////////////////////////////////////////////////
  1007. BString operator+(const BString& string1, const BString& string2)
  1008. {
  1009. BString s;
  1010. s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData,
  1011. string2.GetData()->nDataLength, string2.m_pchData);
  1012. return s;
  1013. }
  1014. BString operator+(const BString& string, LPBTSTR lpsz)
  1015. {
  1016. assert(lpsz == NULL AfxIsValidString(lpsz));
  1017. BString s;
  1018. s.ConcatCopy(string.GetData()->nDataLength, string.m_pchData,
  1019. BString::SafeStrlen(lpsz), lpsz);
  1020. return s;
  1021. }
  1022. BString operator+(LPBTSTR lpsz, const BString& string)
  1023. {
  1024. assert(lpsz == NULL AfxIsValidString(lpsz));
  1025. BString s;
  1026. s.ConcatCopy(BString::SafeStrlen(lpsz), lpsz, string.GetData()->nDataLength,
  1027. string.m_pchData);
  1028. return s;
  1029. }
  1030. bool operator==(const BString& s1, const BString& s2)
  1031. { return s1.Compare(s2) == 0; }
  1032. bool operator==(const BString& s1, LPBTSTR s2)
  1033. { return s1.Compare(s2) == 0; }
  1034. bool operator==(LPBTSTR s1, const BString& s2)
  1035. { return s2.Compare(s1) == 0; }
  1036. bool operator!=(const BString& s1, const BString& s2)
  1037. { return s1.Compare(s2) != 0; }
  1038. bool operator!=(const BString& s1, LPBTSTR s2)
  1039. { return s1.Compare(s2) != 0; }
  1040. bool operator!=(LPBTSTR s1, const BString& s2)
  1041. { return s2.Compare(s1) != 0; }
  1042. bool operator<(const BString& s1, const BString& s2)
  1043. { return s1.Compare(s2) < 0; }
  1044. bool operator<(const BString& s1, LPBTSTR s2)
  1045. { return s1.Compare(s2) < 0; }
  1046. bool operator<(LPBTSTR s1, const BString& s2)
  1047. { return s2.Compare(s1) > 0; }
  1048. bool operator>(const BString& s1, const BString& s2)
  1049. { return s1.Compare(s2) > 0; }
  1050. bool operator>(const BString& s1, LPBTSTR s2)
  1051. { return s1.Compare(s2) > 0; }
  1052. bool operator>(LPBTSTR s1, const BString& s2)
  1053. { return s2.Compare(s1) < 0; }
  1054. bool operator<=(const BString& s1, const BString& s2)
  1055. { return s1.Compare(s2) <= 0; }
  1056. bool operator<=(const BString& s1, LPBTSTR s2)
  1057. { return s1.Compare(s2) <= 0; }
  1058. bool operator<=(LPBTSTR s1, const BString& s2)
  1059. { return s2.Compare(s1) >= 0; }
  1060. bool operator>=(const BString& s1, const BString& s2)
  1061. { return s1.Compare(s2) >= 0; }
  1062. bool operator>=(const BString& s1, LPBTSTR s2)
  1063. { return s1.Compare(s2) >= 0; }
  1064. bool operator>=(LPBTSTR s1, const BString& s2)
  1065. { return s2.Compare(s1) <= 0; }
  1066. ////////////////////////////////////////////////////////////////////////////////
  1067. void ConstructElements(BString* pElements, int nCount)
  1068. {
  1069. assert(nCount == 0
  1070. AfxIsValidAddress(pElements, nCount * sizeof(BString)));
  1071. for (; nCount--; ++pElements)
  1072. memcpy(pElements, &AfxGetEmptyString(), sizeof(*pElements));
  1073. }
  1074. void DestructElements(BString* pElements, int nCount)
  1075. {
  1076. assert(nCount == 0
  1077. AfxIsValidAddress(pElements, nCount * sizeof(BString)));
  1078. for (; nCount--; ++pElements)
  1079. pElements->~BString();
  1080. }
  1081. void CopyElements(BString* pDest, const BString* pSrc, int nCount)
  1082. {
  1083. assert(nCount == 0
  1084. AfxIsValidAddress(pDest, nCount * sizeof(BString)));
  1085. assert(nCount == 0
  1086. AfxIsValidAddress(pSrc, nCount * sizeof(BString)));
  1087. for (; nCount--; ++pDest, ++pSrc)
  1088. *pDest = *pSrc;
  1089. }