diff options
Diffstat (limited to 'plugins/CommonLibs/CString.cpp')
-rw-r--r-- | plugins/CommonLibs/CString.cpp | 382 |
1 files changed, 382 insertions, 0 deletions
diff --git a/plugins/CommonLibs/CString.cpp b/plugins/CommonLibs/CString.cpp new file mode 100644 index 0000000000..87266513d0 --- /dev/null +++ b/plugins/CommonLibs/CString.cpp @@ -0,0 +1,382 @@ +/*
+ TCString.cpp - TCString class
+ Copyright (c) 2005-2008 Chervov Dmitry
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "Common.h"
+#include "CString.h"
+
+#define STR_GROWBY 64
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+
+template <class T>
+void TString<T>::Empty()
+{
+ nBufSize = 1;
+ SetAllocSize(STR_GROWBY);
+ pBuf[0] = 0;
+}
+
+
+template <class T>
+void TString<T>::Free()
+{
+// HeapFree(GetProcessHeap(), 0, pBuf);
+ free(pBuf);
+ pBuf = NULL;
+ nBufSize = 0;
+ nAllocSize = 0;
+}
+
+
+template <class T>
+T *TString<T>::GetBuffer(int nNewLen)
+{
+ if (nNewLen != -1)
+ {
+ SetBufSize(nNewLen + 1);
+ }
+ _ASSERT(pBuf);
+ return pBuf;
+}
+
+
+template <class T>
+void TString<T>::ReleaseBuffer(int nNewLen)
+{
+ if (nNewLen == -1)
+ {
+ nBufSize = My_lstrlen(pBuf) + 1;
+ } else
+ {
+ nBufSize = nNewLen + 1;
+ pBuf[nNewLen] = 0;
+ _ASSERT(My_lstrlen(pBuf) == nNewLen);
+ }
+ _ASSERT(nBufSize <= nAllocSize); // prevent buffer overruns
+}
+
+
+template <class T>
+void TString<T>::SetAllocSize(int nNewAllocSize)
+{
+ _ASSERT(nNewAllocSize > 0);
+ T *pNewBuf = /*(char *)HeapAlloc(GetProcessHeap(), 0, sizeof(char) * nNewAllocSize);*/
+(T *)malloc(sizeof(T) * nNewAllocSize);
+ if (pBuf)
+ {
+ memcpy(pNewBuf, pBuf, sizeof(T) * min(nBufSize, nNewAllocSize));
+ //HeapFree(GetProcessHeap(), 0, pBuf);
+ free(pBuf);
+ }
+ pBuf = pNewBuf;
+ nAllocSize = nNewAllocSize;
+}
+
+
+template <class T>
+void TString<T>::SetBufSize(int nNewBufSize)
+{
+ _ASSERT(nNewBufSize >= 0);
+ if (nNewBufSize < nBufSize)
+ {
+ _ASSERT(pBuf);
+ pBuf[nNewBufSize - 1] = 0;
+ }
+ if ((unsigned)(nAllocSize - nNewBufSize) / STR_GROWBY)
+ {
+ SetAllocSize((nNewBufSize + STR_GROWBY - 1) - (nNewBufSize + STR_GROWBY - 1) % STR_GROWBY);
+ }
+ nBufSize = nNewBufSize;
+}
+
+
+template <class T>
+TString<T>& TString<T>::Cat(const T *pStr)
+{
+ _ASSERT(pBuf && pStr);
+ int StrLen = My_lstrlen(pStr);
+ SetAllocSize(nBufSize + StrLen);
+ My_lstrcpy(GetBuffer() + GetLen(), pStr);
+ ReleaseBuffer(nBufSize + StrLen - 1);
+ return *this;
+}
+
+
+template <class T>
+TString<T>& TString<T>::Cat(const T c)
+{
+ _ASSERT(pBuf);
+ SetAllocSize(nBufSize + 1);
+ int CurLen = GetLen();
+ T *p = GetBuffer();
+ p[CurLen] = c;
+ p[CurLen + 1] = '\0';
+ ReleaseBuffer(nBufSize);
+ return *this;
+}
+
+
+template <class T>
+TString<T>& TString<T>::DiffCat(const T *pStart, const T *pEnd)
+{
+ _ASSERT(pBuf && pStart && pEnd);
+ int StrLen = pEnd - pStart;
+ SetAllocSize(nBufSize + StrLen);
+ My_strncpy(GetBuffer() + GetLen(), pStart, StrLen);
+ ReleaseBuffer(nBufSize + StrLen - 1);
+ return *this;
+}
+
+
+template <class T>
+TString<T>& TString<T>::Replace(const T *szFind, const T *szReplaceBy)
+{
+ if (!pBuf)
+ {
+ return *this;
+ }
+ T *pCurPos = pBuf;
+ int FindLen = My_lstrlen(szFind);
+ T *p;
+ TString<T> Result;
+ Result.GetBuffer(1)[0] = '\0';
+ Result.ReleaseBuffer(0); // set the string to ""; we can't do it in a usual way (using a constructor or an assignment) because we don't know whether "" needs to be unicode or ansi
+ while (p = ( T* )My_strstr(pCurPos, szFind))
+ {
+ Result.DiffCat(pCurPos, p);
+ Result += szReplaceBy;
+ pCurPos = p + FindLen;
+ }
+ Result += pCurPos;
+ *this = Result;
+ return *this;
+}
+
+
+template <class T>
+TString<T>& TString<T>::Replace(int nIndex, int nCount, const T *szReplaceBy)
+{
+ if (!pBuf || !szReplaceBy || nIndex < 0 || nCount < 0)
+ {
+ return *this;
+ }
+
+ TString<T> Result;
+ Result.GetBuffer(1)[0] = '\0';
+ Result.ReleaseBuffer(0); // set the string to ""; we can't do it in a usual way (using a constructor or an assignment) because we don't know whether "" needs to be unicode or ansi
+ if (nIndex > GetLen())
+ {
+ nIndex = GetLen();
+ }
+ if (nIndex + nCount > GetLen())
+ {
+ nCount = GetLen() - nIndex;
+ }
+ Result.DiffCat(pBuf, pBuf + nIndex);
+ Result += szReplaceBy;
+ Result += pBuf + nIndex + nCount;
+ *this = Result;
+ return *this;
+}
+
+
+template <class T>
+TString<T> TString<T>::Left(int nCount) const
+{
+ _ASSERT(nCount >= 0);
+ TString<T> Result(*this);
+ Result.SetBufSize(nCount + 1);
+ return Result;
+}
+
+
+template <class T>
+TString<T> TString<T>::Right(int nCount) const
+{
+ _ASSERT(nCount >= 0);
+ if (nCount < GetLen())
+ {
+ return &pBuf[GetLen() - nCount];
+ } else
+ {
+ return *this;
+ }
+}
+
+
+template <class T>
+TString<T> TString<T>::SubStr(int nIndex, int nCount) const
+{
+ _ASSERT(nIndex >= 0 && nCount >= 0);
+ TString<T> Result;
+ if (nIndex < GetLen())
+ {
+ My_strncpy(Result.GetBuffer(nCount), &pBuf[nIndex], nCount);
+ Result.ReleaseBuffer();
+ } else
+ {
+ Result.GetBuffer(1)[0] = '\0';
+ Result.ReleaseBuffer(0);
+ }
+ return Result;
+}
+
+
+template <class T>
+TString<T> TString<T>::ToLower() const
+{
+ TString<T> Result(*this);
+ if (!pBuf)
+ {
+ return Result; // return NULL string
+ }
+ My_strlwr((T*)Result);
+ return Result;
+}
+
+
+template <class T>
+TString<T>& TString<T>::operator = (const T *pStr)
+{
+ if (pStr)
+ {
+ int StrLen = My_lstrlen(pStr);
+ SetBufSize(StrLen + 1);
+ My_lstrcpy(GetBuffer(), pStr);
+ ReleaseBuffer(StrLen);
+ } else
+ {
+ Free();
+ }
+ return *this;
+}
+
+
+/*TCString& TCString::Format(char *pszFormat, ...)
+{
+ va_list argList;
+ va_start(argList, pszFormat);
+ int StrLen = _vscprintf(pszFormat, argList); // it's stupidity. in some versions of msvcrt.dll there's no _vscprintf function, so there's no any way to determine needed string length. so actually I can't use _vsnprintf too.
+ _vsnprintf(GetBuffer(StrLen), StrLen, pszFormat, argList);
+ ReleaseBuffer(StrLen);
+ va_end(argList);
+ return *this;
+}
+*/
+
+template class TString<TCHAR>;
+template class TString<char>;
+template class TString<WCHAR>;
+
+
+CString DBGetContactSettingString(HANDLE hContact, const char *szModule, const char *szSetting, const char *szDefaultValue)
+{
+ DBVARIANT dbv = {0};
+ DBCONTACTGETSETTING dbcgs;
+ dbcgs.szModule = szModule;
+ dbcgs.pValue = &dbv;
+ dbcgs.szSetting = szSetting;
+ int iRes = CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&dbcgs);
+ CString Result;
+ if (!iRes && dbv.type == DBVT_ASCIIZ)
+ {
+ Result = dbv.pszVal;
+ } else
+ {
+ Result = szDefaultValue;
+ }
+ if (!iRes)
+ {
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ }
+ return Result;
+}
+
+
+#ifdef _UNICODE
+TCString DBGetContactSettingString(HANDLE hContact, const char *szModule, const char *szSetting, const TCHAR *szDefaultValue)
+{
+ DBVARIANT dbv = {0};
+ DBCONTACTGETSETTING dbcgs;
+ dbcgs.szModule = szModule;
+ dbcgs.pValue = &dbv;
+ dbcgs.szSetting = szSetting;
+ dbv.type = DBVT_WCHAR;
+ int iRes = CallService(MS_DB_CONTACT_GETSETTING_STR, (WPARAM)hContact, (LPARAM)&dbcgs);
+ TCString Result;
+ if (!iRes && dbv.type == DBVT_WCHAR)
+ {
+ Result = dbv.ptszVal;
+ } else
+ {
+ Result = szDefaultValue;
+ }
+ if (!iRes)
+ {
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ }
+ return Result;
+}
+#endif
+
+
+int DBGetContactSettingString(HANDLE hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv)
+{
+#ifdef _DEBUG
+ return DBGetContactSettingString_Helper(hContact, szModule, szSetting, dbv, __FILE__, __LINE__, DBVT_ASCIIZ);
+#else
+ return DBGetContactSettingString_Helper(hContact, szModule, szSetting, dbv, DBVT_ASCIIZ);
+#endif
+}
+
+
+
+TCString DBGetContactSettingAsString(HANDLE hContact, const char *szModule, const char *szSetting, const TCHAR *szDefaultValue)
+{ // also converts numeric values to a string
+ DBVARIANT dbv = {0};
+ DBCONTACTGETSETTING dbcgs;
+ dbcgs.szModule = szModule;
+ dbcgs.pValue = &dbv;
+ dbcgs.szSetting = szSetting;
+#ifdef _UNICODE
+ dbv.type = DBVT_WCHAR;
+ int iRes = CallService(MS_DB_CONTACT_GETSETTING_STR, (WPARAM)hContact, (LPARAM)&dbcgs);
+#else
+ int iRes = CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&dbcgs);
+#endif
+ TCString Result;
+ if (!iRes && (dbv.type == DBVT_ASCIIZ || dbv.type == DBVT_WCHAR))
+ {
+ Result = dbv.ptszVal;
+ } else if (dbv.type == DBVT_BYTE || dbv.type == DBVT_WORD || dbv.type == DBVT_DWORD)
+ {
+ long value = (dbv.type == DBVT_DWORD) ? dbv.dVal : (dbv.type == DBVT_WORD ? dbv.wVal : dbv.bVal);
+ _ultot(value, Result.GetBuffer(64), 10);
+ Result.ReleaseBuffer();
+ } else
+ {
+ Result = szDefaultValue;
+ }
+ if (!iRes)
+ {
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ }
+ return Result;
+}
|