比这篇新的文章: 一些工具模板函数
比这篇旧的文章: Codee#2518

一个引用计数实现的字符串类kstring

语言: C++, 标签: 引用计数 字符串 2009/06/28发布 7个月前更新 更新记录
作者: doorfly, 点击269次, 评论(2), 收藏者(0), , 打分:

背景
主题: 字体:
0001 //
0002 //rights reserved by bob kang
0003 //
0004 // kstring.h
0005 //
0006
0007 #include <stdio.h>
0008
0009 class kstring   
0010 {
0011 protected:
0012     class kstringData
0013     {
0014     public:
0015         kstringData(int nMaxLen);
0016         kstringData(long nMaxLen);
0017         kstringData(wchar_t *pszData,int nLen);
0018         void AddRef();
0019         void Release();
0020         long getRef()
0021         {
0022             return _nRef;
0023         }
0024         long getMemLen()
0025         {
0026             return _nMaxLen;
0027         }
0028
0029         //属性设为public,允许kstring直接访问
0030         long _nLen;       
0031         wchar_t *_szV;
0032     protected:
0033         ~kstringData()//不允许调用该函数
0034         {
0035             if(_szV != NULL)
0036                 delete []_szV;
0037         }
0038     private:
0039         long _nMaxLen;//实际允许的最大字节数,\0的字节数不计算在其中
0040         long _nRef;
0041     };
0042 public:
0043    
0044     //构造与析构函数
0045     kstring(const char *p = NULL);
0046     kstring(const wchar_t *p);
0047     kstring(const char *p,int nLen);
0048     kstring(const wchar_t *p,int nLen);
0049     kstring(const kstring& old);
0050     kstring(int nReservedLen);
0051     virtual ~kstring(void);
0052    
0053
0054     //运算符重载函数
0055     kstring& operator=(const char *p);
0056     kstring& operator=(const wchar_t *p);
0057     kstring& operator=(const kstring & rhv);
0058
0059     friend kstring operator+ (const kstring &lhv,wchar_t ch);
0060     friend kstring operator+ (wchar_t ch,const kstring &rhv);
0061     friend kstring operator+(const kstring &lhv,const kstring &rhv);
0062
0063     kstring& operator+= (wchar_t ch);
0064     kstring& operator+=(const char *p);
0065     kstring& operator+=(const wchar_t *p);
0066     kstring& operator+=(const kstring & rhv);
0067
0068     long compare(const wchar_t *p) const;
0069     long compare(const kstring &rhv) const;
0070
0071     long compare(const wchar_t *p,long nLen) const;
0072     long compare(const kstring &rhv,long nLen) const;
0073
0074     long compareNoCase(const wchar_t *p) const;
0075     long compareNoCase(const kstring &rhv) const;
0076
0077     operator wchar_t*();
0078     operator const wchar_t*() const;
0079     operator char*();
0080     operator const char*() const;
0081
0082     wchar_t& operator[](int nPos);
0083     wchar_t& operator[](long nPos)
0084     {
0085         return operator[]((int)nPos);
0086     }
0087     wchar_t operator[](int nPos) const;
0088     wchar_t operator[](long nPos) const
0089     {
0090         return operator[]((int)nPos);
0091     }
0092
0093     wchar_t *getCopyBuf() const;//拷贝函数,返回值需用delete释放内存
0094     long getLength() const;
0095
0096     //与数据类型相关的函数
0097
0098     //对字符串进行简单处理的函数
0099     void trim();//去掉头尾的空白符\r,\n,空格,\t
0100     void trimLeft();//去掉头的空白符\r,\n,空格,\t
0101     void trimRight();//去掉尾的空白符\r,\n,空格,\t
0102     void replace(const kstring strOld,const kstring &strNew);
0103     kstring &format(const wchar_t *pszFormat,...);
0104
0105     kstring sub(long nStart) const;
0106     kstring sub(long nStart,long nLen) const;
0107     long find(wchar_t ch,long nStart = 0) const;
0108     long find(const wchar_t *p,long nStart=0) const;
0109     long find(const kstring& strTag,long nStart=0) const;
0110     long beginWith(const wchar_t *p,long nStart = 0) const;//是否以指定标记开头,并返回匹配长度
0111     long beginWith(const kstring & strTag,long nStart = 0) const;//是否以指定标记开头,并返回匹配长度
0112     long lastIndexOf(wchar_t ch) const;
0113     //对字符串进行编码的函数
0114     static kstring attach(wchar_t *p);
0115     static kstring attach(wchar_t *p,int nLen);
0116
0117     char *toUtf8();
0118 protected:
0119     void formatV(const wchar_t *lpszFormat, va_list argList);
0120     static kstringData* allocBuf(long nLen);
0121     void clearMBCSBuf();
0122    
0123 private:
0124     kstringData *m_pStr;
0125     char *m_pMBCSStr;//用于缓冲某些计算的中间结果,提供释放的安全保护功能,字符串更新时,必须将其置为NULL   
0126 };
0127 kstring operator+ (const kstring &lhv,wchar_t ch);
0128 kstring operator+ (wchar_t ch,const kstring &rhv);
0129 kstring operator+(const kstring &lhv,const kstring &rhv);
0130
0131 bool operator==(const char *lhv,const kstring &rhv);
0132 bool operator==(const kstring &lhv,const char *rhv);
0133 bool operator==(const wchar_t *lhv,const kstring &rhv);
0134 bool operator==(const kstring &lhv,const wchar_t  *rhv);
0135 bool operator==(const kstring &lhv,const kstring &rhv);
0136
0137 bool operator!=(const char *lhv,const kstring &rhv);
0138 bool operator!=(const kstring &lhv,const char *rhv);
0139 bool operator!=(const wchar_t *lhv,const kstring &rhv);
0140 bool operator!=(const kstring &lhv,const wchar_t  *rhv);
0141 bool operator!=(const kstring &lhv,const kstring &rhv);
0142
0143 bool operator>(const char *lhv,const kstring &rhv);
0144 bool operator>(const kstring &lhv,const char *rhv);
0145 bool operator>(const wchar_t *lhv,const kstring &rhv);
0146 bool operator>(const kstring &lhv,const wchar_t  *rhv);
0147 bool operator>(const kstring &lhv,const kstring &rhv);
0148
0149 bool operator<(const char *lhv,const kstring &rhv);
0150 bool operator<(const kstring &lhv,const char *rhv);
0151 bool operator<(const wchar_t *lhv,const kstring &rhv);
0152 bool operator<(const kstring &lhv,const wchar_t  *rhv);
0153 bool operator<(const kstring &lhv,const kstring &rhv);
0154
0155
0156
0157
0158 ///////////////////////////////////////////////////////////////////////////////////////
0159 //
0160 //kstring.cpp
0161 //
0162 //
0163 #include "stdafx.h"
0164
0165 #include <stdlib.h>
0166 #include <string.h>
0167 #include <malloc.h>
0168 #include <stdio.h>
0169
0170 #include "kstring.h"
0171
0172
0173 #define FORCE_ANSI      0x10000
0174 #define FORCE_UNICODE   0x20000
0175 #define FORCE_INT64     0x40000
0176
0177 #define TCHAR_ARG   TCHAR
0178 #define WCHAR_ARG   WCHAR
0179 #define CHAR_ARG    char
0180 #ifdef _X86_
0181     #define DOUBLE_ARG  double/*_AFX_DOUBLE*/
0182 #else
0183     #define DOUBLE_ARG  double
0184 #endif
0185
0186
0187 /****************************************************************************
0188 *内部类的函数实现
0189 ****************************************************************************/
0190 kstring::kstringData::kstringData(int nMaxLen)
0191 {
0192     _nLen = 0;
0193     _nMaxLen = nMaxLen;//实际允许的最大字节数,\0的字节数不计算在其中
0194     _nRef = 1;
0195     _szV = new wchar_t[nMaxLen+1];
0196     _szV[0] = L'\0';
0197 }
0198 kstring::kstringData::kstringData(long nMaxLen)
0199 {
0200     _nLen = 0;
0201     _nMaxLen = nMaxLen;//实际允许的最大字节数,\0的字节数不计算在其中
0202     _nRef = 1;
0203     _szV = new wchar_t[nMaxLen+1];
0204     _szV[0] = L'\0';
0205 }
0206 kstring::kstringData::kstringData(wchar_t *pszData,int nLen)
0207 {
0208     _nLen = nLen;
0209     _nMaxLen = _nLen;//实际允许的最大字节数,\0的字节数不计算在其中
0210     _nRef = 1;
0211     _szV = pszData;
0212 }
0213 void kstring::kstringData::AddRef()
0214 {
0215     //++_nRef;
0216     InterlockedIncrement(&_nRef);
0217 }
0218 void kstring::kstringData::Release()
0219 {
0220     //--_nRef;
0221     InterlockedDecrement(&_nRef);
0222     if(_nRef == 0)
0223         delete this;
0224 }
0225 /****************************************************************************
0226 *接口函数
0227 ****************************************************************************/
0228 //构造与析构函数
0229 kstring::kstring(const char *p):m_pMBCSStr(NULL)
0230 {
0231     if(p == NULL)
0232     {
0233         m_pStr = allocBuf(0);
0234         m_pStr->_szV[0] = L'\0';
0235     }
0236     else
0237     {
0238         long nLen = strlen(p);
0239         long nNeed = MultiByteToWideChar(CP_ACP,0,p,nLen,NULL,0);
0240         m_pStr = allocBuf(nNeed);
0241         MultiByteToWideChar(CP_ACP,0,p,nLen,m_pStr->_szV,nNeed);
0242         m_pStr->_szV[nNeed] = L'\0';
0243     }
0244 }
0245 kstring::kstring(const wchar_t *p):m_pMBCSStr(NULL)
0246 {
0247     if(p ==NULL)
0248     {
0249         m_pStr = allocBuf(0);
0250         m_pStr->_szV[0] = L'\0';
0251     }
0252     else
0253     {
0254         long nLen = wcslen(p);
0255         m_pStr = allocBuf(nLen);
0256         wcscpy(m_pStr->_szV,p);
0257     }
0258 }
0259 kstring::kstring(const char *p,int nLen):m_pMBCSStr(NULL)
0260 {
0261     ASSERT(p != NULL);
0262     long nNeed = MultiByteToWideChar(CP_ACP,0,p,nLen,NULL,0);
0263     m_pStr = allocBuf(nNeed);
0264     MultiByteToWideChar(CP_ACP,0,p,nLen,m_pStr->_szV,nNeed);
0265     m_pStr->_szV[nNeed] = L'\0';
0266 }
0267 kstring::kstring(const wchar_t *p,int nLen):m_pMBCSStr(NULL)
0268 {
0269     ASSERT(p != NULL);
0270     m_pStr = allocBuf(nLen);
0271     wcsncpy(m_pStr->_szV,p,nLen);
0272     m_pStr->_szV[nLen] = L'\0';
0273 }
0274
0275 kstring::kstring(const kstring& old):m_pMBCSStr(NULL)
0276 {
0277     ASSERT(old.m_pStr != NULL);
0278     m_pStr = old.m_pStr;
0279     m_pStr->AddRef();
0280 }
0281 kstring::kstring(int nReservedLen):m_pMBCSStr(NULL)
0282 {
0283     m_pStr = new kstringData(nReservedLen);
0284 }
0285 kstring::~kstring(void)
0286 {
0287     m_pStr->Release();
0288     clearMBCSBuf();
0289 }
0290
0291 //=号重载函数
0292 kstring& kstring::operator=(const char *p)
0293 {
0294     ASSERT(p != NULL);
0295     clearMBCSBuf();
0296
0297     long nLen = strlen(p);
0298     long nNeed = MultiByteToWideChar(CP_ACP,0,p,nLen,NULL,0);
0299     if(m_pStr->getRef() == 1 && nNeed <= m_pStr->getMemLen())
0300     {       
0301         MultiByteToWideChar(CP_ACP,0,p,nLen,m_pStr->_szV,nNeed);
0302         m_pStr->_szV[nNeed] = L'\0';
0303         m_pStr->_nLen = nNeed;
0304     }
0305     else
0306     {
0307         m_pStr->Release();
0308         m_pStr = allocBuf(nNeed);
0309         MultiByteToWideChar(CP_ACP,0,p,nLen,m_pStr->_szV,nNeed);
0310         m_pStr->_szV[nNeed] = L'\0';
0311     }
0312     return *this;
0313 }
0314 kstring& kstring::operator=(const wchar_t *p)
0315 {
0316     ASSERT(p != NULL);
0317     clearMBCSBuf();
0318     long nLen = wcslen(p);
0319     if(m_pStr->getRef() == 1 && nLen <= m_pStr->getMemLen())
0320     {
0321         wcscpy(m_pStr->_szV,p);
0322         m_pStr->_nLen = nLen;
0323     }
0324     else
0325     {
0326         m_pStr->Release();
0327         m_pStr = allocBuf(nLen);
0328         wcscpy(m_pStr->_szV,p);
0329     }
0330     return *this;
0331 }
0332 kstring& kstring::operator=(const kstring & rhv)
0333 {   
0334     if(this == &rhv)
0335         return *this;
0336
0337     ASSERT(rhv.m_pStr != NULL);
0338     clearMBCSBuf();
0339     m_pStr->Release();
0340    
0341     m_pStr = rhv.m_pStr;
0342     m_pStr->AddRef();
0343
0344     return *this;
0345 }
0346 //+号重载函数
0347 kstring operator+ (const kstring &lhv,wchar_t ch)
0348 {
0349     if(ch == L'\0')
0350         return lhv;
0351
0352     long nNeed = 1;
0353     long nTotal = nNeed+lhv.getLength();
0354
0355     kstring strRet(nTotal);
0356     wcscpy(strRet.m_pStr->_szV,(const wchar_t *)lhv);
0357     strRet.m_pStr->_szV[lhv.getLength()] = ch;
0358     strRet.m_pStr->_szV[nTotal] = L'\0';
0359     strRet.m_pStr->_nLen = nTotal;   
0360     return strRet;
0361 }
0362 kstring operator+ (wchar_t ch,const kstring &rhv)
0363 {
0364     if(ch == L'\0')
0365         return rhv;
0366     long nNeed = 1;
0367     long nTotal = nNeed+rhv.getLength();
0368
0369     kstring strRet(nTotal);
0370     strRet.m_pStr->_szV[0] = ch;
0371     wcscpy(strRet.m_pStr->_szV+1,(const wchar_t *)rhv);
0372     strRet.m_pStr->_nLen = nTotal;   
0373     return strRet;
0374 }
0375 kstring operator+(const kstring &lhv,const kstring &rhv)
0376 {
0377     ASSERT(lhv.m_pStr != NULL && rhv.m_pStr != NULL);
0378
0379     long nTotal = lhv.getLength()+rhv.getLength();
0380     kstring strRet(nTotal);
0381     wcscpy(strRet.m_pStr->_szV,(const wchar_t *)lhv);
0382     wcscpy(strRet.m_pStr->_szV+lhv.getLength(),(const wchar_t *)rhv);
0383     strRet.m_pStr->_nLen = nTotal;
0384
0385     return strRet;
0386 }
0387
0388 //+=号重载函数
0389 kstring& kstring::operator+= (wchar_t ch)
0390 {
0391     if(ch == L'\0')//如果是字符串结事符,直接返回
0392         return *this;
0393
0394     clearMBCSBuf();
0395
0396     long nNeed = 1;
0397     long nTotal = nNeed+m_pStr->_nLen;
0398
0399     if(m_pStr->getRef() == 1 && nTotal <= m_pStr->getMemLen())
0400     {
0401         m_pStr->_szV[m_pStr->_nLen] = ch;
0402         m_pStr->_szV[nTotal] = L'\0';
0403         m_pStr->_nLen = nTotal;
0404     }
0405     else
0406     {
0407         kstringData *pStr = allocBuf(nTotal);
0408         wcscpy(pStr->_szV,m_pStr->_szV);
0409         pStr->_szV[m_pStr->_nLen] = ch;
0410         pStr->_szV[nTotal] = L'\0';
0411         m_pStr->Release();
0412         m_pStr = pStr;
0413     }
0414     return *this;
0415 }
0416
0417 kstring& kstring::operator+=(const char *p)
0418 {
0419     ASSERT(p != NULL);
0420     clearMBCSBuf();
0421
0422     long nLen = strlen(p);
0423     long nNeed = MultiByteToWideChar(CP_ACP,0,p,nLen,NULL,0);
0424     long nTotal = nNeed+m_pStr->_nLen;
0425
0426     if(m_pStr->getRef() == 1 && nTotal <= m_pStr->getMemLen())
0427     {
0428         MultiByteToWideChar(CP_ACP,0,p,nLen,m_pStr->_szV+m_pStr->_nLen,nNeed);
0429         m_pStr->_szV[nTotal] = L'\0';
0430         m_pStr->_nLen = nTotal;
0431     }
0432     else
0433     {
0434         kstringData *pStr = allocBuf(nTotal);
0435         wcscpy(pStr->_szV,m_pStr->_szV);
0436         MultiByteToWideChar(CP_ACP,0,p,nLen,pStr->_szV+m_pStr->_nLen,nNeed);
0437         pStr->_szV[nTotal] = L'\0';
0438         m_pStr->Release();
0439         m_pStr = pStr;
0440     }
0441     return *this;
0442 }
0443
0444 kstring& kstring::operator+=(const wchar_t *p)
0445 {
0446     ASSERT(p != NULL);
0447     clearMBCSBuf();
0448
0449     long nNeed = wcslen(p);
0450     long nTotal = nNeed+m_pStr->_nLen;
0451
0452     if(m_pStr->getRef() == 1 && nTotal <= m_pStr->getMemLen())
0453     {
0454         wcscpy(m_pStr->_szV+m_pStr->_nLen,p);
0455         m_pStr->_nLen = nTotal;
0456     }
0457     else
0458     {
0459         kstringData *pStr = allocBuf(nTotal);
0460         wcscpy(pStr->_szV,m_pStr->_szV);
0461         wcscpy(pStr->_szV+m_pStr->_nLen,p);
0462         m_pStr->Release();
0463         m_pStr = pStr;
0464     }
0465     return *this;
0466 }
0467 kstring& kstring::operator+=(const kstring & rhv)
0468 {
0469     ASSERT(rhv.m_pStr != NULL);
0470     clearMBCSBuf();
0471
0472     long nTotal = m_pStr->_nLen+rhv.m_pStr->_nLen;;
0473
0474     if(m_pStr->getRef() == 1 && nTotal <= m_pStr->getMemLen())
0475     {
0476         wcsncpy(m_pStr->_szV+m_pStr->_nLen,rhv.m_pStr->_szV,rhv.m_pStr->_nLen);//避免加等自已造成的结束标记被覆盖的问题
0477         m_pStr->_szV[nTotal] = L'\0';
0478         m_pStr->_nLen = nTotal;
0479     }
0480     else
0481     {
0482         kstringData *pStr = allocBuf(nTotal);
0483         wcscpy(pStr->_szV,m_pStr->_szV);
0484         wcscpy(pStr->_szV+m_pStr->_nLen,rhv.m_pStr->_szV);
0485         m_pStr->Release();
0486         m_pStr = pStr;
0487     }
0488     return *this;
0489 }
0490
0491 //比较函数:0:相等,<0:小于,>0:大于
0492 long kstring::compare(const wchar_t *p) const
0493 {
0494     ASSERT(p != NULL);
0495     return wcscmp(m_pStr->_szV,p);
0496 }
0497 long kstring::compare(const kstring &rhv) const
0498 {
0499     return wcscmp(m_pStr->_szV,rhv.m_pStr->_szV);
0500 }
0501
0502 long kstring::compare(const wchar_t *p,long nLen) const
0503 {
0504     ASSERT(p != NULL);
0505     return wcsncmp(m_pStr->_szV,p,nLen);
0506 }
0507 long kstring::compare(const kstring &rhv,long nLen) const
0508 {
0509     return wcsncmp(m_pStr->_szV,rhv.m_pStr->_szV,nLen);
0510 }
0511
0512 long kstring::compareNoCase(const wchar_t *p) const
0513 {
0514     ASSERT(p != NULL);
0515     return wcsicmp(m_pStr->_szV,p);
0516 }
0517 long kstring::compareNoCase(const kstring &rhv) const
0518 {
0519     return wcsicmp(m_pStr->_szV,rhv.m_pStr->_szV);
0520 }
0521
0522 //强制转换重载函数
0523 kstring::operator wchar_t*()
0524 {
0525     return m_pStr->_szV;
0526 }
0527 kstring::operator const wchar_t*() const
0528 {
0529     return m_pStr->_szV;
0530 }
0531 kstring::operator char*()
0532 {
0533     if(m_pMBCSStr == NULL)
0534     {
0535         //进行转换
0536         int nLen = WideCharToMultiByte(CP_ACP,0,m_pStr->_szV,m_pStr->_nLen,NULL,0,NULL,NULL);
0537         m_pMBCSStr = new char[nLen+1];
0538         WideCharToMultiByte(CP_ACP,0,m_pStr->_szV,m_pStr->_nLen,m_pMBCSStr,nLen,NULL,NULL);
0539         m_pMBCSStr[nLen] = '\0';
0540     }
0541     return m_pMBCSStr;
0542 }
0543 kstring::operator const char*() const
0544 {
0545     char **pMid = (char **)&m_pMBCSStr;
0546     if(m_pMBCSStr == NULL)
0547     {
0548         //进行转换
0549         int nLen = WideCharToMultiByte(CP_ACP,0,m_pStr->_szV,m_pStr->_nLen,NULL,0,NULL,NULL);
0550         *pMid = new char[nLen+1];
0551         WideCharToMultiByte(CP_ACP,0,m_pStr->_szV,m_pStr->_nLen,*pMid,nLen,NULL,NULL);
0552         (*pMid)[nLen] = '\0';
0553     }
0554     return m_pMBCSStr;
0555 }
0556
0557
0558
0559 wchar_t& kstring::operator[](int nPos)
0560 {
0561     if(nPos <0 || nPos>m_pStr->_nLen)
0562         throw "out of range";
0563     return m_pStr->_szV[nPos];
0564 }
0565
0566 wchar_t kstring::operator[](int nPos) const
0567 {
0568     if(nPos <0 || nPos>m_pStr->_nLen)
0569         throw "out of range";
0570     return m_pStr->_szV[nPos];
0571 }
0572 //属性获取函数
0573 wchar_t *kstring::getCopyBuf() const//拷贝函数,返回值需用delete释放内存
0574 {
0575     wchar_t* pRet = new wchar_t[m_pStr->_nLen+1];
0576     wcscpy(pRet,m_pStr->_szV);
0577     return pRet;
0578 }
0579 long kstring::getLength() const
0580 {
0581     return m_pStr->_nLen;
0582 }
0583 //对字符串进行简单处理的函数
0584 void kstring::trim()//去掉头尾的空白符\r,\n,空格,\t
0585 {
0586     trimRight();
0587     trimLeft();
0588 }
0589 void kstring::trimLeft()//去掉头的空白符\r,\n,空格,\t
0590 {
0591     long nStart = 0;
0592     while(m_pStr->_szV[nStart] != L'\0')
0593     {
0594         if(m_pStr->_szV[nStart] != L'\r' &&
0595         m_pStr->_szV[nStart] != L'\n' &&
0596         m_pStr->_szV[nStart] != L'\t' &&
0597         m_pStr->_szV[nStart] != L' ')
0598         {
0599             break;
0600         }
0601         nStart++;
0602     }
0603     if(nStart <= 0)//前面没有空白,直接返回
0604         return;
0605     clearMBCSBuf();
0606
0607     long nRest = m_pStr->_nLen-nStart;
0608     if(m_pStr->getRef() == 1)//直接去空白符
0609     {       
0610         m_pStr->_nLen = nRest;
0611         wcscpy(m_pStr->_szV,m_pStr->_szV+nStart);
0612     }
0613     else
0614     {
0615         kstringData *pStr = allocBuf(nRest);
0616         wcscpy(pStr->_szV,m_pStr->_szV+nStart);
0617         m_pStr->Release();
0618         m_pStr = pStr;
0619     }
0620 }
0621 void kstring::trimRight()//去掉尾的空白符\r,\n,空格,\t
0622 {
0623     long nLast = m_pStr->_nLen-1;
0624     while(nLast >= 0)
0625     {
0626         if(m_pStr->_szV[nLast] != L'\r' &&
0627         m_pStr->_szV[nLast] != L'\n' &&
0628         m_pStr->_szV[nLast] != L'\t' &&
0629         m_pStr->_szV[nLast] != L' ')
0630         {
0631             break;
0632         }
0633         nLast--;
0634     }
0635     if(nLast >= m_pStr->_nLen-1)//后面没有空白,直接返回
0636         return;
0637     clearMBCSBuf();
0638     long nRest = nLast+1;
0639     if(m_pStr->getRef() == 1)//直接去空白符
0640     {       
0641         m_pStr->_nLen = nRest;
0642         m_pStr->_szV[nRest] = L'\0';
0643     }
0644     else//重新拷贝一份数据
0645     {
0646         kstringData *pStr = allocBuf(nRest);
0647         wcsncpy(pStr->_szV,m_pStr->_szV,nRest);
0648         pStr->_szV[nRest] = L'\0';
0649         m_pStr->Release();
0650         m_pStr = pStr;
0651     }
0652 }
0653
0654 void kstring::replace(const kstring strOld,const kstring &strNew)
0655 {
0656     int nPos = find(strOld);
0657     if(nPos < 0)
0658         return;
0659
0660     kstringData *pData = allocBuf(getLength()+strNew.getLength()-strOld.getLength());
0661     wcsncpy(pData->_szV,m_pStr->_szV,nPos);
0662     wcscpy(pData->_szV+nPos,strNew);
0663     wcscpy(pData->_szV+nPos+strNew.getLength(),m_pStr->_szV+nPos+strOld.getLength());
0664     m_pStr->Release();
0665     m_pStr = pData;
0666 }
0667
0668 kstring &kstring::format(const wchar_t *pszFormat,...)
0669 {
0670     va_list argList;
0671     va_start(argList, pszFormat);
0672
0673     formatV(pszFormat, argList);
0674     va_end(argList);
0675     return *this;
0676 }
0677
0678 kstring kstring::sub(long nStart) const
0679 {   
0680     if(nStart<0 || nStart>=m_pStr->_nLen)
0681         return kstring();
0682     long nLen = m_pStr->_nLen-nStart;
0683     return m_pStr->_szV+nStart;
0684 }
0685 kstring kstring::sub(long nStart,long nLen) const
0686 {
0687     if(nStart<0 || nStart>=m_pStr->_nLen || nLen<=0)
0688         return kstring();
0689     if(nStart+nLen>m_pStr->_nLen)
0690         nLen = m_pStr->_nLen - nStart;
0691     if(nLen <= 0)
0692         return kstring();
0693
0694     kstring strRet;
0695     if(strRet.m_pStr->getMemLen() >= nLen)
0696     {
0697         wcsncpy(strRet.m_pStr->_szV,m_pStr->_szV+nStart,nLen);
0698         strRet.m_pStr->_szV[nLen] = L'\0';
0699         strRet.m_pStr->_nLen = nLen;
0700     }
0701     else
0702     {
0703         strRet.m_pStr->Release();
0704         strRet.m_pStr = allocBuf(nLen);
0705         wcsncpy(strRet.m_pStr->_szV,m_pStr->_szV+nStart,nLen);
0706         strRet.m_pStr->_szV[nLen] = L'\0';
0707     }
0708     return strRet;
0709 }
0710 long kstring::find(wchar_t ch,long nStart) const
0711 {
0712     if(nStart < 0 || nStart >= m_pStr->_nLen)
0713         return -1;
0714     const wchar_t* p = m_pStr->_szV+nStart;
0715     while(*p != L'\0')
0716     {
0717         if(*p == ch)
0718         {
0719             return p-m_pStr->_szV;
0720         }
0721         ++p;
0722     }
0723     return -1;
0724 }
0725 long kstring::find(const wchar_t *p,long nStart) const
0726 {
0727     if(nStart < 0 || nStart >= m_pStr->_nLen)
0728         return -1;
0729     wchar_t *pszRet = wcsstr(m_pStr->_szV+nStart,p);
0730     if(pszRet == NULL)
0731         return -1;
0732     return pszRet - m_pStr->_szV;
0733 }
0734 long kstring::find(const kstring& strTag,long nStart) const
0735 {
0736     return find((const wchar_t *)strTag,nStart);
0737 }
0738 long kstring::beginWith(const wchar_t *p,long nStart) const//是否以指定标记开头,并返回结束位置
0739 {
0740     if(nStart < 0 || nStart >= m_pStr->_nLen)
0741         return 0;
0742     long nLen = wcslen(p);
0743     if(wcsncmp(p,m_pStr->_szV+nStart,nLen) == 0)
0744         return nLen;
0745     else
0746         return 0;
0747 }
0748 long kstring::beginWith(const kstring & strTag,long nStart) const//是否以指定标记开头,并返回结束位置
0749 {
0750     return beginWith((const wchar_t*)strTag,nStart);
0751 }
0752 long kstring::lastIndexOf(wchar_t ch) const
0753 {
0754     for(int i=m_pStr->_nLen-1;i>=0;i--)
0755     {
0756         if(m_pStr->_szV[i] == ch)
0757             return i;
0758     }
0759     return -1;
0760 }
0761
0762 kstring kstring::attach(wchar_t *p)
0763 {
0764     kstring str;
0765     str.m_pStr->Release();
0766     str.m_pStr = new kstringData(p,wcslen(p));
0767     return str;
0768 }
0769 kstring kstring::attach(wchar_t *p,int nLen)
0770 {
0771     kstring str;
0772     str.m_pStr->Release();
0773     str.m_pStr = new kstringData(p,nLen);
0774     return str;
0775 }
0776 char *kstring::toUtf8()
0777 {
0778     int nLen = WideCharToMultiByte(CP_UTF8,0,m_pStr->_szV,m_pStr->_nLen,NULL,0,NULL,NULL);
0779     char *pBuf = new char[nLen+1];
0780     WideCharToMultiByte(CP_UTF8,0,m_pStr->_szV,m_pStr->_nLen,pBuf,nLen,NULL,NULL);
0781     pBuf[nLen] = '\0';
0782     return pBuf;
0783 }
0784 void kstring::formatV(const wchar_t *lpszFormat, va_list argList)
0785 {
0786     va_list argListSave = argList;
0787
0788     // make a guess at the maximum length of the resulting string
0789     int nMaxLen = 0;
0790     for (const wchar_t *lpsz = lpszFormat; *lpsz != L'\0'; ++lpsz)
0791     {
0792         // handle '%' character, but watch out for '%%'
0793         if (*lpsz != L'%' || *(++lpsz) == '%')
0794         {
0795             nMaxLen += 1;
0796             continue;
0797         }
0798
0799         int nItemLen = 0;
0800
0801         // handle '%' character with format
0802         int nWidth = 0;
0803         for (; *lpsz != L'\0'; ++lpsz)
0804         {
0805             // check for valid flags
0806             if (*lpsz == '#')
0807                 nMaxLen += 2;   // for '0x'
0808             else if (*lpsz == '*')
0809                 nWidth = va_arg(argList, int);
0810             else if (*lpsz == '-' || *lpsz == '+' || *lpsz == '0' ||
0811                 *lpsz == ' ')
0812                 ;
0813             else // hit non-flag character
0814                 break;
0815         }
0816         // get width and skip it
0817         if (nWidth == 0)
0818         {
0819             // width indicated by
0820             nWidth = _wtoi(lpsz);
0821             for (; *lpsz != L'\0' && iswdigit(*lpsz); lpsz++)
0822                 ;
0823         }
0824         ASSERT(nWidth >= 0);
0825
0826         int nPrecision = 0;
0827         if (*lpsz == L'.')
0828         {
0829             // skip past '.' separator (width.precision)
0830             lpsz++;
0831
0832             // get precision and skip it
0833             if (*lpsz == '*')
0834             {
0835                 nPrecision = va_arg(argList, int);
0836                 lpsz++;
0837             }
0838             else
0839             {
0840                 nPrecision = _wtoi(lpsz);
0841                 for (; *lpsz != L'\0' && iswdigit(*lpsz); lpsz++)
0842                     ;
0843             }
0844             ASSERT(nPrecision >= 0);
0845         }
0846
0847         // should be on type modifier or specifier
0848         int nModifier = 0;
0849         if (wcsncmp(lpsz, L"I64", 3) == 0)
0850         {
0851             lpsz += 3;
0852             nModifier = FORCE_INT64;
0853 #if !defined(_X86_) && !defined(_ALPHA_)
0854             // __int64 is only available on X86 and ALPHA platforms
0855             ASSERT(FALSE);
0856 #endif
0857         }
0858         else
0859         {
0860             switch (*lpsz)
0861             {
0862             // modifiers that affect size
0863             case 'h':
0864                 nModifier = FORCE_ANSI;
0865                 lpsz++;
0866                 break;
0867             case 'l':
0868                 nModifier = FORCE_UNICODE;
0869                 lpsz++;
0870                 break;
0871
0872             // modifiers that do not affect size
0873             case 'F':
0874             case 'N':
0875             case 'L':
0876                 lpsz++;
0877                 break;
0878             }
0879         }
0880
0881         // now should be on specifier
0882         switch (*lpsz | nModifier)
0883         {
0884         // single characters
0885         case 'c':
0886         case 'C':
0887             nItemLen = 2;
0888             va_arg(argList, TCHAR_ARG);
0889             break;
0890         case 'c'|FORCE_ANSI:
0891         case 'C'|FORCE_ANSI:
0892             nItemLen = 2;
0893             va_arg(argList, CHAR_ARG);
0894             break;
0895         case 'c'|FORCE_UNICODE:
0896         case 'C'|FORCE_UNICODE:
0897             nItemLen = 2;
0898             va_arg(argList, WCHAR_ARG);
0899             break;
0900
0901         // strings
0902         case 's':
0903             {
0904                 LPCWSTR pstrNextArg = va_arg(argList, LPCWSTR);
0905                 if (pstrNextArg == NULL)
0906                    nItemLen = 6;  // "(null)"
0907                 else
0908                 {
0909                    nItemLen = wcslen(pstrNextArg);
0910                    nItemLen = max(1, nItemLen);
0911                 }
0912             }
0913             break;
0914
0915         case 'S':
0916             {
0917                 LPWSTR pstrNextArg = va_arg(argList, LPWSTR);
0918                 if (pstrNextArg == NULL)
0919                    nItemLen = 6;  // "(null)"
0920                 else
0921                 {
0922                    nItemLen = wcslen(pstrNextArg);
0923                    nItemLen = max(1, nItemLen);
0924                 }
0925             }
0926             break;
0927
0928         case 's'|FORCE_ANSI:
0929         case 'S'|FORCE_ANSI:
0930             {
0931                 LPCWSTR pstrNextArg = va_arg(argList, LPCWSTR);
0932                 if (pstrNextArg == NULL)
0933                    nItemLen = 6; // "(null)"
0934                 else
0935                 {
0936                    nItemLen = wcslen(pstrNextArg);
0937                    nItemLen = max(1, nItemLen);
0938                 }
0939             }
0940             break;
0941
0942         case 's'|FORCE_UNICODE:
0943         case 'S'|FORCE_UNICODE:
0944             {
0945                 LPWSTR pstrNextArg = va_arg(argList, LPWSTR);
0946                 if (pstrNextArg == NULL)
0947                    nItemLen = 6; // "(null)"
0948                 else
0949                 {
0950                    nItemLen = wcslen(pstrNextArg);
0951                    nItemLen = max(1, nItemLen);
0952                 }
0953             }
0954             break;
0955         }
0956
0957         // adjust nItemLen for strings
0958         if (nItemLen != 0)
0959         {
0960             if (nPrecision != 0)
0961                 nItemLen = min(nItemLen, nPrecision);
0962             nItemLen = max(nItemLen, nWidth);
0963         }
0964         else
0965         {
0966             switch (*lpsz)
0967             {
0968             // integers
0969             case 'd':
0970             case 'i':
0971             case 'u':
0972             case 'x':
0973             case 'X':
0974             case 'o':
0975                 if (nModifier & FORCE_INT64)
0976                     va_arg(argList, __int64);
0977                 else
0978                     va_arg(argList, int);
0979                 nItemLen = 32;
0980                 nItemLen = max(nItemLen, nWidth+nPrecision);
0981                 break;
0982
0983             case 'e':
0984             case 'g':
0985             case 'G':
0986                 va_arg(argList, DOUBLE_ARG);
0987                 nItemLen = 128;
0988                 nItemLen = max(nItemLen, nWidth+nPrecision);
0989                 break;
0990
0991             case 'f':
0992                 {
0993                     double f;
0994                     LPWSTR pszTemp;
0995
0996                     // 312 == strlen("-1+(309 zeroes).")
0997                     // 309 zeroes == max precision of a double
0998                     // 6 == adjustment in case precision is not specified,
0999                     //   which means that the precision defaults to 6
1000                     pszTemp = (LPWSTR)_alloca(max(nWidth, 312+nPrecision+6));
1001
1002                     f = va_arg(argList, double);
1003                     swprintf( pszTemp, L"%*.*f", nWidth, nPrecision+6, f );
1004                     nItemLen = wcslen(pszTemp);
1005                 }
1006                 break;
1007
1008             case 'p':
1009                 va_arg(argList, void*);
1010                 nItemLen = 32;
1011                 nItemLen = max(nItemLen, nWidth+nPrecision);
1012                 break;
1013
1014             // no output
1015             case 'n':
1016                 va_arg(argList, int*);
1017                 break;
1018
1019             default:
1020                 ASSERT(FALSE);  // unknown formatting option
1021             }
1022         }
1023
1024         // adjust nMaxLen for output nItemLen
1025         nMaxLen += nItemLen;
1026     }
1027
1028     kstringData *pNew = allocBuf(nMaxLen);
1029     int nLen = vswprintf(pNew->_szV,lpszFormat,argListSave);
1030     pNew->_nLen = nLen;
1031
1032     m_pStr->Release();
1033     m_pStr = pNew;
1034
1035     va_end(argListSave);
1036 }
1037 /****************************************************************************
1038 *保护函数
1039 ****************************************************************************/
1040 kstring::kstringData* kstring::allocBuf(long nLen)
1041 {
1042     long nMaxLen = nLen;
1043     /*if(nMaxLen<=32)
1044         nMaxLen = 32;
1045     else if(nMaxLen<=64)
1046         nMaxLen = 128;
1047     else if(nMaxLen <= 128)
1048         nMaxLen = 256;
1049     else nMaxLen += 256;*/
1050
1051     kstringData *pData = new kstringData(nMaxLen);
1052     pData->_nLen = nLen;
1053     return pData;
1054 }
1055 void kstring::clearMBCSBuf()
1056 {
1057     if(m_pMBCSStr != NULL)
1058     {
1059         delete []m_pMBCSStr;
1060     }
1061     m_pMBCSStr = NULL;
1062 }
1063
1064 //==号重载函数
1065 bool operator==(const char *lhv,const kstring &rhv)
1066 {
1067     return operator==(kstring(lhv),rhv);
1068 }
1069 bool operator==(const kstring &lhv,const char *rhv)
1070 {
1071     return operator==(lhv,kstring(rhv));
1072 }
1073 bool operator==(const wchar_t *lhv,const kstring &rhv)
1074 {
1075     return wcscmp(lhv,(const wchar_t *)rhv) == 0;
1076 }
1077 bool operator==(const kstring &lhv,const wchar_t  *rhv)
1078 {
1079     return wcscmp((const wchar_t *)lhv,rhv) == 0;
1080 }
1081 bool operator==(const kstring &lhv,const kstring &rhv)
1082 {
1083     return wcscmp((const wchar_t *)lhv,(const wchar_t *)rhv) == 0;
1084 }
1085
1086 //!=号重载函数
1087 bool operator!=(const char *lhv,const kstring &rhv)
1088 {
1089     return operator!=(kstring(lhv),rhv);
1090 }
1091 bool operator!=(const kstring &lhv,const char *rhv)
1092 {
1093     return operator!=(lhv,kstring(rhv));
1094 }
1095 bool operator!=(const wchar_t *lhv,const kstring &rhv)
1096 {
1097     return wcscmp(lhv,(const wchar_t *)rhv)!=0;
1098 }
1099 bool operator!=(const kstring &lhv,const wchar_t  *rhv)
1100 {
1101     return wcscmp((const wchar_t *)lhv,rhv)!=0;
1102 }
1103 bool operator!=(const kstring &lhv,const kstring &rhv)
1104 {
1105     return wcscmp((const wchar_t *)lhv,(const wchar_t *)rhv)!=0;
1106 }
1107 //>号重载函数
1108 bool operator>(const char *lhv,const kstring &rhv)
1109 {
1110     return operator>(kstring(lhv),rhv);
1111 }
1112 bool operator>(const kstring &lhv,const char *rhv)
1113 {
1114     return operator>(lhv,kstring(rhv));
1115 }
1116 bool operator>(const wchar_t *lhv,const kstring &rhv)
1117 {
1118     return wcscmp(lhv,(const wchar_t *)rhv)>0;
1119 }
1120 bool operator>(const kstring &lhv,const wchar_t  *rhv)
1121 {
1122     return wcscmp((const wchar_t *)lhv,rhv)>0;
1123 }
1124 bool operator>(const kstring &lhv,const kstring &rhv)
1125 {
1126     return wcscmp((const wchar_t *)lhv,(const wchar_t *)rhv)>0;
1127 }
1128
1129 //<号重载函数
1130 bool operator<(const char *lhv,const kstring &rhv)
1131 {
1132     return operator<(kstring(lhv),rhv);
1133 }
1134 bool operator<(const kstring &lhv,const char *rhv)
1135 {
1136     return operator<(lhv,kstring(rhv));
1137 }
1138 bool operator<(const wchar_t *lhv,const kstring &rhv)
1139 {
1140     return wcscmp(lhv,(const wchar_t *)rhv)<0;
1141 }
1142 bool operator<(const kstring &lhv,const wchar_t  *rhv)
1143 {
1144     return wcscmp((const wchar_t *)lhv,rhv)<0;
1145 }
1146 bool operator<(const kstring &lhv,const kstring &rhv)
1147 {
1148     return wcscmp((const wchar_t *)lhv,(const wchar_t *)rhv)<0;
1149 }


所有评论,共2条:( 我也来说两句)

1
半瓶墨水 8个月前 回复
0
0
这么长?
2
doorfly 8个月前 回复
0
0

有些东西是弄得复杂了点~

发表评论

注册登录后再发表评论