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 /******************************************* 29 Includes 30 ******************************************/ 31 32 #ifndef _OSL_THREAD_H_ 33 #include "osl/thread.h" 34 #endif 35 36 #ifndef _OSL_FILE_PATH_HELPER_H_ 37 #include "file_path_helper.h" 38 #endif 39 40 #ifndef _OSL_FILE_PATH_HELPER_HXX_ 41 #include "file_path_helper.hxx" 42 #endif 43 44 #ifndef _OSL_UUNXAPI_HXX_ 45 #include "uunxapi.hxx" 46 #endif 47 48 #ifndef _OSL_DIAGNOSE_H_ 49 #include <osl/diagnose.h> 50 #endif 51 52 #ifndef _RTL_USTRING_HXX_ 53 #include <rtl/ustring.hxx> 54 #endif 55 56 /******************************************* 57 Constants 58 ******************************************/ 59 60 const sal_Unicode FPH_CHAR_PATH_SEPARATOR = (sal_Unicode)'\\'; 61 const sal_Unicode FPH_CHAR_DOT = (sal_Unicode)'.'; 62 const sal_Unicode FPH_CHAR_COLON = (sal_Unicode)':'; 63 64 inline const rtl::OUString FPH_PATH_SEPARATOR() 65 { return rtl::OUString::createFromAscii("\\"); } 66 inline const rtl::OUString FPH_LOCAL_DIR_ENTRY() 67 { return rtl::OUString::createFromAscii("."); } 68 inline const rtl::OUString FPH_PARENT_DIR_ENTRY() 69 { return rtl::OUString::createFromAscii(".."); } 70 71 /******************************************* 72 * osl_systemPathRemoveSeparator 73 ******************************************/ 74 75 void SAL_CALL osl_systemPathRemoveSeparator(rtl_uString* pustrPath) 76 { 77 OSL_PRECOND(pustrPath, "osl_systemPathRemoveSeparator: Invalid parameter"); 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 osl_systemPathEnsureSeparator 94 ******************************************/ 95 96 void SAL_CALL osl_systemPathEnsureSeparator(rtl_uString** ppustrPath) 97 { 98 OSL_PRECOND(ppustrPath && (NULL != *ppustrPath), \ 99 "osl_systemPathEnsureSeparator: Invalid parameter"); 100 101 rtl::OUString path(*ppustrPath); 102 sal_Int32 lp = path.getLength(); 103 sal_Int32 i = path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR); 104 105 if ((lp > 1 && i != (lp - 1)) || ((lp < 2) && i < 0)) 106 { 107 path += FPH_PATH_SEPARATOR(); 108 rtl_uString_assign(ppustrPath, path.pData); 109 } 110 111 OSL_POSTCOND(path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR) == (path.getLength() - 1), \ 112 "osl_systemPathEnsureSeparator: Post condition failed"); 113 } 114 115 /******************************************* 116 * osl_systemPathIsRelativePath 117 ******************************************/ 118 119 sal_Bool SAL_CALL osl_systemPathIsRelativePath(const rtl_uString* pustrPath) 120 { 121 OSL_PRECOND(pustrPath, "osl_systemPathIsRelativePath: Invalid parameter"); 122 return (!osl_systemPathIsAbsolutePath(pustrPath)); 123 } 124 125 /****************************************** 126 * osl_systemPathIsAbsolutePath 127 *****************************************/ 128 129 sal_Bool SAL_CALL osl_systemPathIsAbsolutePath(const rtl_uString* pustrPath) 130 { 131 OSL_PRECOND(pustrPath, "osl_systemPathIsAbsolutePath: Invalid parameter"); 132 if (pustrPath->length == 0) 133 return sal_False; 134 if (pustrPath->buffer[0] == FPH_CHAR_PATH_SEPARATOR) 135 return sal_True; 136 if (pustrPath->buffer[1] == FPH_CHAR_COLON 137 && pustrPath->buffer[2] == FPH_CHAR_PATH_SEPARATOR) 138 return sal_True; 139 return sal_False; 140 } 141 142 /****************************************** 143 osl_systemPathMakeAbsolutePath 144 *****************************************/ 145 146 void SAL_CALL osl_systemPathMakeAbsolutePath( 147 const rtl_uString* pustrBasePath, 148 const rtl_uString* pustrRelPath, 149 rtl_uString** ppustrAbsolutePath) 150 { 151 rtl::OUString base(rtl_uString_getStr(const_cast<rtl_uString*>(pustrBasePath))); 152 rtl::OUString rel(const_cast<rtl_uString*>(pustrRelPath)); 153 154 if (base.getLength() > 0) 155 osl_systemPathEnsureSeparator(&base.pData); 156 157 base += rel; 158 159 rtl_uString_acquire(base.pData); 160 *ppustrAbsolutePath = base.pData; 161 } 162 163 164 /***************************************** 165 osl_systemPathGetParent 166 ****************************************/ 167 168 sal_Int32 SAL_CALL osl_systemPathGetParent(rtl_uString* pustrPath) 169 { 170 return 0; 171 } 172 173 /******************************************* 174 osl_systemPathGetFileOrLastDirectoryPart 175 ******************************************/ 176 177 void SAL_CALL osl_systemPathGetFileNameOrLastDirectoryPart( 178 const rtl_uString* pustrPath, 179 rtl_uString** ppustrFileNameOrLastDirPart) 180 { 181 OSL_PRECOND(pustrPath && ppustrFileNameOrLastDirPart, \ 182 "osl_systemPathGetFileNameOrLastDirectoryPart: Invalid parameter"); 183 184 rtl::OUString path(const_cast<rtl_uString*>(pustrPath)); 185 186 osl_systemPathRemoveSeparator(path.pData); 187 188 rtl::OUString last_part; 189 190 if (path.getLength() > 1 || (1 == path.getLength() && *path.getStr() != FPH_CHAR_PATH_SEPARATOR)) 191 { 192 sal_Int32 idx_ps = path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR); 193 idx_ps++; // always right to increment by one even if idx_ps == -1! 194 last_part = rtl::OUString(path.getStr() + idx_ps); 195 } 196 rtl_uString_assign(ppustrFileNameOrLastDirPart, last_part.pData); 197 } 198 199 200 /******************************************** 201 osl_systemPathIsHiddenFileOrDirectoryEntry 202 *********************************************/ 203 204 sal_Bool SAL_CALL osl_systemPathIsHiddenFileOrDirectoryEntry( 205 const rtl_uString* pustrPath) 206 { 207 OSL_PRECOND(pustrPath, "osl_systemPathIsHiddenFileOrDirectoryEntry: Invalid parameter"); 208 209 sal_Bool is_hidden = sal_False; 210 211 if (pustrPath->length > 0) 212 { 213 rtl::OUString fdp; 214 215 osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &fdp.pData); 216 217 is_hidden = ((fdp.pData->length > 0) && (fdp.pData->buffer[0] == FPH_CHAR_DOT) && 218 !osl_systemPathIsLocalOrParentDirectoryEntry(fdp.pData)); 219 } 220 221 return is_hidden; 222 } 223 224 225 /************************************************ 226 osl_systemPathIsLocalOrParentDirectoryEntry 227 ************************************************/ 228 229 sal_Bool SAL_CALL osl_systemPathIsLocalOrParentDirectoryEntry( 230 const rtl_uString* pustrPath) 231 { 232 OSL_PRECOND(pustrPath, "osl_systemPathIsLocalOrParentDirectoryEntry: Invalid parameter"); 233 234 rtl::OUString dirent; 235 236 osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &dirent.pData); 237 238 return ( 239 (dirent == FPH_LOCAL_DIR_ENTRY()) || 240 (dirent == FPH_PARENT_DIR_ENTRY()) 241 ); 242 } 243 244 /*********************************************** 245 Simple iterator for a path list separated by 246 the specified character 247 **********************************************/ 248 249 class path_list_iterator 250 { 251 public: 252 253 /****************************************** 254 constructor 255 256 after construction get_current_item 257 returns the first path in list, no need 258 to call reset first 259 *****************************************/ 260 path_list_iterator(const rtl::OUString& path_list, sal_Unicode list_separator = FPH_CHAR_COLON) : 261 m_path_list(path_list), 262 m_end(m_path_list.getStr() + m_path_list.getLength() + 1), 263 m_separator(list_separator) 264 { 265 reset(); 266 } 267 268 /****************************************** 269 reset the iterator 270 *****************************************/ 271 void reset() 272 { 273 m_path_segment_begin = m_path_segment_end = m_path_list.getStr(); 274 advance(); 275 } 276 277 /****************************************** 278 move the iterator to the next position 279 *****************************************/ 280 void next() 281 { 282 OSL_PRECOND(!done(), "path_list_iterator: Already done!"); 283 284 m_path_segment_begin = ++m_path_segment_end; 285 advance(); 286 } 287 288 /****************************************** 289 check if done 290 *****************************************/ 291 bool done() const 292 { 293 return (m_path_segment_end >= m_end); 294 } 295 296 /****************************************** 297 return the current item 298 *****************************************/ 299 rtl::OUString get_current_item() const 300 { 301 return rtl::OUString( 302 m_path_segment_begin, 303 (m_path_segment_end - m_path_segment_begin)); 304 } 305 306 private: 307 308 /****************************************** 309 move m_path_end to the next separator or 310 to the edn of the string 311 *****************************************/ 312 void advance() 313 { 314 while (!done() && *m_path_segment_end && (*m_path_segment_end != m_separator)) 315 ++m_path_segment_end; 316 317 OSL_ASSERT(m_path_segment_end <= m_end); 318 } 319 320 private: 321 rtl::OUString m_path_list; 322 const sal_Unicode* m_end; 323 const sal_Unicode m_separator; 324 const sal_Unicode* m_path_segment_begin; 325 const sal_Unicode* m_path_segment_end; 326 327 // prevent copy and assignment 328 private: 329 /****************************************** 330 copy constructor 331 remember: do not simply copy m_path_begin 332 and m_path_end because they point to 333 the memory of other.m_path_list! 334 *****************************************/ 335 path_list_iterator(const path_list_iterator& other); 336 337 /****************************************** 338 assignment operator 339 remember: do not simply copy m_path_begin 340 and m_path_end because they point to 341 the memory of other.m_path_list! 342 *****************************************/ 343 path_list_iterator& operator=(const path_list_iterator& other); 344 }; 345 346 /************************************************ 347 osl_searchPath 348 ***********************************************/ 349 350 sal_Bool SAL_CALL osl_searchPath( 351 const rtl_uString* pustrFilePath, 352 const rtl_uString* pustrSearchPathList, 353 rtl_uString** ppustrPathFound) 354 { 355 OSL_PRECOND(pustrFilePath && pustrSearchPathList && ppustrPathFound, "osl_searchPath: Invalid parameter"); 356 357 bool bfound = false; 358 rtl::OUString fp(const_cast<rtl_uString*>(pustrFilePath)); 359 rtl::OUString pl = rtl::OUString(const_cast<rtl_uString*>(pustrSearchPathList)); 360 path_list_iterator pli(pl); 361 362 while (!pli.done()) 363 { 364 rtl::OUString p = pli.get_current_item(); 365 osl::systemPathEnsureSeparator(p); 366 p += fp; 367 368 if (osl::access(p, F_OK) > -1) 369 { 370 bfound = true; 371 rtl_uString_assign(ppustrPathFound, p.pData); 372 break; 373 } 374 pli.next(); 375 } 376 return bfound; 377 } 378