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