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 : #include "file_path_helper.h"
21 : #include "file_path_helper.hxx"
22 : #include "uunxapi.hxx"
23 :
24 : #include <boost/noncopyable.hpp>
25 : #include <osl/diagnose.h>
26 : #include <rtl/ustring.hxx>
27 :
28 : const sal_Unicode FPH_CHAR_PATH_SEPARATOR = (sal_Unicode)'/';
29 : const sal_Unicode FPH_CHAR_DOT = (sal_Unicode)'.';
30 : const sal_Unicode FPH_CHAR_COLON = (sal_Unicode)':';
31 :
32 43 : inline const rtl::OUString FPH_PATH_SEPARATOR()
33 43 : { return rtl::OUString(FPH_CHAR_PATH_SEPARATOR); }
34 :
35 0 : inline const rtl::OUString FPH_LOCAL_DIR_ENTRY()
36 0 : { return rtl::OUString(FPH_CHAR_DOT); }
37 :
38 0 : inline const rtl::OUString FPH_PARENT_DIR_ENTRY()
39 0 : { return rtl::OUString(".."); }
40 :
41 1787258 : void SAL_CALL osl_systemPathRemoveSeparator(rtl_uString* pustrPath)
42 : {
43 : OSL_PRECOND(0 != pustrPath, "osl_systemPathRemoveSeparator: Invalid parameter");
44 1787258 : if (0 != pustrPath)
45 : {
46 : // maybe there are more than one separator at end
47 : // so we run in a loop
48 3574615 : while ((pustrPath->length > 1) && (FPH_CHAR_PATH_SEPARATOR == pustrPath->buffer[pustrPath->length - 1]))
49 : {
50 99 : pustrPath->length--;
51 99 : pustrPath->buffer[pustrPath->length] = (sal_Unicode)'\0';
52 : }
53 :
54 : OSL_POSTCOND((0 == pustrPath->length) || (1 == pustrPath->length) || \
55 : (pustrPath->length > 1 && pustrPath->buffer[pustrPath->length - 1] != FPH_CHAR_PATH_SEPARATOR), \
56 : "osl_systemPathRemoveSeparator: Post condition failed");
57 : }
58 1787258 : }
59 :
60 43 : void SAL_CALL osl_systemPathEnsureSeparator(rtl_uString** ppustrPath)
61 : {
62 : OSL_PRECOND((0 != ppustrPath) && (0 != *ppustrPath), "osl_systemPathEnsureSeparator: Invalid parameter");
63 43 : if ((0 != ppustrPath) && (0 != *ppustrPath))
64 : {
65 43 : rtl::OUString path(*ppustrPath);
66 43 : sal_Int32 lp = path.getLength();
67 43 : sal_Int32 i = path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR);
68 :
69 43 : if ((lp > 1 && i != (lp - 1)) || ((lp < 2) && i < 0))
70 : {
71 43 : path += FPH_PATH_SEPARATOR();
72 43 : rtl_uString_assign(ppustrPath, path.pData);
73 : }
74 :
75 : OSL_POSTCOND(path.endsWith(FPH_PATH_SEPARATOR()), \
76 43 : "osl_systemPathEnsureSeparator: Post condition failed");
77 : }
78 43 : }
79 :
80 127526 : sal_Bool SAL_CALL osl_systemPathIsRelativePath(const rtl_uString* pustrPath)
81 : {
82 : OSL_PRECOND(0 != pustrPath, "osl_systemPathIsRelativePath: Invalid parameter");
83 127526 : return ((0 == pustrPath) || (0 == pustrPath->length) || (pustrPath->buffer[0] != FPH_CHAR_PATH_SEPARATOR));
84 : }
85 :
86 43 : void SAL_CALL osl_systemPathMakeAbsolutePath(
87 : const rtl_uString* pustrBasePath,
88 : const rtl_uString* pustrRelPath,
89 : rtl_uString** ppustrAbsolutePath)
90 : {
91 43 : rtl::OUString base(rtl_uString_getStr(const_cast<rtl_uString*>(pustrBasePath)));
92 86 : rtl::OUString rel(const_cast<rtl_uString*>(pustrRelPath));
93 :
94 43 : if (!base.isEmpty())
95 43 : osl_systemPathEnsureSeparator(&base.pData);
96 :
97 43 : base += rel;
98 :
99 43 : rtl_uString_acquire(base.pData);
100 86 : *ppustrAbsolutePath = base.pData;
101 43 : }
102 :
103 212678 : void SAL_CALL osl_systemPathGetFileNameOrLastDirectoryPart(
104 : const rtl_uString* pustrPath,
105 : rtl_uString** ppustrFileNameOrLastDirPart)
106 : {
107 : OSL_PRECOND(pustrPath && ppustrFileNameOrLastDirPart, \
108 : "osl_systemPathGetFileNameOrLastDirectoryPart: Invalid parameter");
109 :
110 212678 : rtl::OUString path(const_cast<rtl_uString*>(pustrPath));
111 :
112 212678 : osl_systemPathRemoveSeparator(path.pData);
113 :
114 425356 : rtl::OUString last_part;
115 :
116 212678 : if (path.getLength() > 1 || (1 == path.getLength() && *path.getStr() != FPH_CHAR_PATH_SEPARATOR))
117 : {
118 212676 : sal_Int32 idx_ps = path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR);
119 212676 : idx_ps++; // always right to increment by one even if idx_ps == -1!
120 212676 : last_part = rtl::OUString(path.getStr() + idx_ps);
121 : }
122 425356 : rtl_uString_assign(ppustrFileNameOrLastDirPart, last_part.pData);
123 212678 : }
124 :
125 212656 : sal_Bool SAL_CALL osl_systemPathIsHiddenFileOrDirectoryEntry(
126 : const rtl_uString* pustrPath)
127 : {
128 : OSL_PRECOND(0 != pustrPath, "osl_systemPathIsHiddenFileOrDirectoryEntry: Invalid parameter");
129 212656 : if ((0 == pustrPath) || (0 == pustrPath->length))
130 0 : return sal_False;
131 :
132 212656 : rtl::OUString fdp;
133 212656 : osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &fdp.pData);
134 :
135 425310 : return ((fdp.pData->length > 0) &&
136 212656 : (fdp.pData->buffer[0] == FPH_CHAR_DOT) &&
137 212656 : !osl_systemPathIsLocalOrParentDirectoryEntry(fdp.pData));
138 : }
139 :
140 0 : sal_Bool SAL_CALL osl_systemPathIsLocalOrParentDirectoryEntry(
141 : const rtl_uString* pustrPath)
142 : {
143 : OSL_PRECOND(pustrPath, "osl_systemPathIsLocalOrParentDirectoryEntry: Invalid parameter");
144 :
145 0 : rtl::OUString dirent;
146 :
147 0 : osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &dirent.pData);
148 :
149 0 : return (dirent == FPH_LOCAL_DIR_ENTRY() ||
150 0 : dirent == FPH_PARENT_DIR_ENTRY());
151 : }
152 :
153 : /***********************************************
154 : Simple iterator for a path list separated by
155 : the specified character
156 : **********************************************/
157 :
158 0 : class path_list_iterator: private boost::noncopyable
159 : {
160 : public:
161 :
162 : /* after construction get_current_item
163 : returns the first path in list, no need
164 : to call reset first
165 : */
166 0 : path_list_iterator(const rtl::OUString& path_list, sal_Unicode list_separator = FPH_CHAR_COLON) :
167 : m_path_list(path_list),
168 0 : m_end(m_path_list.getStr() + m_path_list.getLength() + 1),
169 0 : m_separator(list_separator)
170 : {
171 0 : reset();
172 0 : }
173 :
174 0 : void reset()
175 : {
176 0 : m_path_segment_begin = m_path_segment_end = m_path_list.getStr();
177 0 : advance();
178 0 : }
179 :
180 0 : void next()
181 : {
182 : OSL_PRECOND(!done(), "path_list_iterator: Already done!");
183 :
184 0 : m_path_segment_begin = ++m_path_segment_end;
185 0 : advance();
186 0 : }
187 :
188 0 : bool done() const
189 : {
190 0 : return (m_path_segment_end >= m_end);
191 : }
192 :
193 0 : rtl::OUString get_current_item() const
194 : {
195 : return rtl::OUString(
196 : m_path_segment_begin,
197 0 : (m_path_segment_end - m_path_segment_begin));
198 : }
199 :
200 : private:
201 : /* move m_path_end to the next separator or
202 : to the end of the string
203 : */
204 0 : void advance()
205 : {
206 0 : while (!done() && *m_path_segment_end && (*m_path_segment_end != m_separator))
207 0 : ++m_path_segment_end;
208 :
209 : OSL_ASSERT(m_path_segment_end <= m_end);
210 0 : }
211 :
212 : private:
213 : rtl::OUString m_path_list;
214 : const sal_Unicode* m_end;
215 : const sal_Unicode m_separator;
216 : const sal_Unicode* m_path_segment_begin;
217 : const sal_Unicode* m_path_segment_end;
218 : };
219 :
220 0 : sal_Bool SAL_CALL osl_searchPath(
221 : const rtl_uString* pustrFilePath,
222 : const rtl_uString* pustrSearchPathList,
223 : rtl_uString** ppustrPathFound)
224 : {
225 : OSL_PRECOND(pustrFilePath && pustrSearchPathList && ppustrPathFound, "osl_searchPath: Invalid parameter");
226 :
227 0 : bool bfound = false;
228 0 : rtl::OUString fp(const_cast<rtl_uString*>(pustrFilePath));
229 0 : rtl::OUString pl = rtl::OUString(const_cast<rtl_uString*>(pustrSearchPathList));
230 0 : path_list_iterator pli(pl);
231 :
232 0 : while (!pli.done())
233 : {
234 0 : rtl::OUString p = pli.get_current_item();
235 0 : osl::systemPathEnsureSeparator(p);
236 0 : p += fp;
237 :
238 0 : if (osl::access(p, F_OK) > -1)
239 : {
240 0 : bfound = true;
241 0 : rtl_uString_assign(ppustrPathFound, p.pData);
242 0 : break;
243 : }
244 0 : pli.next();
245 0 : }
246 0 : return bfound;
247 : }
248 :
249 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|