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 .
21 /*******************************************
23 ******************************************/
25 #include "file_path_helper.h"
26 #include "file_path_helper.hxx"
27 #include "uunxapi.hxx"
29 #include <osl/diagnose.h>
30 #include <rtl/ustring.hxx>
32 /*******************************************
34 ******************************************/
36 const sal_Unicode FPH_CHAR_PATH_SEPARATOR
= (sal_Unicode
)'/';
37 const sal_Unicode FPH_CHAR_DOT
= (sal_Unicode
)'.';
38 const sal_Unicode FPH_CHAR_COLON
= (sal_Unicode
)':';
40 inline const rtl::OUString
FPH_PATH_SEPARATOR()
41 { return rtl::OUString(FPH_CHAR_PATH_SEPARATOR
); }
42 inline const rtl::OUString
FPH_LOCAL_DIR_ENTRY()
43 { return rtl::OUString(FPH_CHAR_PATH_SEPARATOR
); }
44 inline const rtl::OUString
FPH_PARENT_DIR_ENTRY()
45 { return rtl::OUString(".."); }
47 /*******************************************
48 * osl_systemPathRemoveSeparator
49 ******************************************/
51 void SAL_CALL
osl_systemPathRemoveSeparator(rtl_uString
* pustrPath
)
53 OSL_PRECOND(0 != pustrPath
, "osl_systemPathRemoveSeparator: Invalid parameter");
56 // maybe there are more than one separator at end
57 // so we run in a loop
58 while ((pustrPath
->length
> 1) && (FPH_CHAR_PATH_SEPARATOR
== pustrPath
->buffer
[pustrPath
->length
- 1]))
61 pustrPath
->buffer
[pustrPath
->length
] = (sal_Unicode
)'\0';
64 OSL_POSTCOND((0 == pustrPath
->length
) || (1 == pustrPath
->length
) || \
65 (pustrPath
->length
> 1 && pustrPath
->buffer
[pustrPath
->length
- 1] != FPH_CHAR_PATH_SEPARATOR
), \
66 "osl_systemPathRemoveSeparator: Post condition failed");
70 /*******************************************
71 osl_systemPathEnsureSeparator
72 ******************************************/
74 void SAL_CALL
osl_systemPathEnsureSeparator(rtl_uString
** ppustrPath
)
76 OSL_PRECOND((0 != ppustrPath
) && (0 != *ppustrPath
), "osl_systemPathEnsureSeparator: Invalid parameter");
77 if ((0 != ppustrPath
) && (0 != *ppustrPath
))
79 rtl::OUString
path(*ppustrPath
);
80 sal_Int32 lp
= path
.getLength();
81 sal_Int32 i
= path
.lastIndexOf(FPH_CHAR_PATH_SEPARATOR
);
83 if ((lp
> 1 && i
!= (lp
- 1)) || ((lp
< 2) && i
< 0))
85 path
+= FPH_PATH_SEPARATOR();
86 rtl_uString_assign(ppustrPath
, path
.pData
);
89 OSL_POSTCOND(path
.lastIndexOf(FPH_CHAR_PATH_SEPARATOR
) == (path
.getLength() - 1), \
90 "osl_systemPathEnsureSeparator: Post condition failed");
94 /*******************************************
95 * osl_systemPathIsRelativePath
96 ******************************************/
98 sal_Bool SAL_CALL
osl_systemPathIsRelativePath(const rtl_uString
* pustrPath
)
100 OSL_PRECOND(0 != pustrPath
, "osl_systemPathIsRelativePath: Invalid parameter");
101 return ((0 == pustrPath
) || (0 == pustrPath
->length
) || (pustrPath
->buffer
[0] != FPH_CHAR_PATH_SEPARATOR
));
104 /******************************************
105 osl_systemPathMakeAbsolutePath
106 *****************************************/
108 void SAL_CALL
osl_systemPathMakeAbsolutePath(
109 const rtl_uString
* pustrBasePath
,
110 const rtl_uString
* pustrRelPath
,
111 rtl_uString
** ppustrAbsolutePath
)
113 rtl::OUString
base(rtl_uString_getStr(const_cast<rtl_uString
*>(pustrBasePath
)));
114 rtl::OUString
rel(const_cast<rtl_uString
*>(pustrRelPath
));
117 osl_systemPathEnsureSeparator(&base
.pData
);
121 rtl_uString_acquire(base
.pData
);
122 *ppustrAbsolutePath
= base
.pData
;
126 /*******************************************
127 osl_systemPathGetFileOrLastDirectoryPart
128 ******************************************/
130 void SAL_CALL
osl_systemPathGetFileNameOrLastDirectoryPart(
131 const rtl_uString
* pustrPath
,
132 rtl_uString
** ppustrFileNameOrLastDirPart
)
134 OSL_PRECOND(pustrPath
&& ppustrFileNameOrLastDirPart
, \
135 "osl_systemPathGetFileNameOrLastDirectoryPart: Invalid parameter");
137 rtl::OUString
path(const_cast<rtl_uString
*>(pustrPath
));
139 osl_systemPathRemoveSeparator(path
.pData
);
141 rtl::OUString last_part
;
143 if (path
.getLength() > 1 || (1 == path
.getLength() && *path
.getStr() != FPH_CHAR_PATH_SEPARATOR
))
145 sal_Int32 idx_ps
= path
.lastIndexOf(FPH_CHAR_PATH_SEPARATOR
);
146 idx_ps
++; // always right to increment by one even if idx_ps == -1!
147 last_part
= rtl::OUString(path
.getStr() + idx_ps
);
149 rtl_uString_assign(ppustrFileNameOrLastDirPart
, last_part
.pData
);
153 /********************************************
154 osl_systemPathIsHiddenFileOrDirectoryEntry
155 *********************************************/
157 sal_Bool SAL_CALL
osl_systemPathIsHiddenFileOrDirectoryEntry(
158 const rtl_uString
* pustrPath
)
160 OSL_PRECOND(0 != pustrPath
, "osl_systemPathIsHiddenFileOrDirectoryEntry: Invalid parameter");
161 if ((0 == pustrPath
) || (0 == pustrPath
->length
))
165 osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath
, &fdp
.pData
);
167 return ((fdp
.pData
->length
> 0) &&
168 (fdp
.pData
->buffer
[0] == FPH_CHAR_DOT
) &&
169 !osl_systemPathIsLocalOrParentDirectoryEntry(fdp
.pData
));
173 /************************************************
174 osl_systemPathIsLocalOrParentDirectoryEntry
175 ************************************************/
177 sal_Bool SAL_CALL
osl_systemPathIsLocalOrParentDirectoryEntry(
178 const rtl_uString
* pustrPath
)
180 OSL_PRECOND(pustrPath
, "osl_systemPathIsLocalOrParentDirectoryEntry: Invalid parameter");
182 rtl::OUString dirent
;
184 osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath
, &dirent
.pData
);
187 (dirent
== FPH_LOCAL_DIR_ENTRY()) ||
188 (dirent
== FPH_PARENT_DIR_ENTRY())
192 /***********************************************
193 Simple iterator for a path list separated by
194 the specified character
195 **********************************************/
197 class path_list_iterator
201 /******************************************
204 after construction get_current_item
205 returns the first path in list, no need
207 *****************************************/
208 path_list_iterator(const rtl::OUString
& path_list
, sal_Unicode list_separator
= FPH_CHAR_COLON
) :
209 m_path_list(path_list
),
210 m_end(m_path_list
.getStr() + m_path_list
.getLength() + 1),
211 m_separator(list_separator
)
216 /******************************************
218 *****************************************/
221 m_path_segment_begin
= m_path_segment_end
= m_path_list
.getStr();
225 /******************************************
226 move the iterator to the next position
227 *****************************************/
230 OSL_PRECOND(!done(), "path_list_iterator: Already done!");
232 m_path_segment_begin
= ++m_path_segment_end
;
236 /******************************************
238 *****************************************/
241 return (m_path_segment_end
>= m_end
);
244 /******************************************
245 return the current item
246 *****************************************/
247 rtl::OUString
get_current_item() const
249 return rtl::OUString(
250 m_path_segment_begin
,
251 (m_path_segment_end
- m_path_segment_begin
));
256 /******************************************
257 move m_path_end to the next separator or
258 to the edn of the string
259 *****************************************/
262 while (!done() && *m_path_segment_end
&& (*m_path_segment_end
!= m_separator
))
263 ++m_path_segment_end
;
265 OSL_ASSERT(m_path_segment_end
<= m_end
);
269 rtl::OUString m_path_list
;
270 const sal_Unicode
* m_end
;
271 const sal_Unicode m_separator
;
272 const sal_Unicode
* m_path_segment_begin
;
273 const sal_Unicode
* m_path_segment_end
;
275 // prevent copy and assignment
277 /******************************************
279 remember: do not simply copy m_path_begin
280 and m_path_end because they point to
281 the memory of other.m_path_list!
282 *****************************************/
283 path_list_iterator(const path_list_iterator
& other
);
285 /******************************************
287 remember: do not simply copy m_path_begin
288 and m_path_end because they point to
289 the memory of other.m_path_list!
290 *****************************************/
291 path_list_iterator
& operator=(const path_list_iterator
& other
);
294 /************************************************
296 ***********************************************/
298 sal_Bool SAL_CALL
osl_searchPath(
299 const rtl_uString
* pustrFilePath
,
300 const rtl_uString
* pustrSearchPathList
,
301 rtl_uString
** ppustrPathFound
)
303 OSL_PRECOND(pustrFilePath
&& pustrSearchPathList
&& ppustrPathFound
, "osl_searchPath: Invalid parameter");
306 rtl::OUString
fp(const_cast<rtl_uString
*>(pustrFilePath
));
307 rtl::OUString pl
= rtl::OUString(const_cast<rtl_uString
*>(pustrSearchPathList
));
308 path_list_iterator
pli(pl
);
312 rtl::OUString p
= pli
.get_current_item();
313 osl::systemPathEnsureSeparator(p
);
316 if (osl::access(p
, F_OK
) > -1)
319 rtl_uString_assign(ppustrPathFound
, p
.pData
);
327 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */