1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <sal/config.h>
26 #include "file_path_helper.hxx"
27 #include "uunxapi.hxx"
29 #include <osl/diagnose.h>
30 #include <rtl/ustring.hxx>
31 #include <sal/log.hxx>
33 const sal_Unicode FPH_CHAR_PATH_SEPARATOR
= '/';
34 const sal_Unicode FPH_CHAR_DOT
= '.';
35 const sal_Unicode FPH_CHAR_COLON
= ':';
37 void osl_systemPathRemoveSeparator(rtl_String
* pstrPath
)
39 OSL_PRECOND(nullptr != pstrPath
, "osl_systemPathRemoveSeparator: Invalid parameter");
40 if (pstrPath
== nullptr)
43 // maybe there are more than one separator at end
44 // so we run in a loop
45 while ((pstrPath
->length
> 1) && (pstrPath
->buffer
[pstrPath
->length
- 1] == FPH_CHAR_PATH_SEPARATOR
))
48 pstrPath
->buffer
[pstrPath
->length
] = '\0';
51 SAL_WARN_IF( !((0 == pstrPath
->length
) || (1 == pstrPath
->length
) ||
52 (pstrPath
->length
> 1 && pstrPath
->buffer
[pstrPath
->length
- 1] != FPH_CHAR_PATH_SEPARATOR
)),
54 "osl_systemPathRemoveSeparator: Post condition failed");
59 template<typename T
> void systemPathEnsureSeparator(T
* ppstrPath
)
61 assert(nullptr != ppstrPath
);
62 sal_Int32 lp
= ppstrPath
->getLength();
63 sal_Int32 i
= ppstrPath
->lastIndexOf(FPH_CHAR_PATH_SEPARATOR
);
65 if ((lp
> 1 && i
!= (lp
- 1)) || ((lp
< 2) && i
< 0))
70 SAL_WARN_IF( !ppstrPath
->endsWith("/"),
72 "systemPathEnsureSeparator: Post condition failed");
77 bool osl_systemPathIsRelativePath(const rtl_uString
* pustrPath
)
79 OSL_PRECOND(nullptr != pustrPath
, "osl_systemPathIsRelativePath: Invalid parameter");
80 return ((pustrPath
== nullptr) || (pustrPath
->length
== 0) || (pustrPath
->buffer
[0] != FPH_CHAR_PATH_SEPARATOR
));
85 template<typename T
> T
systemPathMakeAbsolutePath_(
92 systemPathEnsureSeparator(&base
);
94 return base
+ RelPath
;
99 OString
osl::systemPathMakeAbsolutePath(
100 const OString
& BasePath
,
101 const OString
& RelPath
)
103 return systemPathMakeAbsolutePath_(BasePath
, RelPath
);
106 OUString
osl::systemPathMakeAbsolutePath(
107 const OUString
& BasePath
,
108 const OUString
& RelPath
)
110 return systemPathMakeAbsolutePath_(BasePath
, RelPath
);
113 void osl_systemPathGetFileNameOrLastDirectoryPart(
114 const rtl_String
* pstrPath
,
115 rtl_String
** ppstrFileNameOrLastDirPart
)
117 OSL_PRECOND(pstrPath
&& ppstrFileNameOrLastDirPart
,
118 "osl_systemPathGetFileNameOrLastDirectoryPart: Invalid parameter");
120 OString
path(const_cast<rtl_String
*>(pstrPath
));
122 osl_systemPathRemoveSeparator(path
.pData
);
126 if (path
.getLength() > 1 || (path
.getLength() == 1 && path
[0] != FPH_CHAR_PATH_SEPARATOR
))
128 sal_Int32 idx_ps
= path
.lastIndexOf(FPH_CHAR_PATH_SEPARATOR
);
129 idx_ps
++; // always right to increment by one even if idx_ps == -1!
130 last_part
= path
.copy(idx_ps
);
132 rtl_string_assign(ppstrFileNameOrLastDirPart
, last_part
.pData
);
135 bool osl_systemPathIsHiddenFileOrDirectoryEntry(
136 const rtl_String
* pstrPath
)
138 OSL_PRECOND(nullptr != pstrPath
, "osl_systemPathIsHiddenFileOrDirectoryEntry: Invalid parameter");
139 if ((pstrPath
== nullptr) || (pstrPath
->length
== 0))
143 osl_systemPathGetFileNameOrLastDirectoryPart(pstrPath
, &fdp
.pData
);
145 return ((fdp
.pData
->length
> 0) &&
146 (fdp
.pData
->buffer
[0] == FPH_CHAR_DOT
) &&
147 !osl_systemPathIsLocalOrParentDirectoryEntry(fdp
.pData
));
150 bool osl_systemPathIsLocalOrParentDirectoryEntry(
151 const rtl_String
* pstrPath
)
153 OSL_PRECOND(pstrPath
, "osl_systemPathIsLocalOrParentDirectoryEntry: Invalid parameter");
157 osl_systemPathGetFileNameOrLastDirectoryPart(pstrPath
, &dirent
.pData
);
159 return (dirent
== "." ||
165 /** Simple iterator for a path list separated by the specified character
167 class path_list_iterator
171 /* after construction get_current_item
172 returns the first path in list, no need
175 path_list_iterator(OUString path_list
, sal_Unicode list_separator
= FPH_CHAR_COLON
) :
176 m_path_list(std::move(path_list
)),
177 m_end(m_path_list
.getStr() + m_path_list
.getLength() + 1),
178 m_separator(list_separator
)
183 path_list_iterator(const path_list_iterator
&) = delete;
184 path_list_iterator
& operator=(const path_list_iterator
&) = delete;
188 m_path_segment_begin
= m_path_segment_end
= m_path_list
.getStr();
194 OSL_PRECOND(!done(), "path_list_iterator: Already done!");
196 m_path_segment_begin
= ++m_path_segment_end
;
202 return (m_path_segment_end
>= m_end
);
205 OUString
get_current_item() const
208 m_path_segment_begin
,
209 (m_path_segment_end
- m_path_segment_begin
));
213 /* move m_path_end to the next separator or
214 to the end of the string
218 while (!done() && *m_path_segment_end
&& (*m_path_segment_end
!= m_separator
))
219 ++m_path_segment_end
;
221 OSL_ASSERT(m_path_segment_end
<= m_end
);
225 OUString m_path_list
;
226 const sal_Unicode
* m_end
;
227 const sal_Unicode m_separator
;
228 const sal_Unicode
* m_path_segment_begin
;
229 const sal_Unicode
* m_path_segment_end
;
235 const rtl_uString
* pustrFilePath
,
236 const rtl_uString
* pustrSearchPathList
,
237 rtl_uString
** ppustrPathFound
)
239 OSL_PRECOND(pustrFilePath
&& pustrSearchPathList
&& ppustrPathFound
, "osl_searchPath: Invalid parameter");
242 OUString
fp(const_cast<rtl_uString
*>(pustrFilePath
));
243 OUString
pl(const_cast<rtl_uString
*>(pustrSearchPathList
));
244 path_list_iterator
pli(pl
);
248 OUString p
= pli
.get_current_item();
249 systemPathEnsureSeparator(&p
);
252 if (osl::access(osl::OUStringToOString(p
), F_OK
) > -1)
255 rtl_uString_assign(ppustrPathFound
, p
.pData
);
263 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */