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 "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
))
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
)),
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()),
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
));
96 osl_systemPathEnsureSeparator(&base
.pData
);
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
);
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))
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");
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
160 /* after construction get_current_item
161 returns the first path in list, no need
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
)
172 path_list_iterator(const path_list_iterator
&) = delete;
173 path_list_iterator
& operator=(const path_list_iterator
&) = delete;
177 m_path_segment_begin
= m_path_segment_end
= m_path_list
.getStr();
183 OSL_PRECOND(!done(), "path_list_iterator: Already done!");
185 m_path_segment_begin
= ++m_path_segment_end
;
191 return (m_path_segment_end
>= m_end
);
194 OUString
get_current_item() const
197 m_path_segment_begin
,
198 (m_path_segment_end
- m_path_segment_begin
));
202 /* move m_path_end to the next separator or
203 to the end of the string
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
);
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
;
222 const rtl_uString
* pustrFilePath
,
223 const rtl_uString
* pustrSearchPathList
,
224 rtl_uString
** ppustrPathFound
)
226 OSL_PRECOND(pustrFilePath
&& pustrSearchPathList
&& ppustrPathFound
, "osl_searchPath: Invalid parameter");
229 OUString
fp(const_cast<rtl_uString
*>(pustrFilePath
));
230 OUString pl
= OUString(const_cast<rtl_uString
*>(pustrSearchPathList
));
231 path_list_iterator
pli(pl
);
235 OUString p
= pli
.get_current_item();
236 osl::systemPathEnsureSeparator(p
);
239 if (osl::access(p
, F_OK
) > -1)
242 rtl_uString_assign(ppustrPathFound
, p
.pData
);
250 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */