bump product version to 4.1.6.2
[LibreOffice.git] / sal / osl / unx / file_path_helper.cxx
blobf233f9179d7308177a292b2b7394144185e05a51
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 /*******************************************
22 Includes
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 /*******************************************
33 Constants
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");
54 if (0 != pustrPath)
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]))
60 pustrPath->length--;
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));
116 if (!base.isEmpty())
117 osl_systemPathEnsureSeparator(&base.pData);
119 base += rel;
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))
162 return sal_False;
164 rtl::OUString fdp;
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);
186 return (
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
199 public:
201 /******************************************
202 constructor
204 after construction get_current_item
205 returns the first path in list, no need
206 to call reset first
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)
213 reset();
216 /******************************************
217 reset the iterator
218 *****************************************/
219 void reset()
221 m_path_segment_begin = m_path_segment_end = m_path_list.getStr();
222 advance();
225 /******************************************
226 move the iterator to the next position
227 *****************************************/
228 void next()
230 OSL_PRECOND(!done(), "path_list_iterator: Already done!");
232 m_path_segment_begin = ++m_path_segment_end;
233 advance();
236 /******************************************
237 check if done
238 *****************************************/
239 bool done() const
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));
254 private:
256 /******************************************
257 move m_path_end to the next separator or
258 to the edn of the string
259 *****************************************/
260 void advance()
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);
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;
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);
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);
294 /************************************************
295 osl_searchPath
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");
305 bool bfound = false;
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);
310 while (!pli.done())
312 rtl::OUString p = pli.get_current_item();
313 osl::systemPathEnsureSeparator(p);
314 p += fp;
316 if (osl::access(p, F_OK) > -1)
318 bfound = true;
319 rtl_uString_assign(ppustrPathFound, p.pData);
320 break;
322 pli.next();
324 return bfound;
327 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */