SimpleString.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. /***********************************//**
  2. * @file SimpleString.h
  3. * @copyright China Merchants Bank Co.,Ltd All rights reserved
  4. * @brief
  5. * @details
  6. * replace char with CHAR and wchar_t with WCHAR for linux compaticity.
  7. **************************************/
  8. #ifndef _RVC_SIMPLESTRING_H_
  9. #define _RVC_SIMPLESTRING_H_
  10. #pragma once
  11. #include <stdexcept>
  12. #include "AutoArray.h"
  13. #ifndef _WIN32
  14. #include <winpr/string.h>
  15. #include <winpr/tchar.h>
  16. #include <winpr/crt.h>
  17. #include <winpr/wlog.h>
  18. #include <stdarg.h>
  19. #include <locale.h>
  20. #include <stdarg.h>
  21. #include <wchar.h>
  22. #endif //NOT _WIN32
  23. #define WTAG "rvc.tools.simplestring"
  24. template<class T> class CSimpleStringT;
  25. typedef CSimpleStringT<CHAR> CSimpleStringA;
  26. typedef CSimpleStringT<TCHAR> CSimpleString;
  27. #if defined(_MSC_VER)
  28. #define SPCHAR WCHAR
  29. #else
  30. #define SPCHAR wchar_t
  31. #endif //_MSC_VER
  32. typedef CSimpleStringT<SPCHAR> CSimpleStringW;
  33. static inline CSimpleStringW CSimpleStringA2W(CSimpleStringA str);
  34. static inline CSimpleStringA CSimpleStringW2A(CSimpleStringW wstr);
  35. #ifndef _WIN32
  36. typedef CSimpleStringT<WCHAR> CSimpleString16Bit;
  37. static inline CSimpleStringA CSimpleString16Bit2A(CSimpleString16Bit wstr);
  38. static inline CSimpleString16Bit CSimpleStringA216Bit(CSimpleStringA str);
  39. static inline CSimpleStringW CSimpleString16Bit2W(CSimpleString16Bit wstr);
  40. static inline CSimpleString16Bit CSimpleStringW216Bit(CSimpleStringW wstr);
  41. #endif //NOT _WIN32
  42. template<class T> class CSimpleStringT
  43. {
  44. public:
  45. CSimpleStringT() {}
  46. CSimpleStringT(const T* pString)
  47. {
  48. if (pString != NULL) {
  49. m_StringBuf.Copy(pString, 0, CalculateStringToBufferLength(pString));
  50. }
  51. }
  52. CSimpleStringT(const T* pString, size_t n)
  53. {
  54. if (n > 0 && pString != NULL) {
  55. if (pString[n - 1]) { // not end with NULL
  56. m_StringBuf.Init(n + 1);
  57. memcpy(&m_StringBuf[0], pString, sizeof(T) * n);
  58. m_StringBuf[n] = 0;
  59. } else {
  60. m_StringBuf.Copy(pString, 0, n);
  61. }
  62. }
  63. }
  64. CSimpleStringT(const CSimpleStringT<T>& String) :m_StringBuf(String.m_StringBuf) {}
  65. CSimpleStringT(T ch, size_t n) : m_StringBuf(n + 1)
  66. {
  67. for (size_t i = 0; i < n; ++i)
  68. m_StringBuf[i] = ch;
  69. m_StringBuf[n] = 0;
  70. }
  71. CSimpleStringT(bool bEmptyString)
  72. {
  73. if (bEmptyString) {
  74. m_StringBuf.Init(1);
  75. m_StringBuf[0] = 0;
  76. }
  77. }
  78. static CSimpleStringT<T> Format(const T* pszFormat, ...)
  79. {
  80. if (pszFormat == NULL) {
  81. return CSimpleStringT<T>();
  82. }
  83. CSimpleStringT strRet;
  84. va_list args;
  85. va_start(args, pszFormat);
  86. int nLen = _CalFormatStrLen(pszFormat, args);
  87. strRet.m_StringBuf.Init(nLen + 1);
  88. _FormatString(strRet.m_StringBuf.GetWriteableArray(), nLen + 1, pszFormat, args);
  89. va_end(args);
  90. return strRet;
  91. }
  92. CSimpleStringT<T> SubString(int nIndex, int nCount = 0)
  93. {
  94. if (nIndex < 0 || nIndex >= GetLength() || nCount < 0)
  95. return CSimpleStringT<T>();
  96. if (nCount == 0)
  97. nCount = GetLength() - nIndex;
  98. else if (nIndex + nCount > GetLength())
  99. nCount = GetLength() - nIndex;
  100. CSimpleStringT<T> strRet;
  101. strRet.m_StringBuf.Init(nCount + 1);
  102. memcpy_s(&strRet.m_StringBuf[0], (nCount + 1) * sizeof(T), &m_StringBuf[nIndex], nCount * sizeof(T));
  103. strRet.m_StringBuf[nCount] = 0;
  104. return strRet;
  105. }
  106. CSimpleStringT<T>& operator=(const T* pString)
  107. {
  108. int m_nStringLen = CalculateStringToBufferLength(pString);
  109. if (m_nStringLen == 0) {
  110. m_StringBuf.Init(0);
  111. return *this;
  112. }
  113. m_StringBuf.Init(m_nStringLen);
  114. memcpy_s(m_StringBuf.GetWriteableArray(), m_nStringLen * sizeof(T), pString, m_nStringLen * sizeof(T));
  115. return *this;
  116. }
  117. CSimpleStringT<T>& operator=(const CSimpleStringT<T>& String)
  118. {
  119. m_StringBuf = String.m_StringBuf;
  120. return *this;
  121. }
  122. bool operator ==(const CSimpleStringT<T>& String)const
  123. {
  124. if (m_StringBuf == String.m_StringBuf)
  125. return true;
  126. if (GetLength() == String.GetLength())
  127. return Compare(String) == 0;
  128. else
  129. return false;
  130. }
  131. bool operator == (const T* pString) const
  132. {
  133. if (pString == NULL)
  134. return false;
  135. return Compare(pString) == 0;
  136. }
  137. bool operator !=(const CSimpleStringT<T>& String)const { return !(operator==(String)); }
  138. operator const T* ()const { return m_StringBuf; }
  139. CSimpleStringT<T> operator + (const CSimpleStringT& RightString)const
  140. {
  141. int nRightLen = RightString.GetLength();
  142. if (nRightLen == 0)
  143. return *this;
  144. int nLeftLen = GetLength();
  145. if (nLeftLen == 0)
  146. return RightString;
  147. // bugfix [3/18/2020 15:34 Gifur]
  148. //CSimpleStringA ResultString;
  149. CSimpleStringT<T> ResultString;
  150. int nResultSize = nLeftLen + nRightLen + 1;
  151. ResultString.m_StringBuf.Init(nResultSize);
  152. T* pTargetString = ResultString.m_StringBuf.GetWriteableArray();
  153. memcpy_s(pTargetString, nResultSize * sizeof(T), m_StringBuf, nLeftLen * sizeof(T));
  154. //memcpy_s(pTargetString+nLeftLen,(nRightLen+1)*sizeof(T),RightString,nRightLen+1); // {bug}
  155. memcpy_s(pTargetString + nLeftLen, (nRightLen + 1) * sizeof(T), RightString, (nRightLen + 1) * sizeof(T));
  156. return ResultString;
  157. }
  158. CSimpleStringT<T>& operator +=(const T* pString)
  159. {
  160. int nRightLen = CalculateStringToBufferLength(pString);
  161. if (nRightLen == 0)
  162. return *this;
  163. int nLeftLen = GetLength();
  164. if (nLeftLen == 0)
  165. return operator=(pString);
  166. //int nResultSize=nLeftLen+nRightLen+1; // {bug} since nRightLen == strlen(pString)+1, no need +1 again!
  167. //m_StringBuf.EnlargeArray(nResultSize);
  168. //memcpy_s(m_StringBuf.GetWriteableArray()+nLeftLen,(nRightLen+1)*sizeof(T),pString,(nRightLen+1)*sizeof(T));
  169. int nResultSize = nLeftLen + nRightLen;
  170. m_StringBuf.EnlargeArray(nResultSize);
  171. memcpy_s(m_StringBuf.GetWriteableArray() + nLeftLen, (nRightLen) * sizeof(T), pString, (nRightLen) * sizeof(T));
  172. return *this;
  173. }
  174. CSimpleStringT<T>& operator +=(const CSimpleStringT& RightString)
  175. {
  176. int nRigthLen = RightString.GetLength();
  177. if (nRigthLen == 0)
  178. return *this;
  179. int nLeftLen = GetLength();
  180. if (nLeftLen == 0)
  181. return operator=(RightString);
  182. int nResultSize = nLeftLen + nRigthLen + 1;
  183. m_StringBuf.EnlargeArray(nResultSize);
  184. memcpy_s(m_StringBuf.GetWriteableArray() + nLeftLen, (nRigthLen + 1) * sizeof(T), RightString, (nRigthLen + 1) * sizeof(T));
  185. return *this;
  186. }
  187. const T operator[](int nIndex)const
  188. {
  189. return m_StringBuf[nIndex];
  190. }
  191. T& operator[](int nIndex)
  192. {
  193. return m_StringBuf[nIndex];
  194. }
  195. const T* GetData() const { return &m_StringBuf[0]; }
  196. int GetLength()const
  197. {
  198. int nLen = m_StringBuf.GetCount();
  199. return nLen == 0 ? nLen : _CalStringLen(m_StringBuf);
  200. }
  201. int GetCapability()const
  202. {
  203. int nLen = m_StringBuf.GetCount();
  204. return nLen == 0 ? nLen : nLen - 1; //to keep the '\0' CHAR
  205. }
  206. void Clear()
  207. {
  208. m_StringBuf.Init(0);
  209. }
  210. CAutoArray<CSimpleStringT<T>> Split(T ch)
  211. {
  212. CAutoArray<CSimpleStringT<T>> ret;
  213. const T* pData = GetData();
  214. int nStringSize = GetLength();
  215. int nBegin(0), nEnd(0);
  216. while (nEnd < nStringSize) {
  217. if (pData[nEnd] == ch || nEnd == nStringSize - 1) {
  218. int nSize = pData[nEnd] == ch ? nEnd - nBegin : nEnd - nBegin + 1;
  219. if (nSize > 0) {
  220. int nNewSize = ret.GetCount() + 1;
  221. ret.EnlargeArray(nNewSize);
  222. ret[nNewSize - 1] = CSimpleStringT(pData + nBegin, nSize).Trim();
  223. }
  224. nBegin = nEnd + 1;
  225. nEnd++;
  226. } else {
  227. nEnd++;
  228. }
  229. }
  230. return ret;
  231. }
  232. CSimpleStringT<T> Trim()
  233. {
  234. int nBegin = 0;
  235. while (nBegin < GetLength() && ((int)m_StringBuf[nBegin]) == 0x20)
  236. nBegin++;
  237. int nEnd = GetLength() - 1;
  238. while (nEnd >= 0 && ((int)m_StringBuf[nEnd]) == 0x20)
  239. nEnd--;
  240. if (nBegin > nEnd)
  241. return CSimpleStringT<T>(true);
  242. else
  243. return SubString(nBegin, nEnd - nBegin + 1);
  244. }
  245. bool IsStartWith(const T* pStr, bool bIgnoreCase = false)
  246. {
  247. int nLen = _CalStringLen(pStr);
  248. if (nLen == 0)
  249. return false;
  250. else if (GetLength() < nLen)
  251. return false;
  252. CSimpleStringT<T> strComp = SubString(0, nLen);
  253. return _CompareString(pStr, strComp, bIgnoreCase) == 0;
  254. }
  255. bool IsEndWith(const T* pStr, bool bIgnoreCase = false)
  256. {
  257. int nLen = _CalStringLen(pStr);
  258. if (nLen == 0)
  259. return false;
  260. else if (GetLength() < nLen)
  261. return false;
  262. int nStart = GetLength() - nLen;
  263. CSimpleStringT<T> strComp = SubString(nStart, nLen);
  264. return _CompareString(pStr, strComp, bIgnoreCase) == 0;
  265. }
  266. int IndexOf(const T* pStr)
  267. {
  268. if (pStr == NULL)
  269. return -1;
  270. int nCompLen = _CalStringLen(pStr);
  271. int nDataLen = GetLength();
  272. if (nCompLen == 0 || nDataLen < nCompLen)
  273. return -1;
  274. for (int i = 0; i <= nDataLen - nCompLen; i++) {
  275. if (_CompareStringN(&m_StringBuf[i], pStr, nCompLen) == 0)
  276. return i;
  277. }
  278. return -1;
  279. }
  280. CSimpleStringT<T>& Append(const T* pString)
  281. {
  282. int nRightLen = CalculateStringToBufferLength(pString);
  283. if (nRightLen == 0)
  284. return *this;
  285. int nLeftLen = GetLength();
  286. if (nLeftLen == 0)
  287. return operator=(pString);
  288. //m_StringBuf.EnlargeArray(nLeftLen+nRightLen+1); // {bug} CalculateStringToBufferLength already includes null
  289. //memcpy_s(m_StringBuf.GetWriteableArray()+nLeftLen,(nRightLen+1)*sizeof(T),pString,(nRightLen+1)*sizeof(T));
  290. m_StringBuf.EnlargeArray(nLeftLen + nRightLen);
  291. memcpy_s(m_StringBuf.GetWriteableArray() + nLeftLen, (nRightLen) * sizeof(T), pString, (nRightLen) * sizeof(T));
  292. return *this;
  293. }
  294. CSimpleStringT<T>& Append(const T* pString, int iCount)
  295. {
  296. if (iCount <= 0)
  297. return *this;
  298. int nRightLen = CalculateStringToBufferLength(pString);
  299. if (nRightLen < iCount)
  300. return *this;
  301. nRightLen = iCount;
  302. int nLeftLen = GetLength();
  303. int nResultSize = nLeftLen + nRightLen;
  304. m_StringBuf.EnlargeArray(nResultSize + 1); // include null-terminated CHAR
  305. memcpy_s(m_StringBuf.GetWriteableArray() + nLeftLen, nRightLen * sizeof(T), pString, nRightLen * sizeof(T));
  306. *(m_StringBuf.GetWriteableArray() + nResultSize) = 0;
  307. return *this;
  308. }
  309. bool IsNullOrEmpty() const
  310. {
  311. return GetLength() == 0;
  312. }
  313. void Resize(int n)
  314. {
  315. m_StringBuf.Init(n);
  316. }
  317. int Compare(const T* p) const
  318. {
  319. if (p == GetData())
  320. return 0;
  321. return _CompareString(m_StringBuf, p);
  322. }
  323. int Compare(const T* p, bool bIgnoreCase) const
  324. {
  325. if (p == GetData())
  326. return 0;
  327. return _CompareString(m_StringBuf, p, bIgnoreCase);
  328. }
  329. int Compare(const CSimpleStringT<T>& str) const
  330. {
  331. return Compare(str.GetData());
  332. }
  333. int Compare(const CSimpleStringT<T>& str, bool bIgnoreCase) const
  334. {
  335. return Compare(str.GetData(), bIgnoreCase);
  336. }
  337. private:
  338. static inline int _CompareString(const CHAR* pStr1, const CHAR* pStr2, bool bIgnoreCase = false)
  339. {
  340. if (pStr2 == NULL || pStr1 == NULL) {
  341. if (pStr2 == NULL && pStr1 == NULL)
  342. return 0;
  343. return 1;
  344. }
  345. if (bIgnoreCase)
  346. return _stricmp(pStr1, pStr2);
  347. else
  348. return strcmp(pStr1, pStr2);
  349. }
  350. static inline int _CompareString(const WCHAR* pStr1, const WCHAR* pStr2, bool bIgnoreCase = false)
  351. {
  352. if (pStr2 == NULL || pStr1 == NULL) {
  353. if (pStr2 == NULL && pStr1 == NULL)
  354. return 0;
  355. return 1;
  356. }
  357. if (bIgnoreCase)
  358. return _wcsicmp(pStr1, pStr2);
  359. else
  360. #if defined(_MSC_VER)
  361. return wcscmp(pStr1, pStr2);
  362. #else
  363. return _wcscmp(pStr1, pStr2);
  364. #endif //_MSC_VER
  365. }
  366. #ifndef _WIN32
  367. static inline int _CompareString(const wchar_t* pStr1, const wchar_t* pStr2, bool bIgnoreCase = false)
  368. {
  369. if (pStr2 == NULL || pStr1 == NULL) {
  370. if (pStr2 == NULL && pStr1 == NULL)
  371. return 0;
  372. return 1;
  373. }
  374. if (bIgnoreCase)
  375. return wcscasecmp(pStr1, pStr2);
  376. else
  377. return wcscmp(pStr1, pStr2);
  378. }
  379. #endif //NOT _WIN32
  380. static inline int _CompareStringN(const CHAR* pStr1, const CHAR* pStr2, int nCompLen, bool bIgnoreCase = false)
  381. {
  382. if (bIgnoreCase)
  383. return _strnicmp(pStr1, pStr2, nCompLen);
  384. else
  385. return strncmp(pStr1, pStr2, nCompLen);
  386. }
  387. static inline int _CompareStringN(const WCHAR* pStr1, const WCHAR* pStr2, int nCompLen, bool bIgnoreCase = false)
  388. {
  389. if (bIgnoreCase)
  390. return _wcsnicmp(pStr1, pStr2, nCompLen);
  391. else
  392. #ifdef _WIN32
  393. return wcsncmp(pStr1, pStr2, nCompLen);
  394. #else
  395. return _wcsncmp(pStr1, pStr2, nCompLen);
  396. #endif //_WIN32
  397. }
  398. #ifndef _WIN32
  399. static inline int _CompareStringN(const wchar_t* pStr1, const wchar_t* pStr2, int nCompLen, bool bIgnoreCase = false)
  400. {
  401. if (bIgnoreCase)
  402. return wcsncasecmp(pStr1, pStr2, nCompLen);
  403. else
  404. return wcsncmp(pStr1, pStr2, nCompLen);
  405. }
  406. #endif //NOT _WIN32
  407. static inline int _CalStringLen(const CHAR* pString)
  408. {
  409. return strlen(pString);
  410. }
  411. static inline int _CalStringLen(const WCHAR* pString)
  412. {
  413. #if defined(_MSC_VER)
  414. return wcslen(pString);
  415. #else
  416. return _wcslen(pString);
  417. #endif //_MSC_VER
  418. }
  419. #ifndef _WIN32
  420. static inline int _CalStringLen(const wchar_t* pString)
  421. {
  422. return wcslen(pString);
  423. }
  424. #endif //NOT _WIN32
  425. static inline int _CalFormatStrLen(const CHAR* pFormat, va_list ArgList)
  426. {
  427. return _vscprintf(pFormat, ArgList);
  428. }
  429. static inline int _CalFormatStrLen(const WCHAR* pFormat, va_list ArgList)
  430. {
  431. return _vscwprintf(pFormat, ArgList);
  432. }
  433. #ifndef _WIN32
  434. static inline int _CalFormatStrLen(const wchar_t* pFormat, va_list ArgList)
  435. {
  436. int buf_size = 1024;
  437. int result = -1;
  438. while (buf_size < 1024 * 1024) {
  439. va_list args;
  440. va_copy(args, ArgList);
  441. wchar_t buffer[buf_size];
  442. int fmt_size = vswprintf(buffer, sizeof(buffer) / sizeof(wchar_t), pFormat, args);
  443. va_end(args);
  444. if (fmt_size >= 0) {
  445. result = fmt_size;
  446. break;
  447. }
  448. buf_size *= 2;
  449. }
  450. return result;
  451. //return vwprintf(pFormat, ArgList);
  452. }
  453. #endif
  454. static inline int _FormatString(CHAR* pBuffer, int nBufLen, const CHAR* pFormat, va_list ArgList)
  455. {
  456. return _vsnprintf_s(pBuffer, nBufLen, _TRUNCATE, pFormat, ArgList);
  457. }
  458. static inline int _FormatString(WCHAR* pBuffer, int nBufLen, const WCHAR* pFormat, va_list ArgList)
  459. {
  460. //bugFix: _vsnwprintf replace with _vsnwprintf_s [3/18/2020 15:36 Gifur]
  461. return _vsnwprintf_s(pBuffer, nBufLen, _TRUNCATE, pFormat, ArgList);
  462. }
  463. #ifndef _WIN32
  464. static inline int _FormatString(wchar_t* pBuffer, int nBufLen, const wchar_t* pFormat, va_list ArgList)
  465. {
  466. return vswprintf(pBuffer, nBufLen, pFormat, ArgList);
  467. }
  468. #endif //NOT _WIN32
  469. static int CalculateStringToBufferLength(const T* pString)
  470. {
  471. if (pString == NULL)
  472. return 0;
  473. int nLen = _CalStringLen(pString);
  474. return nLen + 1;
  475. }
  476. CAutoArray<T> m_StringBuf;
  477. /*
  478. * fixed compiled error: 'static' is invalid in friend declarations
  479. * a function first declared in a friend declaration has external linkage. otherwise the function
  480. * retains its previous linkage. [3/18/2020 13:30 Gifur]
  481. */
  482. friend /*static*/ inline CSimpleStringW CSimpleStringA2W(CSimpleStringA str);
  483. friend /*static*/ inline CSimpleStringA CSimpleStringW2A(CSimpleStringW str);
  484. #ifndef _WIN32
  485. friend /*static*/ CSimpleStringA CSimpleString16Bit2A(CSimpleString16Bit wstr);
  486. friend /*static*/ CSimpleString16Bit CSimpleStringA216Bit(CSimpleStringA str);
  487. friend /*static*/ CSimpleStringW CSimpleString16Bit2W(CSimpleString16Bit wstr);
  488. friend /*static*/ CSimpleString16Bit CSimpleStringW216Bit(CSimpleStringW wstr);
  489. #endif //NOT _WIN32
  490. };
  491. template<class T>
  492. bool operator<(const CSimpleStringT<T>& lhs, const CSimpleStringT<T>& rhs)
  493. {
  494. return lhs.Compare(rhs) < 0;
  495. }
  496. static inline CSimpleStringW CSimpleStringA2W(CSimpleStringA str)
  497. {
  498. #if defined(_MSC_VER)
  499. CSimpleStringW wstr;
  500. int n = ::MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
  501. if (n > 0) {
  502. wstr.m_StringBuf.Init(n);
  503. ::MultiByteToWideChar(CP_ACP, 0, str, -1, &wstr[0], n);
  504. }
  505. return wstr;
  506. #else
  507. if (str.IsNullOrEmpty())
  508. return CSimpleStringW(true);
  509. int len = mbstowcs(NULL, str, 0);
  510. WLog_DBG(WTAG, ">>> %s: origin locale: %s, data: %s(%d): error:%d, %s",
  511. __FUNCTION__, setlocale(LC_CTYPE, NULL), str.GetData(), len, errno, strerror(errno));
  512. if (len == -1) {
  513. return CSimpleStringW(true);
  514. }
  515. len += 1;
  516. wchar_t* p = new wchar_t[len];
  517. wmemset(p, 0, len);
  518. size_t ret = mbstowcs(p, str, len);
  519. if (ret == (size_t)-1) {
  520. delete[] p;
  521. return CSimpleStringW(true);
  522. }
  523. CSimpleStringW result(p);
  524. delete[] p;
  525. WLog_DBG(WTAG, "<<< %s: data: %ls(%d)", __FUNCTION__, result.GetData(), ret);
  526. return result;
  527. #endif //_MSC_VER
  528. }
  529. static inline CSimpleStringA CSimpleStringW2A(CSimpleStringW wstr)
  530. {
  531. #if defined(_MSC_VER)
  532. CSimpleStringA str;
  533. int n = ::WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
  534. if (n > 0) {
  535. str.m_StringBuf.Init(n);
  536. ::WideCharToMultiByte(CP_ACP, 0, wstr, -1, &str[0], n, NULL, NULL);
  537. }
  538. return str;
  539. #else
  540. if (wstr.IsNullOrEmpty())
  541. return CSimpleStringA(true);
  542. int len = wcstombs(NULL, wstr, 0);
  543. WLog_DBG(WTAG, ">>> %s: origin locale: %s, data: %ls(%d)", __FUNCTION__, setlocale(LC_CTYPE, NULL), wstr.GetData(), len);
  544. if (len == -1) {
  545. return CSimpleStringA(true);
  546. }
  547. len += 1;
  548. char* p = new char[len];
  549. memset(p, 0, len * sizeof(char));
  550. size_t ret = wcstombs(p, wstr, len);
  551. if (ret == (size_t)-1) {
  552. delete[] p;
  553. return CSimpleStringA(true);
  554. }
  555. CSimpleStringA result(p);
  556. delete[] p;
  557. WLog_DBG(WTAG, "<<< %s: data: %s(%d)", __FUNCTION__, result.GetData(), ret);
  558. return result;
  559. #endif //_MSC_VER
  560. }
  561. #ifndef _WIN32
  562. static inline CSimpleStringA CSimpleString16Bit2A(CSimpleString16Bit wstr)
  563. {
  564. CSimpleStringA str;
  565. int n = ::WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
  566. if (n > 0) {
  567. str.m_StringBuf.Init(n);
  568. ::WideCharToMultiByte(CP_ACP, 0, wstr, -1, &str[0], n, NULL, NULL);
  569. }
  570. return str;
  571. }
  572. static inline CSimpleString16Bit CSimpleStringA216Bit(CSimpleStringA str)
  573. {
  574. CSimpleString16Bit wstr;
  575. int n = ::MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
  576. if (n > 0) {
  577. wstr.m_StringBuf.Init(n);
  578. ::MultiByteToWideChar(CP_ACP, 0, str, -1, &wstr[0], n);
  579. }
  580. return wstr;
  581. }
  582. static inline CSimpleStringW CSimpleString16Bit2W(CSimpleString16Bit wstr)
  583. {
  584. CSimpleStringA str = CSimpleString16Bit2A(wstr);
  585. return CSimpleStringA2W(str);
  586. }
  587. static inline CSimpleString16Bit CSimpleStringW216Bit(CSimpleStringW wstr)
  588. {
  589. CSimpleStringA str = CSimpleStringW2A(wstr);
  590. return CSimpleStringA216Bit(str);
  591. }
  592. #endif //NOT _WIN32
  593. #endif //_RVC_SIMPLESTRING_H_