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 25967 : inline const rtl::OUString FPH_PATH_SEPARATOR()
33 25967 : { return rtl::OUString(FPH_CHAR_PATH_SEPARATOR); }
34 :
35 306 : inline const rtl::OUString FPH_LOCAL_DIR_ENTRY()
36 306 : { return rtl::OUString(FPH_CHAR_DOT); }
37 :
38 306 : inline const rtl::OUString FPH_PARENT_DIR_ENTRY()
39 306 : { return rtl::OUString(".."); }
40 :
41 416495 : void SAL_CALL osl_systemPathRemoveSeparator(rtl_uString* pustrPath)
42 : {
43 : OSL_PRECOND(0 != pustrPath, "osl_systemPathRemoveSeparator: Invalid parameter");
44 416495 : if (0 != pustrPath)
45 : {
46 : // maybe there are more than one separator at end
47 : // so we run in a loop
48 834801 : while ((pustrPath->length > 1) && (FPH_CHAR_PATH_SEPARATOR == pustrPath->buffer[pustrPath->length - 1]))
49 : {
50 1811 : pustrPath->length--;
51 1811 : 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 416495 : }
59 :
60 26223 : void SAL_CALL osl_systemPathEnsureSeparator(rtl_uString** ppustrPath)
61 : {
62 : OSL_PRECOND((0 != ppustrPath) && (0 != *ppustrPath), "osl_systemPathEnsureSeparator: Invalid parameter");
63 26223 : if ((0 != ppustrPath) && (0 != *ppustrPath))
64 : {
65 26223 : rtl::OUString path(*ppustrPath);
66 26223 : sal_Int32 lp = path.getLength();
67 26223 : sal_Int32 i = path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR);
68 :
69 26223 : if ((lp > 1 && i != (lp - 1)) || ((lp < 2) && i < 0))
70 : {
71 25967 : path += FPH_PATH_SEPARATOR();
72 25967 : rtl_uString_assign(ppustrPath, path.pData);
73 : }
74 :
75 : OSL_POSTCOND(path.endsWith(FPH_PATH_SEPARATOR()), \
76 26223 : "osl_systemPathEnsureSeparator: Post condition failed");
77 : }
78 26223 : }
79 :
80 36796 : sal_Bool SAL_CALL osl_systemPathIsRelativePath(const rtl_uString* pustrPath)
81 : {
82 : OSL_PRECOND(0 != pustrPath, "osl_systemPathIsRelativePath: Invalid parameter");
83 36796 : return ((0 == pustrPath) || (0 == pustrPath->length) || (pustrPath->buffer[0] != FPH_CHAR_PATH_SEPARATOR));
84 : }
85 :
86 25040 : void SAL_CALL osl_systemPathMakeAbsolutePath(
87 : const rtl_uString* pustrBasePath,
88 : const rtl_uString* pustrRelPath,
89 : rtl_uString** ppustrAbsolutePath)
90 : {
91 25040 : rtl::OUString base(rtl_uString_getStr(const_cast<rtl_uString*>(pustrBasePath)));
92 50080 : rtl::OUString rel(const_cast<rtl_uString*>(pustrRelPath));
93 :
94 25040 : if (!base.isEmpty())
95 25040 : osl_systemPathEnsureSeparator(&base.pData);
96 :
97 25040 : base += rel;
98 :
99 25040 : rtl_uString_acquire(base.pData);
100 50080 : *ppustrAbsolutePath = base.pData;
101 25040 : }
102 :
103 70727 : 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 70727 : rtl::OUString path(const_cast<rtl_uString*>(pustrPath));
111 :
112 70727 : osl_systemPathRemoveSeparator(path.pData);
113 :
114 141454 : rtl::OUString last_part;
115 :
116 70727 : if (path.getLength() > 1 || (1 == path.getLength() && *path.getStr() != FPH_CHAR_PATH_SEPARATOR))
117 : {
118 70719 : sal_Int32 idx_ps = path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR);
119 70719 : idx_ps++; // always right to increment by one even if idx_ps == -1!
120 70719 : last_part = rtl::OUString(path.getStr() + idx_ps);
121 : }
122 141454 : rtl_uString_assign(ppustrFileNameOrLastDirPart, last_part.pData);
123 70727 : }
124 :
125 45953 : sal_Bool SAL_CALL osl_systemPathIsHiddenFileOrDirectoryEntry(
126 : const rtl_uString* pustrPath)
127 : {
128 : OSL_PRECOND(0 != pustrPath, "osl_systemPathIsHiddenFileOrDirectoryEntry: Invalid parameter");
129 45953 : if ((0 == pustrPath) || (0 == pustrPath->length))
130 0 : return sal_False;
131 :
132 45953 : rtl::OUString fdp;
133 45953 : osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &fdp.pData);
134 :
135 91898 : return ((fdp.pData->length > 0) &&
136 46259 : (fdp.pData->buffer[0] == FPH_CHAR_DOT) &&
137 46259 : !osl_systemPathIsLocalOrParentDirectoryEntry(fdp.pData));
138 : }
139 :
140 306 : sal_Bool SAL_CALL osl_systemPathIsLocalOrParentDirectoryEntry(
141 : const rtl_uString* pustrPath)
142 : {
143 : OSL_PRECOND(pustrPath, "osl_systemPathIsLocalOrParentDirectoryEntry: Invalid parameter");
144 :
145 306 : rtl::OUString dirent;
146 :
147 306 : osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &dirent.pData);
148 :
149 1530 : return (dirent == FPH_LOCAL_DIR_ENTRY() ||
150 1224 : dirent == FPH_PARENT_DIR_ENTRY());
151 : }
152 :
153 : /***********************************************
154 : Simple iterator for a path list separated by
155 : the specified character
156 : **********************************************/
157 :
158 321 : 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 321 : path_list_iterator(const rtl::OUString& path_list, sal_Unicode list_separator = FPH_CHAR_COLON) :
167 : m_path_list(path_list),
168 321 : m_end(m_path_list.getStr() + m_path_list.getLength() + 1),
169 642 : m_separator(list_separator)
170 : {
171 321 : reset();
172 321 : }
173 :
174 321 : void reset()
175 : {
176 321 : m_path_segment_begin = m_path_segment_end = m_path_list.getStr();
177 321 : advance();
178 321 : }
179 :
180 862 : void next()
181 : {
182 : OSL_PRECOND(!done(), "path_list_iterator: Already done!");
183 :
184 862 : m_path_segment_begin = ++m_path_segment_end;
185 862 : advance();
186 862 : }
187 :
188 42981 : bool done() const
189 : {
190 42981 : return (m_path_segment_end >= m_end);
191 : }
192 :
193 1183 : rtl::OUString get_current_item() const
194 : {
195 : return rtl::OUString(
196 : m_path_segment_begin,
197 1183 : (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 1183 : void advance()
205 : {
206 42981 : while (!done() && *m_path_segment_end && (*m_path_segment_end != m_separator))
207 40615 : ++m_path_segment_end;
208 :
209 : OSL_ASSERT(m_path_segment_end <= m_end);
210 1183 : }
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 321 : 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 321 : bool bfound = false;
228 321 : rtl::OUString fp(const_cast<rtl_uString*>(pustrFilePath));
229 642 : rtl::OUString pl = rtl::OUString(const_cast<rtl_uString*>(pustrSearchPathList));
230 642 : path_list_iterator pli(pl);
231 :
232 1504 : while (!pli.done())
233 : {
234 1183 : rtl::OUString p = pli.get_current_item();
235 1183 : osl::systemPathEnsureSeparator(p);
236 1183 : p += fp;
237 :
238 1183 : if (osl::access(p, F_OK) > -1)
239 : {
240 321 : bfound = true;
241 321 : rtl_uString_assign(ppustrPathFound, p.pData);
242 321 : break;
243 : }
244 862 : pli.next();
245 862 : }
246 642 : return bfound;
247 : }
248 :
249 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|