diff --git a/src/common/util/include/openvino/util/file_util.hpp b/src/common/util/include/openvino/util/file_util.hpp index 05538638c9d..6740f5a181a 100644 --- a/src/common/util/include/openvino/util/file_util.hpp +++ b/src/common/util/include/openvino/util/file_util.hpp @@ -125,6 +125,15 @@ bool is_absolute_file_path(const std::string& path); */ void create_directory_recursive(const std::string& path); +#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT +/** + * @brief Interface function to create directorty recursively by given path + * @param path - path to file wide-string, can be relative to current working directory + * @throw runtime_error if any error occurred + */ +void create_directory_recursive(const std::wstring& path); +#endif + /** * @brief Interface function to check if directory exists for given path * @param path - path to directory diff --git a/src/common/util/src/file_util.cpp b/src/common/util/src/file_util.cpp index b719d4dba3d..971f10cceab 100644 --- a/src/common/util/src/file_util.cpp +++ b/src/common/util/src/file_util.cpp @@ -31,7 +31,10 @@ # define wstat _wstat # endif /// @brief Windows-specific 'mkdir' wrapper -# define makedir(dir) _mkdir(dir) +# define makedir(dir) _mkdir(dir.c_str()) +# ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT +# define wmakedir(dir) _wmkdir(dir.c_str()) +# endif // Copied from linux libc sys/stat.h: # define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) #else @@ -52,7 +55,10 @@ /// @brief Get absolute file path, returns NULL in case of error # define get_absolute_path(result, path) realpath(path.c_str(), result) /// @brief mkdir wrapper -# define makedir(dir) mkdir(dir, 0755) +# define makedir(dir) mkdir(dir.c_str(), 0755) +# ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT +# define wmakedir(dir) mkdir(ov::util::wstring_to_string(dir).c_str(), 0755) +# endif #endif std::string ov::util::get_file_name(const std::string& s) { @@ -337,9 +343,9 @@ void ov::util::convert_path_win_style(std::string& path) { std::string ov::util::wstring_to_string(const std::wstring& wstr) { # ifdef _WIN32 - int size_needed = WideCharToMultiByte(CP_ACP, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL); + int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL); std::string strTo(size_needed, 0); - WideCharToMultiByte(CP_ACP, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL); + WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL); return strTo; # else std::wstring_convert> wstring_decoder; @@ -351,9 +357,9 @@ std::wstring ov::util::string_to_wstring(const std::string& string) { const char* str = string.c_str(); # ifdef _WIN32 int strSize = static_cast(std::strlen(str)); - int size_needed = MultiByteToWideChar(CP_ACP, 0, str, strSize, NULL, 0); + int size_needed = MultiByteToWideChar(CP_UTF8, 0, str, strSize, NULL, 0); std::wstring wstrTo(size_needed, 0); - MultiByteToWideChar(CP_ACP, 0, str, strSize, &wstrTo[0], size_needed); + MultiByteToWideChar(CP_UTF8, 0, str, strSize, &wstrTo[0], size_needed); return wstrTo; # else std::wstring_convert> wstring_encoder; @@ -393,6 +399,27 @@ bool ov::util::is_absolute_file_path(const std::string& path) { #endif // _WIN32 } +#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT +void ov::util::create_directory_recursive(const std::wstring& path) { + if (path.empty() || directory_exists(path)) { + return; + } + + std::size_t pos = path.rfind(ov::util::FileTraits::file_separator); + if (pos != std::wstring::npos) { + create_directory_recursive(path.substr(0, pos)); + } + + int err = wmakedir(path); + if (err != 0 && errno != EEXIST) { + std::stringstream ss; + // TODO: in case of exception it may be needed to remove all created sub-directories + ss << "Couldn't create directory [" << ov::util::wstring_to_string(path) << "], err=" << strerror(errno) << ")"; + throw std::runtime_error(ss.str()); + } +} +#endif + void ov::util::create_directory_recursive(const std::string& path) { if (path.empty() || directory_exists(path)) { return; @@ -403,7 +430,7 @@ void ov::util::create_directory_recursive(const std::string& path) { create_directory_recursive(path.substr(0, pos)); } - int err = makedir(path.c_str()); + int err = makedir(path); if (err != 0 && errno != EEXIST) { std::stringstream ss; // TODO: in case of exception it may be needed to remove all created sub-directories diff --git a/src/inference/dev_api/file_utils.h b/src/inference/dev_api/file_utils.h index 870cc91a1fd..face9ef4f2c 100644 --- a/src/inference/dev_api/file_utils.h +++ b/src/inference/dev_api/file_utils.h @@ -44,6 +44,16 @@ INFERENCE_ENGINE_API_CPP(std::string) absoluteFilePath(const std::string& filePa */ INFERENCE_ENGINE_API_CPP(void) createDirectoryRecursive(const std::string& dirPath); +#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT +/** + * @brief Interface function to create directorty recursively by given path + * @ingroup ie_dev_api_file_utils + * @param dirPath - path to file (wstring), can be relative to current working directory + * @throw InferenceEngine::Exception if any error occurred + */ +INFERENCE_ENGINE_API_CPP(void) createDirectoryRecursive(const std::wstring& dirPath); +#endif + /** * @brief Interface function to check if directory exists for given path * @ingroup ie_dev_api_file_utils diff --git a/src/inference/src/dev/core_impl.cpp b/src/inference/src/dev/core_impl.cpp index 63d73f7c090..44a50f08b22 100644 --- a/src/inference/src/dev/core_impl.cpp +++ b/src/inference/src/dev/core_impl.cpp @@ -1644,7 +1644,11 @@ ov::CoreImpl::CoreConfig::CacheConfig ov::CoreImpl::CoreConfig::CacheConfig::cre std::shared_ptr cache_manager = nullptr; if (!dir.empty()) { - FileUtils::createDirectoryRecursive(dir); +#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT + ov::util::create_directory_recursive(ov::util::string_to_wstring(dir)); +#else + ov::util::create_directory_recursive(dir); +#endif cache_manager = std::make_shared(dir); } diff --git a/src/inference/src/file_utils.cpp b/src/inference/src/file_utils.cpp index b4602873988..e38037f9315 100644 --- a/src/inference/src/file_utils.cpp +++ b/src/inference/src/file_utils.cpp @@ -52,6 +52,12 @@ void FileUtils::createDirectoryRecursive(const std::string& dirPath) { ov::util::create_directory_recursive(dirPath); } +#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT +void FileUtils::createDirectoryRecursive(const std::wstring& dirPath) { + ov::util::create_directory_recursive(dirPath); +} +#endif + namespace InferenceEngine { namespace { diff --git a/src/inference/src/ie_cache_manager.hpp b/src/inference/src/ie_cache_manager.hpp index 09a0f57e5f1..6a95954266a 100644 --- a/src/inference/src/ie_cache_manager.hpp +++ b/src/inference/src/ie_cache_manager.hpp @@ -80,10 +80,15 @@ public: */ class FileStorageCacheManager final : public ICacheManager { std::string m_cachePath; - +#if defined(_WIN32) && defined(OPENVINO_ENABLE_UNICODE_PATH_SUPPORT) + std::wstring getBlobFile(const std::string& blobHash) const { + return ov::util::string_to_wstring(FileUtils::makePath(m_cachePath, blobHash + ".blob")); + } +#else std::string getBlobFile(const std::string& blobHash) const { return FileUtils::makePath(m_cachePath, blobHash + ".blob"); } +#endif public: /** @@ -114,8 +119,13 @@ private: void remove_cache_entry(const std::string& id) override { auto blobFileName = getBlobFile(id); - if (FileUtils::fileExist(blobFileName)) + if (FileUtils::fileExist(blobFileName)) { +#if defined(_WIN32) && defined(OPENVINO_ENABLE_UNICODE_PATH_SUPPORT) + _wremove(blobFileName.c_str()); +#else std::remove(blobFileName.c_str()); +#endif + } } }; diff --git a/src/tests/functional/plugin/shared/src/behavior/ov_plugin/caching_tests.cpp b/src/tests/functional/plugin/shared/src/behavior/ov_plugin/caching_tests.cpp index 77de2069538..3ccca7ca745 100644 --- a/src/tests/functional/plugin/shared/src/behavior/ov_plugin/caching_tests.cpp +++ b/src/tests/functional/plugin/shared/src/behavior/ov_plugin/caching_tests.cpp @@ -351,7 +351,7 @@ TEST_P(CompileModelLoadFromFileTestBase, CanCreateCacheDirAndDumpBinariesUnicode ov::util::string_to_wstring(cache_path_mb + ov::util::FileTraits::file_separator + m_weightsName); try { - ov::test::utils::createDirectory(cache_path_mb); + ov::test::utils::createDirectory(cache_path_w); // Copy IR files into unicode folder for read_model test ov::test::utils::copyFile(m_modelName, model_xml_path_w); diff --git a/src/tests/test_utils/common_test_utils/include/common_test_utils/file_utils.hpp b/src/tests/test_utils/common_test_utils/include/common_test_utils/file_utils.hpp index 243350128ec..eb7967936df 100644 --- a/src/tests/test_utils/common_test_utils/include/common_test_utils/file_utils.hpp +++ b/src/tests/test_utils/common_test_utils/include/common_test_utils/file_utils.hpp @@ -146,6 +146,16 @@ inline bool directoryExists(const std::string& path) { return false; } +#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT +inline int createDirectory(const std::wstring& dirPath) { +# ifdef _WIN32 + return _wmkdir(dirPath.c_str()); +# else + return mkdir(ov::util::wstring_to_string(dirPath).c_str(), mode_t(0777)); +# endif +} +#endif + inline int createDirectory(const std::string& dirPath) { #ifdef _WIN32 return _mkdir(dirPath.c_str());