xref: /aoo41x/main/sal/osl/unx/file_path_helper.cxx (revision 87d2adbc)
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