984 lines
19 KiB
C++
984 lines
19 KiB
C++
|
|
#ifndef STRING__H_
|
|
#define STRING__H_
|
|
|
|
#ifdef _WIN32
|
|
#pragma once
|
|
#endif
|
|
|
|
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <algorithm>
|
|
|
|
#ifndef _WIN32
|
|
#include <iconv.h>
|
|
#endif
|
|
|
|
|
|
|
|
|
|
class HString : public std::string
|
|
{
|
|
public:
|
|
static int ReadOneLine(HString * pstrDst, const char * pszSrc, int nStartOffset)
|
|
{
|
|
const char * p = pszSrc + nStartOffset;
|
|
|
|
int i, nResult = -1;
|
|
for (i = 0; *p != '\0' ; i++)
|
|
{
|
|
if (*p == '\r')
|
|
{
|
|
nResult = nStartOffset + i + 1;
|
|
if (*(p + 1) == '\n')
|
|
nResult++;
|
|
|
|
pstrDst->Assign(pszSrc + nStartOffset, i);
|
|
break;
|
|
}
|
|
else if (*p == '\n')
|
|
{
|
|
nResult = nStartOffset + i + 1;
|
|
pstrDst->Assign(pszSrc + nStartOffset, i);
|
|
break;
|
|
}
|
|
|
|
p++;
|
|
}
|
|
|
|
if (nResult == -1 && i > 0)
|
|
{
|
|
nResult = nStartOffset + i;
|
|
pstrDst->Assign(pszSrc + nStartOffset, i);
|
|
}
|
|
|
|
return nResult;
|
|
}
|
|
|
|
public:
|
|
HString() {}
|
|
HString(char ch) { operator=(ch); }
|
|
//HString(const char * psz) : std::string(psz) {}
|
|
HString(const char * psz) { if (psz) std::string::operator=(psz); }
|
|
HString(const char * p, size_t nSize) : std::string(p, nSize) {}
|
|
HString(const std::string & str) : std::string(str) {}
|
|
|
|
HString(short num) { operator=(num); } //??? HString * pstr = NULL; pstr ? *pstr : NULL
|
|
HString(unsigned short num) { operator=(num); }
|
|
HString(int num) { operator=(num); }
|
|
HString(unsigned int num) { operator=(num); }
|
|
HString(long num) { operator=(num); }
|
|
HString(unsigned long num) { operator=(num); }
|
|
HString(float num) { operator=(num); }
|
|
HString(double num) { operator=(num); }
|
|
#ifdef _WIN32
|
|
HString(time_t num) { operator=(num); }
|
|
#endif
|
|
~HString() {}
|
|
|
|
inline std::string & operator=(char ch)
|
|
{
|
|
return std::string::operator=(ch);
|
|
}
|
|
|
|
inline std::string & operator=(const char * psz)
|
|
{
|
|
if (psz)
|
|
return std::string::operator=(psz);
|
|
|
|
return std::string::operator=("");
|
|
}
|
|
|
|
inline std::string & operator=(short num) //...
|
|
{
|
|
char szBuf[16]; sprintf(szBuf, "%d", num);
|
|
return std::string::operator=(szBuf);
|
|
}
|
|
|
|
inline std::string & operator=(unsigned short num) //...
|
|
{
|
|
char szBuf[16]; sprintf(szBuf, "%hd", num);
|
|
return std::string::operator=(szBuf);
|
|
}
|
|
|
|
inline std::string & operator=(int num) //...
|
|
{
|
|
char szBuf[32]; sprintf(szBuf, "%d", num);
|
|
return std::string::operator=(szBuf);
|
|
}
|
|
|
|
inline std::string & operator=(unsigned int num) //...
|
|
{
|
|
char szBuf[32]; sprintf(szBuf, "%u", num);
|
|
return std::string::operator=(szBuf);
|
|
}
|
|
|
|
inline std::string & operator=(long num) //...
|
|
{
|
|
char szBuf[64]; sprintf(szBuf, "%ld", num);
|
|
return std::string::operator=(szBuf);
|
|
}
|
|
|
|
inline std::string & operator=(unsigned long num) //...
|
|
{
|
|
char szBuf[64]; sprintf(szBuf, "%lu", num);
|
|
return std::string::operator=(szBuf);
|
|
}
|
|
|
|
inline std::string & operator=(float num) //...
|
|
{
|
|
char szBuf[64]; sprintf(szBuf, "%f", num);
|
|
return std::string::operator=(szBuf);
|
|
}
|
|
|
|
inline std::string & operator=(double num) //...
|
|
{
|
|
char szBuf[64]; sprintf(szBuf, "%lf", num);
|
|
return std::string::operator=(szBuf);
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
inline std::string & operator=(time_t num) //...
|
|
{
|
|
char szBuf[64]; sprintf(szBuf, "%lld", num);
|
|
return std::string::operator=(szBuf);
|
|
}
|
|
#endif
|
|
|
|
inline std::string & operator+=(char ch)
|
|
{
|
|
return std::string::operator+=(ch);
|
|
}
|
|
|
|
inline std::string & operator+=(const char * psz)
|
|
{
|
|
if (psz == NULL)
|
|
return *this;
|
|
|
|
return std::string::operator+=(psz);
|
|
}
|
|
|
|
inline std::string & operator+=(const std::string & str)
|
|
{
|
|
return std::string::operator+=(str);
|
|
}
|
|
|
|
inline std::string & operator+=(short num) //...
|
|
{
|
|
char szBuf[16]; sprintf(szBuf, "%d", num);
|
|
return append(szBuf);
|
|
}
|
|
|
|
inline std::string & operator+=(unsigned short num) //...
|
|
{
|
|
char szBuf[16]; sprintf(szBuf, "%hd", num);
|
|
return append(szBuf);
|
|
}
|
|
|
|
inline std::string & operator+=(int num) //...
|
|
{
|
|
char szBuf[32]; sprintf(szBuf, "%d", num);
|
|
return append(szBuf);
|
|
}
|
|
|
|
inline std::string & operator+=(unsigned int num) //...
|
|
{
|
|
char szBuf[32]; sprintf(szBuf, "%u", num);
|
|
return append(szBuf);
|
|
}
|
|
|
|
inline std::string & operator+=(long num) //...
|
|
{
|
|
char szBuf[64]; sprintf(szBuf, "%ld", num);
|
|
return append(szBuf);
|
|
}
|
|
|
|
inline std::string & operator+=(unsigned long num) //...
|
|
{
|
|
char szBuf[64]; sprintf(szBuf, "%lu", num);
|
|
return append(szBuf);
|
|
}
|
|
|
|
inline std::string & operator+=(float num) //...
|
|
{
|
|
char szBuf[64]; sprintf(szBuf, "%f", num);
|
|
return append(szBuf);
|
|
}
|
|
|
|
inline std::string & operator+=(double num) //...
|
|
{
|
|
char szBuf[64]; sprintf(szBuf, "%lf", num);
|
|
return append(szBuf);
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
inline std::string & operator+=(time_t num) //...
|
|
{
|
|
char szBuf[64]; sprintf(szBuf, "%lld", num);
|
|
return append(szBuf);
|
|
}
|
|
#endif
|
|
|
|
inline operator const char *() const
|
|
{
|
|
return c_str();
|
|
}
|
|
|
|
inline operator short() const
|
|
{
|
|
return atoi(c_str());
|
|
}
|
|
|
|
inline operator unsigned short() const
|
|
{
|
|
return atoi(c_str());
|
|
}
|
|
|
|
inline operator int() const
|
|
{
|
|
return atoi(c_str());
|
|
}
|
|
|
|
inline operator unsigned int() const
|
|
{
|
|
return atoi(c_str());
|
|
}
|
|
|
|
inline operator long() const
|
|
{
|
|
return atol(c_str());
|
|
}
|
|
|
|
inline operator unsigned long() const
|
|
{
|
|
return atol(c_str());
|
|
}
|
|
|
|
inline const char * psz() const
|
|
{
|
|
return c_str();
|
|
}
|
|
|
|
inline size_t GetLength() const
|
|
{
|
|
return length();
|
|
}
|
|
|
|
inline bool IsEmpty() const
|
|
{
|
|
return empty();
|
|
}
|
|
|
|
inline void Reserve(size_t nSize)
|
|
{
|
|
reserve(nSize);
|
|
}
|
|
|
|
inline std::string & Assign(const char * psz, size_t nOffset)
|
|
{
|
|
return assign(psz, nOffset);
|
|
}
|
|
|
|
inline size_t Copy(char * psz, size_t len, size_t pos = 0) const
|
|
{
|
|
return copy(psz, len, pos);
|
|
}
|
|
|
|
inline HString SubStr(const size_t pos, size_t len) const
|
|
{
|
|
return substr(pos, len);
|
|
}
|
|
|
|
inline int StrNCmp(const char * psz, unsigned int nCount)
|
|
{
|
|
return ::strncmp(c_str(), psz, nCount);
|
|
}
|
|
|
|
inline int StrNICmp(const char * psz, unsigned int nCount)
|
|
{
|
|
return ::strnicmp(c_str(), psz, nCount);
|
|
}
|
|
|
|
inline const char * StrNStr(const char * psz, int nCount = -1) const
|
|
{
|
|
return ::StrNStr(c_str(), psz, nCount);
|
|
}
|
|
|
|
inline const char * StrNIStr(const char * psz, int nCount = -1) const
|
|
{
|
|
return ::StrNIStr(c_str(), psz, nCount);
|
|
}
|
|
|
|
inline const char * ToUpper()
|
|
{
|
|
char * pszDst = (char *)malloc(GetLength() + 1);
|
|
char * pszOffset = pszDst;
|
|
const char * pszSrc = psz();
|
|
|
|
while (*pszSrc)
|
|
{
|
|
*pszOffset++ = toupper(*pszSrc++);
|
|
}
|
|
*pszOffset = '\0';
|
|
|
|
std::string::operator=(pszDst);
|
|
free(pszDst);
|
|
|
|
return c_str();
|
|
}
|
|
|
|
inline const char * ToLower()
|
|
{
|
|
char * pszDst = (char *)malloc(GetLength() + 1);
|
|
char * pszOffset = pszDst;
|
|
const char * pszSrc = psz();
|
|
|
|
while (*pszSrc)
|
|
{
|
|
*pszOffset++ = tolower(*pszSrc++);
|
|
}
|
|
*pszOffset = '\0';
|
|
|
|
std::string::operator=(pszDst);
|
|
free(pszDst);
|
|
|
|
return c_str();
|
|
}
|
|
|
|
inline int CompareNoCase(const char * p) const
|
|
{
|
|
return stricmp(psz(), p);
|
|
}
|
|
|
|
inline char GetLast() const
|
|
{
|
|
if (empty())
|
|
return -1;
|
|
|
|
return psz()[GetLength() - 1];
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
#pragma warning(disable:4267)
|
|
#endif
|
|
inline long Find(const HString & str, size_t pos = 0) const
|
|
{
|
|
size_t nResult = find(str, pos);
|
|
if (nResult == std::string::npos)
|
|
return -1;
|
|
return nResult;
|
|
}
|
|
|
|
inline long Find(const char * psz, size_t pos = 0) const
|
|
{
|
|
size_t nResult = find(psz, pos);
|
|
if (nResult == std::string::npos)
|
|
return -1;
|
|
return nResult;
|
|
}
|
|
|
|
inline long Find(const char * psz, size_t pos, size_t n) const
|
|
{
|
|
size_t nResult = find(psz, pos, n);
|
|
if (nResult == std::string::npos)
|
|
return -1;
|
|
return nResult;
|
|
}
|
|
|
|
inline long Find(char c, size_t pos = 0) const
|
|
{
|
|
size_t nResult = find(c, pos);
|
|
if (nResult == std::string::npos)
|
|
return -1;
|
|
return nResult;
|
|
}
|
|
#ifdef _WIN32
|
|
#pragma warning(default:4267)
|
|
#endif
|
|
|
|
void Trim(bool bRemoveFront, bool bRemoveRear)
|
|
{
|
|
char * pszBuffer = (char *)malloc(GetLength() + 1);
|
|
char * pszDst = pszBuffer;
|
|
strcpy(pszDst, psz());
|
|
StrTrim(&pszDst, GetLength(), bRemoveFront, bRemoveRear);
|
|
std::string::operator=(pszDst);
|
|
free(pszBuffer);
|
|
}
|
|
|
|
bool Replace(const char * pszKeyword, const char * pszReplace, int nMode = 0, int nCount = -1) // nMode : 0 = case sensitive, 1 = no case, 2 = keyword
|
|
{
|
|
if (nCount == 0)
|
|
return false;
|
|
|
|
const char * (*fnStrStr)(const char *, const char *);
|
|
if (nMode == 0)
|
|
fnStrStr = (const char*(*)(const char*, const char*))strstr;
|
|
else if (nMode == 1)
|
|
fnStrStr = stristr;
|
|
else
|
|
fnStrStr = StrIKeyword;
|
|
|
|
int nRepeatCount = nCount;
|
|
size_t nKeywordLength = strlen(pszKeyword);
|
|
const char * pszNext = psz();
|
|
int nKeywordCount = 0;
|
|
for (;;)
|
|
{
|
|
if ((pszNext = fnStrStr(pszNext, pszKeyword)) == NULL)
|
|
break;
|
|
|
|
nKeywordCount++;
|
|
|
|
if (nRepeatCount > -1 && --nRepeatCount == 0)
|
|
break;
|
|
|
|
pszNext += nKeywordLength;
|
|
}
|
|
|
|
if (nKeywordCount == 0)
|
|
return false;
|
|
|
|
size_t nReplaceLength = strlen(pszReplace);
|
|
size_t nTextLength = GetLength();
|
|
size_t nNewTextLength = nTextLength + (nReplaceLength - nKeywordLength) * nKeywordCount;
|
|
char * pszNewText = (char *)malloc(nNewTextLength + 1);
|
|
|
|
size_t nCopySize;
|
|
size_t nRemainSize = nTextLength;
|
|
char * pszNewTextOffset = pszNewText;
|
|
const char * pszTextOffset = psz();
|
|
|
|
nRepeatCount = nCount;
|
|
for (;;)
|
|
{
|
|
if ((pszNext = fnStrStr(pszTextOffset, pszKeyword)) == NULL)
|
|
break;
|
|
|
|
nCopySize = pszNext - pszTextOffset;
|
|
|
|
memcpy(pszNewTextOffset, pszTextOffset, nCopySize);
|
|
memcpy(pszNewTextOffset + nCopySize, pszReplace, nReplaceLength);
|
|
|
|
pszTextOffset += nCopySize + nKeywordLength;
|
|
pszNewTextOffset += nCopySize + nReplaceLength;
|
|
|
|
nRemainSize -= nCopySize + nKeywordLength;
|
|
|
|
if (nRepeatCount > -1 && --nRepeatCount == 0)
|
|
break;
|
|
}
|
|
|
|
if (nRemainSize > 0)
|
|
memcpy(pszNewTextOffset, pszTextOffset, nRemainSize);
|
|
|
|
pszNewText[nNewTextLength] = '\0';
|
|
std::string::operator=(pszNewText);
|
|
free(pszNewText);
|
|
|
|
return true;
|
|
}
|
|
|
|
// " a b c " --> " a b c "
|
|
void RemoveRedundancyChar(const char * pszSrc, size_t nLength, char ch)
|
|
{
|
|
*this = "";
|
|
|
|
if (pszSrc == NULL || nLength == 0)
|
|
return;
|
|
|
|
for (size_t i = 0; i < nLength; i++)
|
|
{
|
|
if (pszSrc[i] == ch && pszSrc[i + 1] == ch)
|
|
continue;
|
|
|
|
*this += pszSrc[i];
|
|
}
|
|
}
|
|
|
|
void RemoveRedundancyRow(const char * pszSrc, size_t nLength)
|
|
{
|
|
*this = "";
|
|
|
|
if (pszSrc == NULL || nLength == 0)
|
|
return;
|
|
|
|
for (size_t i = 0; i < nLength; i++)
|
|
{
|
|
if (pszSrc[i] == '\r' && pszSrc[i + 1] == '\n' && pszSrc[i + 2] == '\r' && pszSrc[i + 3] == '\n')
|
|
{
|
|
i++;
|
|
continue;
|
|
}
|
|
|
|
*this += pszSrc[i];
|
|
}
|
|
}
|
|
|
|
void Cut(char chDelimiter)
|
|
{
|
|
char * p = (char *)psz();
|
|
size_t nLength = GetLength();
|
|
|
|
for (size_t i = 0; i < nLength; i++)
|
|
{
|
|
if (p[i] == chDelimiter)
|
|
{
|
|
p[i] = '\0';
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void PartAssign(const char * psz, char chDelimiter)
|
|
{
|
|
size_t i = 0;
|
|
for (; psz[i]; i++)
|
|
{
|
|
if (psz[i] == chDelimiter)
|
|
break;
|
|
}
|
|
|
|
if (i == 0)
|
|
return;
|
|
|
|
Assign(psz, i);
|
|
}
|
|
|
|
/*int Tokenize(const char * psz, size_t nSize, char chDelimiter)
|
|
{
|
|
for (size_t i = 0; i < nSize; i++)
|
|
{
|
|
if (psz[i] == ' ')
|
|
{
|
|
if (i > 0)
|
|
Assign(psz, i);
|
|
|
|
return (int)(i + 1);
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}*/
|
|
|
|
// 2019-11-01 0:02 -> YYYY-MM-DD HH:MM
|
|
void ConvertDateTime()
|
|
{
|
|
if (GetLength() == 15)
|
|
{
|
|
HString str(psz(), 11);
|
|
str += "0";
|
|
str += this->SubStr(11, 4);
|
|
*this = str;
|
|
}
|
|
}
|
|
};
|
|
|
|
///////////////////////////////////////
|
|
|
|
class HStringTokenizer : public HObject
|
|
{
|
|
public:
|
|
HStringTokenizer(const HString & str, const char cDelimiter)
|
|
{
|
|
Tokenize(str, cDelimiter);
|
|
}
|
|
|
|
HStringTokenizer(const char * psz, const char cDelimiter)
|
|
{
|
|
HString str = psz;
|
|
Tokenize(str, cDelimiter);
|
|
}
|
|
|
|
~HStringTokenizer()
|
|
{
|
|
if (m_arr)
|
|
delete [] m_arr;
|
|
}
|
|
|
|
inline size_t GetCount() { return m_nCount; }
|
|
|
|
//inline HString & operator [] (int nIndex)
|
|
inline HString & operator [] (size_t nIndex)
|
|
{
|
|
return m_arr[nIndex];
|
|
}
|
|
|
|
protected:
|
|
// |a|b - fail
|
|
inline void Tokenize(const HString & str, const char cDelimiter)
|
|
{
|
|
if (str.IsEmpty())
|
|
{
|
|
m_arr = NULL;
|
|
m_nCount = 0;
|
|
return;
|
|
}
|
|
|
|
m_nCount = std::count(str.begin(), str.end(), cDelimiter) + 1;
|
|
m_arr = new HString[m_nCount];
|
|
|
|
std::istringstream stream(str);
|
|
std::string token;
|
|
int i = 0;
|
|
while (std::getline(stream, token, cDelimiter))
|
|
{
|
|
m_arr[i++] = token;
|
|
}
|
|
}
|
|
|
|
private:
|
|
HString * m_arr;
|
|
size_t m_nCount;
|
|
};
|
|
|
|
///////////////////////////////////////
|
|
|
|
class HUtf16ToUtf8
|
|
{
|
|
public:
|
|
HUtf16ToUtf8()
|
|
{
|
|
#ifndef _WIN32
|
|
m_iconv = iconv_open("UTF-8", "UTF-16LE");
|
|
#endif
|
|
m_pUtf8 = NULL;
|
|
}
|
|
|
|
~HUtf16ToUtf8()
|
|
{
|
|
if (m_pUtf8)
|
|
free(m_pUtf8);
|
|
|
|
#ifndef _WIN32
|
|
iconv_close(m_iconv);
|
|
#endif
|
|
}
|
|
|
|
char * Convert(const char * pSrc, int nLen)
|
|
{
|
|
if (m_pUtf8)
|
|
free(m_pUtf8);
|
|
|
|
#ifndef _WIN32
|
|
size_t nDstLen = nLen * 2;
|
|
m_pUtf8 = (char *)calloc(nDstLen + 1, 1);
|
|
char * pSrc2 = (char *)calloc(nLen + 1, 1);
|
|
memcpy(pSrc2, pSrc, nLen + 1);
|
|
|
|
char * pUtf16 = pSrc2;
|
|
char * pDst = m_pUtf8;
|
|
|
|
iconv(m_iconv, &pUtf16, (size_t *)&nLen, &pDst, &nDstLen);
|
|
|
|
free(pSrc2);
|
|
#else
|
|
int nDstLen = WideCharToMultiByte(CP_UTF8, 0, (const wchar_t *)pSrc, (int)nLen, NULL, 0, NULL, NULL);
|
|
|
|
if (nDstLen > 0)
|
|
{
|
|
m_pUtf8 = (char *)malloc(nDstLen + 1);
|
|
WideCharToMultiByte(CP_UTF8, 0, (const wchar_t *)pSrc, (int)nLen, m_pUtf8, nDstLen, NULL, NULL);
|
|
m_pUtf8[nDstLen] = '\0';
|
|
}
|
|
#endif
|
|
return m_pUtf8;
|
|
}
|
|
|
|
protected:
|
|
#ifndef _WIN32
|
|
iconv_t m_iconv;
|
|
#endif
|
|
char * m_pUtf8;
|
|
};
|
|
|
|
class HUtf8ToEucKr
|
|
{
|
|
public:
|
|
HUtf8ToEucKr()
|
|
{
|
|
#ifndef _WIN32
|
|
m_iconv = iconv_open("EUC-KR", "UTF-8");
|
|
#endif
|
|
m_pEucKr = NULL;
|
|
}
|
|
|
|
~HUtf8ToEucKr()
|
|
{
|
|
if (m_pEucKr)
|
|
free(m_pEucKr);
|
|
|
|
#ifndef _WIN32
|
|
iconv_close(m_iconv);
|
|
#endif
|
|
}
|
|
|
|
char * Convert(const char * pSrc, int nLen)
|
|
{
|
|
if (pSrc == NULL || pSrc[0] == '\0' || nLen <= 0)
|
|
return "";
|
|
|
|
if (m_pEucKr)
|
|
free(m_pEucKr);
|
|
|
|
#ifndef _WIN32
|
|
size_t nDstLen = nLen * 2;
|
|
m_pEucKr = (char *)calloc(nDstLen + 1, 1);
|
|
char * pSrc2 = (char *)calloc(nLen + 1, 1);
|
|
strcpy(pSrc2, pSrc);
|
|
|
|
char * pUtf8 = pSrc2;
|
|
char * pDst = m_pEucKr;
|
|
|
|
iconv(m_iconv, &pUtf8, (size_t *)&nLen, &pDst, &nDstLen);
|
|
|
|
free(pSrc2);
|
|
#else
|
|
int nLength = MultiByteToWideChar(CP_UTF8, 0, pSrc, nLen + 1, NULL, NULL);
|
|
BSTR bstrWide = SysAllocStringLen(NULL, nLength);
|
|
|
|
MultiByteToWideChar(CP_UTF8, 0, pSrc, nLen + 1, bstrWide, nLength);
|
|
|
|
nLength = WideCharToMultiByte(CP_ACP, 0, bstrWide, -1, NULL, 0, NULL, NULL);
|
|
|
|
m_pEucKr = (char *)malloc(nLength);
|
|
|
|
WideCharToMultiByte(CP_ACP, 0, bstrWide, -1, m_pEucKr, nLength, NULL, NULL);
|
|
SysFreeString(bstrWide);
|
|
#endif
|
|
return m_pEucKr;
|
|
}
|
|
|
|
protected:
|
|
#ifndef _WIN32
|
|
iconv_t m_iconv;
|
|
#endif
|
|
char * m_pEucKr;
|
|
};
|
|
|
|
class HEucKrToUtf8
|
|
{
|
|
public:
|
|
HEucKrToUtf8()
|
|
{
|
|
#ifndef _WIN32
|
|
m_iconv = iconv_open("UTF-8", "EUC-KR");
|
|
#endif
|
|
m_pUtf8 = NULL;
|
|
}
|
|
|
|
~HEucKrToUtf8()
|
|
{
|
|
if (m_pUtf8)
|
|
free(m_pUtf8);
|
|
|
|
#ifndef _WIN32
|
|
iconv_close(m_iconv);
|
|
#endif
|
|
}
|
|
|
|
char * Convert(const char * pSrc, int nLen)
|
|
{
|
|
if (m_pUtf8)
|
|
free(m_pUtf8);
|
|
|
|
#ifndef _WIN32
|
|
size_t nDstLen = nLen * 4;
|
|
m_pUtf8 = (char *)calloc(nDstLen + 1, 1);
|
|
char * pSrc2 = (char *)calloc(nLen + 1, 1);
|
|
strcpy(pSrc2, pSrc);
|
|
|
|
char * pUtf16 = pSrc2;
|
|
char * pDst = m_pUtf8;
|
|
|
|
iconv(m_iconv, &pUtf16, (size_t *)&nLen, &pDst, &nDstLen);
|
|
|
|
free(pSrc2);
|
|
#else
|
|
int nLength = MultiByteToWideChar(CP_ACP, 0, pSrc, nLen, NULL, NULL);
|
|
BSTR bstrCode = SysAllocStringLen(NULL, nLength);
|
|
MultiByteToWideChar(CP_ACP, 0, pSrc, nLen, bstrCode, nLength);
|
|
|
|
int nLength2 = WideCharToMultiByte(CP_UTF8, 0, bstrCode, -1, m_pUtf8, 0, NULL, NULL);
|
|
m_pUtf8 = (char*)malloc(nLength2 + 1);
|
|
WideCharToMultiByte(CP_UTF8, 0, bstrCode, -1, m_pUtf8, nLength2, NULL, NULL);
|
|
SysFreeString(bstrCode);
|
|
#endif
|
|
return m_pUtf8;
|
|
}
|
|
|
|
protected:
|
|
#ifndef _WIN32
|
|
iconv_t m_iconv;
|
|
#endif
|
|
char * m_pUtf8;
|
|
};
|
|
|
|
///////////////////////////////////////
|
|
|
|
extern inline void RemoveTagElement(HString * pstrDst, const char * pszSrc, size_t nLength, const char * pszTag)
|
|
{
|
|
*pstrDst = "";
|
|
|
|
if (pszSrc == NULL || nLength == 0)
|
|
return;
|
|
|
|
HString strFrontTag = "<"; strFrontTag += pszTag;
|
|
HString strRearTag = "</"; strRearTag += pszTag; strRearTag += ">";
|
|
|
|
bool bSkip = false;
|
|
for (size_t i = 0; i < nLength; i++, pszSrc++)
|
|
{
|
|
if (bSkip)
|
|
{
|
|
if (strnicmp(pszSrc, strRearTag, strRearTag.GetLength()) == 0)
|
|
{
|
|
bSkip = false;
|
|
i += strRearTag.GetLength() - 1;
|
|
pszSrc += strRearTag.GetLength() - 1;
|
|
}
|
|
continue;
|
|
}
|
|
else if (strnicmp(pszSrc, strFrontTag, strFrontTag.GetLength()) == 0)
|
|
{
|
|
bSkip = true;
|
|
i += strFrontTag.GetLength() - 1;
|
|
pszSrc += strFrontTag.GetLength() - 1;
|
|
continue;
|
|
}
|
|
|
|
*pstrDst += *pszSrc;
|
|
}
|
|
}
|
|
|
|
extern inline void RemoveMarkupTag(HString * pstrDst, const char * pszSrc, size_t nLength)
|
|
{
|
|
*pstrDst = "";
|
|
|
|
if (pszSrc == NULL || nLength == 0)
|
|
return;
|
|
|
|
int nSkipMode = 0; // 0 : no skip, 1 : normal tag, 2 : comment tag
|
|
for (size_t i = 0; i < nLength; i++)
|
|
{
|
|
if (nSkipMode == 1)
|
|
{
|
|
if (pszSrc[i] == '>')
|
|
nSkipMode = 0;
|
|
|
|
continue;
|
|
}
|
|
else if (nSkipMode == 2)
|
|
{
|
|
if (pszSrc[i] == '-' && pszSrc[i + 1] == '-' && pszSrc[i + 2] == '>')
|
|
{
|
|
i += 2;
|
|
nSkipMode = 0;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
else if (pszSrc[i] == '<')
|
|
{
|
|
if (pszSrc[i + 1] == '!' && pszSrc[i + 2] == '-' && pszSrc[i + 3] == '-')
|
|
{
|
|
i += 2;
|
|
nSkipMode = 2;
|
|
}
|
|
else
|
|
nSkipMode = 1;
|
|
|
|
continue;
|
|
}
|
|
|
|
*pstrDst += pszSrc[i];
|
|
}
|
|
}
|
|
|
|
extern inline size_t ClearSpaceAndRow(HString * pstrDst, const char * pszSrc, size_t nLength, bool bRemoveRow)
|
|
{
|
|
size_t nRowCount = 0;
|
|
*pstrDst = "";
|
|
|
|
if (pszSrc == NULL || nLength == 0)
|
|
return nRowCount;
|
|
|
|
char * pNextLine = (char *)pszSrc;
|
|
char * pOneLine;
|
|
do
|
|
{
|
|
pOneLine = pNextLine;
|
|
pNextLine = StrSlice(pOneLine);
|
|
|
|
StrTrim(&pOneLine, strlen(pOneLine), true, true);
|
|
if (pOneLine[0] == '\0')
|
|
continue;
|
|
|
|
*pstrDst += pOneLine;
|
|
|
|
nRowCount++;
|
|
|
|
if (bRemoveRow == false)
|
|
*pstrDst += "\r\n";
|
|
|
|
} while (pNextLine);
|
|
|
|
return nRowCount;
|
|
}
|
|
|
|
extern inline void StrRemoveRow(HString * pstrDst, const char * pszSrc, const char * pszKeyword)
|
|
{
|
|
*pstrDst = "";
|
|
|
|
if (pszSrc == NULL || pszKeyword == NULL)
|
|
return;
|
|
|
|
char * pNextLine = (char *)pszSrc;
|
|
char * pOneLine;
|
|
do
|
|
{
|
|
pOneLine = pNextLine;
|
|
pNextLine = StrSlice(pOneLine);
|
|
|
|
StrTrim(&pOneLine, strlen(pOneLine), true, true);
|
|
if (pOneLine[0] == '\0' || stristr(pOneLine, pszKeyword))
|
|
continue;
|
|
|
|
*pstrDst += pOneLine;
|
|
*pstrDst += "\r\n";
|
|
|
|
} while (pNextLine);
|
|
}
|
|
|
|
// nMode = 0 : between, 1 : with front, 2 : with rear, 3 : both remove
|
|
extern inline void StrBetweenRemove(HString * pstrDst, const char * pszSrc, const char * pszFront, const char * pszRear, int nMode)
|
|
{
|
|
*pstrDst = "";
|
|
|
|
if (pszSrc == NULL || pszFront == NULL || pszRear == NULL)
|
|
return;
|
|
|
|
char * pszStart, * pszEnd;
|
|
|
|
if ((pszStart = (char *)strstr(pszSrc, pszFront)) == NULL)
|
|
return;
|
|
size_t nFrontSize = strlen(pszFront);
|
|
pszStart += nFrontSize;
|
|
|
|
if ((pszEnd = strstr(pszStart, pszRear)) == NULL)
|
|
return;
|
|
|
|
if (nMode == 1 || nMode == 3)
|
|
pszStart -= nFrontSize;
|
|
|
|
pstrDst->Assign(pszSrc, pszStart - pszSrc);
|
|
|
|
if (nMode == 2 || nMode == 3)
|
|
*pstrDst += (pszEnd + strlen(pszRear));
|
|
else
|
|
*pstrDst += pszEnd;
|
|
}
|
|
|
|
#endif // STRING__H_
|