Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : /*******************************************
31 : : Includes
32 : : ******************************************/
33 : :
34 : : #include "file_path_helper.h"
35 : : #include "file_path_helper.hxx"
36 : : #include "uunxapi.hxx"
37 : :
38 : : #include <osl/diagnose.h>
39 : : #include <rtl/ustring.hxx>
40 : :
41 : : /*******************************************
42 : : Constants
43 : : ******************************************/
44 : :
45 : : const sal_Unicode FPH_CHAR_PATH_SEPARATOR = (sal_Unicode)'/';
46 : : const sal_Unicode FPH_CHAR_DOT = (sal_Unicode)'.';
47 : : const sal_Unicode FPH_CHAR_COLON = (sal_Unicode)':';
48 : :
49 : 163478 : inline const rtl::OUString FPH_PATH_SEPARATOR()
50 : 163478 : { return rtl::OUString(FPH_CHAR_PATH_SEPARATOR); }
51 : 500 : inline const rtl::OUString FPH_LOCAL_DIR_ENTRY()
52 : 500 : { return rtl::OUString(FPH_CHAR_PATH_SEPARATOR); }
53 : 500 : inline const rtl::OUString FPH_PARENT_DIR_ENTRY()
54 : 500 : { return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("..")); }
55 : :
56 : : /*******************************************
57 : : * osl_systemPathRemoveSeparator
58 : : ******************************************/
59 : :
60 : 798518 : void SAL_CALL osl_systemPathRemoveSeparator(rtl_uString* pustrPath)
61 : : {
62 : : OSL_PRECOND(0 != pustrPath, "osl_systemPathRemoveSeparator: Invalid parameter");
63 [ + - ]: 798518 : if (0 != pustrPath)
64 : : {
65 : : // maybe there are more than one separator at end
66 : : // so we run in a loop
67 [ + + ][ + + ]: 799210 : while ((pustrPath->length > 1) && (FPH_CHAR_PATH_SEPARATOR == pustrPath->buffer[pustrPath->length - 1]))
[ + + ]
68 : : {
69 : 692 : pustrPath->length--;
70 : 692 : pustrPath->buffer[pustrPath->length] = (sal_Unicode)'\0';
71 : : }
72 : :
73 : : OSL_POSTCOND((0 == pustrPath->length) || (1 == pustrPath->length) || \
74 : : (pustrPath->length > 1 && pustrPath->buffer[pustrPath->length - 1] != FPH_CHAR_PATH_SEPARATOR), \
75 : : "osl_systemPathRemoveSeparator: Post condition failed");
76 : : }
77 : 798518 : }
78 : :
79 : : /*******************************************
80 : : osl_systemPathEnsureSeparator
81 : : ******************************************/
82 : :
83 : 163683 : void SAL_CALL osl_systemPathEnsureSeparator(rtl_uString** ppustrPath)
84 : : {
85 : : OSL_PRECOND((0 != ppustrPath) && (0 != *ppustrPath), "osl_systemPathEnsureSeparator: Invalid parameter");
86 [ + - ][ + - ]: 163683 : if ((0 != ppustrPath) && (0 != *ppustrPath))
87 : : {
88 : 163683 : rtl::OUString path(*ppustrPath);
89 : 163683 : sal_Int32 lp = path.getLength();
90 : 163683 : sal_Int32 i = path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR);
91 : :
92 [ + + ][ - + ]: 163683 : if ((lp > 1 && i != (lp - 1)) || ((lp < 2) && i < 0))
[ # # ][ + - ]
93 : : {
94 : 163478 : path += FPH_PATH_SEPARATOR();
95 : 163478 : rtl_uString_assign(ppustrPath, path.pData);
96 : : }
97 : :
98 : : OSL_POSTCOND(path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR) == (path.getLength() - 1), \
99 : 163683 : "osl_systemPathEnsureSeparator: Post condition failed");
100 : : }
101 : 163683 : }
102 : :
103 : : /*******************************************
104 : : * osl_systemPathIsRelativePath
105 : : ******************************************/
106 : :
107 : 70232 : sal_Bool SAL_CALL osl_systemPathIsRelativePath(const rtl_uString* pustrPath)
108 : : {
109 : : OSL_PRECOND(0 != pustrPath, "osl_systemPathIsRelativePath: Invalid parameter");
110 [ + - ][ + - ]: 70232 : return ((0 == pustrPath) || (0 == pustrPath->length) || (pustrPath->buffer[0] != FPH_CHAR_PATH_SEPARATOR));
[ + + ]
111 : : }
112 : :
113 : : /******************************************
114 : : osl_systemPathMakeAbsolutePath
115 : : *****************************************/
116 : :
117 : 163683 : void SAL_CALL osl_systemPathMakeAbsolutePath(
118 : : const rtl_uString* pustrBasePath,
119 : : const rtl_uString* pustrRelPath,
120 : : rtl_uString** ppustrAbsolutePath)
121 : : {
122 : 163683 : rtl::OUString base(rtl_uString_getStr(const_cast<rtl_uString*>(pustrBasePath)));
123 : 163683 : rtl::OUString rel(const_cast<rtl_uString*>(pustrRelPath));
124 : :
125 [ + - ]: 163683 : if (!base.isEmpty())
126 : 163683 : osl_systemPathEnsureSeparator(&base.pData);
127 : :
128 : 163683 : base += rel;
129 : :
130 : 163683 : rtl_uString_acquire(base.pData);
131 : 163683 : *ppustrAbsolutePath = base.pData;
132 : 163683 : }
133 : :
134 : :
135 : : /*******************************************
136 : : osl_systemPathGetFileOrLastDirectoryPart
137 : : ******************************************/
138 : :
139 : 239375 : void SAL_CALL osl_systemPathGetFileNameOrLastDirectoryPart(
140 : : const rtl_uString* pustrPath,
141 : : rtl_uString** ppustrFileNameOrLastDirPart)
142 : : {
143 : : OSL_PRECOND(pustrPath && ppustrFileNameOrLastDirPart, \
144 : : "osl_systemPathGetFileNameOrLastDirectoryPart: Invalid parameter");
145 : :
146 : 239375 : rtl::OUString path(const_cast<rtl_uString*>(pustrPath));
147 : :
148 : 239375 : osl_systemPathRemoveSeparator(path.pData);
149 : :
150 : 239375 : rtl::OUString last_part;
151 : :
152 [ # # ][ # # ]: 239375 : if (path.getLength() > 1 || (1 == path.getLength() && *path.getStr() != FPH_CHAR_PATH_SEPARATOR))
[ + - ][ - + ]
153 : : {
154 : 239375 : sal_Int32 idx_ps = path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR);
155 : 239375 : idx_ps++; // always right to increment by one even if idx_ps == -1!
156 : 239375 : last_part = rtl::OUString(path.getStr() + idx_ps);
157 : : }
158 : 239375 : rtl_uString_assign(ppustrFileNameOrLastDirPart, last_part.pData);
159 : 239375 : }
160 : :
161 : :
162 : : /********************************************
163 : : osl_systemPathIsHiddenFileOrDirectoryEntry
164 : : *********************************************/
165 : :
166 : 79600 : sal_Bool SAL_CALL osl_systemPathIsHiddenFileOrDirectoryEntry(
167 : : const rtl_uString* pustrPath)
168 : : {
169 : : OSL_PRECOND(0 != pustrPath, "osl_systemPathIsHiddenFileOrDirectoryEntry: Invalid parameter");
170 [ + - ][ - + ]: 79600 : if ((0 == pustrPath) || (0 == pustrPath->length))
171 : 0 : return sal_False;
172 : :
173 : 79600 : rtl::OUString fdp;
174 : 79600 : osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &fdp.pData);
175 : :
176 : : return ((fdp.pData->length > 0) &&
177 : 79600 : (fdp.pData->buffer[0] == FPH_CHAR_DOT) &&
178 [ + + ][ + - ]: 79600 : !osl_systemPathIsLocalOrParentDirectoryEntry(fdp.pData));
[ + - ][ + - ]
179 : : }
180 : :
181 : :
182 : : /************************************************
183 : : osl_systemPathIsLocalOrParentDirectoryEntry
184 : : ************************************************/
185 : :
186 : 500 : sal_Bool SAL_CALL osl_systemPathIsLocalOrParentDirectoryEntry(
187 : : const rtl_uString* pustrPath)
188 : : {
189 : : OSL_PRECOND(pustrPath, "osl_systemPathIsLocalOrParentDirectoryEntry: Invalid parameter");
190 : :
191 : 500 : rtl::OUString dirent;
192 : :
193 : 500 : osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &dirent.pData);
194 : :
195 : : return (
196 [ + - ][ # # ]: 1000 : (dirent == FPH_LOCAL_DIR_ENTRY()) ||
197 [ + - ][ + - ]: 1000 : (dirent == FPH_PARENT_DIR_ENTRY())
[ # # ]
198 [ + - - + ]: 1500 : );
199 : : }
200 : :
201 : : /***********************************************
202 : : Simple iterator for a path list separated by
203 : : the specified character
204 : : **********************************************/
205 : :
206 : 0 : class path_list_iterator
207 : : {
208 : : public:
209 : :
210 : : /******************************************
211 : : constructor
212 : :
213 : : after construction get_current_item
214 : : returns the first path in list, no need
215 : : to call reset first
216 : : *****************************************/
217 : 0 : path_list_iterator(const rtl::OUString& path_list, sal_Unicode list_separator = FPH_CHAR_COLON) :
218 : : m_path_list(path_list),
219 : 0 : m_end(m_path_list.getStr() + m_path_list.getLength() + 1),
220 : 0 : m_separator(list_separator)
221 : : {
222 [ # # ]: 0 : reset();
223 : 0 : }
224 : :
225 : : /******************************************
226 : : reset the iterator
227 : : *****************************************/
228 : 0 : void reset()
229 : : {
230 : 0 : m_path_segment_begin = m_path_segment_end = m_path_list.getStr();
231 : 0 : advance();
232 : 0 : }
233 : :
234 : : /******************************************
235 : : move the iterator to the next position
236 : : *****************************************/
237 : 0 : void next()
238 : : {
239 : : OSL_PRECOND(!done(), "path_list_iterator: Already done!");
240 : :
241 : 0 : m_path_segment_begin = ++m_path_segment_end;
242 : 0 : advance();
243 : 0 : }
244 : :
245 : : /******************************************
246 : : check if done
247 : : *****************************************/
248 : 0 : bool done() const
249 : : {
250 : 0 : return (m_path_segment_end >= m_end);
251 : : }
252 : :
253 : : /******************************************
254 : : return the current item
255 : : *****************************************/
256 : 0 : rtl::OUString get_current_item() const
257 : : {
258 : : return rtl::OUString(
259 : : m_path_segment_begin,
260 : 0 : (m_path_segment_end - m_path_segment_begin));
261 : : }
262 : :
263 : : private:
264 : :
265 : : /******************************************
266 : : move m_path_end to the next separator or
267 : : to the edn of the string
268 : : *****************************************/
269 : 0 : void advance()
270 : : {
271 [ # # ][ # # ]: 0 : while (!done() && *m_path_segment_end && (*m_path_segment_end != m_separator))
[ # # ][ # # ]
272 : 0 : ++m_path_segment_end;
273 : :
274 : : OSL_ASSERT(m_path_segment_end <= m_end);
275 : 0 : }
276 : :
277 : : private:
278 : : rtl::OUString m_path_list;
279 : : const sal_Unicode* m_end;
280 : : const sal_Unicode m_separator;
281 : : const sal_Unicode* m_path_segment_begin;
282 : : const sal_Unicode* m_path_segment_end;
283 : :
284 : : // prevent copy and assignment
285 : : private:
286 : : /******************************************
287 : : copy constructor
288 : : remember: do not simply copy m_path_begin
289 : : and m_path_end because they point to
290 : : the memory of other.m_path_list!
291 : : *****************************************/
292 : : path_list_iterator(const path_list_iterator& other);
293 : :
294 : : /******************************************
295 : : assignment operator
296 : : remember: do not simply copy m_path_begin
297 : : and m_path_end because they point to
298 : : the memory of other.m_path_list!
299 : : *****************************************/
300 : : path_list_iterator& operator=(const path_list_iterator& other);
301 : : };
302 : :
303 : : /************************************************
304 : : osl_searchPath
305 : : ***********************************************/
306 : :
307 : 0 : sal_Bool SAL_CALL osl_searchPath(
308 : : const rtl_uString* pustrFilePath,
309 : : const rtl_uString* pustrSearchPathList,
310 : : rtl_uString** ppustrPathFound)
311 : : {
312 : : OSL_PRECOND(pustrFilePath && pustrSearchPathList && ppustrPathFound, "osl_searchPath: Invalid parameter");
313 : :
314 : 0 : bool bfound = false;
315 : 0 : rtl::OUString fp(const_cast<rtl_uString*>(pustrFilePath));
316 : 0 : rtl::OUString pl = rtl::OUString(const_cast<rtl_uString*>(pustrSearchPathList));
317 [ # # ]: 0 : path_list_iterator pli(pl);
318 : :
319 [ # # ]: 0 : while (!pli.done())
320 : : {
321 : 0 : rtl::OUString p = pli.get_current_item();
322 [ # # ]: 0 : osl::systemPathEnsureSeparator(p);
323 : 0 : p += fp;
324 : :
325 [ # # ][ # # ]: 0 : if (osl::access(p, F_OK) > -1)
326 : : {
327 : 0 : bfound = true;
328 : 0 : rtl_uString_assign(ppustrPathFound, p.pData);
329 : : break;
330 : : }
331 [ # # ][ # # ]: 0 : pli.next();
332 : 0 : }
333 : 0 : return bfound;
334 : : }
335 : :
336 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|