1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 /*******************************************
25 Includes
26 ******************************************/
27
28 #ifndef _OSL_THREAD_H_
29 #include "osl/thread.h"
30 #endif
31
32 #ifndef _OSL_FILE_PATH_HELPER_H_
33 #include "file_path_helper.h"
34 #endif
35
36 #ifndef _OSL_FILE_PATH_HELPER_HXX_
37 #include "file_path_helper.hxx"
38 #endif
39
40 #ifndef _OSL_UUNXAPI_HXX_
41 #include "uunxapi.hxx"
42 #endif
43
44 #ifndef _OSL_DIAGNOSE_H_
45 #include <osl/diagnose.h>
46 #endif
47
48 #ifndef _RTL_USTRING_HXX_
49 #include <rtl/ustring.hxx>
50 #endif
51
52 /*******************************************
53 Constants
54 ******************************************/
55
56 const sal_Unicode FPH_CHAR_PATH_SEPARATOR = (sal_Unicode)'\\';
57 const sal_Unicode FPH_CHAR_DOT = (sal_Unicode)'.';
58 const sal_Unicode FPH_CHAR_COLON = (sal_Unicode)':';
59
FPH_PATH_SEPARATOR()60 inline const rtl::OUString FPH_PATH_SEPARATOR()
61 { return rtl::OUString::createFromAscii("\\"); }
FPH_LOCAL_DIR_ENTRY()62 inline const rtl::OUString FPH_LOCAL_DIR_ENTRY()
63 { return rtl::OUString::createFromAscii("."); }
FPH_PARENT_DIR_ENTRY()64 inline const rtl::OUString FPH_PARENT_DIR_ENTRY()
65 { return rtl::OUString::createFromAscii(".."); }
66
67 /*******************************************
68 * osl_systemPathRemoveSeparator
69 ******************************************/
70
osl_systemPathRemoveSeparator(rtl_uString * pustrPath)71 void SAL_CALL osl_systemPathRemoveSeparator(rtl_uString* pustrPath)
72 {
73 OSL_PRECOND(pustrPath, "osl_systemPathRemoveSeparator: Invalid parameter");
74
75 // maybe there are more than one separator at end
76 // so we run in a loop
77 while ((pustrPath->length > 1) && (FPH_CHAR_PATH_SEPARATOR == pustrPath->buffer[pustrPath->length - 1]))
78 {
79 pustrPath->length--;
80 pustrPath->buffer[pustrPath->length] = (sal_Unicode)'\0';
81 }
82
83 OSL_POSTCOND((0 == pustrPath->length) || (1 == pustrPath->length) || \
84 (pustrPath->length > 1 && pustrPath->buffer[pustrPath->length - 1] != FPH_CHAR_PATH_SEPARATOR), \
85 "osl_systemPathRemoveSeparator: Post condition failed");
86 }
87
88 /*******************************************
89 osl_systemPathEnsureSeparator
90 ******************************************/
91
osl_systemPathEnsureSeparator(rtl_uString ** ppustrPath)92 void SAL_CALL osl_systemPathEnsureSeparator(rtl_uString** ppustrPath)
93 {
94 OSL_PRECOND(ppustrPath && (NULL != *ppustrPath), \
95 "osl_systemPathEnsureSeparator: Invalid parameter");
96
97 rtl::OUString path(*ppustrPath);
98 sal_Int32 lp = path.getLength();
99 sal_Int32 i = path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR);
100
101 if ((lp > 1 && i != (lp - 1)) || ((lp < 2) && i < 0))
102 {
103 path += FPH_PATH_SEPARATOR();
104 rtl_uString_assign(ppustrPath, path.pData);
105 }
106
107 OSL_POSTCOND(path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR) == (path.getLength() - 1), \
108 "osl_systemPathEnsureSeparator: Post condition failed");
109 }
110
111 /*******************************************
112 * osl_systemPathIsRelativePath
113 ******************************************/
114
osl_systemPathIsRelativePath(const rtl_uString * pustrPath)115 sal_Bool SAL_CALL osl_systemPathIsRelativePath(const rtl_uString* pustrPath)
116 {
117 OSL_PRECOND(pustrPath, "osl_systemPathIsRelativePath: Invalid parameter");
118 return (!osl_systemPathIsAbsolutePath(pustrPath));
119 }
120
121 /******************************************
122 * osl_systemPathIsAbsolutePath
123 *****************************************/
124
osl_systemPathIsAbsolutePath(const rtl_uString * pustrPath)125 sal_Bool SAL_CALL osl_systemPathIsAbsolutePath(const rtl_uString* pustrPath)
126 {
127 OSL_PRECOND(pustrPath, "osl_systemPathIsAbsolutePath: Invalid parameter");
128 if (pustrPath->length == 0)
129 return sal_False;
130 if (pustrPath->buffer[0] == FPH_CHAR_PATH_SEPARATOR)
131 return sal_True;
132 if (pustrPath->buffer[1] == FPH_CHAR_COLON
133 && pustrPath->buffer[2] == FPH_CHAR_PATH_SEPARATOR)
134 return sal_True;
135 return sal_False;
136 }
137
138 /******************************************
139 osl_systemPathMakeAbsolutePath
140 *****************************************/
141
osl_systemPathMakeAbsolutePath(const rtl_uString * pustrBasePath,const rtl_uString * pustrRelPath,rtl_uString ** ppustrAbsolutePath)142 void SAL_CALL osl_systemPathMakeAbsolutePath(
143 const rtl_uString* pustrBasePath,
144 const rtl_uString* pustrRelPath,
145 rtl_uString** ppustrAbsolutePath)
146 {
147 rtl::OUString base(rtl_uString_getStr(const_cast<rtl_uString*>(pustrBasePath)));
148 rtl::OUString rel(const_cast<rtl_uString*>(pustrRelPath));
149
150 if (base.getLength() > 0)
151 osl_systemPathEnsureSeparator(&base.pData);
152
153 base += rel;
154
155 rtl_uString_acquire(base.pData);
156 *ppustrAbsolutePath = base.pData;
157 }
158
159
160 /*****************************************
161 osl_systemPathGetParent
162 ****************************************/
163
osl_systemPathGetParent(rtl_uString * pustrPath)164 sal_Int32 SAL_CALL osl_systemPathGetParent(rtl_uString* pustrPath)
165 {
166 return 0;
167 }
168
169 /*******************************************
170 osl_systemPathGetFileOrLastDirectoryPart
171 ******************************************/
172
osl_systemPathGetFileNameOrLastDirectoryPart(const rtl_uString * pustrPath,rtl_uString ** ppustrFileNameOrLastDirPart)173 void SAL_CALL osl_systemPathGetFileNameOrLastDirectoryPart(
174 const rtl_uString* pustrPath,
175 rtl_uString** ppustrFileNameOrLastDirPart)
176 {
177 OSL_PRECOND(pustrPath && ppustrFileNameOrLastDirPart, \
178 "osl_systemPathGetFileNameOrLastDirectoryPart: Invalid parameter");
179
180 rtl::OUString path(const_cast<rtl_uString*>(pustrPath));
181
182 osl_systemPathRemoveSeparator(path.pData);
183
184 rtl::OUString last_part;
185
186 if (path.getLength() > 1 || (1 == path.getLength() && *path.getStr() != FPH_CHAR_PATH_SEPARATOR))
187 {
188 sal_Int32 idx_ps = path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR);
189 idx_ps++; // always right to increment by one even if idx_ps == -1!
190 last_part = rtl::OUString(path.getStr() + idx_ps);
191 }
192 rtl_uString_assign(ppustrFileNameOrLastDirPart, last_part.pData);
193 }
194
195
196 /********************************************
197 osl_systemPathIsHiddenFileOrDirectoryEntry
198 *********************************************/
199
osl_systemPathIsHiddenFileOrDirectoryEntry(const rtl_uString * pustrPath)200 sal_Bool SAL_CALL osl_systemPathIsHiddenFileOrDirectoryEntry(
201 const rtl_uString* pustrPath)
202 {
203 OSL_PRECOND(pustrPath, "osl_systemPathIsHiddenFileOrDirectoryEntry: Invalid parameter");
204
205 sal_Bool is_hidden = sal_False;
206
207 if (pustrPath->length > 0)
208 {
209 rtl::OUString fdp;
210
211 osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &fdp.pData);
212
213 is_hidden = ((fdp.pData->length > 0) && (fdp.pData->buffer[0] == FPH_CHAR_DOT) &&
214 !osl_systemPathIsLocalOrParentDirectoryEntry(fdp.pData));
215 }
216
217 return is_hidden;
218 }
219
220
221 /************************************************
222 osl_systemPathIsLocalOrParentDirectoryEntry
223 ************************************************/
224
osl_systemPathIsLocalOrParentDirectoryEntry(const rtl_uString * pustrPath)225 sal_Bool SAL_CALL osl_systemPathIsLocalOrParentDirectoryEntry(
226 const rtl_uString* pustrPath)
227 {
228 OSL_PRECOND(pustrPath, "osl_systemPathIsLocalOrParentDirectoryEntry: Invalid parameter");
229
230 rtl::OUString dirent;
231
232 osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &dirent.pData);
233
234 return (
235 (dirent == FPH_LOCAL_DIR_ENTRY()) ||
236 (dirent == FPH_PARENT_DIR_ENTRY())
237 );
238 }
239
240 /***********************************************
241 Simple iterator for a path list separated by
242 the specified character
243 **********************************************/
244
245 class path_list_iterator
246 {
247 public:
248
249 /******************************************
250 constructor
251
252 after construction get_current_item
253 returns the first path in list, no need
254 to call reset first
255 *****************************************/
path_list_iterator(const rtl::OUString & path_list,sal_Unicode list_separator=FPH_CHAR_COLON)256 path_list_iterator(const rtl::OUString& path_list, sal_Unicode list_separator = FPH_CHAR_COLON) :
257 m_path_list(path_list),
258 m_end(m_path_list.getStr() + m_path_list.getLength() + 1),
259 m_separator(list_separator)
260 {
261 reset();
262 }
263
264 /******************************************
265 reset the iterator
266 *****************************************/
reset()267 void reset()
268 {
269 m_path_segment_begin = m_path_segment_end = m_path_list.getStr();
270 advance();
271 }
272
273 /******************************************
274 move the iterator to the next position
275 *****************************************/
next()276 void next()
277 {
278 OSL_PRECOND(!done(), "path_list_iterator: Already done!");
279
280 m_path_segment_begin = ++m_path_segment_end;
281 advance();
282 }
283
284 /******************************************
285 check if done
286 *****************************************/
done() const287 bool done() const
288 {
289 return (m_path_segment_end >= m_end);
290 }
291
292 /******************************************
293 return the current item
294 *****************************************/
get_current_item() const295 rtl::OUString get_current_item() const
296 {
297 return rtl::OUString(
298 m_path_segment_begin,
299 (m_path_segment_end - m_path_segment_begin));
300 }
301
302 private:
303
304 /******************************************
305 move m_path_end to the next separator or
306 to the edn of the string
307 *****************************************/
advance()308 void advance()
309 {
310 while (!done() && *m_path_segment_end && (*m_path_segment_end != m_separator))
311 ++m_path_segment_end;
312
313 OSL_ASSERT(m_path_segment_end <= m_end);
314 }
315
316 private:
317 rtl::OUString m_path_list;
318 const sal_Unicode* m_end;
319 const sal_Unicode m_separator;
320 const sal_Unicode* m_path_segment_begin;
321 const sal_Unicode* m_path_segment_end;
322
323 // prevent copy and assignment
324 private:
325 /******************************************
326 copy constructor
327 remember: do not simply copy m_path_begin
328 and m_path_end because they point to
329 the memory of other.m_path_list!
330 *****************************************/
331 path_list_iterator(const path_list_iterator& other);
332
333 /******************************************
334 assignment operator
335 remember: do not simply copy m_path_begin
336 and m_path_end because they point to
337 the memory of other.m_path_list!
338 *****************************************/
339 path_list_iterator& operator=(const path_list_iterator& other);
340 };
341
342 /************************************************
343 osl_searchPath
344 ***********************************************/
345
osl_searchPath(const rtl_uString * pustrFilePath,const rtl_uString * pustrSearchPathList,rtl_uString ** ppustrPathFound)346 sal_Bool SAL_CALL osl_searchPath(
347 const rtl_uString* pustrFilePath,
348 const rtl_uString* pustrSearchPathList,
349 rtl_uString** ppustrPathFound)
350 {
351 OSL_PRECOND(pustrFilePath && pustrSearchPathList && ppustrPathFound, "osl_searchPath: Invalid parameter");
352
353 bool bfound = false;
354 rtl::OUString fp(const_cast<rtl_uString*>(pustrFilePath));
355 rtl::OUString pl = rtl::OUString(const_cast<rtl_uString*>(pustrSearchPathList));
356 path_list_iterator pli(pl);
357
358 while (!pli.done())
359 {
360 rtl::OUString p = pli.get_current_item();
361 osl::systemPathEnsureSeparator(p);
362 p += fp;
363
364 if (osl::access(p, F_OK) > -1)
365 {
366 bfound = true;
367 rtl_uString_assign(ppustrPathFound, p.pData);
368 break;
369 }
370 pli.next();
371 }
372 return bfound;
373 }
374