1 /* 2 mkvmerge -- utility for splicing together matroska files 3 from component media subtypes 4 5 Distributed under the GPL v2 6 see the file COPYING for details 7 or visit https://www.gnu.org/licenses/old-licenses/gpl-2.0.html 8 9 Written by Moritz Bunkus <moritz@bunkus.org>. 10 */ 11 12 #include "common/common_pch.h" 13 14 #include "common/path.h" 15 #include "common/strings/utf8.h" 16 17 namespace mtx::fs { 18 19 std::filesystem::path to_path(std::string const & name)20to_path(std::string const &name) { 21 return std::filesystem::path{to_wide(name)}; 22 } 23 24 std::filesystem::path to_path(std::wstring const & name)25to_path(std::wstring const &name) { 26 return std::filesystem::path{name}; 27 } 28 29 bool is_absolute(std::filesystem::path const & p)30is_absolute(std::filesystem::path const &p) { 31 auto p_s = p.u8string(); 32 33 if ( (p_s.substr(0, 2) == "//"s) 34 || (p_s.substr(0, 2) == "\\\\"s)) 35 return true; 36 37 return p.is_absolute(); 38 } 39 40 void create_directories(std::filesystem::path const & path,std::error_code & error_code)41create_directories(std::filesystem::path const &path, 42 std::error_code &error_code) { 43 auto normalized_path = path.u8string(); 44 45 for (auto &c : normalized_path) 46 if (c == '/') 47 c = '\\'; 48 49 auto directory = mtx::fs::to_path(normalized_path); 50 error_code = {}; 51 52 if (directory.empty() || std::filesystem::is_directory(directory)) 53 return; 54 55 auto is_unc = normalized_path.substr(0, 2) == "\\\\"s; 56 57 std::vector<std::filesystem::path> to_check; 58 59 // path | is_unc | parent_path | parent_path.parent_path | to_check 60 // -----------------------+--------+--------------------+-------------------------+---------------------- 61 // E:\moo\cow | false | E:\moo | E:\ | E:\moo\cow 62 // E:\moo | false | E:\ | E:\ | E:\moo 63 // E:\ | false | E:\ | E:\ | 64 // \\server\share\moo\cow | true | \\server\share\moo | \\server\share | \\sever\share\moo\cow 65 // \\server\share\moo | true | \\server\share | \\server | \\sever\share\moo 66 // \\server\share | true | \\server | \ | 67 // \\server | true | \ | \ | 68 69 while ( !directory.empty() 70 && (directory.parent_path() != directory) 71 && ( !is_unc 72 || (directory.parent_path().parent_path().u8string() != "\\"s))) { 73 to_check.emplace_back(directory); 74 directory = directory.parent_path(); 75 } 76 77 for (auto itr = to_check.rbegin(), end = to_check.rend(); itr != end; ++itr) { 78 if (std::filesystem::is_directory(*itr)) 79 continue; 80 81 std::filesystem::create_directory(*itr, error_code); 82 83 if (error_code) 84 return; 85 } 86 } 87 88 } // namespace mtx::fs 89