Version 4.2.0.1, tag libreoffice-4.2.0.1
[LibreOffice.git] / sal / osl / unx / file_path_helper.cxx
blob71c3c3206d1659fbce13c0ea782a3d093a77631b
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 .
20 #include "file_path_helper.h"
21 #include "file_path_helper.hxx"
22 #include "uunxapi.hxx"
24 #include <osl/diagnose.h>
25 #include <rtl/ustring.hxx>
27 const sal_Unicode FPH_CHAR_PATH_SEPARATOR = (sal_Unicode)'/';
28 const sal_Unicode FPH_CHAR_DOT = (sal_Unicode)'.';
29 const sal_Unicode FPH_CHAR_COLON = (sal_Unicode)':';
31 inline const rtl::OUString FPH_PATH_SEPARATOR()
32 { return rtl::OUString(FPH_CHAR_PATH_SEPARATOR); }
34 inline const rtl::OUString FPH_LOCAL_DIR_ENTRY()
35 { return rtl::OUString(FPH_CHAR_DOT); }
37 inline const rtl::OUString FPH_PARENT_DIR_ENTRY()
38 { return rtl::OUString(".."); }
40 void SAL_CALL osl_systemPathRemoveSeparator(rtl_uString* pustrPath)
42 OSL_PRECOND(0 != pustrPath, "osl_systemPathRemoveSeparator: Invalid parameter");
43 if (0 != pustrPath)
45 // maybe there are more than one separator at end
46 // so we run in a loop
47 while ((pustrPath->length > 1) && (FPH_CHAR_PATH_SEPARATOR == pustrPath->buffer[pustrPath->length - 1]))
49 pustrPath->length--;
50 pustrPath->buffer[pustrPath->length] = (sal_Unicode)'\0';
53 OSL_POSTCOND((0 == pustrPath->length) || (1 == pustrPath->length) || \
54 (pustrPath->length > 1 && pustrPath->buffer[pustrPath->length - 1] != FPH_CHAR_PATH_SEPARATOR), \
55 "osl_systemPathRemoveSeparator: Post condition failed");
59 void SAL_CALL osl_systemPathEnsureSeparator(rtl_uString** ppustrPath)
61 OSL_PRECOND((0 != ppustrPath) && (0 != *ppustrPath), "osl_systemPathEnsureSeparator: Invalid parameter");
62 if ((0 != ppustrPath) && (0 != *ppustrPath))
64 rtl::OUString path(*ppustrPath);
65 sal_Int32 lp = path.getLength();
66 sal_Int32 i = path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR);
68 if ((lp > 1 && i != (lp - 1)) || ((lp < 2) && i < 0))
70 path += FPH_PATH_SEPARATOR();
71 rtl_uString_assign(ppustrPath, path.pData);
74 OSL_POSTCOND(path.endsWith(FPH_PATH_SEPARATOR()), \
75 "osl_systemPathEnsureSeparator: Post condition failed");
79 sal_Bool SAL_CALL osl_systemPathIsRelativePath(const rtl_uString* pustrPath)
81 OSL_PRECOND(0 != pustrPath, "osl_systemPathIsRelativePath: Invalid parameter");
82 return ((0 == pustrPath) || (0 == pustrPath->length) || (pustrPath->buffer[0] != FPH_CHAR_PATH_SEPARATOR));
85 void SAL_CALL osl_systemPathMakeAbsolutePath(
86 const rtl_uString* pustrBasePath,
87 const rtl_uString* pustrRelPath,
88 rtl_uString** ppustrAbsolutePath)
90 rtl::OUString base(rtl_uString_getStr(const_cast<rtl_uString*>(pustrBasePath)));
91 rtl::OUString rel(const_cast<rtl_uString*>(pustrRelPath));
93 if (!base.isEmpty())
94 osl_systemPathEnsureSeparator(&base.pData);
96 base += rel;
98 rtl_uString_acquire(base.pData);
99 *ppustrAbsolutePath = base.pData;
102 void SAL_CALL osl_systemPathGetFileNameOrLastDirectoryPart(
103 const rtl_uString* pustrPath,
104 rtl_uString** ppustrFileNameOrLastDirPart)
106 OSL_PRECOND(pustrPath && ppustrFileNameOrLastDirPart, \
107 "osl_systemPathGetFileNameOrLastDirectoryPart: Invalid parameter");
109 rtl::OUString path(const_cast<rtl_uString*>(pustrPath));
111 osl_systemPathRemoveSeparator(path.pData);
113 rtl::OUString last_part;
115 if (path.getLength() > 1 || (1 == path.getLength() && *path.getStr() != FPH_CHAR_PATH_SEPARATOR))
117 sal_Int32 idx_ps = path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR);
118 idx_ps++; // always right to increment by one even if idx_ps == -1!
119 last_part = rtl::OUString(path.getStr() + idx_ps);
121 rtl_uString_assign(ppustrFileNameOrLastDirPart, last_part.pData);
124 sal_Bool SAL_CALL osl_systemPathIsHiddenFileOrDirectoryEntry(
125 const rtl_uString* pustrPath)
127 OSL_PRECOND(0 != pustrPath, "osl_systemPathIsHiddenFileOrDirectoryEntry: Invalid parameter");
128 if ((0 == pustrPath) || (0 == pustrPath->length))
129 return sal_False;
131 rtl::OUString fdp;
132 osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &fdp.pData);
134 return ((fdp.pData->length > 0) &&
135 (fdp.pData->buffer[0] == FPH_CHAR_DOT) &&
136 !osl_systemPathIsLocalOrParentDirectoryEntry(fdp.pData));
139 sal_Bool SAL_CALL osl_systemPathIsLocalOrParentDirectoryEntry(
140 const rtl_uString* pustrPath)
142 OSL_PRECOND(pustrPath, "osl_systemPathIsLocalOrParentDirectoryEntry: Invalid parameter");
144 rtl::OUString dirent;
146 osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &dirent.pData);
148 return (dirent == FPH_LOCAL_DIR_ENTRY() ||
149 dirent == FPH_PARENT_DIR_ENTRY());
152 /***********************************************
153 Simple iterator for a path list separated by
154 the specified character
155 **********************************************/
157 class path_list_iterator
159 public:
161 /* after construction get_current_item
162 returns the first path in list, no need
163 to call reset first
165 path_list_iterator(const rtl::OUString& path_list, sal_Unicode list_separator = FPH_CHAR_COLON) :
166 m_path_list(path_list),
167 m_end(m_path_list.getStr() + m_path_list.getLength() + 1),
168 m_separator(list_separator)
170 reset();
173 void reset()
175 m_path_segment_begin = m_path_segment_end = m_path_list.getStr();
176 advance();
179 void next()
181 OSL_PRECOND(!done(), "path_list_iterator: Already done!");
183 m_path_segment_begin = ++m_path_segment_end;
184 advance();
187 bool done() const
189 return (m_path_segment_end >= m_end);
192 rtl::OUString get_current_item() const
194 return rtl::OUString(
195 m_path_segment_begin,
196 (m_path_segment_end - m_path_segment_begin));
199 private:
200 /* move m_path_end to the next separator or
201 to the end of the string
203 void advance()
205 while (!done() && *m_path_segment_end && (*m_path_segment_end != m_separator))
206 ++m_path_segment_end;
208 OSL_ASSERT(m_path_segment_end <= m_end);
211 private:
212 rtl::OUString m_path_list;
213 const sal_Unicode* m_end;
214 const sal_Unicode m_separator;
215 const sal_Unicode* m_path_segment_begin;
216 const sal_Unicode* m_path_segment_end;
218 // prevent copy and assignment
219 private:
220 /******************************************
221 copy constructor
222 remember: do not simply copy m_path_begin
223 and m_path_end because they point to
224 the memory of other.m_path_list!
225 *****************************************/
226 path_list_iterator(const path_list_iterator& other);
228 /******************************************
229 assignment operator
230 remember: do not simply copy m_path_begin
231 and m_path_end because they point to
232 the memory of other.m_path_list!
233 *****************************************/
234 path_list_iterator& operator=(const path_list_iterator& other);
237 sal_Bool SAL_CALL osl_searchPath(
238 const rtl_uString* pustrFilePath,
239 const rtl_uString* pustrSearchPathList,
240 rtl_uString** ppustrPathFound)
242 OSL_PRECOND(pustrFilePath && pustrSearchPathList && ppustrPathFound, "osl_searchPath: Invalid parameter");
244 bool bfound = false;
245 rtl::OUString fp(const_cast<rtl_uString*>(pustrFilePath));
246 rtl::OUString pl = rtl::OUString(const_cast<rtl_uString*>(pustrSearchPathList));
247 path_list_iterator pli(pl);
249 while (!pli.done())
251 rtl::OUString p = pli.get_current_item();
252 osl::systemPathEnsureSeparator(p);
253 p += fp;
255 if (osl::access(p, F_OK) > -1)
257 bfound = true;
258 rtl_uString_assign(ppustrPathFound, p.pData);
259 break;
261 pli.next();
263 return bfound;
266 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */