Files
smartservice_native/hdssd/huslib/String.h
T
2026-05-20 03:08:08 +09:00

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_