diff --git a/Common/kernel.pro b/Common/kernel.pro index 3aa2c5eca2..8bb5412242 100644 --- a/Common/kernel.pro +++ b/Common/kernel.pro @@ -35,6 +35,8 @@ core_windows { LIBS += -lAdvapi32 LIBS += -lurlmon + LIBS += -lRpcrt4 + LIBS += -lShell32 } core_linux { SOURCES += \ @@ -72,3 +74,28 @@ HEADERS += \ SOURCES += \ ./../DesktopEditor/graphics/Timer.cpp + +# PATH +DEFINES += PATH_USE_DYNAMIC_LIBRARY +HEADERS += ./../DesktopEditor/common/Path.h +SOURCES += ./../DesktopEditor/common/Path.cpp + +# STRINGS +DEFINES += STRINGBUILDER_USE_DYNAMIC_LIBRARY +HEADERS += ./../DesktopEditor/common/StringBuilder.h +SOURCES += ./../DesktopEditor/common/StringBuilder.cpp + +# BASE64 +DEFINES += BASE64_USE_DYNAMIC_LIBRARY +HEADERS += ./../DesktopEditor/common/Base64.h +SOURCES += ./../DesktopEditor/common/Base64.cpp + +# FILE +DEFINES += FILE_USE_DYNAMIC_LIBRARY +HEADERS += ./../DesktopEditor/common/File.h +SOURCES += ./../DesktopEditor/common/File.cpp + +# DIRECTORY +DEFINES += DIRECTORY_USE_DYNAMIC_LIBRARY +HEADERS += ./../DesktopEditor/common/Directory.h +SOURCES += ./../DesktopEditor/common/Directory.cpp diff --git a/DesktopEditor/common/Base64.cpp b/DesktopEditor/common/Base64.cpp new file mode 100644 index 0000000000..8fb1230231 --- /dev/null +++ b/DesktopEditor/common/Base64.cpp @@ -0,0 +1,242 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2018 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Base64.h" + +namespace NSBase64 +{ + int Base64EncodeGetRequiredLength(int nSrcLen, DWORD dwFlags) + { + T_LONG64 nSrcLen4 = static_cast(nSrcLen)*4; + if (nSrcLen4 > INT_MAX) + return -1; + + int nRet = static_cast(nSrcLen4/3); + + if ((dwFlags & B64_BASE64_FLAG_NOPAD) == 0) + nRet += nSrcLen % 3; + + int nCRLFs = nRet / 76 + 1; + int nOnLastLine = nRet % 76; + + if (nOnLastLine) + { + if (nOnLastLine % 4) + nRet += 4-(nOnLastLine % 4); + } + + nCRLFs *= 2; + + if ((dwFlags & B64_BASE64_FLAG_NOCRLF) == 0) + nRet += nCRLFs; + + return nRet; + } + + int Base64DecodeGetRequiredLength(int nSrcLen) + { + return nSrcLen; + } + + int Base64Encode(const BYTE *pbSrcData, int nSrcLen, BYTE* szDest, int *pnDestLen, DWORD dwFlags) + { + static const char s_chBase64EncodingTable[64] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', + 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', + 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; + + if (!pbSrcData || !szDest || !pnDestLen) + return FALSE; + + if (*pnDestLen < Base64EncodeGetRequiredLength(nSrcLen, dwFlags)) + return FALSE; + + int nWritten( 0 ); + int nLen1( (nSrcLen/3)*4 ); + int nLen2( nLen1/76 ); + int nLen3( 19 ); + + for (int i=0; i<=nLen2; i++) + { + if (i==nLen2) + nLen3 = (nLen1%76)/4; + + for (int j=0; j>26); + *szDest++ = s_chBase64EncodingTable[b]; + dwCurr <<= 6; + } + } + nWritten+= nLen3*4; + + if ((dwFlags & B64_BASE64_FLAG_NOCRLF)==0) + { + *szDest++ = '\r'; + *szDest++ = '\n'; + nWritten+= 2; + } + } + + if (nWritten && (dwFlags & B64_BASE64_FLAG_NOCRLF)==0) + { + szDest-= 2; + nWritten -= 2; + } + + nLen2 = (nSrcLen%3) ? (nSrcLen%3 + 1) : 0; + if (nLen2) + { + UINT dwCurr(0); + for (int n=0; n<3; n++) + { + if (n<(nSrcLen%3)) + dwCurr |= *pbSrcData++; + dwCurr <<= 8; + } + for (int k=0; k>26); + *szDest++ = s_chBase64EncodingTable[b]; + dwCurr <<= 6; + } + nWritten+= nLen2; + if ((dwFlags & B64_BASE64_FLAG_NOPAD)==0) + { + nLen3 = nLen2 ? 4-nLen2 : 0; + for (int j=0; j= 'A' && ch <= 'Z') + return ch - 'A' + 0; // 0 range starts at 'A' + if (ch >= 'a' && ch <= 'z') + return ch - 'a' + 26; // 26 range starts at 'a' + if (ch >= '0' && ch <= '9') + return ch - '0' + 52; // 52 range starts at '0' + if (ch == '+') + return 62; + if (ch == '/') + return 63; + return -1; + } + + int Base64Decode(const char* szSrc, int nSrcLen, BYTE *pbDest, int *pnDestLen) + { + // walk the source buffer + // each four character sequence is converted to 3 bytes + // CRLFs and =, and any characters not in the encoding table + // are skiped + + if (szSrc == NULL || pnDestLen == NULL) + return FALSE; + + const char* szSrcEnd = szSrc + nSrcLen; + int nWritten = 0; + + INT bOverflow = (pbDest == NULL) ? TRUE : FALSE; + + while (szSrc < szSrcEnd &&(*szSrc) != 0) + { + DWORD dwCurr = 0; + int i; + int nBits = 0; + for (i=0; i<4; i++) + { + if (szSrc >= szSrcEnd) + break; + int nCh = DecodeBase64Char(*szSrc); + szSrc++; + if (nCh == -1) + { + // skip this char + i--; + continue; + } + dwCurr <<= 6; + dwCurr |= nCh; + nBits += 6; + } + + if(!bOverflow && nWritten + (nBits/8) > (*pnDestLen)) + bOverflow = TRUE; + + // dwCurr has the 3 bytes to write to the output buffer + // left to right + dwCurr <<= 24-nBits; + for (i=0; i> 16); + pbDest++; + } + dwCurr <<= 8; + nWritten++; + } + + } + + *pnDestLen = nWritten; + + if(bOverflow) + { + // if (pbDest != NULL) ATLASSERT(FALSE); + + return FALSE; + } + + return TRUE; + } +} diff --git a/DesktopEditor/common/Base64.h b/DesktopEditor/common/Base64.h index af5a77f02e..292caf9a91 100644 --- a/DesktopEditor/common/Base64.h +++ b/DesktopEditor/common/Base64.h @@ -36,6 +36,13 @@ #include #include "Types.h" +#ifndef BASE64_USE_DYNAMIC_LIBRARY +#define BASE64_DECL_EXPORT +#else +#include "./base_export.h" +#define BASE64_DECL_EXPORT Q_DECL_EXPORT +#endif + namespace NSBase64 { const int B64_BASE64_FLAG_NONE = 0; @@ -44,212 +51,15 @@ namespace NSBase64 #define _BASE64_INT_MAX 2147483647 - inline int Base64EncodeGetRequiredLength(int nSrcLen, DWORD dwFlags = B64_BASE64_FLAG_NONE) - { - T_LONG64 nSrcLen4 = static_cast(nSrcLen)*4; - if (nSrcLen4 > INT_MAX) - return -1; + BASE64_DECL_EXPORT int Base64EncodeGetRequiredLength(int nSrcLen, DWORD dwFlags = B64_BASE64_FLAG_NONE); - int nRet = static_cast(nSrcLen4/3); + BASE64_DECL_EXPORT int Base64DecodeGetRequiredLength(int nSrcLen); - if ((dwFlags & B64_BASE64_FLAG_NOPAD) == 0) - nRet += nSrcLen % 3; + BASE64_DECL_EXPORT int Base64Encode(const BYTE *pbSrcData, int nSrcLen, BYTE* szDest, int *pnDestLen, DWORD dwFlags = B64_BASE64_FLAG_NONE); - int nCRLFs = nRet / 76 + 1; - int nOnLastLine = nRet % 76; + BASE64_DECL_EXPORT int DecodeBase64Char(unsigned int ch); - if (nOnLastLine) - { - if (nOnLastLine % 4) - nRet += 4-(nOnLastLine % 4); - } - - nCRLFs *= 2; - - if ((dwFlags & B64_BASE64_FLAG_NOCRLF) == 0) - nRet += nCRLFs; - - return nRet; - } - - inline int Base64DecodeGetRequiredLength(int nSrcLen) - { - return nSrcLen; - } - - inline INT Base64Encode(const BYTE *pbSrcData, int nSrcLen, BYTE* szDest, int *pnDestLen, DWORD dwFlags = B64_BASE64_FLAG_NONE) - { - static const char s_chBase64EncodingTable[64] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', - 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', - 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', - 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; - - if (!pbSrcData || !szDest || !pnDestLen) - return FALSE; - - if (*pnDestLen < Base64EncodeGetRequiredLength(nSrcLen, dwFlags)) - return FALSE; - - int nWritten( 0 ); - int nLen1( (nSrcLen/3)*4 ); - int nLen2( nLen1/76 ); - int nLen3( 19 ); - - for (int i=0; i<=nLen2; i++) - { - if (i==nLen2) - nLen3 = (nLen1%76)/4; - - for (int j=0; j>26); - *szDest++ = s_chBase64EncodingTable[b]; - dwCurr <<= 6; - } - } - nWritten+= nLen3*4; - - if ((dwFlags & B64_BASE64_FLAG_NOCRLF)==0) - { - *szDest++ = '\r'; - *szDest++ = '\n'; - nWritten+= 2; - } - } - - if (nWritten && (dwFlags & B64_BASE64_FLAG_NOCRLF)==0) - { - szDest-= 2; - nWritten -= 2; - } - - nLen2 = (nSrcLen%3) ? (nSrcLen%3 + 1) : 0; - if (nLen2) - { - UINT dwCurr(0); - for (int n=0; n<3; n++) - { - if (n<(nSrcLen%3)) - dwCurr |= *pbSrcData++; - dwCurr <<= 8; - } - for (int k=0; k>26); - *szDest++ = s_chBase64EncodingTable[b]; - dwCurr <<= 6; - } - nWritten+= nLen2; - if ((dwFlags & B64_BASE64_FLAG_NOPAD)==0) - { - nLen3 = nLen2 ? 4-nLen2 : 0; - for (int j=0; j= 'A' && ch <= 'Z') - return ch - 'A' + 0; // 0 range starts at 'A' - if (ch >= 'a' && ch <= 'z') - return ch - 'a' + 26; // 26 range starts at 'a' - if (ch >= '0' && ch <= '9') - return ch - '0' + 52; // 52 range starts at '0' - if (ch == '+') - return 62; - if (ch == '/') - return 63; - return -1; - } - - inline INT Base64Decode(const char* szSrc, int nSrcLen, BYTE *pbDest, int *pnDestLen) - { - // walk the source buffer - // each four character sequence is converted to 3 bytes - // CRLFs and =, and any characters not in the encoding table - // are skiped - - if (szSrc == NULL || pnDestLen == NULL) - return FALSE; - - const char* szSrcEnd = szSrc + nSrcLen; - int nWritten = 0; - - INT bOverflow = (pbDest == NULL) ? TRUE : FALSE; - - while (szSrc < szSrcEnd &&(*szSrc) != 0) - { - DWORD dwCurr = 0; - int i; - int nBits = 0; - for (i=0; i<4; i++) - { - if (szSrc >= szSrcEnd) - break; - int nCh = DecodeBase64Char(*szSrc); - szSrc++; - if (nCh == -1) - { - // skip this char - i--; - continue; - } - dwCurr <<= 6; - dwCurr |= nCh; - nBits += 6; - } - - if(!bOverflow && nWritten + (nBits/8) > (*pnDestLen)) - bOverflow = TRUE; - - // dwCurr has the 3 bytes to write to the output buffer - // left to right - dwCurr <<= 24-nBits; - for (i=0; i> 16); - pbDest++; - } - dwCurr <<= 8; - nWritten++; - } - - } - - *pnDestLen = nWritten; - - if(bOverflow) - { - // if (pbDest != NULL) ATLASSERT(FALSE); - - return FALSE; - } - - return TRUE; - } + BASE64_DECL_EXPORT int Base64Decode(const char* szSrc, int nSrcLen, BYTE *pbDest, int *pnDestLen); } -#endif//_BUILD_BASE64_CROSSPLATFORM_DEFINE \ No newline at end of file +#endif//_BUILD_BASE64_CROSSPLATFORM_DEFINE diff --git a/DesktopEditor/common/Directory.cpp b/DesktopEditor/common/Directory.cpp new file mode 100644 index 0000000000..244d21d0f6 --- /dev/null +++ b/DesktopEditor/common/Directory.cpp @@ -0,0 +1,472 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2018 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#if defined(_WIN32) || defined (_WIN64) + #include "windows.h" + #include "windef.h" + #include + #include +#elif __linux__ + #include + #include + #include + #include +#elif MAC + #include + #include + #include + #include +#elif _IOS + #include + #include + #include + #include +#endif + +#include "Directory.h" + +namespace NSDirectory +{ +#if !defined(_WIN32) && !defined (_WIN64) + static bool is_directory_exist(char* dir) + { + struct stat st; + bool bRes = (0 == stat(dir, &st)) && S_ISDIR(st.st_mode); + return bRes; + } + + static bool _mkdir (const char *dir) + { + char tmp[MAX_PATH]; + char *p = NULL; + size_t len; + bool res = true; + + snprintf(tmp, sizeof(tmp),"%s",dir); + len = strlen(tmp); + if(tmp[len - 1] == '/') + tmp[len - 1] = 0; + for(p = tmp + 1; *p; p++) + if(*p == '/') { + *p = 0; + res = is_directory_exist(tmp); + if (!res) + res = (0 == mkdir(tmp, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); + *p = '/'; + if (!res) + break; + } + if (res) + res = (0 == mkdir(tmp, S_IRWXU)); + return res; + } +#endif + + void GetFiles2(std::wstring strDirectory, std::vector& oArray, bool bIsRecursion) + { +#if defined(_WIN32) || defined (_WIN64) + WIN32_FIND_DATAW oFD; + + std::wstring sSpec = strDirectory + L"\\*.*"; + HANDLE hRes = FindFirstFileW( sSpec.c_str(), &oFD ); + if( INVALID_HANDLE_VALUE == hRes ) + return; + do + { + sSpec = oFD.cFileName; + if (sSpec != L"." && sSpec != L"..") + { + sSpec = strDirectory + L"\\" + sSpec; + if( !( oFD.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ) + { + oArray.push_back(sSpec); + } + else if (bIsRecursion) + { + GetFiles2(sSpec, oArray, bIsRecursion); + } + } + } while( FindNextFileW( hRes, &oFD ) ); + FindClose( hRes ); +#endif + +#ifdef __linux__ + BYTE* pUtf8 = NULL; + LONG lLen = 0; + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strDirectory.c_str(), strDirectory.length(), pUtf8, lLen, false); + DIR *dp; + struct dirent *dirp; + if((dp = opendir((char*)pUtf8)) != NULL) + { + while ((dirp = readdir(dp)) != NULL) + { + int nType = 0; + if(DT_REG == dirp->d_type) + nType = 2; + else if (DT_DIR == dirp->d_type) + nType = 1; + else if (DT_UNKNOWN == dirp->d_type) + { + // XFS problem + struct stat buff; + std::string sTmp = std::string((char*)pUtf8) + "/" + std::string(dirp->d_name); + stat(sTmp.c_str(), &buff); + if (S_ISREG(buff.st_mode)) + nType = 2; + else if (S_ISDIR(buff.st_mode)) + nType = 1; + } + + if (2 == nType) + { + std::wstring sName = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)dirp->d_name, strlen(dirp->d_name)); + oArray.push_back(strDirectory + L"/" + sName); + } + + if (bIsRecursion && (1 == nType)) + { + if(dirp->d_name[0] != '.') + { + std::wstring sName = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)dirp->d_name, strlen(dirp->d_name)); + GetFiles2(strDirectory + L"/" + sName, oArray, bIsRecursion); + } + } + } + closedir(dp); + } + delete [] pUtf8; +#endif + +#if defined(MAC) || defined (_IOS) + BYTE* pUtf8 = NULL; + LONG lLen = 0; + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strDirectory.c_str(), strDirectory.length(), pUtf8, lLen, false); + DIR *dp; + struct dirent *dirp; + if((dp = opendir((char*)pUtf8)) != NULL) + { + while ((dirp = readdir(dp)) != NULL) + { + if(DT_REG == dirp->d_type) + { + std::wstring sName = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)dirp->d_name, strlen(dirp->d_name)); + oArray.push_back(strDirectory + L"/" + sName); + } + + if (bIsRecursion && DT_DIR == dirp->d_type) + { + if(dirp->d_name[0] != '.') + { + std::wstring sName = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)dirp->d_name, strlen(dirp->d_name)); + GetFiles2(strDirectory + L"/" + sName, oArray, bIsRecursion); + } + } + } + closedir(dp); + } + delete [] pUtf8; + return; +#endif + } + + std::vector GetFiles(std::wstring strDirectory, bool bIsRecursion) + { + std::vector oArray; + + if (!strDirectory.empty()) + { + GetFiles2(strDirectory, oArray, bIsRecursion); + } + return oArray; + } + std::vector GetDirectories(std::wstring strDirectory) + { + std::vector oArray; + +#if defined(_WIN32) || defined (_WIN64) + WIN32_FIND_DATAW oFD; + + std::wstring sSpec = strDirectory + L"\\*"; + HANDLE hRes = FindFirstFileW( sSpec.c_str(), &oFD ); + if( INVALID_HANDLE_VALUE == hRes ) + return oArray; + do + { + sSpec = oFD.cFileName; + if (sSpec != L"." && sSpec != L"..") + { + sSpec = strDirectory + L"\\" + sSpec; + if( oFD.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) + { + oArray.push_back(sSpec); + } + } + } while( FindNextFileW( hRes, &oFD ) ); + FindClose( hRes ); +#elif __linux__ + BYTE* pUtf8 = NULL; + LONG lLen = 0; + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strDirectory.c_str(), strDirectory.length(), pUtf8, lLen, false); + DIR *dp; + struct dirent *dirp; + if((dp = opendir((char*)pUtf8)) != NULL) + { + while ((dirp = readdir(dp)) != NULL) + { + bool bIsDir = false; + if (DT_DIR == dirp->d_type) + bIsDir = true; + else if (DT_UNKNOWN == dirp->d_type) + { + // XFS problem + struct stat buff; + std::string sTmp = std::string((char*)pUtf8) + "/" + std::string(dirp->d_name); + stat(sTmp.c_str(), &buff); + if (S_ISDIR(buff.st_mode)) + bIsDir = true; + } + if(bIsDir) + { + if(dirp->d_name[0] != '.') + { + std::wstring sName = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)dirp->d_name, strlen(dirp->d_name)); + oArray.push_back(strDirectory + L"/" + sName); + } + } + } + closedir(dp); + } + delete [] pUtf8; +#elif MAC + BYTE* pUtf8 = NULL; + LONG lLen = 0; + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strDirectory.c_str(), strDirectory.length(), pUtf8, lLen, false); + DIR *dp; + struct dirent *dirp; + if((dp = opendir((char*)pUtf8)) != NULL) + { + while ((dirp = readdir(dp)) != NULL) + { + if(DT_DIR == dirp->d_type) + { + if(dirp->d_name[0] != '.') + { + std::wstring sName = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)dirp->d_name, strlen(dirp->d_name)); + oArray.push_back(strDirectory + L"/" + sName); + } + } + } + closedir(dp); + } + delete [] pUtf8; +#endif + return oArray; + } + bool Exists(const std::wstring& strDirectory) + { +#if defined(_WIN32) || defined (_WIN64) + DWORD dwAttrib = ::GetFileAttributesW(strDirectory.c_str()); + return (dwAttrib != INVALID_FILE_ATTRIBUTES && 0 != (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); +#elif __linux__ + BYTE* pUtf8 = NULL; + LONG lLen = 0; + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strDirectory.c_str(), strDirectory.length(), pUtf8, lLen, false); + bool bRes = is_directory_exist((char*)pUtf8); + delete [] pUtf8; + return bRes; +#elif MAC + BYTE* pUtf8 = NULL; + LONG lLen = 0; + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strDirectory.c_str(), strDirectory.length(), pUtf8, lLen, false); + struct stat st; + bool bRes = is_directory_exist((char*)pUtf8); + delete [] pUtf8; + return bRes; +#endif + return false; + } + bool CreateDirectory(const std::wstring& strDirectory) + { + if (Exists(strDirectory) == true) return true; + +#if defined(_WIN32) || defined (_WIN64) + return FALSE != ::CreateDirectoryW(strDirectory.c_str(), NULL); +#else + BYTE* pUtf8 = NULL; + LONG lLen = 0; + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strDirectory.c_str(), strDirectory.length(), pUtf8, lLen, false); + struct stat st; + int nRes = 0; + if (stat((char*)pUtf8, &st) == -1) { + nRes = mkdir((char*)pUtf8, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + } + delete [] pUtf8; + return 0 == nRes; +#endif + } + bool CreateDirectories(const std::wstring& strDirectory) + { + if (Exists(strDirectory) == true) return true; + +#if defined(_WIN32) || defined (_WIN64) + DWORD dwAttrib = ::GetFileAttributesW(strDirectory.c_str()); + if (dwAttrib != INVALID_FILE_ATTRIBUTES && 0 != (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) return true; + + int codeResult = ERROR_SUCCESS; + + SECURITY_ATTRIBUTES sa={}; + + if (strDirectory.find(L"./") == 0) + { + std::wstring sDir = NSFile::GetProcessDirectory() + L"/" + strDirectory; + codeResult = SHCreateDirectoryExW(NULL, sDir.c_str(), &sa); + } + else + codeResult = SHCreateDirectoryExW(NULL, strDirectory.c_str(), &sa); + + bool created = false; + if (codeResult == ERROR_SUCCESS) + created = true; + + return created; +#else + std::string pathUtf8 = U_TO_UTF8(strDirectory); + return _mkdir (pathUtf8.c_str()); +#endif + return false; + } + void DeleteDirectory(const std::wstring& strDirectory, bool deleteRoot) + { + std::vector aFiles = GetFiles(strDirectory); + for(size_t i = 0; i < aFiles.size(); ++i) + { + NSFile::CFileBinary::Remove(aFiles[i]); + } + std::vector aDirectories = GetDirectories(strDirectory); + for(size_t i = 0; i < aDirectories.size(); ++i) + { + DeleteDirectory(aDirectories[i]); + } +#if defined(_WIN32) || defined (_WIN64) + if (deleteRoot) RemoveDirectoryW(strDirectory.c_str()); +#elif __linux__ + BYTE* pUtf8 = NULL; + LONG lLen = 0; + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strDirectory.c_str(), strDirectory.length(), pUtf8, lLen, false); + rmdir((char*)pUtf8); + delete [] pUtf8; + + if (deleteRoot = false)CreateDirectory(strDirectory); +#elif MAC + BYTE* pUtf8 = NULL; + LONG lLen = 0; + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strDirectory.c_str(), strDirectory.length(), pUtf8, lLen, false); + rmdir((char*)pUtf8); + delete [] pUtf8; + + if (deleteRoot = false)CreateDirectory(strDirectory); +#endif + } + std::wstring GetFolderPath(const std::wstring& wsFolderPath) + { + int n1 = (int)wsFolderPath.rfind('\\'); + if (n1 < 0) + { + n1 = (int)wsFolderPath.rfind('/'); + if (n1 < 0) + { + return L""; + } + return wsFolderPath.substr(0, n1); + } + return wsFolderPath.substr(0, n1); + } + std::wstring CreateTempFileWithUniqueName (const std::wstring & strFolderPathRoot, std::wstring Prefix) + { + return NSFile::CFileBinary::CreateTempFileWithUniqueName(strFolderPathRoot, Prefix); + } + std::wstring CreateDirectoryWithUniqueName (const std::wstring & strFolderPathRoot) + { +#if defined(_WIN32) || defined (_WIN64) + UUID uuid; + RPC_WSTR str_uuid; + UuidCreate (&uuid); + UuidToStringW (&uuid, &str_uuid); + std::wstring pcTemplate = strFolderPathRoot + FILE_SEPARATOR_STR; + pcTemplate += (wchar_t *) str_uuid; + RpcStringFreeW (&str_uuid); + + int attemps = 10; + while (!CreateDirectory(pcTemplate)) + { + UuidCreate (&uuid); + UuidToStringW (&uuid, &str_uuid); + pcTemplate = strFolderPathRoot + FILE_SEPARATOR_STR; + pcTemplate += (wchar_t *) str_uuid; + RpcStringFreeW (&str_uuid); + attemps--; + + if (0 == attemps) + { + pcTemplate = L""; + } + } + return pcTemplate; +#else + std::string pcTemplate = U_TO_UTF8(strFolderPathRoot) + "/ascXXXXXX"; + char *pcRes = mkdtemp(const_cast (pcTemplate.c_str())); + if (NULL == pcRes) + return L""; + + std::string sRes = pcRes; + return NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)sRes.c_str(), (LONG)sRes.length()); +#endif + } + std::wstring GetTempPath() + { + return NSFile::CFileBinary::GetTempPath(); + } + + int GetFilesCount(const std::wstring& path, const bool& recursive) + { + std::vector arrFiles = NSDirectory::GetFiles(path, recursive); +#if defined(_WIN32) || defined (_WIN64) + return (int)arrFiles.size(); +#endif + return (int)arrFiles.size() + 1; + // ??? + } + bool PathIsDirectory(const std::wstring& pathName) + { + return Exists(pathName); + } +} diff --git a/DesktopEditor/common/Directory.h b/DesktopEditor/common/Directory.h index cdaeea37b1..b4cbb948e4 100644 --- a/DesktopEditor/common/Directory.h +++ b/DesktopEditor/common/Directory.h @@ -37,28 +37,6 @@ #include #include "File.h" -#if defined(_WIN32) || defined (_WIN64) - #include "windows.h" - #include "windef.h" - #include - #include -#elif __linux__ - #include - #include - #include - #include -#elif MAC - #include - #include - #include - #include -#elif _IOS - #include - #include - #include - #include -#endif - #ifndef FILE_SEPARATOR #if defined(_WIN32) || defined(_WIN64) #define FILE_SEPARATOR @@ -71,426 +49,33 @@ #endif #endif +#ifndef DIRECTORY_USE_DYNAMIC_LIBRARY +#define DIRECTORY_DECL_EXPORT +#else +#include "./base_export.h" +#define DIRECTORY_DECL_EXPORT Q_DECL_EXPORT +#endif + namespace NSDirectory { -#if !defined(_WIN32) && !defined (_WIN64) - static bool is_directory_exist(char* dir) - { - struct stat st; - bool bRes = (0 == stat(dir, &st)) && S_ISDIR(st.st_mode); - return bRes; - } - - static bool _mkdir (const char *dir) - { - char tmp[MAX_PATH]; - char *p = NULL; - size_t len; - bool res = true; - - snprintf(tmp, sizeof(tmp),"%s",dir); - len = strlen(tmp); - if(tmp[len - 1] == '/') - tmp[len - 1] = 0; - for(p = tmp + 1; *p; p++) - if(*p == '/') { - *p = 0; - res = is_directory_exist(tmp); - if (!res) - res = (0 == mkdir(tmp, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)); - *p = '/'; - if (!res) - break; - } - if (res) - res = (0 == mkdir(tmp, S_IRWXU)); - return res; - } -#endif - #ifdef _IOS - void GetFiles2_ios(std::wstring strDirectory, std::vector& oArray, bool bIsRecursion); + DIRECTORY_DECL_EXPORT void GetFiles2_ios(std::wstring strDirectory, std::vector& oArray, bool bIsRecursion); #endif - static void GetFiles2(std::wstring strDirectory, std::vector& oArray, bool bIsRecursion = false) - { -#if defined(_WIN32) || defined (_WIN64) - WIN32_FIND_DATAW oFD; + DIRECTORY_DECL_EXPORT void GetFiles2(std::wstring strDirectory, std::vector& oArray, bool bIsRecursion = false); - std::wstring sSpec = strDirectory + L"\\*.*"; - HANDLE hRes = FindFirstFileW( sSpec.c_str(), &oFD ); - if( INVALID_HANDLE_VALUE == hRes ) - return; - do - { - sSpec = oFD.cFileName; - if (sSpec != L"." && sSpec != L"..") - { - sSpec = strDirectory + L"\\" + sSpec; - if( !( oFD.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ) - { - oArray.push_back(sSpec); - } - else if (bIsRecursion) - { - GetFiles2(sSpec, oArray, bIsRecursion); - } - } - } while( FindNextFileW( hRes, &oFD ) ); - FindClose( hRes ); -#endif + DIRECTORY_DECL_EXPORT std::vector GetFiles(std::wstring strDirectory, bool bIsRecursion = false); + DIRECTORY_DECL_EXPORT std::vector GetDirectories(std::wstring strDirectory); + DIRECTORY_DECL_EXPORT bool Exists(const std::wstring& strDirectory); + DIRECTORY_DECL_EXPORT bool CreateDirectory(const std::wstring& strDirectory); + DIRECTORY_DECL_EXPORT bool CreateDirectories(const std::wstring& strDirectory); + DIRECTORY_DECL_EXPORT void DeleteDirectory(const std::wstring& strDirectory, bool deleteRoot = true); + DIRECTORY_DECL_EXPORT std::wstring GetFolderPath(const std::wstring& wsFolderPath); + DIRECTORY_DECL_EXPORT std::wstring CreateTempFileWithUniqueName (const std::wstring & strFolderPathRoot, std::wstring Prefix); + DIRECTORY_DECL_EXPORT std::wstring CreateDirectoryWithUniqueName (const std::wstring & strFolderPathRoot); + DIRECTORY_DECL_EXPORT std::wstring GetTempPath(); -#ifdef __linux__ - BYTE* pUtf8 = NULL; - LONG lLen = 0; - NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strDirectory.c_str(), strDirectory.length(), pUtf8, lLen, false); - DIR *dp; - struct dirent *dirp; - if((dp = opendir((char*)pUtf8)) != NULL) - { - while ((dirp = readdir(dp)) != NULL) - { - int nType = 0; - if(DT_REG == dirp->d_type) - nType = 2; - else if (DT_DIR == dirp->d_type) - nType = 1; - else if (DT_UNKNOWN == dirp->d_type) - { - // XFS problem - struct stat buff; - std::string sTmp = std::string((char*)pUtf8) + "/" + std::string(dirp->d_name); - stat(sTmp.c_str(), &buff); - if (S_ISREG(buff.st_mode)) - nType = 2; - else if (S_ISDIR(buff.st_mode)) - nType = 1; - } - - if (2 == nType) - { - std::wstring sName = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)dirp->d_name, strlen(dirp->d_name)); - oArray.push_back(strDirectory + L"/" + sName); - } - - if (bIsRecursion && (1 == nType)) - { - if(dirp->d_name[0] != '.') - { - std::wstring sName = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)dirp->d_name, strlen(dirp->d_name)); - GetFiles2(strDirectory + L"/" + sName, oArray, bIsRecursion); - } - } - } - closedir(dp); - } - delete [] pUtf8; -#endif - -#if defined(MAC) || defined (_IOS) - BYTE* pUtf8 = NULL; - LONG lLen = 0; - NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strDirectory.c_str(), strDirectory.length(), pUtf8, lLen, false); - DIR *dp; - struct dirent *dirp; - if((dp = opendir((char*)pUtf8)) != NULL) - { - while ((dirp = readdir(dp)) != NULL) - { - if(DT_REG == dirp->d_type) - { - std::wstring sName = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)dirp->d_name, strlen(dirp->d_name)); - oArray.push_back(strDirectory + L"/" + sName); - } - - if (bIsRecursion && DT_DIR == dirp->d_type) - { - if(dirp->d_name[0] != '.') - { - std::wstring sName = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)dirp->d_name, strlen(dirp->d_name)); - GetFiles2(strDirectory + L"/" + sName, oArray, bIsRecursion); - } - } - } - closedir(dp); - } - delete [] pUtf8; - return; -#endif - } - - static std::vector GetFiles(std::wstring strDirectory, bool bIsRecursion = false) - { - std::vector oArray; - - if (!strDirectory.empty()) - { - GetFiles2(strDirectory, oArray, bIsRecursion); - } - return oArray; - } - static std::vector GetDirectories(std::wstring strDirectory) - { - std::vector oArray; - -#if defined(_WIN32) || defined (_WIN64) - WIN32_FIND_DATAW oFD; - - std::wstring sSpec = strDirectory + L"\\*"; - HANDLE hRes = FindFirstFileW( sSpec.c_str(), &oFD ); - if( INVALID_HANDLE_VALUE == hRes ) - return oArray; - do - { - sSpec = oFD.cFileName; - if (sSpec != L"." && sSpec != L"..") - { - sSpec = strDirectory + L"\\" + sSpec; - if( oFD.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) - { - oArray.push_back(sSpec); - } - } - } while( FindNextFileW( hRes, &oFD ) ); - FindClose( hRes ); -#elif __linux__ - BYTE* pUtf8 = NULL; - LONG lLen = 0; - NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strDirectory.c_str(), strDirectory.length(), pUtf8, lLen, false); - DIR *dp; - struct dirent *dirp; - if((dp = opendir((char*)pUtf8)) != NULL) - { - while ((dirp = readdir(dp)) != NULL) - { - bool bIsDir = false; - if (DT_DIR == dirp->d_type) - bIsDir = true; - else if (DT_UNKNOWN == dirp->d_type) - { - // XFS problem - struct stat buff; - std::string sTmp = std::string((char*)pUtf8) + "/" + std::string(dirp->d_name); - stat(sTmp.c_str(), &buff); - if (S_ISDIR(buff.st_mode)) - bIsDir = true; - } - if(bIsDir) - { - if(dirp->d_name[0] != '.') - { - std::wstring sName = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)dirp->d_name, strlen(dirp->d_name)); - oArray.push_back(strDirectory + L"/" + sName); - } - } - } - closedir(dp); - } - delete [] pUtf8; -#elif MAC - BYTE* pUtf8 = NULL; - LONG lLen = 0; - NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strDirectory.c_str(), strDirectory.length(), pUtf8, lLen, false); - DIR *dp; - struct dirent *dirp; - if((dp = opendir((char*)pUtf8)) != NULL) - { - while ((dirp = readdir(dp)) != NULL) - { - if(DT_DIR == dirp->d_type) - { - if(dirp->d_name[0] != '.') - { - std::wstring sName = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)dirp->d_name, strlen(dirp->d_name)); - oArray.push_back(strDirectory + L"/" + sName); - } - } - } - closedir(dp); - } - delete [] pUtf8; -#endif - return oArray; - } - static bool Exists(const std::wstring& strDirectory) - { -#if defined(_WIN32) || defined (_WIN64) - DWORD dwAttrib = ::GetFileAttributesW(strDirectory.c_str()); - return (dwAttrib != INVALID_FILE_ATTRIBUTES && 0 != (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); -#elif __linux__ - BYTE* pUtf8 = NULL; - LONG lLen = 0; - NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strDirectory.c_str(), strDirectory.length(), pUtf8, lLen, false); - bool bRes = is_directory_exist((char*)pUtf8); - delete [] pUtf8; - return bRes; -#elif MAC - BYTE* pUtf8 = NULL; - LONG lLen = 0; - NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strDirectory.c_str(), strDirectory.length(), pUtf8, lLen, false); - struct stat st; - bool bRes = is_directory_exist((char*)pUtf8); - delete [] pUtf8; - return bRes; -#endif - return false; - } - static bool CreateDirectory(const std::wstring& strDirectory) - { - if (Exists(strDirectory) == true) return true; - -#if defined(_WIN32) || defined (_WIN64) - return FALSE != ::CreateDirectoryW(strDirectory.c_str(), NULL); -#else - BYTE* pUtf8 = NULL; - LONG lLen = 0; - NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strDirectory.c_str(), strDirectory.length(), pUtf8, lLen, false); - struct stat st; - int nRes = 0; - if (stat((char*)pUtf8, &st) == -1) { - nRes = mkdir((char*)pUtf8, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - } - delete [] pUtf8; - return 0 == nRes; -#endif - } - static bool CreateDirectories(const std::wstring& strDirectory) - { - if (Exists(strDirectory) == true) return true; - -#if defined(_WIN32) || defined (_WIN64) - DWORD dwAttrib = ::GetFileAttributesW(strDirectory.c_str()); - if (dwAttrib != INVALID_FILE_ATTRIBUTES && 0 != (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) return true; - - int codeResult = ERROR_SUCCESS; - - SECURITY_ATTRIBUTES sa={}; - - if (strDirectory.find(L"./") == 0) - { - std::wstring sDir = NSFile::GetProcessDirectory() + L"/" + strDirectory; - codeResult = SHCreateDirectoryExW(NULL, sDir.c_str(), &sa); - } - else - codeResult = SHCreateDirectoryExW(NULL, strDirectory.c_str(), &sa); - - bool created = false; - if (codeResult == ERROR_SUCCESS) - created = true; - - return created; -#else - std::string pathUtf8 = U_TO_UTF8(strDirectory); - return _mkdir (pathUtf8.c_str()); -#endif - return false; - } - static void DeleteDirectory(const std::wstring& strDirectory, bool deleteRoot = true) - { - std::vector aFiles = GetFiles(strDirectory); - for(size_t i = 0; i < aFiles.size(); ++i) - { - NSFile::CFileBinary::Remove(aFiles[i]); - } - std::vector aDirectories = GetDirectories(strDirectory); - for(size_t i = 0; i < aDirectories.size(); ++i) - { - DeleteDirectory(aDirectories[i]); - } -#if defined(_WIN32) || defined (_WIN64) - if (deleteRoot) RemoveDirectoryW(strDirectory.c_str()); -#elif __linux__ - BYTE* pUtf8 = NULL; - LONG lLen = 0; - NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strDirectory.c_str(), strDirectory.length(), pUtf8, lLen, false); - rmdir((char*)pUtf8); - delete [] pUtf8; - - if (deleteRoot = false)CreateDirectory(strDirectory); -#elif MAC - BYTE* pUtf8 = NULL; - LONG lLen = 0; - NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strDirectory.c_str(), strDirectory.length(), pUtf8, lLen, false); - rmdir((char*)pUtf8); - delete [] pUtf8; - - if (deleteRoot = false)CreateDirectory(strDirectory); -#endif - } - static std::wstring GetFolderPath(const std::wstring& wsFolderPath) - { - int n1 = (int)wsFolderPath.rfind('\\'); - if (n1 < 0) - { - n1 = (int)wsFolderPath.rfind('/'); - if (n1 < 0) - { - return L""; - } - return wsFolderPath.substr(0, n1); - } - return wsFolderPath.substr(0, n1); - } - static std::wstring CreateTempFileWithUniqueName (const std::wstring & strFolderPathRoot, std::wstring Prefix) - { - return NSFile::CFileBinary::CreateTempFileWithUniqueName(strFolderPathRoot, Prefix); - } - static std::wstring CreateDirectoryWithUniqueName (const std::wstring & strFolderPathRoot) - { -#if defined(_WIN32) || defined (_WIN64) - UUID uuid; - RPC_WSTR str_uuid; - UuidCreate (&uuid); - UuidToStringW (&uuid, &str_uuid); - std::wstring pcTemplate = strFolderPathRoot + FILE_SEPARATOR_STR; - pcTemplate += (wchar_t *) str_uuid; - RpcStringFreeW (&str_uuid); - - int attemps = 10; - while (!CreateDirectory(pcTemplate)) - { - UuidCreate (&uuid); - UuidToStringW (&uuid, &str_uuid); - pcTemplate = strFolderPathRoot + FILE_SEPARATOR_STR; - pcTemplate += (wchar_t *) str_uuid; - RpcStringFreeW (&str_uuid); - attemps--; - - if (0 == attemps) - { - pcTemplate = L""; - } - } - return pcTemplate; -#else - std::string pcTemplate = U_TO_UTF8(strFolderPathRoot) + "/ascXXXXXX"; - char *pcRes = mkdtemp(const_cast (pcTemplate.c_str())); - if (NULL == pcRes) - return L""; - - std::string sRes = pcRes; - return NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)sRes.c_str(), (LONG)sRes.length()); -#endif - } - static std::wstring GetTempPath() - { - return NSFile::CFileBinary::GetTempPath(); - } - - static int GetFilesCount(const std::wstring& path, const bool& recursive) - { - std::vector arrFiles = NSDirectory::GetFiles(path, recursive); -#if defined(_WIN32) || defined (_WIN64) - return (int)arrFiles.size(); -#endif - return (int)arrFiles.size() + 1; - // ??? - } -#if !defined(_WIN32) && !defined (_WIN64) - static bool PathIsDirectory(const std::wstring& pathName) - { - return Exists(pathName); - } -#endif + DIRECTORY_DECL_EXPORT int GetFilesCount(const std::wstring& path, const bool& recursive); + DIRECTORY_DECL_EXPORT bool PathIsDirectory(const std::wstring& pathName); } #endif //_BUILD_DIRECTORY_CROSSPLATFORM_H_ diff --git a/DesktopEditor/common/File.cpp b/DesktopEditor/common/File.cpp index 9752b05d87..eb20a88056 100644 --- a/DesktopEditor/common/File.cpp +++ b/DesktopEditor/common/File.cpp @@ -30,46 +30,583 @@ * */ -#include "File.h" +#include +#include +#include "errno.h" +#include + +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) + #include + #include +#endif + +#if defined(__linux__) || defined(_MAC) && !defined(_IOS) +#include +#include +#endif #ifdef _IOS +#include +#endif -#import +#ifdef _MAC +#include +#endif -static const char* fileSystemRepresentation(const std::wstring& sFileName) +#ifndef MAX_PATH + #define MAX_PATH 1024 +#endif + +#include "File.h" + +namespace NSFile { - NSString *path = [[NSString alloc] initWithBytes:(char*)sFileName.data() - length:sFileName.size()* sizeof(wchar_t) - encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF32LE)]; - - return (const char*)[path fileSystemRepresentation]; + std::wstring CUtf8Converter::GetUnicodeFromCharPtr(const char* pData, LONG lCount, INT bIsUtf8) + { + if (bIsUtf8) + return GetUnicodeStringFromUTF8((BYTE*)pData, lCount); + + wchar_t* pUnicode = new wchar_t[lCount + 1]; + for (LONG i = 0; i < lCount; ++i) + pUnicode[i] = (wchar_t)(BYTE)pData[i]; + + pUnicode[lCount] = 0; + + std::wstring s(pUnicode, lCount); + RELEASEARRAYOBJECTS(pUnicode); + + return s; + } + std::wstring CUtf8Converter::GetUnicodeFromCharPtr(const std::string& sParam, INT bIsUtf8) + { + return GetUnicodeFromCharPtr(sParam.c_str(), (LONG)sParam.length(), bIsUtf8); + } + std::wstring CUtf8Converter::GetUnicodeStringFromUTF8_4bytes( BYTE* pBuffer, LONG lCount ) + { + WCHAR* pUnicodeString = new WCHAR[lCount + 1]; + LONG lIndexUnicode = 0; + + LONG lIndex = 0; + while (lIndex < lCount) + { + BYTE byteMain = pBuffer[lIndex]; + if (0x00 == (byteMain & 0x80)) + { + // 1 byte + pUnicodeString[lIndexUnicode++] = (WCHAR)byteMain; + ++lIndex; + } + else if (0x00 == (byteMain & 0x20)) + { + // 2 byte + int val = (int)(((byteMain & 0x1F) << 6) | + (pBuffer[lIndex + 1] & 0x3F)); + pUnicodeString[lIndexUnicode++] = (WCHAR)(val); + lIndex += 2; + } + else if (0x00 == (byteMain & 0x10)) + { + // 3 byte + int val = (int)(((byteMain & 0x0F) << 12) | + ((pBuffer[lIndex + 1] & 0x3F) << 6) | + (pBuffer[lIndex + 2] & 0x3F)); + pUnicodeString[lIndexUnicode++] = (WCHAR)(val); + lIndex += 3; + } + else if (0x00 == (byteMain & 0x0F)) + { + // 4 byte + int val = (int)(((byteMain & 0x07) << 18) | + ((pBuffer[lIndex + 1] & 0x3F) << 12) | + ((pBuffer[lIndex + 2] & 0x3F) << 6) | + (pBuffer[lIndex + 3] & 0x3F)); + pUnicodeString[lIndexUnicode++] = (WCHAR)(val); + lIndex += 4; + } + else if (0x00 == (byteMain & 0x08)) + { + // 4 byte + int val = (int)(((byteMain & 0x07) << 18) | + ((pBuffer[lIndex + 1] & 0x3F) << 12) | + ((pBuffer[lIndex + 2] & 0x3F) << 6) | + (pBuffer[lIndex + 3] & 0x3F)); + pUnicodeString[lIndexUnicode++] = (WCHAR)(val); + lIndex += 4; + } + else if (0x00 == (byteMain & 0x04)) + { + // 5 byte + int val = (int)(((byteMain & 0x03) << 24) | + ((pBuffer[lIndex + 1] & 0x3F) << 18) | + ((pBuffer[lIndex + 2] & 0x3F) << 12) | + ((pBuffer[lIndex + 3] & 0x3F) << 6) | + (pBuffer[lIndex + 4] & 0x3F)); + pUnicodeString[lIndexUnicode++] = (WCHAR)(val); + lIndex += 5; + } + else + { + // 6 byte + int val = (int)(((byteMain & 0x01) << 30) | + ((pBuffer[lIndex + 1] & 0x3F) << 24) | + ((pBuffer[lIndex + 2] & 0x3F) << 18) | + ((pBuffer[lIndex + 3] & 0x3F) << 12) | + ((pBuffer[lIndex + 4] & 0x3F) << 6) | + (pBuffer[lIndex + 5] & 0x3F)); + pUnicodeString[lIndexUnicode++] = (WCHAR)(val); + lIndex += 5; + } + } + + pUnicodeString[lIndexUnicode] = 0; + + std::wstring strRes(pUnicodeString); + + delete [] pUnicodeString; + + return strRes; + } + std::wstring CUtf8Converter::GetUnicodeStringFromUTF8_2bytes( BYTE* pBuffer, LONG lCount ) + { + WCHAR* pUnicodeString = new WCHAR[lCount + 1]; + WCHAR* pStart = pUnicodeString; + + LONG lIndex = 0; + while (lIndex < lCount) + { + BYTE byteMain = pBuffer[lIndex]; + if (0x00 == (byteMain & 0x80)) + { + // 1 byte + *pUnicodeString++ = (WCHAR)byteMain; + ++lIndex; + } + else if (0x00 == (byteMain & 0x20)) + { + // 2 byte + int val = (int)(((byteMain & 0x1F) << 6) | + (pBuffer[lIndex + 1] & 0x3F)); + *pUnicodeString++ = (WCHAR)(val); + lIndex += 2; + } + else if (0x00 == (byteMain & 0x10)) + { + // 3 byte + int val = (int)(((byteMain & 0x0F) << 12) | + ((pBuffer[lIndex + 1] & 0x3F) << 6) | + (pBuffer[lIndex + 2] & 0x3F)); + + WriteUtf16_WCHAR(val, pUnicodeString); + lIndex += 3; + } + else if (0x00 == (byteMain & 0x0F)) + { + // 4 byte + int val = (int)(((byteMain & 0x07) << 18) | + ((pBuffer[lIndex + 1] & 0x3F) << 12) | + ((pBuffer[lIndex + 2] & 0x3F) << 6) | + (pBuffer[lIndex + 3] & 0x3F)); + + WriteUtf16_WCHAR(val, pUnicodeString); + lIndex += 4; + } + else if (0x00 == (byteMain & 0x08)) + { + // 4 byte + int val = (int)(((byteMain & 0x07) << 18) | + ((pBuffer[lIndex + 1] & 0x3F) << 12) | + ((pBuffer[lIndex + 2] & 0x3F) << 6) | + (pBuffer[lIndex + 3] & 0x3F)); + + WriteUtf16_WCHAR(val, pUnicodeString); + lIndex += 4; + } + else if (0x00 == (byteMain & 0x04)) + { + // 5 byte + int val = (int)(((byteMain & 0x03) << 24) | + ((pBuffer[lIndex + 1] & 0x3F) << 18) | + ((pBuffer[lIndex + 2] & 0x3F) << 12) | + ((pBuffer[lIndex + 3] & 0x3F) << 6) | + (pBuffer[lIndex + 4] & 0x3F)); + + WriteUtf16_WCHAR(val, pUnicodeString); + lIndex += 5; + } + else + { + // 6 byte + int val = (int)(((byteMain & 0x01) << 30) | + ((pBuffer[lIndex + 1] & 0x3F) << 24) | + ((pBuffer[lIndex + 2] & 0x3F) << 18) | + ((pBuffer[lIndex + 3] & 0x3F) << 12) | + ((pBuffer[lIndex + 4] & 0x3F) << 6) | + (pBuffer[lIndex + 5] & 0x3F)); + + WriteUtf16_WCHAR(val, pUnicodeString); + lIndex += 5; + } + } + + *pUnicodeString++ = 0; + + std::wstring strRes(pStart); + + delete [] pStart; + + return strRes; + } + + std::wstring CUtf8Converter::GetUnicodeStringFromUTF8( BYTE* pBuffer, LONG lCount ) + { + if (sizeof(WCHAR) == 2) + return GetUnicodeStringFromUTF8_2bytes(pBuffer, lCount); + return GetUnicodeStringFromUTF8_4bytes(pBuffer, lCount); + } + + void CUtf8Converter::GetUtf8StringFromUnicode_4bytes(const wchar_t* pUnicodes, LONG lCount, BYTE*& pData, LONG& lOutputCount, bool bIsBOM) + { + if (NULL == pData) + { + pData = new BYTE[6 * lCount + 3 + 1 ]; + } + + BYTE* pCodesCur = pData; + if (bIsBOM) + { + pCodesCur[0] = 0xEF; + pCodesCur[1] = 0xBB; + pCodesCur[2] = 0xBF; + pCodesCur += 3; + } + + const wchar_t* pEnd = pUnicodes + lCount; + const wchar_t* pCur = pUnicodes; + + while (pCur < pEnd) + { + unsigned int code = (unsigned int)*pCur++; + + if (code < 0x80) + { + *pCodesCur++ = (BYTE)code; + } + else if (code < 0x0800) + { + *pCodesCur++ = 0xC0 | (code >> 6); + *pCodesCur++ = 0x80 | (code & 0x3F); + } + else if (code < 0x10000) + { + *pCodesCur++ = 0xE0 | (code >> 12); + *pCodesCur++ = 0x80 | (code >> 6 & 0x3F); + *pCodesCur++ = 0x80 | (code & 0x3F); + } + else if (code < 0x1FFFFF) + { + *pCodesCur++ = 0xF0 | (code >> 18); + *pCodesCur++ = 0x80 | (code >> 12 & 0x3F); + *pCodesCur++ = 0x80 | (code >> 6 & 0x3F); + *pCodesCur++ = 0x80 | (code & 0x3F); + } + else if (code < 0x3FFFFFF) + { + *pCodesCur++ = 0xF8 | (code >> 24); + *pCodesCur++ = 0x80 | (code >> 18 & 0x3F); + *pCodesCur++ = 0x80 | (code >> 12 & 0x3F); + *pCodesCur++ = 0x80 | (code >> 6 & 0x3F); + *pCodesCur++ = 0x80 | (code & 0x3F); + } + else if (code < 0x7FFFFFFF) + { + *pCodesCur++ = 0xFC | (code >> 30); + *pCodesCur++ = 0x80 | (code >> 24 & 0x3F); + *pCodesCur++ = 0x80 | (code >> 18 & 0x3F); + *pCodesCur++ = 0x80 | (code >> 12 & 0x3F); + *pCodesCur++ = 0x80 | (code >> 6 & 0x3F); + *pCodesCur++ = 0x80 | (code & 0x3F); + } + } + + lOutputCount = (LONG)(pCodesCur - pData); + *pCodesCur++ = 0; + } + + void CUtf8Converter::GetUtf8StringFromUnicode_2bytes(const wchar_t* pUnicodes, LONG lCount, BYTE*& pData, LONG& lOutputCount, bool bIsBOM) + { + if (NULL == pData) + { + pData = new BYTE[6 * lCount + 3 + 1]; + } + + BYTE* pCodesCur = pData; + if (bIsBOM) + { + pCodesCur[0] = 0xEF; + pCodesCur[1] = 0xBB; + pCodesCur[2] = 0xBF; + pCodesCur += 3; + } + + const wchar_t* pEnd = pUnicodes + lCount; + const wchar_t* pCur = pUnicodes; + + while (pCur < pEnd) + { + unsigned int code = (unsigned int)*pCur++; + if (code >= 0xD800 && code <= 0xDFFF && pCur < pEnd) + { + code = 0x10000 + (((code & 0x3FF) << 10) | (0x03FF & *pCur++)); + } + + if (code < 0x80) + { + *pCodesCur++ = (BYTE)code; + } + else if (code < 0x0800) + { + *pCodesCur++ = 0xC0 | (code >> 6); + *pCodesCur++ = 0x80 | (code & 0x3F); + } + else if (code < 0x10000) + { + *pCodesCur++ = 0xE0 | (code >> 12); + *pCodesCur++ = 0x80 | ((code >> 6) & 0x3F); + *pCodesCur++ = 0x80 | (code & 0x3F); + } + else if (code < 0x1FFFFF) + { + *pCodesCur++ = 0xF0 | (code >> 18); + *pCodesCur++ = 0x80 | ((code >> 12) & 0x3F); + *pCodesCur++ = 0x80 | ((code >> 6) & 0x3F); + *pCodesCur++ = 0x80 | (code & 0x3F); + } + else if (code < 0x3FFFFFF) + { + *pCodesCur++ = 0xF8 | (code >> 24); + *pCodesCur++ = 0x80 | ((code >> 18) & 0x3F); + *pCodesCur++ = 0x80 | ((code >> 12) & 0x3F); + *pCodesCur++ = 0x80 | ((code >> 6) & 0x3F); + *pCodesCur++ = 0x80 | (code & 0x3F); + } + else if (code < 0x7FFFFFFF) + { + *pCodesCur++ = 0xFC | (code >> 30); + *pCodesCur++ = 0x80 | ((code >> 24) & 0x3F); + *pCodesCur++ = 0x80 | ((code >> 18) & 0x3F); + *pCodesCur++ = 0x80 | ((code >> 12) & 0x3F); + *pCodesCur++ = 0x80 | ((code >> 6) & 0x3F); + *pCodesCur++ = 0x80 | (code & 0x3F); + } + } + + lOutputCount = (LONG)(pCodesCur - pData); + *pCodesCur++ = 0; + } + + void CUtf8Converter::GetUtf8StringFromUnicode(const wchar_t* pUnicodes, LONG lCount, BYTE*& pData, LONG& lOutputCount, bool bIsBOM) + { + if (sizeof(WCHAR) == 2) + return GetUtf8StringFromUnicode_2bytes(pUnicodes, lCount, pData, lOutputCount, bIsBOM); + return GetUtf8StringFromUnicode_4bytes(pUnicodes, lCount, pData, lOutputCount, bIsBOM); + } + + std::string CUtf8Converter::GetUtf8StringFromUnicode2(const wchar_t* pUnicodes, LONG lCount, bool bIsBOM) + { + BYTE* pData = NULL; + LONG lLen = 0; + + GetUtf8StringFromUnicode(pUnicodes, lCount, pData, lLen, bIsBOM); + + std::string s((char*)pData, lLen); + + RELEASEARRAYOBJECTS(pData); + return s; + } + + std::string CUtf8Converter::GetUtf8StringFromUnicode(const std::wstring& sData) + { + return GetUtf8StringFromUnicode2(sData.c_str(), (LONG)sData.length()); + } + + // utf16 + void CUtf8Converter::GetUtf16StringFromUnicode_4bytes(const wchar_t* pUnicodes, LONG lCount, BYTE*& pData, int& lOutputCount, bool bIsBOM) + { + if (NULL == pData) + { + pData = new BYTE[4 * lCount + 3 + 2]; + } + + BYTE* pCodesCur = pData; + if (bIsBOM) + { + pCodesCur[0] = 0xEF; + pCodesCur[1] = 0xBB; + pCodesCur[2] = 0xBF; + pCodesCur += 3; + } + + const wchar_t* pEnd = pUnicodes + lCount; + const wchar_t* pCur = pUnicodes; + + while (pCur < pEnd) + { + unsigned int code = (unsigned int)*pCur++; + + if (code <= 0xFFFF) + { + USHORT usCode = (USHORT)(code & 0xFFFF); + memcpy(pCodesCur, &usCode, 2); + pCodesCur += 2; + } + else + { + code -= 0x10000; + code &= 0xFFFFF; + + USHORT us1 = 0xD800 | ((code >> 10) & 0x03FF); + USHORT us2 = 0xDC00 | (code & 0x03FF); + + memcpy(pCodesCur, &us1, 2); + pCodesCur += 2; + + memcpy(pCodesCur, &us2, 2); + pCodesCur += 2; + } + } + + lOutputCount = (LONG)(pCodesCur - pData); + *pCodesCur++ = 0; + *pCodesCur++ = 0; + } + + void CUtf8Converter::GetUtf16StringFromUnicode_4bytes2(const wchar_t* pUnicodes, LONG lCount, CStringUtf16& data) + { + GetUtf16StringFromUnicode_4bytes(pUnicodes, lCount, data.Data, data.Length); + } + + std::wstring CUtf8Converter::GetWStringFromUTF16(const CStringUtf16& data) + { + if (0 == data.Length) + return L""; + + if (sizeof(wchar_t) == 2) + return std::wstring((wchar_t*)data.Data, data.Length / 2); + + int nCount = data.Length / 2; + USHORT* pShort = (USHORT*)data.Data; + + wchar_t* pWChar = new wchar_t[nCount + 1]; + wchar_t* pWCurrent = pWChar; + + int nCurrent = 0; + while (nCurrent < nCount) + { + if (*pShort < 0xD800 || *pShort > 0xDBFF) + { + *pWCurrent = (wchar_t)(*pShort); + ++pShort; + ++nCurrent; + } + else + { + *pWCurrent = (wchar_t)(((((pShort[0] - 0xD800) & 0x03FF) << 10) | ((pShort[1] - 0xDC00) & 0x03FF)) + 0x10000); + pShort += 2; + nCurrent += 2; + } + ++pWCurrent; + } + + std::wstring sRet(pWChar, pWCurrent - pWChar); + + RELEASEARRAYOBJECTS(pWChar); + return sRet; + } + std::wstring CUtf8Converter::GetWStringFromUTF16(const unsigned short* pUtf16, LONG lCount) + { + CStringUtf16 oString; + oString.Data = (BYTE*)pUtf16; + oString.Length = lCount * 2; + std::wstring wsResult = GetWStringFromUTF16(oString); + oString.Data = NULL; + return wsResult; + } } namespace NSFile { + CFileBinary::CFileBinary() + { + m_pFile = NULL; + m_lFilePosition = 0; + m_lFileSize = 0; + } + CFileBinary::~CFileBinary() + { + CloseFile(); + } + + void CFileBinary::CloseFile() + { + m_lFilePosition = 0; + m_lFileSize = 0; + + if (m_pFile != NULL) + { + fclose(m_pFile); + m_pFile = NULL; + } + } + + FILE* CFileBinary::GetFileNative() + { + return m_pFile; + } + long CFileBinary::GetFileSize() + { + return m_lFileSize; + } + long CFileBinary::GetFilePosition() + { + return m_lFilePosition; + } + +#ifdef _IOS + + #import + + static const char* fileSystemRepresentation(const std::wstring& sFileName) + { + NSString *path = [[NSString alloc] initWithBytes:(char*)sFileName.data() + length:sFileName.size()* sizeof(wchar_t) + encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF32LE)]; + + return (const char*)[path fileSystemRepresentation]; + } + bool CFileBinary::OpenFile(const std::wstring& sFileName, bool bRewrite) { m_pFile = fopen(fileSystemRepresentation(sFileName), bRewrite ? "rb+" : "rb"); - + if (NULL == m_pFile) { #if DEBUG // printf ("NSFile::OpenFile - error open file : %s\n",strerror(errno)); #endif return false; } - + fseek(m_pFile, 0, SEEK_END); m_lFileSize = ftell(m_pFile); fseek(m_pFile, 0, SEEK_SET); - + m_lFilePosition = 0; - + if (0 < sFileName.length()) { if (((wchar_t)'/') == sFileName.c_str()[sFileName.length() - 1]) m_lFileSize = 0x7FFFFFFF; } - + unsigned int err = 0x7FFFFFFF; unsigned int cur = (unsigned int)m_lFileSize; if (err == cur) @@ -77,24 +614,652 @@ namespace NSFile CloseFile(); return false; } - + return true; } - + bool CFileBinary::CreateFileW(const std::wstring& sFileName) { m_pFile = fopen(fileSystemRepresentation(sFileName), "wb"); - + if (NULL == m_pFile) { #if DEBUG // printf ("NSFile::CreateFileW - error create file : %s\n",strerror(errno)); #endif return false; } - + m_lFilePosition = 0; return true; } } +#else + + bool CFileBinary::OpenFile(const std::wstring& sFileName, bool bRewrite) + { +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) + if ( 0 != _wfopen_s(&m_pFile, sFileName.c_str(), bRewrite ? L"rb+" : L"rb")) + return false; +#else + BYTE* pUtf8 = NULL; + LONG lLen = 0; + CUtf8Converter::GetUtf8StringFromUnicode(sFileName.c_str(), sFileName.length(), pUtf8, lLen, false); + m_pFile = fopen((char*)pUtf8, bRewrite ? "rb+" : "rb"); + + delete [] pUtf8; #endif + if (NULL == m_pFile) + return false; + + fseek(m_pFile, 0, SEEK_END); + m_lFileSize = ftell(m_pFile); + fseek(m_pFile, 0, SEEK_SET); + + m_lFilePosition = 0; + + if (0 < sFileName.length()) + { + if (((wchar_t)'/') == sFileName.c_str()[sFileName.length() - 1]) + m_lFileSize = 0x7FFFFFFF; + } + + unsigned int err = 0x7FFFFFFF; + unsigned int cur = (unsigned int)m_lFileSize; + if (err == cur) + { + CloseFile(); + return false; + } + + return true; + } + + bool CFileBinary::CreateFileW(const std::wstring& sFileName) + { +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) + if ( 0 != _wfopen_s(&m_pFile, sFileName.c_str(), L"wb")) + return false; +#else + BYTE* pUtf8 = NULL; + LONG lLen = 0; + CUtf8Converter::GetUtf8StringFromUnicode(sFileName.c_str(), sFileName.length(), pUtf8, lLen, false); + m_pFile = fopen((char*)pUtf8, "wb"); + delete [] pUtf8; +#endif + if (NULL == m_pFile) + return false; + + m_lFilePosition = 0; + return true; + } + +#endif + + bool CFileBinary::CreateTempFile() + { +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) + if (0 != tmpfile_s(&m_pFile)) + return false; +#else + m_pFile = tmpfile(); + if (NULL == m_pFile) + return false; +#endif + m_lFilePosition = 0; + return true; + } + bool CFileBinary::SeekFile(int lFilePosition, int nSeekMode) + { + if (!m_pFile) + return false; + + m_lFilePosition = fseek(m_pFile, lFilePosition, nSeekMode); + return true; + } + bool CFileBinary::ReadFile(BYTE* pData, DWORD nBytesToRead, DWORD& dwSizeRead) + { + if (!m_pFile) + return false; + + dwSizeRead = (DWORD)fread((void*)pData, 1, nBytesToRead, m_pFile); + return true; + } + bool CFileBinary::WriteFile(const BYTE* pData, DWORD nBytesCount) + { + if (!m_pFile) + return false; + + size_t nCountWrite = fwrite((const void*)pData, 1, nBytesCount, m_pFile); + return true; + } + long CFileBinary::TellFile() + { + if (!m_pFile) + return 0; + + return ftell(m_pFile); + } + long CFileBinary::SizeFile() + { + if (!m_pFile) + return 0; + + long lPos = TellFile(); + fseek(m_pFile, 0, SEEK_END); + m_lFileSize = ftell(m_pFile); + fseek(m_pFile, lPos, SEEK_SET); + + return m_lFileSize; + } + void CFileBinary::WriteStringUTF8(const std::wstring& strXml, bool bIsBOM) + { + BYTE* pData = NULL; + LONG lLen = 0; + + CUtf8Converter::GetUtf8StringFromUnicode(strXml.c_str(), (LONG)strXml.length(), pData, lLen, bIsBOM); + + WriteFile(pData, lLen); + + RELEASEARRAYOBJECTS(pData); + } + bool CFileBinary::ReadAllBytes(const std::wstring& strFileName, BYTE** ppData, DWORD& nBytesCount) + { + *ppData = NULL; + nBytesCount = 0; + bool bRes = false; + CFileBinary oFileBinary; + if (oFileBinary.OpenFile(strFileName)) + { + long nFileSize = oFileBinary.GetFileSize(); + BYTE* pData = new BYTE[nFileSize]; + DWORD dwSizeRead; + if (oFileBinary.ReadFile(pData, nFileSize, dwSizeRead)) + { + oFileBinary.CloseFile(); + *ppData = pData; + nBytesCount = dwSizeRead; + bRes = true; + } + else + RELEASEARRAYOBJECTS(pData); + } + return bRes; + } + bool CFileBinary::ReadAllTextUtf8(const std::wstring& strFileName, std::wstring& sData) + { + bool bRes = false; + BYTE* pData = NULL; + DWORD nDataSize; + if (CFileBinary::ReadAllBytes(strFileName, &pData, nDataSize)) + { + //remove BOM if exist + BYTE* pDataStart = pData; + DWORD nBOMSize = 3; + if (nDataSize > nBOMSize && 0xef == pDataStart[0] && 0xbb == pDataStart[1] && 0xbf == pDataStart[2]) + { + pDataStart += nBOMSize; + nDataSize -= nBOMSize; + } + sData = CUtf8Converter::GetUnicodeStringFromUTF8(pDataStart, nDataSize); + RELEASEARRAYOBJECTS(pData); + bRes = true; + } + return bRes; + } + bool CFileBinary::ReadAllTextUtf8A(const std::wstring& strFileName, std::string& sData) + { + bool bRes = false; + BYTE* pData = NULL; + DWORD nDataSize; + if (CFileBinary::ReadAllBytes(strFileName, &pData, nDataSize)) + { + //remove BOM if exist + BYTE* pDataStart = pData; + DWORD nBOMSize = 3; + if (nDataSize > nBOMSize && 0xef == pDataStart[0] && 0xbb == pDataStart[1] && 0xbf == pDataStart[2]) + { + pDataStart += nBOMSize; + nDataSize -= nBOMSize; + } + sData = std::string((char*)pDataStart, nDataSize); + RELEASEARRAYOBJECTS(pData); + bRes = true; + } + return bRes; + } + bool CFileBinary::SaveToFile(const std::wstring& strFileName, const std::wstring& strXml, bool bIsBOM) + { + CFileBinary oFile; + oFile.CreateFileW(strFileName); + oFile.WriteStringUTF8(strXml, bIsBOM); + oFile.CloseFile(); + return true; + } + bool CFileBinary::Exists(const std::wstring& strFileName) + { +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) + FILE* pFile = NULL; + if ( 0 != _wfopen_s( &pFile, strFileName.c_str(), L"rb")) + return false; +#else + BYTE* pUtf8 = NULL; + LONG lLen = 0; + CUtf8Converter::GetUtf8StringFromUnicode(strFileName.c_str(), strFileName.length(), pUtf8, lLen, false); + FILE* pFile = fopen((char*)pUtf8, "rb"); + delete [] pUtf8; +#endif + if (NULL != pFile) + { + fclose(pFile); + return true; + } + else + return false; + } + bool CFileBinary::Copy(const std::wstring& strSrc, const std::wstring& strDst) + { + if (strSrc == strDst) + return true; + + std::ifstream src; + std::ofstream dst; + + int nLenBuffer = 1024 * 1024; // 10 + CFileBinary oFile; + if (oFile.OpenFile(strSrc)) + { + int nFileSize = (int)oFile.GetFileSize(); + if (nFileSize < nLenBuffer) + nLenBuffer = nFileSize; + + oFile.CloseFile(); + } + + char* pBuffer_in = NULL; + char* pBuffer_out = NULL; + + if (nLenBuffer > 0) + { + pBuffer_in = new char[nLenBuffer]; + pBuffer_out = new char[nLenBuffer]; + + src.rdbuf()->pubsetbuf(pBuffer_in, nLenBuffer); + dst.rdbuf()->pubsetbuf(pBuffer_out, nLenBuffer); + } + +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) + src.open(strSrc.c_str(), std::ios::binary); + dst.open(strDst.c_str(), std::ios::binary); +#else + BYTE* pUtf8Src = NULL; + LONG lLenSrc = 0; + CUtf8Converter::GetUtf8StringFromUnicode(strSrc.c_str(), strSrc.length(), pUtf8Src, lLenSrc, false); + BYTE* pUtf8Dst = NULL; + LONG lLenDst = 0; + CUtf8Converter::GetUtf8StringFromUnicode(strDst.c_str(), strDst.length(), pUtf8Dst, lLenDst, false); + + src.open((char*)pUtf8Src, std::ios::binary); + dst.open((char*)pUtf8Dst, std::ios::binary); + + delete [] pUtf8Src; + delete [] pUtf8Dst; +#endif + + bool bRet = false; + + if (src.is_open() && dst.is_open()) + { + dst << src.rdbuf(); + src.close(); + dst.close(); + + bRet = true; + } + RELEASEARRAYOBJECTS(pBuffer_in); + RELEASEARRAYOBJECTS(pBuffer_out); + return bRet; + } + bool CFileBinary::Remove(const std::wstring& strFileName) + { +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) + int nRes = _wremove(strFileName.c_str()); +#else + BYTE* pUtf8 = NULL; + LONG lLen = 0; + CUtf8Converter::GetUtf8StringFromUnicode(strFileName.c_str(), strFileName.length(), pUtf8, lLen, false); + int nRes = std::remove((char*)pUtf8); + delete [] pUtf8; +#endif + return 0 == nRes; + } + bool CFileBinary::Move(const std::wstring& strSrc, const std::wstring& strDst) + { + if (strSrc == strDst) + return true; + if (Copy(strSrc, strDst)) + if (Remove(strSrc)) + return true; + return false; + } + + bool CFileBinary::Truncate(const std::wstring& sPath, size_t nNewSize) + { + bool bIsSuccess = false; + +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) + HANDLE hFile = ::CreateFileW( sPath.c_str(), GENERIC_WRITE, FILE_SHARE_READ, + NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL ); + if ( hFile == INVALID_HANDLE_VALUE ) + { + return bIsSuccess; + } + + LARGE_INTEGER Size = { 0 }; + + if ( GetFileSizeEx( hFile, &Size ) ) + { + LARGE_INTEGER Distance = { 0 }; + // Negative values move the pointer backward in the file + Distance.QuadPart = (LONGLONG)nNewSize - Size.QuadPart; + bIsSuccess = (SetFilePointerEx(hFile, Distance, NULL, FILE_END) && SetEndOfFile(hFile)); + } + + CloseHandle( hFile ); +#else + std::string sFileUTF8 = U_TO_UTF8(sPath); + bIsSuccess = (0 == truncate(sFileUTF8.c_str(), nNewSize)); +#endif + return bIsSuccess; + } + + std::wstring CFileBinary::GetTempPath() + { +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) + wchar_t pBuffer[MAX_PATH + 1]; + memset(pBuffer, 0, sizeof(wchar_t) * (MAX_PATH + 1)); + ::GetTempPathW(MAX_PATH, pBuffer); + + std::wstring sRet(pBuffer); + + size_t nSeparatorPos = sRet.find_last_of(wchar_t('/')); + if (std::wstring::npos == nSeparatorPos) + { + nSeparatorPos = sRet.find_last_of(wchar_t('\\')); + } + + if (std::wstring::npos == nSeparatorPos) + return L""; + + return sRet.substr(0, nSeparatorPos); +#else + char *folder = getenv("TEMP"); + + if (NULL == folder) + folder = getenv("TMP"); + if (NULL == folder) + folder = getenv("TMPDIR"); + + if (NULL == folder) + folder = "/tmp"; + + return NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)folder, strlen(folder)); +#endif + } + std::wstring CFileBinary::CreateTempFileWithUniqueName(const std::wstring& strFolderPathRoot, const std::wstring& Prefix) + { +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) + wchar_t pBuffer[MAX_PATH + 1]; + ::GetTempFileNameW(strFolderPathRoot.c_str(), Prefix.c_str(), 0, pBuffer); + std::wstring sRet(pBuffer); + return sRet; +#else + char pcRes[MAX_PATH]; + BYTE* pData = (BYTE*)pcRes; + + std::wstring sPrefix = strFolderPathRoot + L"/" + Prefix + L"_XXXXXX"; + LONG lLen = 0; + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(sPrefix.c_str(), (LONG)sPrefix.length(), pData, lLen); + pcRes[lLen] = '\0'; + + int res = mkstemp(pcRes); + if (-1 != res) + close(res); + + std::string sRes = pcRes; + return NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)sRes.c_str(), sRes.length()); +#endif + } + bool CFileBinary::OpenTempFile(std::wstring *pwsName, FILE **ppFile, wchar_t *wsMode, wchar_t *wsExt, wchar_t *wsFolder, wchar_t* wsName) + { + // TODO: Реализовать когда wsName != NULL + + std::wstring wsTemp, wsFileName; + FILE *pTempFile = NULL; +#if defined(_WIN32) || defined (_WIN64) + wchar_t *wsTempDir = NULL; + size_t sz = 0; + if ( (0 == _wdupenv_s(&wsTempDir, &sz, L"TEMP")) && (wsFolder == NULL)) + { + wsTemp = std::wstring(wsTempDir, sz-1); +#else + char *wsTempDirA; + if ((wsTempDirA = getenv("TEMP")) && (wsFolder == NULL)) + { + std::wstring wsTempDir = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)wsTempDirA, strlen(wsTempDirA)); + wsTemp = wsTempDir.c_str(); +#endif + wsTemp += L"/"; + } + else if (wsFolder != NULL) + { + wsTemp = std::wstring(wsFolder); + wsTemp += L"/"; + } + else + { + wsTemp = L""; + } + wsTemp += L"x"; + int nTime = (int)time(NULL); + for (int nIndex = 0; nIndex < 1000; ++nIndex) + { + wsFileName = wsTemp; + wsFileName.append(std::to_wstring(nTime + nIndex)); + + if (wsExt) + { + wsFileName.append(wsExt); + } +#if defined (_WIN32) || defined (_WIN64) + if ( 0 != _wfopen_s(&pTempFile, wsFileName.c_str(), L"r") ) + { + if (0 != _wfopen_s(&pTempFile, wsFileName.c_str(), wsMode)) +#else + std::string sFileName = U_TO_UTF8(wsFileName); + if (!(pTempFile = fopen(sFileName.c_str(), "r"))) + { + std::wstring strMode(wsMode); + std::string sMode = U_TO_UTF8(strMode); + if (!(pTempFile = fopen(sFileName.c_str(), sMode.c_str()))) +#endif + { + return FALSE; + } + *pwsName = wsFileName; + *ppFile = pTempFile; + return TRUE; + } + + fclose(pTempFile); + } + + return FALSE; + } + FILE* CFileBinary::OpenFileNative(const std::wstring& sFileName, const std::wstring& sMode) + { +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) + FILE* pFile = NULL; + _wfopen_s(&pFile, sFileName.c_str(), sMode.c_str()); + + return pFile; +#else + BYTE* pUtf8 = NULL; + LONG lLen = 0; + CUtf8Converter::GetUtf8StringFromUnicode(sFileName.c_str(), sFileName.length(), pUtf8, lLen, false); + + BYTE* pMode = NULL; + LONG lLenMode; + CUtf8Converter::GetUtf8StringFromUnicode(sMode.c_str(), sMode.length(), pMode, lLenMode, false); + + FILE* pFile = fopen((char*)pUtf8, (char*)pMode); + + delete [] pUtf8; + delete [] pMode; + + return pFile; +#endif + } +} + +namespace NSFile +{ + bool CBase64Converter::Encode(BYTE* pDataSrc, int nLenSrc, char*& pDataDst, int& nLenDst, DWORD dwFlags) + { + if (!pDataSrc || nLenSrc < 1) + return false; + + nLenDst = NSBase64::Base64EncodeGetRequiredLength(nLenSrc, dwFlags); + pDataDst = new char[nLenDst]; + + if (FALSE == NSBase64::Base64Encode(pDataSrc, nLenSrc, (BYTE*)pDataDst, &nLenDst, dwFlags)) + { + RELEASEARRAYOBJECTS(pDataDst); + return false; + } + return true; + } + bool CBase64Converter::Decode(const char* pDataSrc, int nLenSrc, BYTE*& pDataDst, int& nLenDst) + { + if (!pDataSrc || nLenSrc < 1) + return false; + + nLenDst = NSBase64::Base64DecodeGetRequiredLength(nLenSrc); + pDataDst = new BYTE[nLenDst]; + + if (FALSE == NSBase64::Base64Decode(pDataSrc, nLenSrc, pDataDst, &nLenDst)) + { + RELEASEARRAYOBJECTS(pDataDst); + return false; + } + return true; + } +} + +namespace NSFile +{ + std::wstring GetProcessPath() + { +#if defined (_WIN64) || defined(_WIN32) + wchar_t buf [NS_FILE_MAX_PATH]; + GetModuleFileNameW(GetModuleHandle(NULL), buf, NS_FILE_MAX_PATH); + return std::wstring(buf); +#endif + +#if defined(__linux__) || defined(_MAC) && !defined(_IOS) + char buf[NS_FILE_MAX_PATH]; + memset(buf, 0, NS_FILE_MAX_PATH); + if (readlink ("/proc/self/exe", buf, NS_FILE_MAX_PATH) <= 0) + { +#ifdef _MAC + uint32_t _size = NS_FILE_MAX_PATH; + _NSGetExecutablePath(buf, &_size); + std::string sUTF8(buf); + std::wstring sRet = CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)sUTF8.c_str(), sUTF8.length()); + return sRet; +#endif + return L""; + } + + std::string sUTF8(buf); + std::wstring sRet = CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)sUTF8.c_str(), sUTF8.length()); + return sRet; +#endif + + return L""; + } + + std::wstring GetProcessDirectory() + { + std::wstring sPath = GetProcessPath(); + + size_t pos1 = sPath.find_last_of(wchar_t('/')); + size_t pos2 = sPath.find_last_of(wchar_t('\\')); + + size_t pos = std::wstring::npos; + if (pos1 != std::wstring::npos) + pos = pos1; + + if (pos2 != std::wstring::npos) + { + if (pos == std::wstring::npos) + pos = pos2; + else if (pos2 > pos) + pos = pos2; + } + + if (pos != std::wstring::npos) + { + sPath = sPath.substr(0, pos); + } + return sPath; + } + + // CommonFunctions + std::wstring GetFileExtention(const std::wstring& sPath) + { + std::wstring::size_type nPos = sPath.rfind('.'); + if (nPos != std::wstring::npos) + return sPath.substr(nPos + 1); + return sPath; + } + std::wstring GetFileName(const std::wstring& sPath) + { + std::wstring::size_type nPos1 = sPath.rfind('\\'); + std::wstring::size_type nPos2 = sPath.rfind('/'); + std::wstring::size_type nPos = std::wstring::npos; + + if (nPos1 != std::wstring::npos) + { + nPos = nPos1; + if (nPos2 != std::wstring::npos && nPos2 > nPos) + nPos = nPos2; + } + else + nPos = nPos2; + + if (nPos == std::wstring::npos) + return sPath; + return sPath.substr(nPos + 1); + } + std::wstring GetDirectoryName(const std::wstring& sPath) + { + std::wstring::size_type nPos1 = sPath.rfind('\\'); + std::wstring::size_type nPos2 = sPath.rfind('/'); + std::wstring::size_type nPos = std::wstring::npos; + + if (nPos1 != std::wstring::npos) + { + nPos = nPos1; + if (nPos2 != std::wstring::npos && nPos2 > nPos) + nPos = nPos2; + } + else + nPos = nPos2; + + if (nPos == std::wstring::npos) + return sPath; + return sPath.substr(0, nPos); + } +} diff --git a/DesktopEditor/common/File.h b/DesktopEditor/common/File.h index e174541f99..207495beef 100644 --- a/DesktopEditor/common/File.h +++ b/DesktopEditor/common/File.h @@ -32,41 +32,27 @@ #ifndef _BUILD_FILE_CROSSPLATFORM_H_ #define _BUILD_FILE_CROSSPLATFORM_H_ -#include #include -#include -#include -#include "errno.h" +#include #include "Base64.h" -#include -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) - #include - #include +#ifndef FILE_USE_DYNAMIC_LIBRARY +#define FILE_DECL_EXPORT +#else +#include "./base_export.h" +#define FILE_DECL_EXPORT Q_DECL_EXPORT #endif #define U_TO_UTF8(val) NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(val.c_str(), (LONG)val.length()) #define UTF8_TO_U(val) NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)val.c_str(), (LONG)val.length()) -#if defined(__linux__) || defined(_MAC) && !defined(_IOS) -#include -#include -#endif - -#ifdef _IOS -#include -#endif - -#ifdef _MAC -#include -#endif - #ifndef MAX_PATH #define MAX_PATH 1024 #endif -//#include "../../Common/DocxFormat/Source/SystemUtility/SystemUtility.h" -//перенесено выше +#if defined(GetTempPath) +#undef GetTempPath +#endif namespace NSFile { @@ -87,494 +73,44 @@ namespace NSFile int Length; public: - CStringUtf16() - { - Data = NULL; - Length = 0; - } - ~CStringUtf16() - { - RELEASEARRAYOBJECTS(Data); - } + CStringUtf16() + { + Data = NULL; + Length = 0; + } + ~CStringUtf16() + { + RELEASEARRAYOBJECTS(Data); + } }; - class CUtf8Converter + class FILE_DECL_EXPORT CUtf8Converter { public: - static std::wstring GetUnicodeFromCharPtr(const char* pData, LONG lCount, INT bIsUtf8 = FALSE) - { - if (bIsUtf8) - return GetUnicodeStringFromUTF8((BYTE*)pData, lCount); + static std::wstring GetUnicodeFromCharPtr(const char* pData, LONG lCount, INT bIsUtf8 = FALSE); + static std::wstring GetUnicodeFromCharPtr(const std::string& sParam, INT bIsUtf8 = FALSE); + static std::wstring GetUnicodeStringFromUTF8_4bytes( BYTE* pBuffer, LONG lCount ); + static std::wstring GetUnicodeStringFromUTF8_2bytes( BYTE* pBuffer, LONG lCount ); - wchar_t* pUnicode = new wchar_t[lCount + 1]; - for (LONG i = 0; i < lCount; ++i) - pUnicode[i] = (wchar_t)(BYTE)pData[i]; + static std::wstring GetUnicodeStringFromUTF8( BYTE* pBuffer, LONG lCount ); - pUnicode[lCount] = 0; + static void GetUtf8StringFromUnicode_4bytes(const wchar_t* pUnicodes, LONG lCount, BYTE*& pData, LONG& lOutputCount, bool bIsBOM = false); + static void GetUtf8StringFromUnicode_2bytes(const wchar_t* pUnicodes, LONG lCount, BYTE*& pData, LONG& lOutputCount, bool bIsBOM = false); + static void GetUtf8StringFromUnicode(const wchar_t* pUnicodes, LONG lCount, BYTE*& pData, LONG& lOutputCount, bool bIsBOM = false); - std::wstring s(pUnicode, lCount); - RELEASEARRAYOBJECTS(pUnicode); - - return s; - } - static std::wstring GetUnicodeFromCharPtr(const std::string& sParam, INT bIsUtf8 = FALSE) - { - return GetUnicodeFromCharPtr(sParam.c_str(), (LONG)sParam.length(), bIsUtf8); - } - static std::wstring GetUnicodeStringFromUTF8_4bytes( BYTE* pBuffer, LONG lCount ) - { - WCHAR* pUnicodeString = new WCHAR[lCount + 1]; - LONG lIndexUnicode = 0; - - LONG lIndex = 0; - while (lIndex < lCount) - { - BYTE byteMain = pBuffer[lIndex]; - if (0x00 == (byteMain & 0x80)) - { - // 1 byte - pUnicodeString[lIndexUnicode++] = (WCHAR)byteMain; - ++lIndex; - } - else if (0x00 == (byteMain & 0x20)) - { - // 2 byte - int val = (int)(((byteMain & 0x1F) << 6) | - (pBuffer[lIndex + 1] & 0x3F)); - pUnicodeString[lIndexUnicode++] = (WCHAR)(val); - lIndex += 2; - } - else if (0x00 == (byteMain & 0x10)) - { - // 3 byte - int val = (int)(((byteMain & 0x0F) << 12) | - ((pBuffer[lIndex + 1] & 0x3F) << 6) | - (pBuffer[lIndex + 2] & 0x3F)); - pUnicodeString[lIndexUnicode++] = (WCHAR)(val); - lIndex += 3; - } - else if (0x00 == (byteMain & 0x0F)) - { - // 4 byte - int val = (int)(((byteMain & 0x07) << 18) | - ((pBuffer[lIndex + 1] & 0x3F) << 12) | - ((pBuffer[lIndex + 2] & 0x3F) << 6) | - (pBuffer[lIndex + 3] & 0x3F)); - pUnicodeString[lIndexUnicode++] = (WCHAR)(val); - lIndex += 4; - } - else if (0x00 == (byteMain & 0x08)) - { - // 4 byte - int val = (int)(((byteMain & 0x07) << 18) | - ((pBuffer[lIndex + 1] & 0x3F) << 12) | - ((pBuffer[lIndex + 2] & 0x3F) << 6) | - (pBuffer[lIndex + 3] & 0x3F)); - pUnicodeString[lIndexUnicode++] = (WCHAR)(val); - lIndex += 4; - } - else if (0x00 == (byteMain & 0x04)) - { - // 5 byte - int val = (int)(((byteMain & 0x03) << 24) | - ((pBuffer[lIndex + 1] & 0x3F) << 18) | - ((pBuffer[lIndex + 2] & 0x3F) << 12) | - ((pBuffer[lIndex + 3] & 0x3F) << 6) | - (pBuffer[lIndex + 4] & 0x3F)); - pUnicodeString[lIndexUnicode++] = (WCHAR)(val); - lIndex += 5; - } - else - { - // 6 byte - int val = (int)(((byteMain & 0x01) << 30) | - ((pBuffer[lIndex + 1] & 0x3F) << 24) | - ((pBuffer[lIndex + 2] & 0x3F) << 18) | - ((pBuffer[lIndex + 3] & 0x3F) << 12) | - ((pBuffer[lIndex + 4] & 0x3F) << 6) | - (pBuffer[lIndex + 5] & 0x3F)); - pUnicodeString[lIndexUnicode++] = (WCHAR)(val); - lIndex += 5; - } - } - - pUnicodeString[lIndexUnicode] = 0; - - std::wstring strRes(pUnicodeString); - - delete [] pUnicodeString; - - return strRes; - } - static std::wstring GetUnicodeStringFromUTF8_2bytes( BYTE* pBuffer, LONG lCount ) - { - WCHAR* pUnicodeString = new WCHAR[lCount + 1]; - WCHAR* pStart = pUnicodeString; - - LONG lIndex = 0; - while (lIndex < lCount) - { - BYTE byteMain = pBuffer[lIndex]; - if (0x00 == (byteMain & 0x80)) - { - // 1 byte - *pUnicodeString++ = (WCHAR)byteMain; - ++lIndex; - } - else if (0x00 == (byteMain & 0x20)) - { - // 2 byte - int val = (int)(((byteMain & 0x1F) << 6) | - (pBuffer[lIndex + 1] & 0x3F)); - *pUnicodeString++ = (WCHAR)(val); - lIndex += 2; - } - else if (0x00 == (byteMain & 0x10)) - { - // 3 byte - int val = (int)(((byteMain & 0x0F) << 12) | - ((pBuffer[lIndex + 1] & 0x3F) << 6) | - (pBuffer[lIndex + 2] & 0x3F)); - - WriteUtf16_WCHAR(val, pUnicodeString); - lIndex += 3; - } - else if (0x00 == (byteMain & 0x0F)) - { - // 4 byte - int val = (int)(((byteMain & 0x07) << 18) | - ((pBuffer[lIndex + 1] & 0x3F) << 12) | - ((pBuffer[lIndex + 2] & 0x3F) << 6) | - (pBuffer[lIndex + 3] & 0x3F)); - - WriteUtf16_WCHAR(val, pUnicodeString); - lIndex += 4; - } - else if (0x00 == (byteMain & 0x08)) - { - // 4 byte - int val = (int)(((byteMain & 0x07) << 18) | - ((pBuffer[lIndex + 1] & 0x3F) << 12) | - ((pBuffer[lIndex + 2] & 0x3F) << 6) | - (pBuffer[lIndex + 3] & 0x3F)); - - WriteUtf16_WCHAR(val, pUnicodeString); - lIndex += 4; - } - else if (0x00 == (byteMain & 0x04)) - { - // 5 byte - int val = (int)(((byteMain & 0x03) << 24) | - ((pBuffer[lIndex + 1] & 0x3F) << 18) | - ((pBuffer[lIndex + 2] & 0x3F) << 12) | - ((pBuffer[lIndex + 3] & 0x3F) << 6) | - (pBuffer[lIndex + 4] & 0x3F)); - - WriteUtf16_WCHAR(val, pUnicodeString); - lIndex += 5; - } - else - { - // 6 byte - int val = (int)(((byteMain & 0x01) << 30) | - ((pBuffer[lIndex + 1] & 0x3F) << 24) | - ((pBuffer[lIndex + 2] & 0x3F) << 18) | - ((pBuffer[lIndex + 3] & 0x3F) << 12) | - ((pBuffer[lIndex + 4] & 0x3F) << 6) | - (pBuffer[lIndex + 5] & 0x3F)); - - WriteUtf16_WCHAR(val, pUnicodeString); - lIndex += 5; - } - } - - *pUnicodeString++ = 0; - - std::wstring strRes(pStart); - - delete [] pStart; - - return strRes; - } - - static std::wstring GetUnicodeStringFromUTF8( BYTE* pBuffer, LONG lCount ) - { - if (sizeof(WCHAR) == 2) - return GetUnicodeStringFromUTF8_2bytes(pBuffer, lCount); - return GetUnicodeStringFromUTF8_4bytes(pBuffer, lCount); - } - - static void GetUtf8StringFromUnicode_4bytes(const wchar_t* pUnicodes, LONG lCount, BYTE*& pData, LONG& lOutputCount, bool bIsBOM = false) - { - if (NULL == pData) - { - pData = new BYTE[6 * lCount + 3 + 1 ]; - } - - BYTE* pCodesCur = pData; - if (bIsBOM) - { - pCodesCur[0] = 0xEF; - pCodesCur[1] = 0xBB; - pCodesCur[2] = 0xBF; - pCodesCur += 3; - } - - const wchar_t* pEnd = pUnicodes + lCount; - const wchar_t* pCur = pUnicodes; - - while (pCur < pEnd) - { - unsigned int code = (unsigned int)*pCur++; - - if (code < 0x80) - { - *pCodesCur++ = (BYTE)code; - } - else if (code < 0x0800) - { - *pCodesCur++ = 0xC0 | (code >> 6); - *pCodesCur++ = 0x80 | (code & 0x3F); - } - else if (code < 0x10000) - { - *pCodesCur++ = 0xE0 | (code >> 12); - *pCodesCur++ = 0x80 | (code >> 6 & 0x3F); - *pCodesCur++ = 0x80 | (code & 0x3F); - } - else if (code < 0x1FFFFF) - { - *pCodesCur++ = 0xF0 | (code >> 18); - *pCodesCur++ = 0x80 | (code >> 12 & 0x3F); - *pCodesCur++ = 0x80 | (code >> 6 & 0x3F); - *pCodesCur++ = 0x80 | (code & 0x3F); - } - else if (code < 0x3FFFFFF) - { - *pCodesCur++ = 0xF8 | (code >> 24); - *pCodesCur++ = 0x80 | (code >> 18 & 0x3F); - *pCodesCur++ = 0x80 | (code >> 12 & 0x3F); - *pCodesCur++ = 0x80 | (code >> 6 & 0x3F); - *pCodesCur++ = 0x80 | (code & 0x3F); - } - else if (code < 0x7FFFFFFF) - { - *pCodesCur++ = 0xFC | (code >> 30); - *pCodesCur++ = 0x80 | (code >> 24 & 0x3F); - *pCodesCur++ = 0x80 | (code >> 18 & 0x3F); - *pCodesCur++ = 0x80 | (code >> 12 & 0x3F); - *pCodesCur++ = 0x80 | (code >> 6 & 0x3F); - *pCodesCur++ = 0x80 | (code & 0x3F); - } - } - - lOutputCount = (LONG)(pCodesCur - pData); - *pCodesCur++ = 0; - } - - static void GetUtf8StringFromUnicode_2bytes(const wchar_t* pUnicodes, LONG lCount, BYTE*& pData, LONG& lOutputCount, bool bIsBOM = false) - { - if (NULL == pData) - { - pData = new BYTE[6 * lCount + 3 + 1]; - } - - BYTE* pCodesCur = pData; - if (bIsBOM) - { - pCodesCur[0] = 0xEF; - pCodesCur[1] = 0xBB; - pCodesCur[2] = 0xBF; - pCodesCur += 3; - } - - const wchar_t* pEnd = pUnicodes + lCount; - const wchar_t* pCur = pUnicodes; - - while (pCur < pEnd) - { - unsigned int code = (unsigned int)*pCur++; - if (code >= 0xD800 && code <= 0xDFFF && pCur < pEnd) - { - code = 0x10000 + (((code & 0x3FF) << 10) | (0x03FF & *pCur++)); - } - - if (code < 0x80) - { - *pCodesCur++ = (BYTE)code; - } - else if (code < 0x0800) - { - *pCodesCur++ = 0xC0 | (code >> 6); - *pCodesCur++ = 0x80 | (code & 0x3F); - } - else if (code < 0x10000) - { - *pCodesCur++ = 0xE0 | (code >> 12); - *pCodesCur++ = 0x80 | ((code >> 6) & 0x3F); - *pCodesCur++ = 0x80 | (code & 0x3F); - } - else if (code < 0x1FFFFF) - { - *pCodesCur++ = 0xF0 | (code >> 18); - *pCodesCur++ = 0x80 | ((code >> 12) & 0x3F); - *pCodesCur++ = 0x80 | ((code >> 6) & 0x3F); - *pCodesCur++ = 0x80 | (code & 0x3F); - } - else if (code < 0x3FFFFFF) - { - *pCodesCur++ = 0xF8 | (code >> 24); - *pCodesCur++ = 0x80 | ((code >> 18) & 0x3F); - *pCodesCur++ = 0x80 | ((code >> 12) & 0x3F); - *pCodesCur++ = 0x80 | ((code >> 6) & 0x3F); - *pCodesCur++ = 0x80 | (code & 0x3F); - } - else if (code < 0x7FFFFFFF) - { - *pCodesCur++ = 0xFC | (code >> 30); - *pCodesCur++ = 0x80 | ((code >> 24) & 0x3F); - *pCodesCur++ = 0x80 | ((code >> 18) & 0x3F); - *pCodesCur++ = 0x80 | ((code >> 12) & 0x3F); - *pCodesCur++ = 0x80 | ((code >> 6) & 0x3F); - *pCodesCur++ = 0x80 | (code & 0x3F); - } - } - - lOutputCount = (LONG)(pCodesCur - pData); - *pCodesCur++ = 0; - } - - static void GetUtf8StringFromUnicode(const wchar_t* pUnicodes, LONG lCount, BYTE*& pData, LONG& lOutputCount, bool bIsBOM = false) - { - if (sizeof(WCHAR) == 2) - return GetUtf8StringFromUnicode_2bytes(pUnicodes, lCount, pData, lOutputCount, bIsBOM); - return GetUtf8StringFromUnicode_4bytes(pUnicodes, lCount, pData, lOutputCount, bIsBOM); - } - - static std::string GetUtf8StringFromUnicode2(const wchar_t* pUnicodes, LONG lCount, bool bIsBOM = false) - { - BYTE* pData = NULL; - LONG lLen = 0; - - GetUtf8StringFromUnicode(pUnicodes, lCount, pData, lLen, bIsBOM); - - std::string s((char*)pData, lLen); - - RELEASEARRAYOBJECTS(pData); - return s; - } - - static std::string GetUtf8StringFromUnicode(const std::wstring& sData) - { - return GetUtf8StringFromUnicode2(sData.c_str(), (LONG)sData.length()); - } + static std::string GetUtf8StringFromUnicode2(const wchar_t* pUnicodes, LONG lCount, bool bIsBOM = false); + static std::string GetUtf8StringFromUnicode(const std::wstring& sData); // utf16 - static void GetUtf16StringFromUnicode_4bytes(const wchar_t* pUnicodes, LONG lCount, BYTE*& pData, int& lOutputCount, bool bIsBOM = false) - { - if (NULL == pData) - { - pData = new BYTE[4 * lCount + 3 + 2]; - } - - BYTE* pCodesCur = pData; - if (bIsBOM) - { - pCodesCur[0] = 0xEF; - pCodesCur[1] = 0xBB; - pCodesCur[2] = 0xBF; - pCodesCur += 3; - } - - const wchar_t* pEnd = pUnicodes + lCount; - const wchar_t* pCur = pUnicodes; - - while (pCur < pEnd) - { - unsigned int code = (unsigned int)*pCur++; - - if (code <= 0xFFFF) - { - USHORT usCode = (USHORT)(code & 0xFFFF); - memcpy(pCodesCur, &usCode, 2); - pCodesCur += 2; - } - else - { - code -= 0x10000; - code &= 0xFFFFF; - - USHORT us1 = 0xD800 | ((code >> 10) & 0x03FF); - USHORT us2 = 0xDC00 | (code & 0x03FF); - - memcpy(pCodesCur, &us1, 2); - pCodesCur += 2; - - memcpy(pCodesCur, &us2, 2); - pCodesCur += 2; - } - } - - lOutputCount = (LONG)(pCodesCur - pData); - *pCodesCur++ = 0; - *pCodesCur++ = 0; - } - - static void GetUtf16StringFromUnicode_4bytes2(const wchar_t* pUnicodes, LONG lCount, CStringUtf16& data) - { - GetUtf16StringFromUnicode_4bytes(pUnicodes, lCount, data.Data, data.Length); - } + static void GetUtf16StringFromUnicode_4bytes(const wchar_t* pUnicodes, LONG lCount, BYTE*& pData, int& lOutputCount, bool bIsBOM = false); + static void GetUtf16StringFromUnicode_4bytes2(const wchar_t* pUnicodes, LONG lCount, CStringUtf16& data); - static std::wstring GetWStringFromUTF16(const CStringUtf16& data) - { - if (0 == data.Length) - return L""; - - if (sizeof(wchar_t) == 2) - return std::wstring((wchar_t*)data.Data, data.Length / 2); - - int nCount = data.Length / 2; - USHORT* pShort = (USHORT*)data.Data; - - wchar_t* pWChar = new wchar_t[nCount + 1]; - wchar_t* pWCurrent = pWChar; - - int nCurrent = 0; - while (nCurrent < nCount) - { - if (*pShort < 0xD800 || *pShort > 0xDBFF) - { - *pWCurrent = (wchar_t)(*pShort); - ++pShort; - ++nCurrent; - } - else - { - *pWCurrent = (wchar_t)(((((pShort[0] - 0xD800) & 0x03FF) << 10) | ((pShort[1] - 0xDC00) & 0x03FF)) + 0x10000); - pShort += 2; - nCurrent += 2; - } - ++pWCurrent; - } - - std::wstring sRet(pWChar, pWCurrent - pWChar); - - RELEASEARRAYOBJECTS(pWChar); - return sRet; - } - static std::wstring GetWStringFromUTF16(const unsigned short* pUtf16, LONG lCount) - { - CStringUtf16 oString; - oString.Data = (BYTE*)pUtf16; - oString.Length = lCount * 2; - std::wstring wsResult = GetWStringFromUTF16(oString); - oString.Data = NULL; - return wsResult; - } + static std::wstring GetWStringFromUTF16(const CStringUtf16& data); + static std::wstring GetWStringFromUTF16(const unsigned short* pUtf16, LONG lCount); }; - class CFileBinary + class FILE_DECL_EXPORT CFileBinary { protected: FILE* m_pFile; @@ -583,678 +119,59 @@ namespace NSFile long m_lFileSize; public: - CFileBinary() - { - m_pFile = NULL; - m_lFilePosition = 0; - m_lFileSize = 0; - } - ~CFileBinary() - { - CloseFile(); - } + CFileBinary(); + ~CFileBinary(); - void CloseFile() - { - m_lFilePosition = 0; - m_lFileSize = 0; + void CloseFile(); - if (m_pFile != NULL) - { - fclose(m_pFile); - m_pFile = NULL; - } - } + inline FILE* GetFileNative(); + inline long GetFileSize(); + inline long GetFilePosition(); - inline FILE* GetFileNative() - { - return m_pFile; - } - inline long GetFileSize() - { - return m_lFileSize; - } - inline long GetFilePosition() - { - return m_lFilePosition; - } - - #ifdef _IOS - bool OpenFile(const std::wstring& sFileName, bool bRewrite = false); bool CreateFileW(const std::wstring& sFileName); - - #else - bool OpenFile(const std::wstring& sFileName, bool bRewrite = false) - { -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) - if ( 0 != _wfopen_s(&m_pFile, sFileName.c_str(), bRewrite ? L"rb+" : L"rb")) - return false; -#else - BYTE* pUtf8 = NULL; - LONG lLen = 0; - CUtf8Converter::GetUtf8StringFromUnicode(sFileName.c_str(), sFileName.length(), pUtf8, lLen, false); - m_pFile = fopen((char*)pUtf8, bRewrite ? "rb+" : "rb"); + bool CreateTempFile(); + bool SeekFile(int lFilePosition, int nSeekMode = 0); + bool ReadFile(BYTE* pData, DWORD nBytesToRead, DWORD& dwSizeRead); + bool WriteFile(const BYTE* pData, DWORD nBytesCount); + long TellFile(); + long SizeFile(); + void WriteStringUTF8(const std::wstring& strXml, bool bIsBOM = false); + static bool ReadAllBytes(const std::wstring& strFileName, BYTE** ppData, DWORD& nBytesCount); + static bool ReadAllTextUtf8(const std::wstring& strFileName, std::wstring& sData); + static bool ReadAllTextUtf8A(const std::wstring& strFileName, std::string& sData); + static bool SaveToFile(const std::wstring& strFileName, const std::wstring& strXml, bool bIsBOM = false); + static bool Exists(const std::wstring& strFileName); + static bool Copy(const std::wstring& strSrc, const std::wstring& strDst); + static bool Remove(const std::wstring& strFileName); + static bool Move(const std::wstring& strSrc, const std::wstring& strDst); + static bool Truncate(const std::wstring& sPath, size_t nNewSize); - delete [] pUtf8; -#endif - if (NULL == m_pFile) - return false; - - fseek(m_pFile, 0, SEEK_END); - m_lFileSize = ftell(m_pFile); - fseek(m_pFile, 0, SEEK_SET); - - m_lFilePosition = 0; - - if (0 < sFileName.length()) - { - if (((wchar_t)'/') == sFileName.c_str()[sFileName.length() - 1]) - m_lFileSize = 0x7FFFFFFF; - } - - unsigned int err = 0x7FFFFFFF; - unsigned int cur = (unsigned int)m_lFileSize; - if (err == cur) - { - CloseFile(); - return false; - } - - return true; - } - - bool CreateFileW(const std::wstring& sFileName) - { -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) - if ( 0 != _wfopen_s(&m_pFile, sFileName.c_str(), L"wb")) - return false; -#else - BYTE* pUtf8 = NULL; - LONG lLen = 0; - CUtf8Converter::GetUtf8StringFromUnicode(sFileName.c_str(), sFileName.length(), pUtf8, lLen, false); - m_pFile = fopen((char*)pUtf8, "wb"); - delete [] pUtf8; -#endif - if (NULL == m_pFile) - return false; - - m_lFilePosition = 0; - return true; - } - - #endif - - bool CreateTempFile() - { -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) - if (0 != tmpfile_s(&m_pFile)) - return false; -#else - m_pFile = tmpfile(); - if (NULL == m_pFile) - return false; -#endif - m_lFilePosition = 0; - return true; - } - bool SeekFile(int lFilePosition, int nSeekMode = 0) - { - if (!m_pFile) - return false; - - m_lFilePosition = fseek(m_pFile, lFilePosition, nSeekMode); - return true; - } - bool ReadFile(BYTE* pData, DWORD nBytesToRead, DWORD& dwSizeRead) - { - if (!m_pFile) - return false; - - dwSizeRead = (DWORD)fread((void*)pData, 1, nBytesToRead, m_pFile); - return true; - } - bool WriteFile(const BYTE* pData, DWORD nBytesCount) - { - if (!m_pFile) - return false; - - size_t nCountWrite = fwrite((const void*)pData, 1, nBytesCount, m_pFile); - return true; - } - long TellFile() - { - if (!m_pFile) - return 0; - - return ftell(m_pFile); - } - long SizeFile() - { - if (!m_pFile) - return 0; - - long lPos = TellFile(); - fseek(m_pFile, 0, SEEK_END); - m_lFileSize = ftell(m_pFile); - fseek(m_pFile, lPos, SEEK_SET); - - return m_lFileSize; - } - void WriteStringUTF8(const std::wstring& strXml, bool bIsBOM = false) - { - BYTE* pData = NULL; - LONG lLen = 0; - - CUtf8Converter::GetUtf8StringFromUnicode(strXml.c_str(), (LONG)strXml.length(), pData, lLen, bIsBOM); - - WriteFile(pData, lLen); - - RELEASEARRAYOBJECTS(pData); - } - static bool ReadAllBytes(const std::wstring& strFileName, BYTE** ppData, DWORD& nBytesCount) - { - *ppData = NULL; - nBytesCount = 0; - bool bRes = false; - CFileBinary oFileBinary; - if (oFileBinary.OpenFile(strFileName)) - { - long nFileSize = oFileBinary.GetFileSize(); - BYTE* pData = new BYTE[nFileSize]; - DWORD dwSizeRead; - if (oFileBinary.ReadFile(pData, nFileSize, dwSizeRead)) - { - oFileBinary.CloseFile(); - *ppData = pData; - nBytesCount = dwSizeRead; - bRes = true; - } - else - RELEASEARRAYOBJECTS(pData); - } - return bRes; - } - static bool ReadAllTextUtf8(const std::wstring& strFileName, std::wstring& sData) - { - bool bRes = false; - BYTE* pData = NULL; - DWORD nDataSize; - if (CFileBinary::ReadAllBytes(strFileName, &pData, nDataSize)) - { - //remove BOM if exist - BYTE* pDataStart = pData; - DWORD nBOMSize = 3; - if (nDataSize > nBOMSize && 0xef == pDataStart[0] && 0xbb == pDataStart[1] && 0xbf == pDataStart[2]) - { - pDataStart += nBOMSize; - nDataSize -= nBOMSize; - } - sData = CUtf8Converter::GetUnicodeStringFromUTF8(pDataStart, nDataSize); - RELEASEARRAYOBJECTS(pData); - bRes = true; - } - return bRes; - } - static bool ReadAllTextUtf8A(const std::wstring& strFileName, std::string& sData) - { - bool bRes = false; - BYTE* pData = NULL; - DWORD nDataSize; - if (CFileBinary::ReadAllBytes(strFileName, &pData, nDataSize)) - { - //remove BOM if exist - BYTE* pDataStart = pData; - DWORD nBOMSize = 3; - if (nDataSize > nBOMSize && 0xef == pDataStart[0] && 0xbb == pDataStart[1] && 0xbf == pDataStart[2]) - { - pDataStart += nBOMSize; - nDataSize -= nBOMSize; - } - sData = std::string((char*)pDataStart, nDataSize); - RELEASEARRAYOBJECTS(pData); - bRes = true; - } - return bRes; - } - static bool SaveToFile(const std::wstring& strFileName, const std::wstring& strXml, bool bIsBOM = false) - { - CFileBinary oFile; - oFile.CreateFileW(strFileName); - oFile.WriteStringUTF8(strXml, bIsBOM); - oFile.CloseFile(); - return true; - } - static bool Exists(const std::wstring& strFileName) - { -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) - FILE* pFile = NULL; - if ( 0 != _wfopen_s( &pFile, strFileName.c_str(), L"rb")) - return false; -#else - BYTE* pUtf8 = NULL; - LONG lLen = 0; - CUtf8Converter::GetUtf8StringFromUnicode(strFileName.c_str(), strFileName.length(), pUtf8, lLen, false); - FILE* pFile = fopen((char*)pUtf8, "rb"); - delete [] pUtf8; -#endif - if (NULL != pFile) - { - fclose(pFile); - return true; - } - else - return false; - } - static bool Copy(const std::wstring& strSrc, const std::wstring& strDst) - { - if (strSrc == strDst) - return true; - - std::ifstream src; - std::ofstream dst; - - int nLenBuffer = 1024 * 1024; // 10 - CFileBinary oFile; - if (oFile.OpenFile(strSrc)) - { - int nFileSize = (int)oFile.GetFileSize(); - if (nFileSize < nLenBuffer) - nLenBuffer = nFileSize; - - oFile.CloseFile(); - } - - char* pBuffer_in = NULL; - char* pBuffer_out = NULL; - - if (nLenBuffer > 0) - { - pBuffer_in = new char[nLenBuffer]; - pBuffer_out = new char[nLenBuffer]; - - src.rdbuf()->pubsetbuf(pBuffer_in, nLenBuffer); - dst.rdbuf()->pubsetbuf(pBuffer_out, nLenBuffer); - } - -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) - src.open(strSrc.c_str(), std::ios::binary); - dst.open(strDst.c_str(), std::ios::binary); -#else - BYTE* pUtf8Src = NULL; - LONG lLenSrc = 0; - CUtf8Converter::GetUtf8StringFromUnicode(strSrc.c_str(), strSrc.length(), pUtf8Src, lLenSrc, false); - BYTE* pUtf8Dst = NULL; - LONG lLenDst = 0; - CUtf8Converter::GetUtf8StringFromUnicode(strDst.c_str(), strDst.length(), pUtf8Dst, lLenDst, false); - - src.open((char*)pUtf8Src, std::ios::binary); - dst.open((char*)pUtf8Dst, std::ios::binary); - - delete [] pUtf8Src; - delete [] pUtf8Dst; -#endif - - bool bRet = false; - - if (src.is_open() && dst.is_open()) - { - dst << src.rdbuf(); - src.close(); - dst.close(); - - bRet = true; - } - RELEASEARRAYOBJECTS(pBuffer_in); - RELEASEARRAYOBJECTS(pBuffer_out); - return bRet; - } - static bool Remove(const std::wstring& strFileName) - { -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) - int nRes = _wremove(strFileName.c_str()); -#else - BYTE* pUtf8 = NULL; - LONG lLen = 0; - CUtf8Converter::GetUtf8StringFromUnicode(strFileName.c_str(), strFileName.length(), pUtf8, lLen, false); - int nRes = std::remove((char*)pUtf8); - delete [] pUtf8; -#endif - return 0 == nRes; - } - static bool Move(const std::wstring& strSrc, const std::wstring& strDst) - { - if (strSrc == strDst) - return true; - if (Copy(strSrc, strDst)) - if (Remove(strSrc)) - return true; - return false; - } - - static bool Truncate(const std::wstring& sPath, size_t nNewSize) - { - bool bIsSuccess = false; - -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) - HANDLE hFile = ::CreateFileW( sPath.c_str(), GENERIC_WRITE, FILE_SHARE_READ, - NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL ); - if ( hFile == INVALID_HANDLE_VALUE ) - { - return bIsSuccess; - } - - LARGE_INTEGER Size = { 0 }; - - if ( GetFileSizeEx( hFile, &Size ) ) - { - LARGE_INTEGER Distance = { 0 }; - // Negative values move the pointer backward in the file - Distance.QuadPart = (LONGLONG)nNewSize - Size.QuadPart; - bIsSuccess = (SetFilePointerEx(hFile, Distance, NULL, FILE_END) && SetEndOfFile(hFile)); - } - - CloseHandle( hFile ); -#else - std::string sFileUTF8 = U_TO_UTF8(sPath); - bIsSuccess = (0 == truncate(sFileUTF8.c_str(), nNewSize)); -#endif - return bIsSuccess; - } - - static std::wstring GetTempPath() - { -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) - wchar_t pBuffer[MAX_PATH + 1]; - memset(pBuffer, 0, sizeof(wchar_t) * (MAX_PATH + 1)); - ::GetTempPathW(MAX_PATH, pBuffer); - - std::wstring sRet(pBuffer); - - size_t nSeparatorPos = sRet.find_last_of(wchar_t('/')); - if (std::wstring::npos == nSeparatorPos) - { - nSeparatorPos = sRet.find_last_of(wchar_t('\\')); - } - - if (std::wstring::npos == nSeparatorPos) - return L""; - - return sRet.substr(0, nSeparatorPos); -#else - char *folder = getenv("TEMP"); - - if (NULL == folder) - folder = getenv("TMP"); - if (NULL == folder) - folder = getenv("TMPDIR"); - - if (NULL == folder) - folder = "/tmp"; - - return NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)folder, strlen(folder)); -#endif - } - static std::wstring CreateTempFileWithUniqueName(const std::wstring& strFolderPathRoot, const std::wstring& Prefix) - { -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) - wchar_t pBuffer[MAX_PATH + 1]; - ::GetTempFileNameW(strFolderPathRoot.c_str(), Prefix.c_str(), 0, pBuffer); - std::wstring sRet(pBuffer); - return sRet; -#else - char pcRes[MAX_PATH]; - BYTE* pData = (BYTE*)pcRes; - - std::wstring sPrefix = strFolderPathRoot + L"/" + Prefix + L"_XXXXXX"; - LONG lLen = 0; - NSFile::CUtf8Converter::GetUtf8StringFromUnicode(sPrefix.c_str(), (LONG)sPrefix.length(), pData, lLen); - pcRes[lLen] = '\0'; - - int res = mkstemp(pcRes); - if (-1 != res) - close(res); - - std::string sRes = pcRes; - return NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)sRes.c_str(), sRes.length()); -#endif - } - static bool OpenTempFile(std::wstring *pwsName, FILE **ppFile, wchar_t *wsMode, wchar_t *wsExt, wchar_t *wsFolder, wchar_t* wsName = NULL) - { - // TODO: Реализовать когда wsName != NULL - - std::wstring wsTemp, wsFileName; - FILE *pTempFile = NULL; -#if defined(_WIN32) || defined (_WIN64) - wchar_t *wsTempDir = NULL; - size_t sz = 0; - if ( (0 == _wdupenv_s(&wsTempDir, &sz, L"TEMP")) && (wsFolder == NULL)) - { - wsTemp = std::wstring(wsTempDir, sz-1); -#else - char *wsTempDirA; - if ((wsTempDirA = getenv("TEMP")) && (wsFolder == NULL)) - { - std::wstring wsTempDir = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)wsTempDirA, strlen(wsTempDirA)); - wsTemp = wsTempDir.c_str(); -#endif - wsTemp += L"/"; - } - else if (wsFolder != NULL) - { - wsTemp = std::wstring(wsFolder); - wsTemp += L"/"; - } - else - { - wsTemp = L""; - } - wsTemp += L"x"; - int nTime = (int)time(NULL); - for (int nIndex = 0; nIndex < 1000; ++nIndex) - { - wsFileName = wsTemp; - wsFileName.append(std::to_wstring(nTime + nIndex)); - - if (wsExt) - { - wsFileName.append(wsExt); - } -#if defined (_WIN32) || defined (_WIN64) - if ( 0 != _wfopen_s(&pTempFile, wsFileName.c_str(), L"r") ) - { - if (0 != _wfopen_s(&pTempFile, wsFileName.c_str(), wsMode)) -#else - std::string sFileName = U_TO_UTF8(wsFileName); - if (!(pTempFile = fopen(sFileName.c_str(), "r"))) - { - std::wstring strMode(wsMode); - std::string sMode = U_TO_UTF8(strMode); - if (!(pTempFile = fopen(sFileName.c_str(), sMode.c_str()))) -#endif - { - return FALSE; - } - *pwsName = wsFileName; - *ppFile = pTempFile; - return TRUE; - } - - fclose(pTempFile); - } - - return FALSE; - } - static FILE* OpenFileNative(const std::wstring& sFileName, const std::wstring& sMode) - { -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) - FILE* pFile = NULL; - _wfopen_s(&pFile, sFileName.c_str(), sMode.c_str()); - - return pFile; -#else - BYTE* pUtf8 = NULL; - LONG lLen = 0; - CUtf8Converter::GetUtf8StringFromUnicode(sFileName.c_str(), sFileName.length(), pUtf8, lLen, false); - - BYTE* pMode = NULL; - LONG lLenMode; - CUtf8Converter::GetUtf8StringFromUnicode(sMode.c_str(), sMode.length(), pMode, lLenMode, false); - - FILE* pFile = fopen((char*)pUtf8, (char*)pMode); - - delete [] pUtf8; - delete [] pMode; - - return pFile; -#endif - } + static std::wstring GetTempPath(); + static std::wstring CreateTempFileWithUniqueName(const std::wstring& strFolderPathRoot, const std::wstring& Prefix); + static bool OpenTempFile(std::wstring *pwsName, FILE **ppFile, wchar_t *wsMode, wchar_t *wsExt, wchar_t *wsFolder, wchar_t* wsName = NULL); + static FILE* OpenFileNative(const std::wstring& sFileName, const std::wstring& sMode); }; - class CBase64Converter + class FILE_DECL_EXPORT CBase64Converter { public: - static bool Encode(BYTE* pDataSrc, int nLenSrc, char*& pDataDst, int& nLenDst, DWORD dwFlags = NSBase64::B64_BASE64_FLAG_NONE) - { - if (!pDataSrc || nLenSrc < 1) - return false; - - nLenDst = NSBase64::Base64EncodeGetRequiredLength(nLenSrc, dwFlags); - pDataDst = new char[nLenDst]; - - if (FALSE == NSBase64::Base64Encode(pDataSrc, nLenSrc, (BYTE*)pDataDst, &nLenDst, dwFlags)) - { - RELEASEARRAYOBJECTS(pDataDst); - return false; - } - return true; - } - static bool Decode(const char* pDataSrc, int nLenSrc, BYTE*& pDataDst, int& nLenDst) - { - if (!pDataSrc || nLenSrc < 1) - return false; - - nLenDst = NSBase64::Base64DecodeGetRequiredLength(nLenSrc); - pDataDst = new BYTE[nLenDst]; - - if (FALSE == NSBase64::Base64Decode(pDataSrc, nLenSrc, pDataDst, &nLenDst)) - { - RELEASEARRAYOBJECTS(pDataDst); - return false; - } - return true; - } + static bool Encode(BYTE* pDataSrc, int nLenSrc, char*& pDataDst, int& nLenDst, DWORD dwFlags = NSBase64::B64_BASE64_FLAG_NONE); + static bool Decode(const char* pDataSrc, int nLenSrc, BYTE*& pDataDst, int& nLenDst); }; } namespace NSFile { #define NS_FILE_MAX_PATH 32768 - static std::wstring GetProcessPath() - { -#if defined (_WIN64) || defined(_WIN32) - wchar_t buf [NS_FILE_MAX_PATH]; - GetModuleFileNameW(GetModuleHandle(NULL), buf, NS_FILE_MAX_PATH); - return std::wstring(buf); -#endif - -#if defined(__linux__) || defined(_MAC) && !defined(_IOS) - char buf[NS_FILE_MAX_PATH]; - memset(buf, 0, NS_FILE_MAX_PATH); - if (readlink ("/proc/self/exe", buf, NS_FILE_MAX_PATH) <= 0) - { -#ifdef _MAC - uint32_t _size = NS_FILE_MAX_PATH; - _NSGetExecutablePath(buf, &_size); - std::string sUTF8(buf); - std::wstring sRet = CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)sUTF8.c_str(), sUTF8.length()); - return sRet; -#endif - return L""; - } - - std::string sUTF8(buf); - std::wstring sRet = CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)sUTF8.c_str(), sUTF8.length()); - return sRet; -#endif - - return L""; - } - - static std::wstring GetProcessDirectory() - { - std::wstring sPath = GetProcessPath(); - - size_t pos1 = sPath.find_last_of(wchar_t('/')); - size_t pos2 = sPath.find_last_of(wchar_t('\\')); - - size_t pos = std::wstring::npos; - if (pos1 != std::wstring::npos) - pos = pos1; - - if (pos2 != std::wstring::npos) - { - if (pos == std::wstring::npos) - pos = pos2; - else if (pos2 > pos) - pos = pos2; - } - - if (pos != std::wstring::npos) - { - sPath = sPath.substr(0, pos); - } - return sPath; - } + FILE_DECL_EXPORT std::wstring GetProcessPath(); + FILE_DECL_EXPORT std::wstring GetProcessDirectory(); // CommonFunctions - static std::wstring GetFileExtention(const std::wstring& sPath) - { - std::wstring::size_type nPos = sPath.rfind('.'); - if (nPos != std::wstring::npos) - return sPath.substr(nPos + 1); - return sPath; - } - static std::wstring GetFileName(const std::wstring& sPath) - { - std::wstring::size_type nPos1 = sPath.rfind('\\'); - std::wstring::size_type nPos2 = sPath.rfind('/'); - std::wstring::size_type nPos = std::wstring::npos; - - if (nPos1 != std::wstring::npos) - { - nPos = nPos1; - if (nPos2 != std::wstring::npos && nPos2 > nPos) - nPos = nPos2; - } - else - nPos = nPos2; - - if (nPos == std::wstring::npos) - return sPath; - return sPath.substr(nPos + 1); - } - static std::wstring GetDirectoryName(const std::wstring& sPath) - { - std::wstring::size_type nPos1 = sPath.rfind('\\'); - std::wstring::size_type nPos2 = sPath.rfind('/'); - std::wstring::size_type nPos = std::wstring::npos; - - if (nPos1 != std::wstring::npos) - { - nPos = nPos1; - if (nPos2 != std::wstring::npos && nPos2 > nPos) - nPos = nPos2; - } - else - nPos = nPos2; - - if (nPos == std::wstring::npos) - return sPath; - return sPath.substr(0, nPos); - } + FILE_DECL_EXPORT std::wstring GetFileExtention(const std::wstring& sPath); + FILE_DECL_EXPORT std::wstring GetFileName(const std::wstring& sPath); + FILE_DECL_EXPORT std::wstring GetDirectoryName(const std::wstring& sPath); } #endif //_BUILD_FILE_CROSSPLATFORM_H_ diff --git a/DesktopEditor/common/Path.cpp b/DesktopEditor/common/Path.cpp new file mode 100644 index 0000000000..ecb376f102 --- /dev/null +++ b/DesktopEditor/common/Path.cpp @@ -0,0 +1,111 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2018 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Path.h" +#include "File.h" + +#if defined(_WIN32) || defined (_WIN64) + #include +#elif __linux__ || MAC + #include +#endif + +namespace NSSystemPath +{ + std::wstring GetDirectoryName(const std::wstring& strFileName) + { + std::wstring sRes; + //_wsplitpath return directory path, including trailing slash. + //dirname() returns the string up to, but not including, the final '/', +#if defined(_WIN32) || defined (_WIN64) + wchar_t tDrive[256]; + wchar_t tFolder[256]; + _wsplitpath( strFileName.c_str(), tDrive, tFolder, NULL, NULL ); + sRes.append(tDrive); + sRes.append(tFolder); + if(sRes.length() > 0) + sRes.erase(sRes.length()-1); +#elif __linux__ || MAC + BYTE* pUtf8 = NULL; + LONG lLen = 0; + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strFileName.c_str(), strFileName.length(), pUtf8, lLen, false); + char* pDirName = dirname((char*)pUtf8); + sRes = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)pDirName, strlen(pDirName)); + delete [] pUtf8; +#endif + return sRes; + } + std::wstring GetFileName(const std::wstring& strFileName) + { + std::wstring sRes; +#if defined(_WIN32) || defined (_WIN64) + wchar_t tFilename[256]; + wchar_t tExt[256]; + _wsplitpath( strFileName.c_str(), NULL, NULL, tFilename, tExt ); + sRes.append(tFilename); + sRes.append(tExt); + return sRes; +#elif __linux__ || MAC + BYTE* pUtf8 = NULL; + LONG lLen = 0; + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strFileName.c_str(), strFileName.length(), pUtf8, lLen, false); + char* pBaseName = basename((char*)pUtf8); + sRes = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)pBaseName, strlen(pBaseName)); + delete [] pUtf8; +#endif + return sRes; + } + std::wstring Combine(const std::wstring& strLeft, const std::wstring& strRight) + { + std::wstring sRes; + bool bLeftSlash = false; + bool bRightSlash = false; + if(strLeft.length() > 0) + { + wchar_t cLeft = strLeft[strLeft.length() - 1]; + bLeftSlash = ('/' == cLeft) || ('\\' == cLeft); + } + if(strRight.length() > 0) + { + wchar_t cRight = strRight[0]; + bRightSlash = ('/' == cRight) || ('\\' == cRight); + } + if(bLeftSlash && bRightSlash) + { + sRes = strLeft + strRight.substr(1); + } + else if(!bLeftSlash && !bRightSlash) + sRes = strLeft + L"/" + strRight; + else + sRes = strLeft + strRight; + return sRes; + } +} diff --git a/DesktopEditor/common/Path.h b/DesktopEditor/common/Path.h index e1b51cfd6d..4bdd981fe4 100644 --- a/DesktopEditor/common/Path.h +++ b/DesktopEditor/common/Path.h @@ -34,84 +34,19 @@ #include #include -#include "File.h" -#if defined(_WIN32) || defined (_WIN64) - #include -#elif __linux__ || MAC - #include +#ifndef PATH_USE_DYNAMIC_LIBRARY +#define PATH_DECL_EXPORT +#else +#include "./base_export.h" +#define PATH_DECL_EXPORT Q_DECL_EXPORT #endif namespace NSSystemPath { - static std::wstring GetDirectoryName(const std::wstring& strFileName) - { - std::wstring sRes; - //_wsplitpath return directory path, including trailing slash. - //dirname() returns the string up to, but not including, the final '/', -#if defined(_WIN32) || defined (_WIN64) - wchar_t tDrive[256]; - wchar_t tFolder[256]; - _wsplitpath( strFileName.c_str(), tDrive, tFolder, NULL, NULL ); - sRes.append(tDrive); - sRes.append(tFolder); - if(sRes.length() > 0) - sRes.erase(sRes.length()-1); -#elif __linux__ || MAC - BYTE* pUtf8 = NULL; - LONG lLen = 0; - NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strFileName.c_str(), strFileName.length(), pUtf8, lLen, false); - char* pDirName = dirname((char*)pUtf8); - sRes = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)pDirName, strlen(pDirName)); - delete [] pUtf8; -#endif - return sRes; - } - static std::wstring GetFileName(const std::wstring& strFileName) - { - std::wstring sRes; -#if defined(_WIN32) || defined (_WIN64) - wchar_t tFilename[256]; - wchar_t tExt[256]; - _wsplitpath( strFileName.c_str(), NULL, NULL, tFilename, tExt ); - sRes.append(tFilename); - sRes.append(tExt); - return sRes; -#elif __linux__ || MAC - BYTE* pUtf8 = NULL; - LONG lLen = 0; - NSFile::CUtf8Converter::GetUtf8StringFromUnicode(strFileName.c_str(), strFileName.length(), pUtf8, lLen, false); - char* pBaseName = basename((char*)pUtf8); - sRes = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)pBaseName, strlen(pBaseName)); - delete [] pUtf8; -#endif - return sRes; - } - static std::wstring Combine(const std::wstring& strLeft, const std::wstring& strRight) - { - std::wstring sRes; - bool bLeftSlash = false; - bool bRightSlash = false; - if(strLeft.length() > 0) - { - wchar_t cLeft = strLeft[strLeft.length() - 1]; - bLeftSlash = ('/' == cLeft) || ('\\' == cLeft); - } - if(strRight.length() > 0) - { - wchar_t cRight = strRight[0]; - bRightSlash = ('/' == cRight) || ('\\' == cRight); - } - if(bLeftSlash && bRightSlash) - { - sRes = strLeft + strRight.substr(1); - } - else if(!bLeftSlash && !bRightSlash) - sRes = strLeft + L"/" + strRight; - else - sRes = strLeft + strRight; - return sRes; - } + PATH_DECL_EXPORT std::wstring GetDirectoryName(const std::wstring& strFileName); + PATH_DECL_EXPORT std::wstring GetFileName(const std::wstring& strFileName); + PATH_DECL_EXPORT std::wstring Combine(const std::wstring& strLeft, const std::wstring& strRight); } #endif //_BUILD_PATH_CROSSPLATFORM_H_ diff --git a/DesktopEditor/common/StringBuilder.cpp b/DesktopEditor/common/StringBuilder.cpp new file mode 100644 index 0000000000..892df83f33 --- /dev/null +++ b/DesktopEditor/common/StringBuilder.cpp @@ -0,0 +1,691 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2018 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, + * EU, LV-1021. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "StringBuilder.h" + +namespace NSStringUtils +{ + const wchar_t g_hex_values[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + CStringBuilderA::CStringBuilderA() + { + m_pData = NULL; + m_lSize = 0; + + m_pDataCur = m_pData; + m_lSizeCur = m_lSize; + } + CStringBuilderA::~CStringBuilderA() + { + if (NULL != m_pData) + free(m_pData); + m_pData = NULL; + } + + void CStringBuilderA::AddSize(size_t nSize) + { + if (NULL == m_pData) + { + m_lSize = (std::max)((int)nSize, 1000); + m_pData = (char*)malloc(m_lSize * sizeof(char)); + + m_lSizeCur = 0; + m_pDataCur = m_pData; + return; + } + + if ((m_lSizeCur + nSize) > m_lSize) + { + while ((m_lSizeCur + nSize) > m_lSize) + { + m_lSize *= 2; + } + + char* pRealloc = (char*)realloc(m_pData, m_lSize * sizeof(char)); + if (NULL != pRealloc) + { + // реаллок сработал + m_pData = pRealloc; + m_pDataCur = m_pData + m_lSizeCur; + } + else + { + char* pMalloc = (char*)malloc(m_lSize * sizeof(char)); + memcpy(pMalloc, m_pData, m_lSizeCur * sizeof(char)); + + free(m_pData); + m_pData = pMalloc; + m_pDataCur = m_pData + m_lSizeCur; + } + } + } + + void CStringBuilderA::SetText(const std::string& sText) + { + ClearNoAttack(); + WriteString(sText); + } + void CStringBuilderA::WriteString(const std::string& str) + { + WriteString(str.c_str(), str.length()); + } + + void CStringBuilderA::WriteStringNoSafe(const char* pString, size_t nLen) + { + memcpy(m_pDataCur, pString, nLen * sizeof(char)); + + m_pDataCur += nLen; + m_lSizeCur += nLen; + } + void CStringBuilderA::WriteString(const char* pString, size_t nLen) + { + AddSize(nLen); + WriteStringNoSafe(pString, nLen); + } + + void CStringBuilderA::AddCharNoSafe(const char& _c) + { + *m_pDataCur++ = _c; + ++m_lSizeCur; + } + void CStringBuilderA::AddCharSafe(const char& _c) + { + AddSize(1); + *m_pDataCur++ = _c; + ++m_lSizeCur; + } + + size_t CStringBuilderA::GetCurSize() + { + return m_lSizeCur; + } + void CStringBuilderA::SetCurSize(size_t lCurSize) + { + m_lSizeCur = lCurSize; + m_pDataCur = m_pData + m_lSizeCur; + } + size_t CStringBuilderA::GetSize() + { + return m_lSize; + } + + void CStringBuilderA::Clear() + { + if (NULL != m_pData) + free(m_pData); + m_pData = NULL; + + m_pData = NULL; + m_lSize = 0; + + m_pDataCur = m_pData; + m_lSizeCur = 0; + } + void CStringBuilderA::ClearNoAttack() + { + m_pDataCur = m_pData; + m_lSizeCur = 0; + } + + std::string CStringBuilderA::GetData() + { + std::string str(m_pData, (int)m_lSizeCur); + return str; + } + char* CStringBuilderA::GetBuffer() + { + return m_pData; + } +} + +namespace NSStringUtils +{ + CStringBuilder::CStringBuilder() + { + m_pData = NULL; + m_lSize = 0; + + m_pDataCur = m_pData; + m_lSizeCur = m_lSize; + } + CStringBuilder::~CStringBuilder() + { + if (NULL != m_pData) + free(m_pData); + m_pData = NULL; + } + + void CStringBuilder::AddSize(size_t nSize) + { + if (NULL == m_pData) + { + m_lSize = (std::max)((int)nSize, 1000); + m_pData = (wchar_t*)malloc(m_lSize * sizeof(wchar_t)); + + m_lSizeCur = 0; + m_pDataCur = m_pData; + return; + } + + if ((m_lSizeCur + nSize) > m_lSize) + { + while ((m_lSizeCur + nSize) > m_lSize) + { + m_lSize *= 2; + } + + wchar_t* pRealloc = (wchar_t*)realloc(m_pData, m_lSize * sizeof(wchar_t)); + if (NULL != pRealloc) + { + // реаллок сработал + m_pData = pRealloc; + m_pDataCur = m_pData + m_lSizeCur; + } + else + { + wchar_t* pMalloc = (wchar_t*)malloc(m_lSize * sizeof(wchar_t)); + memcpy(pMalloc, m_pData, m_lSizeCur * sizeof(wchar_t)); + + free(m_pData); + m_pData = pMalloc; + m_pDataCur = m_pData + m_lSizeCur; + } + } + } + + void CStringBuilder::SetText(const std::wstring& bsText) + { + ClearNoAttack(); + WriteString(bsText); + + for (size_t i = 0; i < m_lSizeCur; ++i) + { + if (WCHAR(8233) == m_pData[i]) + m_pData[i] = WCHAR(' '); + } + } + + void CStringBuilder::operator+=(const std::wstring& oTemp) + { + WriteString(oTemp.c_str(), oTemp.length()); + } + + void CStringBuilder::WriteStringNoSafe(const wchar_t* pString, size_t nLen) + { + memcpy(m_pDataCur, pString, nLen * sizeof(wchar_t)); + + m_pDataCur += nLen; + m_lSizeCur += nLen; + } + void CStringBuilder::WriteString(const wchar_t* pString, size_t nLen) + { + if (-1 == nLen) + { + nLen = wcslen(pString); + } + AddSize(nLen); + WriteStringNoSafe(pString, nLen); + } + + void CStringBuilder::WriteString(const std::wstring& sString) + { + this->WriteString(sString.c_str(), sString.length()); + } + + void CStringBuilder::AddCharNoSafe(const wchar_t& _c) + { + *m_pDataCur++ = _c; + ++m_lSizeCur; + } + void CStringBuilder::AddCharNoCheck(const wchar_t& _c) + { + *m_pDataCur++ = _c; + ++m_lSizeCur; + } + void CStringBuilder::AddSpaceNoCheck() + { + *m_pDataCur++ = ' '; + ++m_lSizeCur; + } + void CStringBuilder::AddCharSafe(const wchar_t& _c) + { + AddSize(1); + *m_pDataCur++ = _c; + ++m_lSizeCur; + } + void CStringBuilder::AddChar2Safe(const wchar_t _c1, const wchar_t& _c2) + { + AddSize(2); + *m_pDataCur++ = _c1; + *m_pDataCur++ = _c2; + m_lSizeCur += 2; + } + + void CStringBuilder::WriteEncodeXmlString(const std::wstring& sString) + { + WriteEncodeXmlString(sString.c_str(), (int)sString.length()); + } + + void CStringBuilder::WriteEncodeXmlString(const wchar_t* pString, int nCount) + { + const wchar_t* pData = pString; + int nCounter = 0; + while (*pData != 0) + { + BYTE _code = CheckCode(*pData); + + switch (_code) + { + case 1: + AddCharSafe(*pData); + break; + case 0: + AddCharSafe((wchar_t)' '); + break; + case 2: + AddSize(5); + *m_pDataCur++ = (wchar_t)('&'); + *m_pDataCur++ = (wchar_t)('a'); + *m_pDataCur++ = (wchar_t)('m'); + *m_pDataCur++ = (wchar_t)('p'); + *m_pDataCur++ = (wchar_t)(';'); + m_lSizeCur += 5; + break; + case 3: + AddSize(6); + *m_pDataCur++ = (wchar_t)('&'); + *m_pDataCur++ = (wchar_t)('a'); + *m_pDataCur++ = (wchar_t)('p'); + *m_pDataCur++ = (wchar_t)('o'); + *m_pDataCur++ = (wchar_t)('s'); + *m_pDataCur++ = (wchar_t)(';'); + m_lSizeCur += 6; + break; + case 4: + AddSize(4); + *m_pDataCur++ = (wchar_t)('&'); + *m_pDataCur++ = (wchar_t)('l'); + *m_pDataCur++ = (wchar_t)('t'); + *m_pDataCur++ = (wchar_t)(';'); + m_lSizeCur += 4; + break; + case 5: + AddSize(4); + *m_pDataCur++ = (wchar_t)('&'); + *m_pDataCur++ = (wchar_t)('g'); + *m_pDataCur++ = (wchar_t)('t'); + *m_pDataCur++ = (wchar_t)(';'); + m_lSizeCur += 4; + break; + case 6: + AddSize(6); + *m_pDataCur++ = (wchar_t)('&'); + *m_pDataCur++ = (wchar_t)('q'); + *m_pDataCur++ = (wchar_t)('u'); + *m_pDataCur++ = (wchar_t)('o'); + *m_pDataCur++ = (wchar_t)('t'); + *m_pDataCur++ = (wchar_t)(';'); + m_lSizeCur += 6; + break; + default: + break; + } + + ++pData; + if (-1 != nCount) + { + ++nCounter; + if (nCounter == nCount) + break; + } + } + } + + size_t CStringBuilder::GetCurSize() + { + return m_lSizeCur; + } + void CStringBuilder::SetCurSize(size_t lCurSize) + { + m_lSizeCur = lCurSize; + m_pDataCur = m_pData + m_lSizeCur; + } + size_t CStringBuilder::GetSize() + { + return m_lSize; + } + + void CStringBuilder::Write(CStringBuilder& oWriter, const size_t& offset) + { + WriteString(oWriter.m_pData + offset, oWriter.m_lSizeCur - offset); + } + + void CStringBuilder::Clear() + { + if (NULL != m_pData) + free(m_pData); + m_pData = NULL; + + m_pData = NULL; + m_lSize = 0; + + m_pDataCur = m_pData; + m_lSizeCur = 0; + } + void CStringBuilder::ClearNoAttack() + { + m_pDataCur = m_pData; + m_lSizeCur = 0; + } + + std::wstring CStringBuilder::GetData() + { + std::wstring str(m_pData, (int)m_lSizeCur); + return str; + } + wchar_t* CStringBuilder::GetBuffer() + { + return m_pData; + } + + void CStringBuilder::RemoveLastSpaces() + { + wchar_t* pMemory = m_pDataCur - 1; + while ((pMemory > m_pData) && (wchar_t(' ') == *pMemory)) + { + --pMemory; + --m_lSizeCur; + --m_pDataCur; + } + + } + bool CStringBuilder::IsSpace() + { + if (1 != m_lSizeCur) + return false; + return (wchar_t(' ') == *m_pData); + } + + void CStringBuilder::AddInt(int val) + { + AddSize(10); + AddIntNoCheck(val); + } + void CStringBuilder::AddIntDel10(int val) + { + AddSize(11); + AddIntNoCheckDel10(val); + } + void CStringBuilder::AddIntDel100(int val) + { + AddSize(11); + AddIntNoCheckDel100(val); + } + void CStringBuilder::AddInt64(__int64 val) + { + //todo AddIntNoCheck + WriteString(std::to_wstring(val)); + } + + void CStringBuilder::AddIntNoCheck(int val) + { + if (0 == val) + { + *m_pDataCur++ = (wchar_t)'0'; + ++m_lSizeCur; + return; + } + if (val < 0) + { + val = -val; + *m_pDataCur++ = (wchar_t)'-'; + ++m_lSizeCur; + } + + int len = 0; + int oval = val; + while (oval > 0) + { + oval /= 10; + ++len; + } + + oval = 1; + while (val > 0) + { + m_pDataCur[len - oval] = (wchar_t)('0' + (val % 10)); + ++oval; + val /= 10; + } + + m_pDataCur += len; + m_lSizeCur += len; + } + + void CStringBuilder::AddIntNoCheckDel10(int val) + { + if (0 == val) + { + *m_pDataCur++ = (wchar_t)'0'; + ++m_lSizeCur; + return; + } + if (val < 0) + { + val = -val; + *m_pDataCur++ = (wchar_t)'-'; + ++m_lSizeCur; + } + + int len = 0; + int oval = val; + while (oval > 0) + { + oval /= 10; + ++len; + } + + oval = 1; + int nLastS = (val % 10); + if (0 != nLastS) + { + ++len; + m_pDataCur[len - oval] = (wchar_t)('0' + nLastS); + ++oval; + m_pDataCur[len - oval] = (wchar_t)('.'); + ++oval; + val /= 10; + } + else + { + --len; + val /= 10; + } + + while (val > 0) + { + m_pDataCur[len - oval] = (wchar_t)('0' + (val % 10)); + ++oval; + val /= 10; + } + + m_pDataCur += len; + m_lSizeCur += len; + } + void CStringBuilder::AddIntNoCheckDel100(int val) + { + if (0 == val) + { + *m_pDataCur++ = (wchar_t)'0'; + ++m_lSizeCur; + return; + } + if (val < 0) + { + val = -val; + *m_pDataCur++ = (wchar_t)'-'; + ++m_lSizeCur; + } + + int len = 0; + int oval = val; + while (oval > 0) + { + oval /= 10; + ++len; + } + + oval = 1; + int nLastS = (val % 10); + if (0 != nLastS) + { + ++len; + m_pDataCur[len - oval] = (wchar_t)('0' + nLastS); + ++oval; + m_pDataCur[len - oval] = (wchar_t)('.'); + ++oval; + val /= 10; + } + else + { + --len; + val /= 10; + } + + while (val > 0) + { + m_pDataCur[len - oval] = (wchar_t)('0' + (val % 10)); + ++oval; + val /= 10; + } + + m_pDataCur += len; + m_lSizeCur += len; + } + void CStringBuilder::AddDouble(double val, int count) + { + std::wstring s = std::to_wstring(val); + + if (count != -1) + { + size_t nSize = s.length(); + std::wstring::size_type pos1 = s.find(wchar_t('.')); + if (pos1 != std::wstring::npos) + { + size_t nCountNeed = pos1 + 1 + count; + if (nCountNeed < nSize) + s = s.substr(0, nCountNeed); + } + std::wstring::size_type pos2 = s.find(wchar_t(',')); + if (pos2 != std::wstring::npos) + { + size_t nCountNeed = pos2 + 1 + count; + if (nCountNeed < nSize) + s = s.substr(0, nCountNeed); + } + } + + WriteString(s); + } + + void CStringBuilder::WriteHexByteNoSafe(const unsigned char& value) + { + *m_pDataCur++ = g_hex_values[(value >> 4) & 0x0F]; + ++m_lSizeCur; + *m_pDataCur++ = g_hex_values[value & 0x0F]; + ++m_lSizeCur; + } + void CStringBuilder::WriteHexByte(const unsigned char& value) + { + AddSize(2); + WriteHexByteNoSafe(value); + } + void CStringBuilder::WriteHexInt3(const unsigned int& value) + { + AddSize(6); + WriteHexByteNoSafe((value >> 16) & 0xFF); + WriteHexByteNoSafe((value >> 8) & 0xFF); + WriteHexByteNoSafe(value & 0xFF); + } + void CStringBuilder::WriteHexColor3(const unsigned char& r, const unsigned char& g, const unsigned char& b) + { + AddSize(7); + *m_pDataCur++ = (wchar_t)'#'; + ++m_lSizeCur; + WriteHexByteNoSafe(r); + WriteHexByteNoSafe(g); + WriteHexByteNoSafe(b); + } + void CStringBuilder::WriteHexColor3(const unsigned int& value) + { + AddSize(7); + *m_pDataCur++ = (wchar_t)'#'; + ++m_lSizeCur; + WriteHexByteNoSafe(value & 0xFF); + WriteHexByteNoSafe((value >> 8) & 0xFF); + WriteHexByteNoSafe((value >> 16) & 0xFF); + } + + unsigned char CStringBuilder::CheckCode(const wchar_t& c) + { + if ('&' == c) + return 2; + if ('\'' == c) + return 3; + if ('<' == c) + return 4; + if ('>' == c) + return 5; + if ('\"' == c) + return 6; + + return 1; + } + + void string_replace(std::wstring& text, const std::wstring& replaceFrom, const std::wstring& replaceTo) + { + size_t posn = 0; + while (std::wstring::npos != (posn = text.find(replaceFrom, posn))) + { + text.replace(posn, replaceFrom.length(), replaceTo); + posn += replaceTo.length(); + } + } + void string_replaceA(std::string& text, const std::string& replaceFrom, const std::string& replaceTo) + { + size_t posn = 0; + while (std::string::npos != (posn = text.find(replaceFrom, posn))) + { + text.replace(posn, replaceFrom.length(), replaceTo); + posn += replaceTo.length(); + } + } +} diff --git a/DesktopEditor/common/StringBuilder.h b/DesktopEditor/common/StringBuilder.h index 5130a1d6a6..d0b71a2fe3 100644 --- a/DesktopEditor/common/StringBuilder.h +++ b/DesktopEditor/common/StringBuilder.h @@ -35,14 +35,18 @@ #include #include #include - #include "Types.h" +#ifndef STRINGBUILDER_USE_DYNAMIC_LIBRARY +#define STRINGBUILDER_DECL_EXPORT +#else +#include "./base_export.h" +#define STRINGBUILDER_DECL_EXPORT Q_DECL_EXPORT +#endif + namespace NSStringUtils { - const wchar_t g_hex_values[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - - class CStringBuilderA + class STRINGBUILDER_DECL_EXPORT CStringBuilderA { private: char* m_pData; @@ -52,140 +56,32 @@ namespace NSStringUtils size_t m_lSizeCur; public: - CStringBuilderA() - { - m_pData = NULL; - m_lSize = 0; - - m_pDataCur = m_pData; - m_lSizeCur = m_lSize; - } - ~CStringBuilderA() - { - if (NULL != m_pData) - free(m_pData); - m_pData = NULL; - } - - inline void AddSize(size_t nSize) - { - if (NULL == m_pData) - { - m_lSize = (std::max)((int)nSize, 1000); - m_pData = (char*)malloc(m_lSize * sizeof(char)); - - m_lSizeCur = 0; - m_pDataCur = m_pData; - return; - } - - if ((m_lSizeCur + nSize) > m_lSize) - { - while ((m_lSizeCur + nSize) > m_lSize) - { - m_lSize *= 2; - } - - char* pRealloc = (char*)realloc(m_pData, m_lSize * sizeof(char)); - if (NULL != pRealloc) - { - // реаллок сработал - m_pData = pRealloc; - m_pDataCur = m_pData + m_lSizeCur; - } - else - { - char* pMalloc = (char*)malloc(m_lSize * sizeof(char)); - memcpy(pMalloc, m_pData, m_lSizeCur * sizeof(char)); - - free(m_pData); - m_pData = pMalloc; - m_pDataCur = m_pData + m_lSizeCur; - } - } - } + CStringBuilderA(); + ~CStringBuilderA(); + void AddSize(size_t nSize); public: + void SetText(const std::string& sText); + void WriteString(const std::string& str); - inline void SetText(const std::string& sText) - { - ClearNoAttack(); - WriteString(sText); - } - inline void WriteString(const std::string& str) - { - WriteString(str.c_str(), str.length()); - } + void WriteStringNoSafe(const char* pString, size_t nLen); + void WriteString(const char* pString, size_t nLen); - inline void WriteStringNoSafe(const char* pString, size_t nLen) - { - memcpy(m_pDataCur, pString, nLen * sizeof(char)); + void AddCharNoSafe(const char& _c); + void AddCharSafe(const char& _c); - m_pDataCur += nLen; - m_lSizeCur += nLen; - } - inline void WriteString(const char* pString, size_t nLen) - { - AddSize(nLen); - WriteStringNoSafe(pString, nLen); - } + size_t GetCurSize(); + void SetCurSize(size_t lCurSize); + size_t GetSize(); - inline void AddCharNoSafe(const char& _c) - { - *m_pDataCur++ = _c; - ++m_lSizeCur; - } - inline void AddCharSafe(const char& _c) - { - AddSize(1); - *m_pDataCur++ = _c; - ++m_lSizeCur; - } + void Clear(); + void ClearNoAttack(); - inline size_t GetCurSize() - { - return m_lSizeCur; - } - inline void SetCurSize(size_t lCurSize) - { - m_lSizeCur = lCurSize; - m_pDataCur = m_pData + m_lSizeCur; - } - inline size_t GetSize() - { - return m_lSize; - } - - inline void Clear() - { - if (NULL != m_pData) - free(m_pData); - m_pData = NULL; - - m_pData = NULL; - m_lSize = 0; - - m_pDataCur = m_pData; - m_lSizeCur = 0; - } - inline void ClearNoAttack() - { - m_pDataCur = m_pData; - m_lSizeCur = 0; - } - - std::string GetData() - { - std::string str(m_pData, (int)m_lSizeCur); - return str; - } - char* GetBuffer() - { - return m_pData; - } + std::string GetData(); + char* GetBuffer(); }; - class CStringBuilder + class STRINGBUILDER_DECL_EXPORT CStringBuilder { private: wchar_t* m_pData; @@ -195,530 +91,70 @@ namespace NSStringUtils size_t m_lSizeCur; public: - CStringBuilder() - { - m_pData = NULL; - m_lSize = 0; + CStringBuilder(); + ~CStringBuilder(); - m_pDataCur = m_pData; - m_lSizeCur = m_lSize; - } - ~CStringBuilder() - { - if (NULL != m_pData) - free(m_pData); - m_pData = NULL; - } - - inline void AddSize(size_t nSize) - { - if (NULL == m_pData) - { - m_lSize = (std::max)((int)nSize, 1000); - m_pData = (wchar_t*)malloc(m_lSize * sizeof(wchar_t)); - - m_lSizeCur = 0; - m_pDataCur = m_pData; - return; - } - - if ((m_lSizeCur + nSize) > m_lSize) - { - while ((m_lSizeCur + nSize) > m_lSize) - { - m_lSize *= 2; - } - - wchar_t* pRealloc = (wchar_t*)realloc(m_pData, m_lSize * sizeof(wchar_t)); - if (NULL != pRealloc) - { - // реаллок сработал - m_pData = pRealloc; - m_pDataCur = m_pData + m_lSizeCur; - } - else - { - wchar_t* pMalloc = (wchar_t*)malloc(m_lSize * sizeof(wchar_t)); - memcpy(pMalloc, m_pData, m_lSizeCur * sizeof(wchar_t)); - - free(m_pData); - m_pData = pMalloc; - m_pDataCur = m_pData + m_lSizeCur; - } - } - } + void AddSize(size_t nSize); public: - inline void SetText(const std::wstring& bsText) - { - ClearNoAttack(); - WriteString(bsText); + void SetText(const std::wstring& bsText); - for (size_t i = 0; i < m_lSizeCur; ++i) - { - if (WCHAR(8233) == m_pData[i]) - m_pData[i] = WCHAR(' '); - } - } + void operator+=(const std::wstring& oTemp); - inline void operator+=(const std::wstring& oTemp) - { - WriteString(oTemp.c_str(), oTemp.length()); - } + void WriteStringNoSafe(const wchar_t* pString, size_t nLen); + void WriteString(const wchar_t* pString, size_t nLen = -1); - inline void WriteStringNoSafe(const wchar_t* pString, size_t nLen) - { - memcpy(m_pDataCur, pString, nLen * sizeof(wchar_t)); + void WriteString(const std::wstring& sString); - m_pDataCur += nLen; - m_lSizeCur += nLen; - } - inline void WriteString(const wchar_t* pString, size_t nLen = -1) - { - if (-1 == nLen) - { - nLen = wcslen(pString); - } - AddSize(nLen); - WriteStringNoSafe(pString, nLen); - } + void AddCharNoSafe(const wchar_t& _c); + void AddCharNoCheck(const wchar_t& _c); + void AddSpaceNoCheck(); + void AddCharSafe(const wchar_t& _c); + void AddChar2Safe(const wchar_t _c1, const wchar_t& _c2); - inline void WriteString(const std::wstring& sString) - { - this->WriteString(sString.c_str(), sString.length()); - } + void WriteEncodeXmlString(const std::wstring& sString); - inline void AddCharNoSafe(const wchar_t& _c) - { - *m_pDataCur++ = _c; - ++m_lSizeCur; - } - inline void AddCharNoCheck(const wchar_t& _c) - { - *m_pDataCur++ = _c; - ++m_lSizeCur; - } - inline void AddSpaceNoCheck() - { - *m_pDataCur++ = ' '; - ++m_lSizeCur; - } - inline void AddCharSafe(const wchar_t& _c) - { - AddSize(1); - *m_pDataCur++ = _c; - ++m_lSizeCur; - } - inline void AddChar2Safe(const wchar_t _c1, const wchar_t& _c2) - { - AddSize(2); - *m_pDataCur++ = _c1; - *m_pDataCur++ = _c2; - m_lSizeCur += 2; - } + void WriteEncodeXmlString(const wchar_t* pString, int nCount = -1); - inline void WriteEncodeXmlString(const std::wstring& sString) - { - WriteEncodeXmlString(sString.c_str(), (int)sString.length()); - } + size_t GetCurSize(); + void SetCurSize(size_t lCurSize); + size_t GetSize(); - inline void WriteEncodeXmlString(const wchar_t* pString, int nCount = -1) - { - const wchar_t* pData = pString; - int nCounter = 0; - while (*pData != 0) - { - BYTE _code = CheckCode(*pData); + void Write(CStringBuilder& oWriter, const size_t& offset = 0); - switch (_code) - { - case 1: - AddCharSafe(*pData); - break; - case 0: - AddCharSafe((wchar_t)' '); - break; - case 2: - AddSize(5); - *m_pDataCur++ = (wchar_t)('&'); - *m_pDataCur++ = (wchar_t)('a'); - *m_pDataCur++ = (wchar_t)('m'); - *m_pDataCur++ = (wchar_t)('p'); - *m_pDataCur++ = (wchar_t)(';'); - m_lSizeCur += 5; - break; - case 3: - AddSize(6); - *m_pDataCur++ = (wchar_t)('&'); - *m_pDataCur++ = (wchar_t)('a'); - *m_pDataCur++ = (wchar_t)('p'); - *m_pDataCur++ = (wchar_t)('o'); - *m_pDataCur++ = (wchar_t)('s'); - *m_pDataCur++ = (wchar_t)(';'); - m_lSizeCur += 6; - break; - case 4: - AddSize(4); - *m_pDataCur++ = (wchar_t)('&'); - *m_pDataCur++ = (wchar_t)('l'); - *m_pDataCur++ = (wchar_t)('t'); - *m_pDataCur++ = (wchar_t)(';'); - m_lSizeCur += 4; - break; - case 5: - AddSize(4); - *m_pDataCur++ = (wchar_t)('&'); - *m_pDataCur++ = (wchar_t)('g'); - *m_pDataCur++ = (wchar_t)('t'); - *m_pDataCur++ = (wchar_t)(';'); - m_lSizeCur += 4; - break; - case 6: - AddSize(6); - *m_pDataCur++ = (wchar_t)('&'); - *m_pDataCur++ = (wchar_t)('q'); - *m_pDataCur++ = (wchar_t)('u'); - *m_pDataCur++ = (wchar_t)('o'); - *m_pDataCur++ = (wchar_t)('t'); - *m_pDataCur++ = (wchar_t)(';'); - m_lSizeCur += 6; - break; - default: - break; - } + void Clear(); + void ClearNoAttack(); - ++pData; - if (-1 != nCount) - { - ++nCounter; - if (nCounter == nCount) - break; - } - } - } + std::wstring GetData(); + wchar_t* GetBuffer(); - inline size_t GetCurSize() - { - return m_lSizeCur; - } - inline void SetCurSize(size_t lCurSize) - { - m_lSizeCur = lCurSize; - m_pDataCur = m_pData + m_lSizeCur; - } - inline size_t GetSize() - { - return m_lSize; - } + void RemoveLastSpaces(); + bool IsSpace(); - inline void Write(CStringBuilder& oWriter, const size_t& offset = 0) - { - WriteString(oWriter.m_pData + offset, oWriter.m_lSizeCur - offset); - } + void AddInt(int val); + void AddIntDel10(int val); + void AddIntDel100(int val); + void AddInt64(__int64 val); - inline void Clear() - { - if (NULL != m_pData) - free(m_pData); - m_pData = NULL; + void AddIntNoCheck(int val); - m_pData = NULL; - m_lSize = 0; + void AddIntNoCheckDel10(int val); + void AddIntNoCheckDel100(int val); + void AddDouble(double val, int count); - m_pDataCur = m_pData; - m_lSizeCur = 0; - } - inline void ClearNoAttack() - { - m_pDataCur = m_pData; - m_lSizeCur = 0; - } - - std::wstring GetData() - { - std::wstring str(m_pData, (int)m_lSizeCur); - return str; - } - wchar_t* GetBuffer() - { - return m_pData; - } - - inline void RemoveLastSpaces() - { - wchar_t* pMemory = m_pDataCur - 1; - while ((pMemory > m_pData) && (wchar_t(' ') == *pMemory)) - { - --pMemory; - --m_lSizeCur; - --m_pDataCur; - } - - } - inline bool IsSpace() - { - if (1 != m_lSizeCur) - return false; - return (wchar_t(' ') == *m_pData); - } - - void AddInt(int val) - { - AddSize(10); - AddIntNoCheck(val); - } - void AddIntDel10(int val) - { - AddSize(11); - AddIntNoCheckDel10(val); - } - void AddIntDel100(int val) - { - AddSize(11); - AddIntNoCheckDel100(val); - } - void AddInt64(__int64 val) - { - //todo AddIntNoCheck - WriteString(std::to_wstring(val)); - } - - void AddIntNoCheck(int val) - { - if (0 == val) - { - *m_pDataCur++ = (wchar_t)'0'; - ++m_lSizeCur; - return; - } - if (val < 0) - { - val = -val; - *m_pDataCur++ = (wchar_t)'-'; - ++m_lSizeCur; - } - - int len = 0; - int oval = val; - while (oval > 0) - { - oval /= 10; - ++len; - } - - oval = 1; - while (val > 0) - { - m_pDataCur[len - oval] = (wchar_t)('0' + (val % 10)); - ++oval; - val /= 10; - } - - m_pDataCur += len; - m_lSizeCur += len; - } - - void AddIntNoCheckDel10(int val) - { - if (0 == val) - { - *m_pDataCur++ = (wchar_t)'0'; - ++m_lSizeCur; - return; - } - if (val < 0) - { - val = -val; - *m_pDataCur++ = (wchar_t)'-'; - ++m_lSizeCur; - } - - int len = 0; - int oval = val; - while (oval > 0) - { - oval /= 10; - ++len; - } - - oval = 1; - int nLastS = (val % 10); - if (0 != nLastS) - { - ++len; - m_pDataCur[len - oval] = (wchar_t)('0' + nLastS); - ++oval; - m_pDataCur[len - oval] = (wchar_t)('.'); - ++oval; - val /= 10; - } - else - { - --len; - val /= 10; - } - - while (val > 0) - { - m_pDataCur[len - oval] = (wchar_t)('0' + (val % 10)); - ++oval; - val /= 10; - } - - m_pDataCur += len; - m_lSizeCur += len; - } - void AddIntNoCheckDel100(int val) - { - if (0 == val) - { - *m_pDataCur++ = (wchar_t)'0'; - ++m_lSizeCur; - return; - } - if (val < 0) - { - val = -val; - *m_pDataCur++ = (wchar_t)'-'; - ++m_lSizeCur; - } - - int len = 0; - int oval = val; - while (oval > 0) - { - oval /= 10; - ++len; - } - - oval = 1; - int nLastS = (val % 10); - if (0 != nLastS) - { - ++len; - m_pDataCur[len - oval] = (wchar_t)('0' + nLastS); - ++oval; - m_pDataCur[len - oval] = (wchar_t)('.'); - ++oval; - val /= 10; - } - else - { - --len; - val /= 10; - } - - while (val > 0) - { - m_pDataCur[len - oval] = (wchar_t)('0' + (val % 10)); - ++oval; - val /= 10; - } - - m_pDataCur += len; - m_lSizeCur += len; - } - void AddDouble(double val, int count) - { - std::wstring s = std::to_wstring(val); - - if (count != -1) - { - size_t nSize = s.length(); - std::wstring::size_type pos1 = s.find(wchar_t('.')); - if (pos1 != std::wstring::npos) - { - size_t nCountNeed = pos1 + 1 + count; - if (nCountNeed < nSize) - s = s.substr(0, nCountNeed); - } - std::wstring::size_type pos2 = s.find(wchar_t(',')); - if (pos2 != std::wstring::npos) - { - size_t nCountNeed = pos2 + 1 + count; - if (nCountNeed < nSize) - s = s.substr(0, nCountNeed); - } - } - - WriteString(s); - } - - inline void WriteHexByteNoSafe(const unsigned char& value) - { - *m_pDataCur++ = g_hex_values[(value >> 4) & 0x0F]; - ++m_lSizeCur; - *m_pDataCur++ = g_hex_values[value & 0x0F]; - ++m_lSizeCur; - } - inline void WriteHexByte(const unsigned char& value) - { - AddSize(2); - WriteHexByteNoSafe(value); - } - inline void WriteHexInt3(const unsigned int& value) - { - AddSize(6); - WriteHexByteNoSafe((value >> 16) & 0xFF); - WriteHexByteNoSafe((value >> 8) & 0xFF); - WriteHexByteNoSafe(value & 0xFF); - } - inline void WriteHexColor3(const unsigned char& r, const unsigned char& g, const unsigned char& b) - { - AddSize(7); - *m_pDataCur++ = (wchar_t)'#'; - ++m_lSizeCur; - WriteHexByteNoSafe(r); - WriteHexByteNoSafe(g); - WriteHexByteNoSafe(b); - } - inline void WriteHexColor3(const unsigned int& value) - { - AddSize(7); - *m_pDataCur++ = (wchar_t)'#'; - ++m_lSizeCur; - WriteHexByteNoSafe(value & 0xFF); - WriteHexByteNoSafe((value >> 8) & 0xFF); - WriteHexByteNoSafe((value >> 16) & 0xFF); - } + inline void WriteHexByteNoSafe(const unsigned char& value); + inline void WriteHexByte(const unsigned char& value); + inline void WriteHexInt3(const unsigned int& value); + inline void WriteHexColor3(const unsigned char& r, const unsigned char& g, const unsigned char& b); + inline void WriteHexColor3(const unsigned int& value); protected: - inline unsigned char CheckCode(const wchar_t& c) - { - if ('&' == c) - return 2; - if ('\'' == c) - return 3; - if ('<' == c) - return 4; - if ('>' == c) - return 5; - if ('\"' == c) - return 6; - - return 1; - } + unsigned char CheckCode(const wchar_t& c); }; - static void string_replace(std::wstring& text, const std::wstring& replaceFrom, const std::wstring& replaceTo) - { - size_t posn = 0; - while (std::wstring::npos != (posn = text.find(replaceFrom, posn))) - { - text.replace(posn, replaceFrom.length(), replaceTo); - posn += replaceTo.length(); - } - } - static void string_replaceA(std::string& text, const std::string& replaceFrom, const std::string& replaceTo) - { - size_t posn = 0; - while (std::string::npos != (posn = text.find(replaceFrom, posn))) - { - text.replace(posn, replaceFrom.length(), replaceTo); - posn += replaceTo.length(); - } - } + STRINGBUILDER_DECL_EXPORT void string_replace(std::wstring& text, const std::wstring& replaceFrom, const std::wstring& replaceTo); + STRINGBUILDER_DECL_EXPORT void string_replaceA(std::string& text, const std::string& replaceFrom, const std::string& replaceTo); } #endif // _BUILD_STRING_BUILDER_CROSSPLATFORM_H_ diff --git a/OfficeUtils/src/ZipUtilsCP.h b/OfficeUtils/src/ZipUtilsCP.h index b928040635..d2ea6bed3e 100644 --- a/OfficeUtils/src/ZipUtilsCP.h +++ b/OfficeUtils/src/ZipUtilsCP.h @@ -39,6 +39,7 @@ #if defined(_WIN32) || defined (_WIN64) #include + #include #endif #include "OfficeUtilsCommon.h"