xref: /AOO41X/main/sal/osl/os2/file_path_helper.cxx (revision 87d2adbc9cadf14644c3679b041b9226f7630199)
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