Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : /*******************************************
22 : Includes
23 : ******************************************/
24 :
25 : #include "file_path_helper.h"
26 : #include "file_path_helper.hxx"
27 : #include "uunxapi.hxx"
28 :
29 : #include <osl/diagnose.h>
30 : #include <rtl/ustring.hxx>
31 :
32 : /*******************************************
33 : Constants
34 : ******************************************/
35 :
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)':';
39 :
40 44449 : inline const rtl::OUString FPH_PATH_SEPARATOR()
41 44449 : { return rtl::OUString(FPH_CHAR_PATH_SEPARATOR); }
42 10 : inline const rtl::OUString FPH_LOCAL_DIR_ENTRY()
43 10 : { return rtl::OUString(FPH_CHAR_PATH_SEPARATOR); }
44 10 : inline const rtl::OUString FPH_PARENT_DIR_ENTRY()
45 10 : { return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("..")); }
46 :
47 : /*******************************************
48 : * osl_systemPathRemoveSeparator
49 : ******************************************/
50 :
51 209218 : void SAL_CALL osl_systemPathRemoveSeparator(rtl_uString* pustrPath)
52 : {
53 : OSL_PRECOND(0 != pustrPath, "osl_systemPathRemoveSeparator: Invalid parameter");
54 209218 : if (0 != pustrPath)
55 : {
56 : // maybe there are more than one separator at end
57 : // so we run in a loop
58 418526 : while ((pustrPath->length > 1) && (FPH_CHAR_PATH_SEPARATOR == pustrPath->buffer[pustrPath->length - 1]))
59 : {
60 90 : pustrPath->length--;
61 90 : pustrPath->buffer[pustrPath->length] = (sal_Unicode)'\0';
62 : }
63 :
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");
67 : }
68 209218 : }
69 :
70 : /*******************************************
71 : osl_systemPathEnsureSeparator
72 : ******************************************/
73 :
74 44527 : void SAL_CALL osl_systemPathEnsureSeparator(rtl_uString** ppustrPath)
75 : {
76 : OSL_PRECOND((0 != ppustrPath) && (0 != *ppustrPath), "osl_systemPathEnsureSeparator: Invalid parameter");
77 44527 : if ((0 != ppustrPath) && (0 != *ppustrPath))
78 : {
79 44527 : rtl::OUString path(*ppustrPath);
80 44527 : sal_Int32 lp = path.getLength();
81 44527 : sal_Int32 i = path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR);
82 :
83 44527 : if ((lp > 1 && i != (lp - 1)) || ((lp < 2) && i < 0))
84 : {
85 44449 : path += FPH_PATH_SEPARATOR();
86 44449 : rtl_uString_assign(ppustrPath, path.pData);
87 : }
88 :
89 : OSL_POSTCOND(path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR) == (path.getLength() - 1), \
90 44527 : "osl_systemPathEnsureSeparator: Post condition failed");
91 : }
92 44527 : }
93 :
94 : /*******************************************
95 : * osl_systemPathIsRelativePath
96 : ******************************************/
97 :
98 33130 : sal_Bool SAL_CALL osl_systemPathIsRelativePath(const rtl_uString* pustrPath)
99 : {
100 : OSL_PRECOND(0 != pustrPath, "osl_systemPathIsRelativePath: Invalid parameter");
101 33130 : return ((0 == pustrPath) || (0 == pustrPath->length) || (pustrPath->buffer[0] != FPH_CHAR_PATH_SEPARATOR));
102 : }
103 :
104 : /******************************************
105 : osl_systemPathMakeAbsolutePath
106 : *****************************************/
107 :
108 44527 : void SAL_CALL osl_systemPathMakeAbsolutePath(
109 : const rtl_uString* pustrBasePath,
110 : const rtl_uString* pustrRelPath,
111 : rtl_uString** ppustrAbsolutePath)
112 : {
113 44527 : rtl::OUString base(rtl_uString_getStr(const_cast<rtl_uString*>(pustrBasePath)));
114 44527 : rtl::OUString rel(const_cast<rtl_uString*>(pustrRelPath));
115 :
116 44527 : if (!base.isEmpty())
117 44527 : osl_systemPathEnsureSeparator(&base.pData);
118 :
119 44527 : base += rel;
120 :
121 44527 : rtl_uString_acquire(base.pData);
122 44527 : *ppustrAbsolutePath = base.pData;
123 44527 : }
124 :
125 :
126 : /*******************************************
127 : osl_systemPathGetFileOrLastDirectoryPart
128 : ******************************************/
129 :
130 39445 : void SAL_CALL osl_systemPathGetFileNameOrLastDirectoryPart(
131 : const rtl_uString* pustrPath,
132 : rtl_uString** ppustrFileNameOrLastDirPart)
133 : {
134 : OSL_PRECOND(pustrPath && ppustrFileNameOrLastDirPart, \
135 : "osl_systemPathGetFileNameOrLastDirectoryPart: Invalid parameter");
136 :
137 39445 : rtl::OUString path(const_cast<rtl_uString*>(pustrPath));
138 :
139 39445 : osl_systemPathRemoveSeparator(path.pData);
140 :
141 39445 : rtl::OUString last_part;
142 :
143 39445 : if (path.getLength() > 1 || (1 == path.getLength() && *path.getStr() != FPH_CHAR_PATH_SEPARATOR))
144 : {
145 39445 : sal_Int32 idx_ps = path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR);
146 39445 : idx_ps++; // always right to increment by one even if idx_ps == -1!
147 39445 : last_part = rtl::OUString(path.getStr() + idx_ps);
148 : }
149 39445 : rtl_uString_assign(ppustrFileNameOrLastDirPart, last_part.pData);
150 39445 : }
151 :
152 :
153 : /********************************************
154 : osl_systemPathIsHiddenFileOrDirectoryEntry
155 : *********************************************/
156 :
157 4080 : sal_Bool SAL_CALL osl_systemPathIsHiddenFileOrDirectoryEntry(
158 : const rtl_uString* pustrPath)
159 : {
160 : OSL_PRECOND(0 != pustrPath, "osl_systemPathIsHiddenFileOrDirectoryEntry: Invalid parameter");
161 4080 : if ((0 == pustrPath) || (0 == pustrPath->length))
162 0 : return sal_False;
163 :
164 4080 : rtl::OUString fdp;
165 4080 : osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &fdp.pData);
166 :
167 : return ((fdp.pData->length > 0) &&
168 4080 : (fdp.pData->buffer[0] == FPH_CHAR_DOT) &&
169 8160 : !osl_systemPathIsLocalOrParentDirectoryEntry(fdp.pData));
170 : }
171 :
172 :
173 : /************************************************
174 : osl_systemPathIsLocalOrParentDirectoryEntry
175 : ************************************************/
176 :
177 10 : sal_Bool SAL_CALL osl_systemPathIsLocalOrParentDirectoryEntry(
178 : const rtl_uString* pustrPath)
179 : {
180 : OSL_PRECOND(pustrPath, "osl_systemPathIsLocalOrParentDirectoryEntry: Invalid parameter");
181 :
182 10 : rtl::OUString dirent;
183 :
184 10 : osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &dirent.pData);
185 :
186 : return (
187 30 : (dirent == FPH_LOCAL_DIR_ENTRY()) ||
188 30 : (dirent == FPH_PARENT_DIR_ENTRY())
189 60 : );
190 : }
191 :
192 : /***********************************************
193 : Simple iterator for a path list separated by
194 : the specified character
195 : **********************************************/
196 :
197 0 : class path_list_iterator
198 : {
199 : public:
200 :
201 : /******************************************
202 : constructor
203 :
204 : after construction get_current_item
205 : returns the first path in list, no need
206 : to call reset first
207 : *****************************************/
208 0 : path_list_iterator(const rtl::OUString& path_list, sal_Unicode list_separator = FPH_CHAR_COLON) :
209 : m_path_list(path_list),
210 0 : m_end(m_path_list.getStr() + m_path_list.getLength() + 1),
211 0 : m_separator(list_separator)
212 : {
213 0 : reset();
214 0 : }
215 :
216 : /******************************************
217 : reset the iterator
218 : *****************************************/
219 0 : void reset()
220 : {
221 0 : m_path_segment_begin = m_path_segment_end = m_path_list.getStr();
222 0 : advance();
223 0 : }
224 :
225 : /******************************************
226 : move the iterator to the next position
227 : *****************************************/
228 0 : void next()
229 : {
230 : OSL_PRECOND(!done(), "path_list_iterator: Already done!");
231 :
232 0 : m_path_segment_begin = ++m_path_segment_end;
233 0 : advance();
234 0 : }
235 :
236 : /******************************************
237 : check if done
238 : *****************************************/
239 0 : bool done() const
240 : {
241 0 : return (m_path_segment_end >= m_end);
242 : }
243 :
244 : /******************************************
245 : return the current item
246 : *****************************************/
247 0 : rtl::OUString get_current_item() const
248 : {
249 : return rtl::OUString(
250 : m_path_segment_begin,
251 0 : (m_path_segment_end - m_path_segment_begin));
252 : }
253 :
254 : private:
255 :
256 : /******************************************
257 : move m_path_end to the next separator or
258 : to the edn of the string
259 : *****************************************/
260 0 : void advance()
261 : {
262 0 : while (!done() && *m_path_segment_end && (*m_path_segment_end != m_separator))
263 0 : ++m_path_segment_end;
264 :
265 : OSL_ASSERT(m_path_segment_end <= m_end);
266 0 : }
267 :
268 : private:
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;
274 :
275 : // prevent copy and assignment
276 : private:
277 : /******************************************
278 : copy constructor
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);
284 :
285 : /******************************************
286 : assignment operator
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);
292 : };
293 :
294 : /************************************************
295 : osl_searchPath
296 : ***********************************************/
297 :
298 0 : sal_Bool SAL_CALL osl_searchPath(
299 : const rtl_uString* pustrFilePath,
300 : const rtl_uString* pustrSearchPathList,
301 : rtl_uString** ppustrPathFound)
302 : {
303 : OSL_PRECOND(pustrFilePath && pustrSearchPathList && ppustrPathFound, "osl_searchPath: Invalid parameter");
304 :
305 0 : bool bfound = false;
306 0 : rtl::OUString fp(const_cast<rtl_uString*>(pustrFilePath));
307 0 : rtl::OUString pl = rtl::OUString(const_cast<rtl_uString*>(pustrSearchPathList));
308 0 : path_list_iterator pli(pl);
309 :
310 0 : while (!pli.done())
311 : {
312 0 : rtl::OUString p = pli.get_current_item();
313 0 : osl::systemPathEnsureSeparator(p);
314 0 : p += fp;
315 :
316 0 : if (osl::access(p, F_OK) > -1)
317 : {
318 0 : bfound = true;
319 0 : rtl_uString_assign(ppustrPathFound, p.pData);
320 : break;
321 : }
322 0 : pli.next();
323 0 : }
324 0 : return bfound;
325 : }
326 :
327 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|