标签:
好久没有写过程序,最近想学习下界面库的开发,基于directui的界面个人觉得还不错,像金山的源代码和duilib都是不错的。本人想结合二者做一个轻量级的界面库,同时又不依赖于常用的MFC、WTL等。在程序开发中字符串的使用是必须的,C++语音没有原生字符串,STL等标准库又多是模板类,如果开发DLL导出时就出现问题了。今天从WTL库里摘出来一个简单的字符串类,实现了基本功能,可在此基础上进行扩展。
头文件
1 struct CStringDataE 2 { 3 long nRefs; 4 int nDataLength; 5 int nAllocLength; 6 TCHAR* data() { return (TCHAR*)(this + 1); } 7 }; 8 _declspec(selectany) int rgInitData[] = { -1, 0, 0, 0 }; 9 _declspec(selectany) CStringDataE* _atltmpDataNil = (CStringDataE*)&rgInitData; 10 _declspec(selectany) LPCTSTR _atltmpPchNil = (LPCTSTR)(((BYTE*)&rgInitData) + sizeof(CStringDataE)); 11 class UI_API CUIString 12 { 13 public: 14 CUIString(void); 15 CUIString(const CUIString& stringSrc); 16 ~CUIString(void); 17 18 CUIString& operator =(const CUIString& stringSrc); 19 CUIString& operator =(TCHAR ch); 20 CUIString& operator =(LPCTSTR lpsz); 21 protected: 22 LPTSTR m_pchData; // pointer to ref counted string data 23 CStringDataE* GetData() const; 24 void Init(); 25 BOOL AllocBuffer(int nLen); 26 void AssignCopy(int nSrcLen, LPCTSTR lpszSrcData); 27 BOOL AllocBeforeWrite(int nLen); 28 void Release(); 29 static const CUIString& PASCAL _GetEmptyString(); 30 };
源文件
1 #include "stdafx.h" 2 #include "UIString.h" 3 #include "tchar.h" 4 #include "limits.h" 5 #include "assert.h" 6 CUIString::CUIString(void) 7 { 8 Init(); 9 } 10 CUIString::CUIString(const CUIString& stringSrc) 11 { 12 assert(stringSrc.GetData()->nRefs != 0); 13 if (stringSrc.GetData()->nRefs >= 0) 14 { 15 assert(stringSrc.GetData() != _atltmpDataNil); 16 m_pchData = stringSrc.m_pchData; 17 InterlockedIncrement(&GetData()->nRefs); 18 } 19 else 20 { 21 Init(); 22 *this = stringSrc.m_pchData; 23 } 24 } 25 // overloaded assignment 26 CUIString& CUIString::operator =(const CUIString& stringSrc) 27 { 28 if (m_pchData != stringSrc.m_pchData) 29 { 30 if ((GetData()->nRefs < 0 && GetData() != _atltmpDataNil) || stringSrc.GetData()->nRefs < 0) 31 { 32 // actual copy necessary since one of the strings is locked 33 AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData); 34 } 35 else 36 { 37 // can just copy references around 38 Release(); 39 assert(stringSrc.GetData() != _atltmpDataNil); 40 m_pchData = stringSrc.m_pchData; 41 InterlockedIncrement(&GetData()->nRefs); 42 } 43 } 44 return *this; 45 } 46 CUIString& CUIString::operator =(TCHAR ch) 47 { 48 assert(!_istlead(ch)); // can‘t set single lead byte 49 AssignCopy(1, &ch); 50 return *this; 51 } 52 CUIString& CUIString::operator =(LPCTSTR lpsz) 53 { 54 assert(lpsz!= NULL ); 55 AssignCopy(lstrlen(lpsz), lpsz); 56 return *this; 57 } 58 CUIString::~CUIString(void) 59 { 60 if (GetData() != _atltmpDataNil) 61 { 62 if (InterlockedDecrement(&GetData()->nRefs) <= 0) 63 delete[](BYTE*)GetData(); 64 } 65 } 66 67 void CUIString::Init() 68 { 69 m_pchData = _GetEmptyString().m_pchData; 70 } 71 72 BOOL CUIString::AllocBuffer(int nLen) 73 { 74 assert(nLen >= 0); 75 assert(nLen <= INT_MAX - 1); // max size (enough room for 1 extra) 76 if (nLen == 0) 77 { 78 Init(); 79 } 80 else 81 { 82 CStringDataE* pData = NULL; 83 assert(pData = (CStringDataE*)new BYTE[sizeof(CStringDataE) + (nLen + 1) * sizeof(TCHAR)]); 84 if (pData == NULL) 85 return FALSE; 86 pData->nRefs = 1; 87 pData->data()[nLen] = TEXT(‘\0‘); 88 pData->nDataLength = nLen; 89 pData->nAllocLength = nLen; 90 m_pchData = pData->data(); 91 } 92 return TRUE; 93 } 94 CStringDataE* CUIString::GetData() const 95 { 96 assert(m_pchData != NULL); 97 return ((CStringDataE*)m_pchData) - 1; 98 } 99 void CUIString::AssignCopy(int nSrcLen, LPCTSTR lpszSrcData) 100 { 101 if (AllocBeforeWrite(nSrcLen)) 102 { 103 memcpy(m_pchData, lpszSrcData, nSrcLen * sizeof(TCHAR));//需改动 104 //SecureHelper::memcpy_x(m_pchData, (nSrcLen + 1) * sizeof(TCHAR), lpszSrcData, nSrcLen * sizeof(TCHAR)); 105 GetData()->nDataLength = nSrcLen; 106 m_pchData[nSrcLen] = TEXT(‘\0‘); 107 } 108 } 109 110 BOOL CUIString::AllocBeforeWrite(int nLen) 111 { 112 BOOL bRet = TRUE; 113 if (GetData()->nRefs > 1 || nLen > GetData()->nAllocLength) 114 { 115 Release(); 116 bRet = AllocBuffer(nLen); 117 } 118 assert(GetData()->nRefs <= 1); 119 return bRet; 120 } 121 void CUIString::Release() 122 { 123 if (GetData() != _atltmpDataNil) 124 { 125 assert(GetData()->nRefs != 0); 126 if (InterlockedDecrement(&GetData()->nRefs) <= 0) 127 delete[](BYTE*)GetData(); 128 Init(); 129 } 130 } 131 132 const CUIString& CUIString::_GetEmptyString() 133 { 134 return *(CUIString*)&_atltmpPchNil; 135 }
欢迎吐槽
标签:
原文地址:http://www.cnblogs.com/gushandujian/p/5425428.html