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