diff --git a/DesktopEditor/common/File.cpp b/DesktopEditor/common/File.cpp index eeebe8b305..7b2129febc 100644 --- a/DesktopEditor/common/File.cpp +++ b/DesktopEditor/common/File.cpp @@ -57,6 +57,19 @@ #define MAX_PATH 1024 #endif +#ifdef __ANDROID__ +#define USE_LINUX_SENDFILE_INSTEAD_STREAMS + +// Available since API level 21. +// iostream operation throwing exception when exceptions not enabled +#endif + +#ifdef USE_LINUX_SENDFILE_INSTEAD_STREAMS +#include +#include +#include +#endif + // реализация возможности подмены определения GetTempPath std::wstring g_overrideTmpPath = L""; @@ -1204,6 +1217,43 @@ namespace NSFile if (strSrc == strDst) return true; +#if !defined(_WIN32) && !defined(_WIN32_WCE) && !defined(_WIN64) + std::string strSrcA = U_TO_UTF8(strSrc); + std::string strDstA = U_TO_UTF8(strDst); +#endif + +#ifdef USE_LINUX_SENDFILE_INSTEAD_STREAMS + int src = open(strSrcA.c_str(), O_RDONLY); + int dst = open(strDstA.c_str(), O_WRONLY | O_CREAT); + + // struct required, rationale: function stat() exists also + struct stat stat_source; + fstat(src, &stat_source); + + if (stat_source.st_size > 0x7FFFFFFF) + return false; + + off_t offset = 0; + long long file_size = stat_source.st_size; + long long file_size_tmp = file_size; + long long read_size = 0; + long long read_size_marker = (long long)sendfile(dst, src, &offset, file_size_tmp); + while (-1 != read_size_marker) + { + if (read_size == file_size) + break; + + file_size_tmp -= read_size_marker; + read_size += read_size_marker; + + if (read_size != file_size) + read_size_marker = (long long)sendfile(dst, src, &offset, file_size_tmp); + } + + close(src); + close(dst); + return (-1 != read_size_marker) ? true : false; +#else std::ifstream src; std::ofstream dst; @@ -1240,18 +1290,8 @@ namespace NSFile 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; + src.open(strSrcA.c_str(), std::ios::binary); + dst.open(strDstA.c_str(), std::ios::binary); #endif bool bRet = false; @@ -1267,6 +1307,7 @@ namespace NSFile RELEASEARRAYOBJECTS(pBuffer_in); RELEASEARRAYOBJECTS(pBuffer_out); return bRet; +#endif } bool CFileBinary::Remove(const std::wstring& strFileName) {