1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: file_path_helper.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sal.hxx"
34 /*******************************************
36 ******************************************/
38 #ifndef _OSL_FILE_PATH_HELPER_H_
39 #include "file_path_helper.h"
42 #ifndef _OSL_FILE_PATH_HELPER_HXX_
43 #include "file_path_helper.hxx"
46 #ifndef _OSL_UUNXAPI_HXX_
47 #include "uunxapi.hxx"
50 #ifndef _OSL_DIAGNOSE_H_
51 #include <osl/diagnose.h>
54 #ifndef _RTL_USTRING_HXX_
55 #include <rtl/ustring.hxx>
58 /*******************************************
60 ******************************************/
62 const sal_Unicode FPH_CHAR_PATH_SEPARATOR
= (sal_Unicode
)'/';
63 const sal_Unicode FPH_CHAR_DOT
= (sal_Unicode
)'.';
64 const sal_Unicode FPH_CHAR_COLON
= (sal_Unicode
)':';
66 inline const rtl::OUString
FPH_PATH_SEPARATOR()
67 { return rtl::OUString::createFromAscii("/"); }
68 inline const rtl::OUString
FPH_LOCAL_DIR_ENTRY()
69 { return rtl::OUString::createFromAscii("."); }
70 inline const rtl::OUString
FPH_PARENT_DIR_ENTRY()
71 { return rtl::OUString::createFromAscii(".."); }
73 /*******************************************
74 * osl_systemPathRemoveSeparator
75 ******************************************/
77 void SAL_CALL
osl_systemPathRemoveSeparator(rtl_uString
* pustrPath
)
79 OSL_PRECOND(pustrPath
, "osl_systemPathRemoveSeparator: Invalid parameter");
81 // maybe there are more than one separator at end
82 // so we run in a loop
83 while ((pustrPath
->length
> 1) && (FPH_CHAR_PATH_SEPARATOR
== pustrPath
->buffer
[pustrPath
->length
- 1]))
86 pustrPath
->buffer
[pustrPath
->length
] = (sal_Unicode
)'\0';
89 OSL_POSTCOND((0 == pustrPath
->length
) || (1 == pustrPath
->length
) || \
90 (pustrPath
->length
> 1 && pustrPath
->buffer
[pustrPath
->length
- 1] != FPH_CHAR_PATH_SEPARATOR
), \
91 "osl_systemPathRemoveSeparator: Post condition failed");
94 /*******************************************
95 osl_systemPathEnsureSeparator
96 ******************************************/
98 void SAL_CALL
osl_systemPathEnsureSeparator(rtl_uString
** ppustrPath
)
100 OSL_PRECOND(ppustrPath
&& (NULL
!= *ppustrPath
), \
101 "osl_systemPathEnsureSeparator: Invalid parameter");
103 rtl::OUString
path(*ppustrPath
);
104 sal_Int32 lp
= path
.getLength();
105 sal_Int32 i
= path
.lastIndexOf(FPH_CHAR_PATH_SEPARATOR
);
107 if ((lp
> 1 && i
!= (lp
- 1)) || ((lp
< 2) && i
< 0))
109 path
+= FPH_PATH_SEPARATOR();
110 rtl_uString_assign(ppustrPath
, path
.pData
);
113 OSL_POSTCOND(path
.lastIndexOf(FPH_CHAR_PATH_SEPARATOR
) == (path
.getLength() - 1), \
114 "osl_systemPathEnsureSeparator: Post condition failed");
117 /*******************************************
118 * osl_systemPathIsRelativePath
119 ******************************************/
121 sal_Bool SAL_CALL
osl_systemPathIsRelativePath(const rtl_uString
* pustrPath
)
123 OSL_PRECOND(pustrPath
, "osl_systemPathIsRelativePath: Invalid parameter");
124 return ((0 == pustrPath
->length
) || (pustrPath
->buffer
[0] != FPH_CHAR_PATH_SEPARATOR
));
127 /******************************************
128 osl_systemPathMakeAbsolutePath
129 *****************************************/
131 void SAL_CALL
osl_systemPathMakeAbsolutePath(
132 const rtl_uString
* pustrBasePath
,
133 const rtl_uString
* pustrRelPath
,
134 rtl_uString
** ppustrAbsolutePath
)
136 rtl::OUString
base(rtl_uString_getStr(const_cast<rtl_uString
*>(pustrBasePath
)));
137 rtl::OUString
rel(const_cast<rtl_uString
*>(pustrRelPath
));
139 if (base
.getLength() > 0)
140 osl_systemPathEnsureSeparator(&base
.pData
);
144 rtl_uString_acquire(base
.pData
);
145 *ppustrAbsolutePath
= base
.pData
;
149 /*******************************************
150 osl_systemPathGetFileOrLastDirectoryPart
151 ******************************************/
153 void SAL_CALL
osl_systemPathGetFileNameOrLastDirectoryPart(
154 const rtl_uString
* pustrPath
,
155 rtl_uString
** ppustrFileNameOrLastDirPart
)
157 OSL_PRECOND(pustrPath
&& ppustrFileNameOrLastDirPart
, \
158 "osl_systemPathGetFileNameOrLastDirectoryPart: Invalid parameter");
160 rtl::OUString
path(const_cast<rtl_uString
*>(pustrPath
));
162 osl_systemPathRemoveSeparator(path
.pData
);
164 rtl::OUString last_part
;
166 if (path
.getLength() > 1 || (1 == path
.getLength() && *path
.getStr() != FPH_CHAR_PATH_SEPARATOR
))
168 sal_Int32 idx_ps
= path
.lastIndexOf(FPH_CHAR_PATH_SEPARATOR
);
169 idx_ps
++; // always right to increment by one even if idx_ps == -1!
170 last_part
= rtl::OUString(path
.getStr() + idx_ps
);
172 rtl_uString_assign(ppustrFileNameOrLastDirPart
, last_part
.pData
);
176 /********************************************
177 osl_systemPathIsHiddenFileOrDirectoryEntry
178 *********************************************/
180 sal_Bool SAL_CALL
osl_systemPathIsHiddenFileOrDirectoryEntry(
181 const rtl_uString
* pustrPath
)
183 OSL_PRECOND(pustrPath
, "osl_systemPathIsHiddenFileOrDirectoryEntry: Invalid parameter");
185 sal_Bool is_hidden
= sal_False
;
187 if (pustrPath
->length
> 0)
191 osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath
, &fdp
.pData
);
193 is_hidden
= ((fdp
.pData
->length
> 0) && (fdp
.pData
->buffer
[0] == FPH_CHAR_DOT
) &&
194 !osl_systemPathIsLocalOrParentDirectoryEntry(fdp
.pData
));
201 /************************************************
202 osl_systemPathIsLocalOrParentDirectoryEntry
203 ************************************************/
205 sal_Bool SAL_CALL
osl_systemPathIsLocalOrParentDirectoryEntry(
206 const rtl_uString
* pustrPath
)
208 OSL_PRECOND(pustrPath
, "osl_systemPathIsLocalOrParentDirectoryEntry: Invalid parameter");
210 rtl::OUString dirent
;
212 osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath
, &dirent
.pData
);
215 (dirent
== FPH_LOCAL_DIR_ENTRY()) ||
216 (dirent
== FPH_PARENT_DIR_ENTRY())
220 /***********************************************
221 Simple iterator for a path list separated by
222 the specified character
223 **********************************************/
225 class path_list_iterator
229 /******************************************
232 after construction get_current_item
233 returns the first path in list, no need
235 *****************************************/
236 path_list_iterator(const rtl::OUString
& path_list
, sal_Unicode list_separator
= FPH_CHAR_COLON
) :
237 m_path_list(path_list
),
238 m_end(m_path_list
.getStr() + m_path_list
.getLength() + 1),
239 m_separator(list_separator
)
244 /******************************************
246 *****************************************/
249 m_path_segment_begin
= m_path_segment_end
= m_path_list
.getStr();
253 /******************************************
254 move the iterator to the next position
255 *****************************************/
258 OSL_PRECOND(!done(), "path_list_iterator: Already done!");
260 m_path_segment_begin
= ++m_path_segment_end
;
264 /******************************************
266 *****************************************/
269 return (m_path_segment_end
>= m_end
);
272 /******************************************
273 return the current item
274 *****************************************/
275 rtl::OUString
get_current_item() const
277 return rtl::OUString(
278 m_path_segment_begin
,
279 (m_path_segment_end
- m_path_segment_begin
));
284 /******************************************
285 move m_path_end to the next separator or
286 to the edn of the string
287 *****************************************/
290 while (!done() && *m_path_segment_end
&& (*m_path_segment_end
!= m_separator
))
291 ++m_path_segment_end
;
293 OSL_ASSERT(m_path_segment_end
<= m_end
);
297 rtl::OUString m_path_list
;
298 const sal_Unicode
* m_end
;
299 const sal_Unicode m_separator
;
300 const sal_Unicode
* m_path_segment_begin
;
301 const sal_Unicode
* m_path_segment_end
;
303 // prevent copy and assignment
305 /******************************************
307 remember: do not simply copy m_path_begin
308 and m_path_end because they point to
309 the memory of other.m_path_list!
310 *****************************************/
311 path_list_iterator(const path_list_iterator
& other
);
313 /******************************************
315 remember: do not simply copy m_path_begin
316 and m_path_end because they point to
317 the memory of other.m_path_list!
318 *****************************************/
319 path_list_iterator
& operator=(const path_list_iterator
& other
);
322 /************************************************
324 ***********************************************/
326 sal_Bool SAL_CALL
osl_searchPath(
327 const rtl_uString
* pustrFilePath
,
328 const rtl_uString
* pustrSearchPathList
,
329 rtl_uString
** ppustrPathFound
)
331 OSL_PRECOND(pustrFilePath
&& pustrSearchPathList
&& ppustrPathFound
, "osl_searchPath: Invalid parameter");
334 rtl::OUString
fp(const_cast<rtl_uString
*>(pustrFilePath
));
335 rtl::OUString pl
= rtl::OUString(const_cast<rtl_uString
*>(pustrSearchPathList
));
336 path_list_iterator
pli(pl
);
340 rtl::OUString p
= pli
.get_current_item();
341 osl::systemPathEnsureSeparator(p
);
344 if (osl::access(p
, F_OK
) > -1)
347 rtl_uString_assign(ppustrPathFound
, p
.pData
);