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