lok: vcl: fix multiple floatwin removal case more robustly.
[LibreOffice.git] / sal / osl / unx / file_path_helper.cxx
blob7fc2effb5f03a2ba817f2760f99fa990997e3f25
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "file_path_helper.hxx"
21 #include "uunxapi.hxx"
23 #include <osl/diagnose.h>
24 #include <rtl/ustring.hxx>
25 #include <sal/log.hxx>
27 const sal_Unicode FPH_CHAR_PATH_SEPARATOR = '/';
28 const sal_Unicode FPH_CHAR_DOT = '.';
29 const sal_Unicode FPH_CHAR_COLON = ':';
31 static const OUString FPH_PATH_SEPARATOR()
32 { return OUString(FPH_CHAR_PATH_SEPARATOR); }
34 static const OUString FPH_LOCAL_DIR_ENTRY()
35 { return OUString(FPH_CHAR_DOT); }
37 static const OUString FPH_PARENT_DIR_ENTRY()
38 { return OUString(".."); }
40 void osl_systemPathRemoveSeparator(rtl_uString* pustrPath)
42 OSL_PRECOND(nullptr != pustrPath, "osl_systemPathRemoveSeparator: Invalid parameter");
43 if (pustrPath != nullptr)
45 // maybe there are more than one separator at end
46 // so we run in a loop
47 while ((pustrPath->length > 1) && (pustrPath->buffer[pustrPath->length - 1] == FPH_CHAR_PATH_SEPARATOR))
49 pustrPath->length--;
50 pustrPath->buffer[pustrPath->length] = '\0';
53 SAL_WARN_IF( !((0 == pustrPath->length) || (1 == pustrPath->length) ||
54 (pustrPath->length > 1 && pustrPath->buffer[pustrPath->length - 1] != FPH_CHAR_PATH_SEPARATOR)),
55 "sal.osl",
56 "osl_systemPathRemoveSeparator: Post condition failed");
60 void osl_systemPathEnsureSeparator(rtl_uString** ppustrPath)
62 OSL_PRECOND((nullptr != ppustrPath) && (nullptr != *ppustrPath), "osl_systemPathEnsureSeparator: Invalid parameter");
63 if ((ppustrPath != nullptr) && (*ppustrPath != nullptr))
65 OUString path(*ppustrPath);
66 sal_Int32 lp = path.getLength();
67 sal_Int32 i = path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR);
69 if ((lp > 1 && i != (lp - 1)) || ((lp < 2) && i < 0))
71 path += FPH_PATH_SEPARATOR();
72 rtl_uString_assign(ppustrPath, path.pData);
75 SAL_WARN_IF( !path.endsWith(FPH_PATH_SEPARATOR()),
76 "sal.osl",
77 "osl_systemPathEnsureSeparator: Post condition failed");
81 bool osl_systemPathIsRelativePath(const rtl_uString* pustrPath)
83 OSL_PRECOND(nullptr != pustrPath, "osl_systemPathIsRelativePath: Invalid parameter");
84 return ((pustrPath == nullptr) || (pustrPath->length == 0) || (pustrPath->buffer[0] != FPH_CHAR_PATH_SEPARATOR));
87 void osl_systemPathMakeAbsolutePath(
88 const rtl_uString* pustrBasePath,
89 const rtl_uString* pustrRelPath,
90 rtl_uString** ppustrAbsolutePath)
92 OUString base(rtl_uString_getStr(const_cast<rtl_uString*>(pustrBasePath)));
93 OUString rel(const_cast<rtl_uString*>(pustrRelPath));
95 if (!base.isEmpty())
96 osl_systemPathEnsureSeparator(&base.pData);
98 base += rel;
100 rtl_uString_acquire(base.pData);
101 *ppustrAbsolutePath = base.pData;
104 void osl_systemPathGetFileNameOrLastDirectoryPart(
105 const rtl_uString* pustrPath,
106 rtl_uString** ppustrFileNameOrLastDirPart)
108 OSL_PRECOND(pustrPath && ppustrFileNameOrLastDirPart,
109 "osl_systemPathGetFileNameOrLastDirectoryPart: Invalid parameter");
111 OUString path(const_cast<rtl_uString*>(pustrPath));
113 osl_systemPathRemoveSeparator(path.pData);
115 OUString last_part;
117 if (path.getLength() > 1 || (path.getLength() == 1 && path[0] != FPH_CHAR_PATH_SEPARATOR))
119 sal_Int32 idx_ps = path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR);
120 idx_ps++; // always right to increment by one even if idx_ps == -1!
121 last_part = path.copy(idx_ps);
123 rtl_uString_assign(ppustrFileNameOrLastDirPart, last_part.pData);
126 bool osl_systemPathIsHiddenFileOrDirectoryEntry(
127 const rtl_uString* pustrPath)
129 OSL_PRECOND(nullptr != pustrPath, "osl_systemPathIsHiddenFileOrDirectoryEntry: Invalid parameter");
130 if ((pustrPath == nullptr) || (pustrPath->length == 0))
131 return false;
133 OUString fdp;
134 osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &fdp.pData);
136 return ((fdp.pData->length > 0) &&
137 (fdp.pData->buffer[0] == FPH_CHAR_DOT) &&
138 !osl_systemPathIsLocalOrParentDirectoryEntry(fdp.pData));
141 bool osl_systemPathIsLocalOrParentDirectoryEntry(
142 const rtl_uString* pustrPath)
144 OSL_PRECOND(pustrPath, "osl_systemPathIsLocalOrParentDirectoryEntry: Invalid parameter");
146 OUString dirent;
148 osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &dirent.pData);
150 return (dirent == FPH_LOCAL_DIR_ENTRY() ||
151 dirent == FPH_PARENT_DIR_ENTRY());
154 /** Simple iterator for a path list separated by the specified character
156 class path_list_iterator
158 public:
160 /* after construction get_current_item
161 returns the first path in list, no need
162 to call reset first
164 path_list_iterator(const OUString& path_list, sal_Unicode list_separator = FPH_CHAR_COLON) :
165 m_path_list(path_list),
166 m_end(m_path_list.getStr() + m_path_list.getLength() + 1),
167 m_separator(list_separator)
169 reset();
172 path_list_iterator(const path_list_iterator&) = delete;
173 path_list_iterator& operator=(const path_list_iterator&) = delete;
175 void reset()
177 m_path_segment_begin = m_path_segment_end = m_path_list.getStr();
178 advance();
181 void next()
183 OSL_PRECOND(!done(), "path_list_iterator: Already done!");
185 m_path_segment_begin = ++m_path_segment_end;
186 advance();
189 bool done() const
191 return (m_path_segment_end >= m_end);
194 OUString get_current_item() const
196 return OUString(
197 m_path_segment_begin,
198 (m_path_segment_end - m_path_segment_begin));
201 private:
202 /* move m_path_end to the next separator or
203 to the end of the string
205 void advance()
207 while (!done() && *m_path_segment_end && (*m_path_segment_end != m_separator))
208 ++m_path_segment_end;
210 OSL_ASSERT(m_path_segment_end <= m_end);
213 private:
214 OUString const m_path_list;
215 const sal_Unicode* m_end;
216 const sal_Unicode m_separator;
217 const sal_Unicode* m_path_segment_begin;
218 const sal_Unicode* m_path_segment_end;
221 bool osl_searchPath(
222 const rtl_uString* pustrFilePath,
223 const rtl_uString* pustrSearchPathList,
224 rtl_uString** ppustrPathFound)
226 OSL_PRECOND(pustrFilePath && pustrSearchPathList && ppustrPathFound, "osl_searchPath: Invalid parameter");
228 bool bfound = false;
229 OUString fp(const_cast<rtl_uString*>(pustrFilePath));
230 OUString pl = OUString(const_cast<rtl_uString*>(pustrSearchPathList));
231 path_list_iterator pli(pl);
233 while (!pli.done())
235 OUString p = pli.get_current_item();
236 osl::systemPathEnsureSeparator(p);
237 p += fp;
239 if (osl::access(p, F_OK) > -1)
241 bfound = true;
242 rtl_uString_assign(ppustrPathFound, p.pData);
243 break;
245 pli.next();
247 return bfound;
250 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */