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