sw: clean up Start/EndAction in SwViewShell hierarchy
[LibreOffice.git] / comphelper / source / misc / DirectoryHelper.cxx
blobbadfe9b62d80495788ad64ba049f3eb9fd829de2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <comphelper/DirectoryHelper.hxx>
12 #include <sal/config.h>
13 #include <osl/file.hxx>
14 #include <rtl/uri.hxx>
16 #include <memory>
18 namespace comphelper
20 typedef std::shared_ptr<osl::File> FileSharedPtr;
22 std::u16string_view DirectoryHelper::splitAtLastToken(std::u16string_view rSrc, sal_Unicode aToken,
23 OUString& rRight)
25 const size_t nIndex(rSrc.rfind(aToken));
26 std::u16string_view aRetval;
28 if (std::u16string_view::npos == nIndex)
30 aRetval = rSrc;
31 rRight.clear();
33 else if (nIndex > 0)
35 aRetval = rSrc.substr(0, nIndex);
37 if (rSrc.size() > nIndex + 1)
39 rRight = rSrc.substr(nIndex + 1);
43 return aRetval;
46 bool DirectoryHelper::fileExists(const OUString& rBaseURL)
48 if (!rBaseURL.isEmpty())
50 FileSharedPtr aBaseFile = std::make_shared<osl::File>(rBaseURL);
52 return (osl::File::E_None == aBaseFile->open(osl_File_OpenFlag_Read));
55 return false;
58 bool DirectoryHelper::dirExists(const OUString& rDirURL)
60 if (!rDirURL.isEmpty())
62 osl::Directory aDirectory(rDirURL);
64 return (osl::FileBase::E_None == aDirectory.open());
67 return false;
70 void DirectoryHelper::scanDirsAndFiles(const OUString& rDirURL, std::set<OUString>& rDirs,
71 std::set<std::pair<OUString, OUString>>& rFiles)
73 if (rDirURL.isEmpty())
74 return;
76 osl::Directory aDirectory(rDirURL);
78 if (osl::FileBase::E_None != aDirectory.open())
79 return;
81 auto lcl_encodeUriSegment = [](OUString const& rPath) {
82 return rtl::Uri::encode(rPath, rtl_UriCharClassUricNoSlash, rtl_UriEncodeIgnoreEscapes,
83 RTL_TEXTENCODING_UTF8);
86 osl::DirectoryItem aDirectoryItem;
88 while (osl::FileBase::E_None == aDirectory.getNextItem(aDirectoryItem))
90 osl::FileStatus aFileStatus(osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileName);
92 if (osl::FileBase::E_None == aDirectoryItem.getFileStatus(aFileStatus))
94 if (aFileStatus.isDirectory())
96 const OUString aFileName(aFileStatus.getFileName());
98 if (!aFileName.isEmpty())
100 rDirs.insert(lcl_encodeUriSegment(aFileName));
103 else if (aFileStatus.isRegular())
105 OUString aFileName(aFileStatus.getFileName());
106 OUString aExtension;
107 aFileName = splitAtLastToken(aFileName, '.', aExtension);
109 if (!aFileName.isEmpty())
111 rFiles.insert(std::pair<OUString, OUString>(lcl_encodeUriSegment(aFileName),
112 lcl_encodeUriSegment(aExtension)));
119 bool DirectoryHelper::deleteDirRecursively(const OUString& rDirURL)
121 std::set<OUString> aDirs;
122 std::set<std::pair<OUString, OUString>> aFiles;
123 bool bError(false);
125 scanDirsAndFiles(rDirURL, aDirs, aFiles);
127 for (const auto& dir : aDirs)
129 const OUString aNewDirURL(rDirURL + "/" + dir);
131 bError |= deleteDirRecursively(aNewDirURL);
134 for (const auto& file : aFiles)
136 OUString aNewFileURL(rDirURL + "/" + file.first);
138 if (!file.second.isEmpty())
140 aNewFileURL += "." + file.second;
142 bError |= (osl::FileBase::E_None != osl::File::remove(aNewFileURL));
145 bError |= (osl::FileBase::E_None != osl::Directory::remove(rDirURL));
147 return bError;
150 // both exist, move content
151 bool DirectoryHelper::moveDirContent(const OUString& rSourceDirURL,
152 std::u16string_view rTargetDirURL,
153 const std::set<OUString>& rExcludeList)
155 std::set<OUString> aDirs;
156 std::set<std::pair<OUString, OUString>> aFiles;
157 bool bError(false);
159 scanDirsAndFiles(rSourceDirURL, aDirs, aFiles);
161 for (const auto& dir : aDirs)
163 const bool bExcluded(!rExcludeList.empty() && rExcludeList.find(dir) != rExcludeList.end());
165 if (!bExcluded)
167 const OUString aNewSourceDirURL(rSourceDirURL + "/" + dir);
169 if (dirExists(aNewSourceDirURL))
171 const OUString aNewTargetDirURL(OUString::Concat(rTargetDirURL) + "/" + dir);
173 if (dirExists(aNewTargetDirURL))
175 deleteDirRecursively(aNewTargetDirURL);
178 bError |= (osl::FileBase::E_None
179 != osl::File::move(aNewSourceDirURL, aNewTargetDirURL));
184 for (const auto& file : aFiles)
186 OUString aSourceFileURL(rSourceDirURL + "/" + file.first);
188 if (!file.second.isEmpty())
190 aSourceFileURL += "." + file.second;
193 if (fileExists(aSourceFileURL))
195 OUString aTargetFileURL(OUString::Concat(rTargetDirURL) + "/" + file.first);
197 if (!file.second.isEmpty())
199 aTargetFileURL += "." + file.second;
202 if (fileExists(aTargetFileURL))
204 osl::File::remove(aTargetFileURL);
207 bError |= (osl::FileBase::E_None != osl::File::move(aSourceFileURL, aTargetFileURL));
211 return bError;