diff --git a/src/csync/CMakeLists.txt b/src/csync/CMakeLists.txt index a35ad8f971..bf1cdc1480 100644 --- a/src/csync/CMakeLists.txt +++ b/src/csync/CMakeLists.txt @@ -28,8 +28,7 @@ set(csync_SRCS std/c_alloc.c std/c_string.c - std/c_time.c - std/c_utf8.cpp + std/c_time.cpp ) diff --git a/src/csync/csync_exclude.cpp b/src/csync/csync_exclude.cpp index c3009d73df..9cf920167a 100644 --- a/src/csync/csync_exclude.cpp +++ b/src/csync/csync_exclude.cpp @@ -26,7 +26,6 @@ #include "c_lib.h" #include "c_private.h" -#include "c_utf8.h" #include "csync_exclude.h" diff --git a/src/csync/std/c_lib.h b/src/csync/std/c_lib.h index 2f0135ede7..db49e8e8b0 100644 --- a/src/csync/std/c_lib.h +++ b/src/csync/std/c_lib.h @@ -24,5 +24,4 @@ #include "c_macro.h" #include "c_alloc.h" #include "c_string.h" -#include "c_time.h" #include "c_private.h" diff --git a/src/csync/std/c_time.c b/src/csync/std/c_time.cpp similarity index 85% rename from src/csync/std/c_time.c rename to src/csync/std/c_time.cpp index c150d894b6..1dc1de8ca1 100644 --- a/src/csync/std/c_time.c +++ b/src/csync/std/c_time.cpp @@ -23,13 +23,12 @@ #include "c_string.h" #include "c_time.h" -#include "c_utf8.h" + +#include #ifdef HAVE_UTIMES -int c_utimes(const char *uri, const struct timeval *times) { - mbchar_t *wuri = c_utf8_path_to_locale(uri); - int ret = utimes(wuri, times); - c_free_locale_string(wuri); +int c_utimes(const QString &uri, const struct timeval *times) { + int ret = utimes(QFile::encodeName(uri).constData(), times); return ret; } #else // HAVE_UTIMES @@ -51,12 +50,12 @@ static void UnixTimevalToFileTime(struct timeval t, LPFILETIME pft) pft->dwHighDateTime = ll >> 32; } -int c_utimes(const char *uri, const struct timeval *times) { +int c_utimes(const QString &uri, const struct timeval *times) { FILETIME LastAccessTime; FILETIME LastModificationTime; HANDLE hFile; - mbchar_t *wuri = c_utf8_path_to_locale( uri ); + auto wuri = uri.toStdWString(); if(times) { UnixTimevalToFileTime(times[0], &LastAccessTime); @@ -67,7 +66,7 @@ int c_utimes(const char *uri, const struct timeval *times) { GetSystemTimeAsFileTime(&LastModificationTime); } - hFile=CreateFileW(wuri, FILE_WRITE_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + hFile=CreateFileW(wuri.data(), FILE_WRITE_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL+FILE_FLAG_BACKUP_SEMANTICS, NULL); if(hFile==INVALID_HANDLE_VALUE) { switch(GetLastError()) { @@ -95,12 +94,10 @@ int c_utimes(const char *uri, const struct timeval *times) { //can this happen? errno=ENOENT; CloseHandle(hFile); - c_free_locale_string(wuri); return -1; } CloseHandle(hFile); - c_free_locale_string(wuri); return 0; } diff --git a/src/csync/std/c_time.h b/src/csync/std/c_time.h index 3792198f8c..55a6aa6bc8 100644 --- a/src/csync/std/c_time.h +++ b/src/csync/std/c_time.h @@ -21,11 +21,9 @@ #ifndef _C_TIME_H #define _C_TIME_H -#include "ocsynclib.h" +#include -#ifdef __cplusplus -extern "C" { -#endif +#include "ocsynclib.h" #ifdef _WIN32 #include @@ -33,10 +31,7 @@ extern "C" { #include #endif -OCSYNC_EXPORT int c_utimes(const char *uri, const struct timeval *times); +OCSYNC_EXPORT int c_utimes(const QString &uri, const struct timeval *times); -#ifdef __cplusplus -} -#endif #endif /* _C_TIME_H */ diff --git a/src/csync/std/c_utf8.cpp b/src/csync/std/c_utf8.cpp deleted file mode 100644 index d260a9950a..0000000000 --- a/src/csync/std/c_utf8.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - * cynapses libc functions - * - * Copyright (c) 2008-2013 by Andreas Schneider - * Copyright (c) 2012-2013 by Klaas Freitag - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config_csync.h" -#include "c_utf8.h" - -#ifdef _WIN32 -#include -#include -#include -#include -#include -#include -#include -#else -#include -#include -#endif - -#include "c_alloc.h" -#include "c_string.h" -#include "common/filesystembase.h" - -/* Convert a locale String to UTF8 */ -QByteArray c_utf8_from_locale(const mbchar_t *wstr) -{ - if (wstr == nullptr) { - return QByteArray(); - } - -#ifdef _WIN32 - QByteArray dst; - int size_needed; - size_t len; - len = wcslen(wstr); - /* Call once to get the required size. */ - size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr, len, NULL, 0, NULL, NULL); - if (size_needed > 0) { - dst.resize(size_needed); - WideCharToMultiByte(CP_UTF8, 0, wstr, len, dst.data(), size_needed, NULL, NULL); - } - return dst; -#else - auto codec = QTextCodec::codecForLocale(); -#ifndef __APPLE__ - if (codec->mibEnum() == 106) { // UTF-8 - // Optimisation for UTF-8: no need to convert to QString. - // We still need to do it for mac because of normalization - return QByteArray(wstr); - } -#endif - QTextDecoder dec(codec); - QString s = dec.toUnicode(wstr, qstrlen(wstr)); - if (s.isEmpty() || dec.hasFailure()) { - /* Conversion error: since we can't report error from this function, just return the original - string. We take care of invalid utf-8 in SyncEngine::treewalkFile */ - return QByteArray(wstr); - } -#ifdef __APPLE__ - s = s.normalized(QString::NormalizationForm_C); -#endif - return std::move(s).toUtf8(); -#endif -} - -extern "C" { - -/* Convert a an UTF8 string to locale */ -mbchar_t* c_utf8_string_to_locale(const char *str) -{ - if (str == nullptr ) { - return nullptr; - } -#ifdef _WIN32 - mbchar_t *dst = NULL; - size_t len; - int size_needed; - - len = strlen(str); - size_needed = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0); - if (size_needed > 0) { - int size_char = (size_needed + 1) * sizeof(mbchar_t); - dst = (mbchar_t*)c_malloc(size_char); - memset((void*)dst, 0, size_char); - MultiByteToWideChar(CP_UTF8, 0, str, -1, dst, size_needed); - } - return dst; -#else - return c_strdup(QFile::encodeName(QString::fromUtf8(str))); -#endif -} - - mbchar_t* c_utf8_path_to_locale(const char *str) - { - if( str == nullptr ) { - return nullptr; - } else { - #ifdef _WIN32 - QByteArray unc_str = OCC::FileSystem::pathtoUNC(QByteArray::fromRawData(str, strlen(str))); - mbchar_t *dst = c_utf8_string_to_locale(unc_str); - return dst; - #else - return c_utf8_string_to_locale(str); - #endif - } - } - -} diff --git a/src/csync/std/c_utf8.h b/src/csync/std/c_utf8.h deleted file mode 100644 index 2446405f03..0000000000 --- a/src/csync/std/c_utf8.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * cynapses libc functions - * - * Copyright (c) 2008-2013 by Andreas Schneider - * Copyright (c) 2012-2013 by Klaas Freitag - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file c_string.h - * - * @brief Interface of the cynapses string implementations - * - * @defgroup cynStringInternals cynapses libc string functions - * @ingroup cynLibraryAPI - * - * @{ - */ -#ifndef _C_UTF8_H -#define _C_UTF8_H - -#include "c_private.h" -#include "c_macro.h" - -#ifdef __cplusplus -#include - -/** - * @brief Convert a platform locale string to utf8. - * - * This function is part of the multi platform abstraction of basic file - * operations to handle various platform encoding correctly. - * - * Instead of using the standard file operations the multi platform aliases - * defined in c_private.h have to be used instead. - * - * To convert path names returned by these functions to the internally used - * utf8 format this function has to be used. - * - * @param str The multibyte encoded string to convert - * - * @return The converted string or a null QByteArray on error. - * - * @see c_free_locale_string() - * @see c_utf8_to_locale() - * - */ - OCSYNC_EXPORT QByteArray c_utf8_from_locale(const mbchar_t *str); - -extern "C" { - -#endif // __cplusplus - -/** - * @brief Convert a utf8 encoded string to platform specific locale. - * - * This function is part of the multi platform abstraction of basic file - * operations to handle various platform encoding correctly. - * - * Instead of using the standard file operations the multi platform aliases - * defined in c_private.h have to be used instead. - * - * To convert strings as input for the cross platform functions from the - * internally used utf8 format, this function has to be used. - * The returned string has to be freed by c_free_locale_string(). On some - * platforms this method allocates memory and on others not but it has never - * sto be cared about. - * - * If the string to convert is a path, consider using c_utf8_path_to_locale(). - * - * @param str The utf8 string to convert. - * - * @return The malloced converted multibyte string or NULL on error. - * - * @see c_free_locale_string() - * @see c_utf8_from_locale() - * - */ -OCSYNC_EXPORT mbchar_t* c_utf8_string_to_locale(const char *wstr); - -/** - * @brief c_utf8_path_to_locale converts a unixoid path to the locale aware format - * - * On windows, it converts to UNC and multibyte. - * On Mac, it converts to the correct utf8 using iconv. - * On Linux, it returns utf8 - * - * @param str The path to convert - * - * @return a pointer to the converted string. Caller has to free it using the - * function c_free_locale_string. - */ -OCSYNC_EXPORT mbchar_t* c_utf8_path_to_locale(const char *str); - -/** - * @brief Free buffer malloced by c_utf8_to_locale(). - * - * This function is part of the multi platform abstraction of basic file - * operations to handle various platform encoding correctly. - * - * Instead of using the standard file operations the multi platform aliases - * defined in c_private.h have to be used instead. - * - * This function frees the memory that was allocated by a previous call to - * c_utf8_to_locale(). - * - * @param buf The buffer to free. - * - * @see c_utf8_from_locale(), c_utf8_to_locale() - * - */ -#define c_free_locale_string(x) SAFE_FREE(x) - - -/** - * }@ - */ - -#ifdef __cplusplus -} -#endif - -#endif /* _C_UTF8_H */ diff --git a/src/csync/vio/csync_vio_local.h b/src/csync/vio/csync_vio_local.h index 769d1d0201..04bd057ea4 100644 --- a/src/csync/vio/csync_vio_local.h +++ b/src/csync/vio/csync_vio_local.h @@ -21,6 +21,8 @@ #ifndef _CSYNC_VIO_LOCAL_H #define _CSYNC_VIO_LOCAL_H +#include + struct csync_vio_handle_t; namespace OCC { class Vfs; @@ -30,6 +32,6 @@ csync_vio_handle_t OCSYNC_EXPORT *csync_vio_local_opendir(const QString &name); int OCSYNC_EXPORT csync_vio_local_closedir(csync_vio_handle_t *dhandle); std::unique_ptr OCSYNC_EXPORT csync_vio_local_readdir(csync_vio_handle_t *dhandle, OCC::Vfs *vfs); -int OCSYNC_EXPORT csync_vio_local_stat(const char *uri, csync_file_stat_t *buf); +int OCSYNC_EXPORT csync_vio_local_stat(const QString &uri, csync_file_stat_t *buf); #endif /* _CSYNC_VIO_LOCAL_H */ diff --git a/src/csync/vio/csync_vio_local_unix.cpp b/src/csync/vio/csync_vio_local_unix.cpp index 544d80f738..95883fa47b 100644 --- a/src/csync/vio/csync_vio_local_unix.cpp +++ b/src/csync/vio/csync_vio_local_unix.cpp @@ -29,7 +29,6 @@ #include "c_private.h" #include "c_lib.h" #include "c_string.h" -#include "c_utf8.h" #include "csync_util.h" #include "vio/csync_vio_local.h" @@ -84,7 +83,7 @@ std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *h } while (qstrcmp(dirent->d_name, ".") == 0 || qstrcmp(dirent->d_name, "..") == 0); file_stat.reset(new csync_file_stat_t); - file_stat->path = c_utf8_from_locale(dirent->d_name); + file_stat->path = QFile::decodeName(dirent->d_name).toUtf8(); QByteArray fullPath = handle->path % '/' % QByteArray() % const_cast(dirent->d_name); if (file_stat->path.isNull()) { file_stat->original_path = fullPath; @@ -131,13 +130,9 @@ std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *h } -int csync_vio_local_stat(const char *uri, csync_file_stat_t *buf) +int csync_vio_local_stat(const QString &uri, csync_file_stat_t *buf) { - mbchar_t *wuri = c_utf8_path_to_locale(uri); - *buf = csync_file_stat_t(); - int rc = _csync_vio_local_stat_mb(wuri, buf); - c_free_locale_string(wuri); - return rc; + return _csync_vio_local_stat_mb(QFile::encodeName(uri).constData(), buf); } static int _csync_vio_local_stat_mb(const mbchar_t *wuri, csync_file_stat_t *buf) diff --git a/src/csync/vio/csync_vio_local_win.cpp b/src/csync/vio/csync_vio_local_win.cpp index 98a02def5d..a60e6f6444 100644 --- a/src/csync/vio/csync_vio_local_win.cpp +++ b/src/csync/vio/csync_vio_local_win.cpp @@ -29,7 +29,6 @@ #include "c_private.h" #include "c_lib.h" -#include "c_utf8.h" #include "csync_util.h" #include "vio/csync_vio_local.h" #include "common/filesystembase.h" @@ -135,12 +134,12 @@ std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *h return nullptr; } } - auto path = c_utf8_from_locale(handle->ffd.cFileName); + auto path = QString::fromWCharArray(handle->ffd.cFileName); if (path == "." || path == "..") return csync_vio_local_readdir(handle, vfs); file_stat.reset(new csync_file_stat_t); - file_stat->path = path; + file_stat->path = path.toUtf8(); if (vfs && vfs->statTypeVirtualFile(file_stat.get(), &handle->ffd)) { // all good @@ -175,7 +174,7 @@ std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *h std::wstring fullPath; fullPath.reserve(handle->path.size() + std::wcslen(handle->ffd.cFileName)); - fullPath += reinterpret_cast(handle->path.utf16()); // path always ends with '\', by construction + fullPath += handle->path.toStdWString(); // path always ends with '\', by construction fullPath += handle->ffd.cFileName; if (_csync_vio_local_stat_mb(fullPath.data(), file_stat.get()) < 0) { @@ -187,11 +186,10 @@ std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *h } -int csync_vio_local_stat(const char *uri, csync_file_stat_t *buf) +int csync_vio_local_stat(const QString &uri, csync_file_stat_t *buf) { - mbchar_t *wuri = c_utf8_path_to_locale(uri); - int rc = _csync_vio_local_stat_mb(wuri, buf); - c_free_locale_string(wuri); + const std::wstring wuri = uri.toStdWString(); + int rc = _csync_vio_local_stat_mb(wuri.data(), buf); return rc; } diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index e78e3678e6..a9a661bd52 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -550,7 +550,7 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo( if (!base.isDirectory()) { csync_file_stat_t buf; - if (csync_vio_local_stat((_discoveryData->_localDir + originalPathAdjusted).toUtf8(), &buf)) { + if (csync_vio_local_stat(_discoveryData->_localDir + originalPathAdjusted, &buf)) { qCInfo(lcDisco) << "Local file does not exist anymore." << originalPathAdjusted; return; } diff --git a/src/libsync/filesystem.cpp b/src/libsync/filesystem.cpp index 0f210262e2..90926a6381 100644 --- a/src/libsync/filesystem.cpp +++ b/src/libsync/filesystem.cpp @@ -21,13 +21,10 @@ #include #include -// We use some internals of csync: -extern "C" int c_utimes(const char *, const struct timeval *); - #include "csync.h" #include "vio/csync_vio_local.h" #include "std/c_string.h" -#include "std/c_utf8.h" +#include "std/c_time.h" #ifdef Q_OS_WIN32 #include @@ -72,7 +69,7 @@ time_t FileSystem::getModTime(const QString &filename) { csync_file_stat_t stat; qint64 result = -1; - if (csync_vio_local_stat(filename.toUtf8().data(), &stat) != -1 + if (csync_vio_local_stat(filename, &stat) != -1 && (stat.modtime != 0)) { result = stat.modtime; } else { @@ -88,7 +85,7 @@ bool FileSystem::setModTime(const QString &filename, time_t modTime) struct timeval times[2]; times[0].tv_sec = times[1].tv_sec = modTime; times[0].tv_usec = times[1].tv_usec = 0; - int rc = c_utimes(filename.toUtf8().data(), times); + int rc = c_utimes(filename, times); if (rc != 0) { qCWarning(lcFileSystem) << "Error setting mtime for" << filename << "failed: rc" << rc << ", errno:" << errno; @@ -125,7 +122,7 @@ static qint64 getSizeWithCsync(const QString &filename) { qint64 result = 0; csync_file_stat_t stat; - if (csync_vio_local_stat(filename.toUtf8().data(), &stat) != -1) { + if (csync_vio_local_stat(filename, &stat) != -1) { result = stat.size; } else { qCWarning(lcFileSystem) << "Could not get size for" << filename << "with csync"; @@ -196,7 +193,7 @@ bool FileSystem::removeRecursively(const QString &path, const std::function #include "c_string.h" -#include "c_utf8.h" #include "common/filesystembase.h" #include "torture.h" @@ -29,87 +28,6 @@ #include "torture.h" -static void check_iconv_to_native_normalization(void **state) -{ - mbchar_t *out = NULL; - const char *in= "\x48\xc3\xa4"; // UTF8 -#ifdef __APPLE__ - const char *exp_out = "\x48\x61\xcc\x88"; // UTF-8-MAC -#else - const char *exp_out = "\x48\xc3\xa4"; // UTF8 -#endif - - out = c_utf8_path_to_locale(in); - assert_string_equal(out, exp_out); - - c_free_locale_string(out); - assert_null(out); - - (void) state; /* unused */ -} - -static void check_iconv_from_native_normalization(void **state) -{ -#ifdef _WIN32 - const mbchar_t *in = L"\x48\xc3\xa4"; // UTF-8 -#else -#ifdef __APPLE__ - const mbchar_t *in = "\x48\x61\xcc\x88"; // UTF-8-MAC -#else - const mbchar_t *in = "\x48\xc3\xa4"; // UTF-8 -#endif -#endif - const char *exp_out = "\x48\xc3\xa4"; // UTF-8 - - QByteArray out = c_utf8_from_locale(in); - assert_string_equal(out, exp_out); - - (void) state; /* unused */ -} - -static void check_iconv_ascii(void **state) -{ -#ifdef _WIN32 - const mbchar_t *in = L"abc/ABC\\123"; // UTF-8 -#else -#ifdef __APPLE__ - const mbchar_t *in = "abc/ABC\\123"; // UTF-8-MAC -#else - const mbchar_t *in = "abc/ABC\\123"; // UTF-8 -#endif -#endif - const char *exp_out = "abc/ABC\\123"; - - QByteArray out = c_utf8_from_locale(in); - assert_string_equal(out, exp_out); - - (void) state; /* unused */ -} - -#define TESTSTRING "#cA\\#fß§4" -#define LTESTSTRING L"#cA\\#fß§4" - -static void check_to_multibyte(void **state) -{ - int rc = -1; - - mbchar_t *mb_string = c_utf8_path_to_locale( TESTSTRING ); - mbchar_t *mb_null = c_utf8_path_to_locale( NULL ); - - (void) state; - -#ifdef _WIN32 - assert_int_equal( wcscmp( LTESTSTRING, mb_string), 0 ); -#else - assert_string_equal(mb_string, TESTSTRING); -#endif - assert_true( mb_null == NULL ); - assert_int_equal(rc, -1); - - c_free_locale_string(mb_string); - c_free_locale_string(mb_null); -} - static void check_long_win_path(void **state) { (void) state; /* unused */ @@ -171,10 +89,6 @@ int torture_run_tests(void) { const struct CMUnitTest tests[] = { cmocka_unit_test(check_long_win_path), - cmocka_unit_test(check_to_multibyte), - cmocka_unit_test(check_iconv_ascii), - cmocka_unit_test(check_iconv_to_native_normalization), - cmocka_unit_test(check_iconv_from_native_normalization), }; diff --git a/test/csync/vio_tests/check_vio_ext.cpp b/test/csync/vio_tests/check_vio_ext.cpp index fbe21ef788..1fdf253bd9 100644 --- a/test/csync/vio_tests/check_vio_ext.cpp +++ b/test/csync/vio_tests/check_vio_ext.cpp @@ -25,7 +25,6 @@ #include #include "csync.h" -#include "std/c_utf8.h" #include "std/c_alloc.h" #include "std/c_string.h" #include "vio/csync_vio_local.h"