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 60 inline const rtl::OUString FPH_PATH_SEPARATOR() 61 { return rtl::OUString::createFromAscii("\\"); } 62 inline const rtl::OUString FPH_LOCAL_DIR_ENTRY() 63 { return rtl::OUString::createFromAscii("."); } 64 inline const rtl::OUString FPH_PARENT_DIR_ENTRY() 65 { return rtl::OUString::createFromAscii(".."); } 66 67 /******************************************* 68 * osl_systemPathRemoveSeparator 69 ******************************************/ 70 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 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 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 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 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 164 sal_Int32 SAL_CALL osl_systemPathGetParent(rtl_uString* pustrPath) 165 { 166 return 0; 167 } 168 169 /******************************************* 170 osl_systemPathGetFileOrLastDirectoryPart 171 ******************************************/ 172 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 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 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 *****************************************/ 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 *****************************************/ 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 *****************************************/ 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 *****************************************/ 287 bool done() const 288 { 289 return (m_path_segment_end >= m_end); 290 } 291 292 /****************************************** 293 return the current item 294 *****************************************/ 295 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 *****************************************/ 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 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