57bd2623e5
2008/03/31 13:23:43 rt 1.7.234.1: #i87441# Change license header to LPGL v3.
363 lines
11 KiB
C++
363 lines
11 KiB
C++
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2008 by Sun Microsystems, Inc.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* $RCSfile: file_path_helper.cxx,v $
|
|
* $Revision: 1.8 $
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
#include "precompiled_sal.hxx"
|
|
|
|
/*******************************************
|
|
Includes
|
|
******************************************/
|
|
|
|
#ifndef _OSL_FILE_PATH_HELPER_H_
|
|
#include "file_path_helper.h"
|
|
#endif
|
|
|
|
#ifndef _OSL_FILE_PATH_HELPER_HXX_
|
|
#include "file_path_helper.hxx"
|
|
#endif
|
|
|
|
#ifndef _OSL_UUNXAPI_HXX_
|
|
#include "uunxapi.hxx"
|
|
#endif
|
|
|
|
#ifndef _OSL_DIAGNOSE_H_
|
|
#include <osl/diagnose.h>
|
|
#endif
|
|
|
|
#ifndef _RTL_USTRING_HXX_
|
|
#include <rtl/ustring.hxx>
|
|
#endif
|
|
|
|
/*******************************************
|
|
Constants
|
|
******************************************/
|
|
|
|
const sal_Unicode FPH_CHAR_PATH_SEPARATOR = (sal_Unicode)'/';
|
|
const sal_Unicode FPH_CHAR_DOT = (sal_Unicode)'.';
|
|
const sal_Unicode FPH_CHAR_COLON = (sal_Unicode)':';
|
|
|
|
inline const rtl::OUString FPH_PATH_SEPARATOR()
|
|
{ return rtl::OUString::createFromAscii("/"); }
|
|
inline const rtl::OUString FPH_LOCAL_DIR_ENTRY()
|
|
{ return rtl::OUString::createFromAscii("."); }
|
|
inline const rtl::OUString FPH_PARENT_DIR_ENTRY()
|
|
{ return rtl::OUString::createFromAscii(".."); }
|
|
|
|
/*******************************************
|
|
* osl_systemPathRemoveSeparator
|
|
******************************************/
|
|
|
|
void SAL_CALL osl_systemPathRemoveSeparator(rtl_uString* pustrPath)
|
|
{
|
|
OSL_PRECOND(pustrPath, "osl_systemPathRemoveSeparator: Invalid parameter");
|
|
|
|
// maybe there are more than one separator at end
|
|
// so we run in a loop
|
|
while ((pustrPath->length > 1) && (FPH_CHAR_PATH_SEPARATOR == pustrPath->buffer[pustrPath->length - 1]))
|
|
{
|
|
pustrPath->length--;
|
|
pustrPath->buffer[pustrPath->length] = (sal_Unicode)'\0';
|
|
}
|
|
|
|
OSL_POSTCOND((0 == pustrPath->length) || (1 == pustrPath->length) || \
|
|
(pustrPath->length > 1 && pustrPath->buffer[pustrPath->length - 1] != FPH_CHAR_PATH_SEPARATOR), \
|
|
"osl_systemPathRemoveSeparator: Post condition failed");
|
|
}
|
|
|
|
/*******************************************
|
|
osl_systemPathEnsureSeparator
|
|
******************************************/
|
|
|
|
void SAL_CALL osl_systemPathEnsureSeparator(rtl_uString** ppustrPath)
|
|
{
|
|
OSL_PRECOND(ppustrPath && (NULL != *ppustrPath), \
|
|
"osl_systemPathEnsureSeparator: Invalid parameter");
|
|
|
|
rtl::OUString path(*ppustrPath);
|
|
sal_Int32 lp = path.getLength();
|
|
sal_Int32 i = path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR);
|
|
|
|
if ((lp > 1 && i != (lp - 1)) || ((lp < 2) && i < 0))
|
|
{
|
|
path += FPH_PATH_SEPARATOR();
|
|
rtl_uString_assign(ppustrPath, path.pData);
|
|
}
|
|
|
|
OSL_POSTCOND(path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR) == (path.getLength() - 1), \
|
|
"osl_systemPathEnsureSeparator: Post condition failed");
|
|
}
|
|
|
|
/*******************************************
|
|
* osl_systemPathIsRelativePath
|
|
******************************************/
|
|
|
|
sal_Bool SAL_CALL osl_systemPathIsRelativePath(const rtl_uString* pustrPath)
|
|
{
|
|
OSL_PRECOND(pustrPath, "osl_systemPathIsRelativePath: Invalid parameter");
|
|
return ((0 == pustrPath->length) || (pustrPath->buffer[0] != FPH_CHAR_PATH_SEPARATOR));
|
|
}
|
|
|
|
/******************************************
|
|
* osl_systemPathIsAbsolutePath
|
|
*****************************************/
|
|
|
|
sal_Bool SAL_CALL osl_systemPathIsAbsolutePath(const rtl_uString* pustrPath)
|
|
{
|
|
OSL_PRECOND(pustrPath, "osl_systemPathIsAbsolutePath: Invalid parameter");
|
|
return (!osl_systemPathIsRelativePath(pustrPath));
|
|
}
|
|
|
|
/******************************************
|
|
osl_systemPathMakeAbsolutePath
|
|
*****************************************/
|
|
|
|
void SAL_CALL osl_systemPathMakeAbsolutePath(
|
|
const rtl_uString* pustrBasePath,
|
|
const rtl_uString* pustrRelPath,
|
|
rtl_uString** ppustrAbsolutePath)
|
|
{
|
|
rtl::OUString base(rtl_uString_getStr(const_cast<rtl_uString*>(pustrBasePath)));
|
|
rtl::OUString rel(const_cast<rtl_uString*>(pustrRelPath));
|
|
|
|
if (base.getLength() > 0)
|
|
osl_systemPathEnsureSeparator(&base.pData);
|
|
|
|
base += rel;
|
|
|
|
rtl_uString_acquire(base.pData);
|
|
*ppustrAbsolutePath = base.pData;
|
|
}
|
|
|
|
|
|
/*******************************************
|
|
osl_systemPathGetFileOrLastDirectoryPart
|
|
******************************************/
|
|
|
|
void SAL_CALL osl_systemPathGetFileNameOrLastDirectoryPart(
|
|
const rtl_uString* pustrPath,
|
|
rtl_uString** ppustrFileNameOrLastDirPart)
|
|
{
|
|
OSL_PRECOND(pustrPath && ppustrFileNameOrLastDirPart, \
|
|
"osl_systemPathGetFileNameOrLastDirectoryPart: Invalid parameter");
|
|
|
|
rtl::OUString path(const_cast<rtl_uString*>(pustrPath));
|
|
|
|
osl_systemPathRemoveSeparator(path.pData);
|
|
|
|
rtl::OUString last_part;
|
|
|
|
if (path.getLength() > 1 || (1 == path.getLength() && *path.getStr() != FPH_CHAR_PATH_SEPARATOR))
|
|
{
|
|
sal_Int32 idx_ps = path.lastIndexOf(FPH_CHAR_PATH_SEPARATOR);
|
|
idx_ps++; // always right to increment by one even if idx_ps == -1!
|
|
last_part = rtl::OUString(path.getStr() + idx_ps);
|
|
}
|
|
rtl_uString_assign(ppustrFileNameOrLastDirPart, last_part.pData);
|
|
}
|
|
|
|
|
|
/********************************************
|
|
osl_systemPathIsHiddenFileOrDirectoryEntry
|
|
*********************************************/
|
|
|
|
sal_Bool SAL_CALL osl_systemPathIsHiddenFileOrDirectoryEntry(
|
|
const rtl_uString* pustrPath)
|
|
{
|
|
OSL_PRECOND(pustrPath, "osl_systemPathIsHiddenFileOrDirectoryEntry: Invalid parameter");
|
|
|
|
sal_Bool is_hidden = sal_False;
|
|
|
|
if (pustrPath->length > 0)
|
|
{
|
|
rtl::OUString fdp;
|
|
|
|
osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &fdp.pData);
|
|
|
|
is_hidden = ((fdp.pData->length > 0) && (fdp.pData->buffer[0] == FPH_CHAR_DOT) &&
|
|
!osl_systemPathIsLocalOrParentDirectoryEntry(fdp.pData));
|
|
}
|
|
|
|
return is_hidden;
|
|
}
|
|
|
|
|
|
/************************************************
|
|
osl_systemPathIsLocalOrParentDirectoryEntry
|
|
************************************************/
|
|
|
|
sal_Bool SAL_CALL osl_systemPathIsLocalOrParentDirectoryEntry(
|
|
const rtl_uString* pustrPath)
|
|
{
|
|
OSL_PRECOND(pustrPath, "osl_systemPathIsLocalOrParentDirectoryEntry: Invalid parameter");
|
|
|
|
rtl::OUString dirent;
|
|
|
|
osl_systemPathGetFileNameOrLastDirectoryPart(pustrPath, &dirent.pData);
|
|
|
|
return (
|
|
(dirent == FPH_LOCAL_DIR_ENTRY()) ||
|
|
(dirent == FPH_PARENT_DIR_ENTRY())
|
|
);
|
|
}
|
|
|
|
/***********************************************
|
|
Simple iterator for a path list separated by
|
|
the specified character
|
|
**********************************************/
|
|
|
|
class path_list_iterator
|
|
{
|
|
public:
|
|
|
|
/******************************************
|
|
constructor
|
|
|
|
after construction get_current_item
|
|
returns the first path in list, no need
|
|
to call reset first
|
|
*****************************************/
|
|
path_list_iterator(const rtl::OUString& path_list, sal_Unicode list_separator = FPH_CHAR_COLON) :
|
|
m_path_list(path_list),
|
|
m_end(m_path_list.getStr() + m_path_list.getLength() + 1),
|
|
m_separator(list_separator)
|
|
{
|
|
reset();
|
|
}
|
|
|
|
/******************************************
|
|
reset the iterator
|
|
*****************************************/
|
|
void reset()
|
|
{
|
|
m_path_segment_begin = m_path_segment_end = m_path_list.getStr();
|
|
advance();
|
|
}
|
|
|
|
/******************************************
|
|
move the iterator to the next position
|
|
*****************************************/
|
|
void next()
|
|
{
|
|
OSL_PRECOND(!done(), "path_list_iterator: Already done!");
|
|
|
|
m_path_segment_begin = ++m_path_segment_end;
|
|
advance();
|
|
}
|
|
|
|
/******************************************
|
|
check if done
|
|
*****************************************/
|
|
bool done() const
|
|
{
|
|
return (m_path_segment_end >= m_end);
|
|
}
|
|
|
|
/******************************************
|
|
return the current item
|
|
*****************************************/
|
|
rtl::OUString get_current_item() const
|
|
{
|
|
return rtl::OUString(
|
|
m_path_segment_begin,
|
|
(m_path_segment_end - m_path_segment_begin));
|
|
}
|
|
|
|
private:
|
|
|
|
/******************************************
|
|
move m_path_end to the next separator or
|
|
to the edn of the string
|
|
*****************************************/
|
|
void advance()
|
|
{
|
|
while (!done() && *m_path_segment_end && (*m_path_segment_end != m_separator))
|
|
++m_path_segment_end;
|
|
|
|
OSL_ASSERT(m_path_segment_end <= m_end);
|
|
}
|
|
|
|
private:
|
|
rtl::OUString m_path_list;
|
|
const sal_Unicode* m_end;
|
|
const sal_Unicode m_separator;
|
|
const sal_Unicode* m_path_segment_begin;
|
|
const sal_Unicode* m_path_segment_end;
|
|
|
|
// prevent copy and assignment
|
|
private:
|
|
/******************************************
|
|
copy constructor
|
|
remember: do not simply copy m_path_begin
|
|
and m_path_end because they point to
|
|
the memory of other.m_path_list!
|
|
*****************************************/
|
|
path_list_iterator(const path_list_iterator& other);
|
|
|
|
/******************************************
|
|
assignment operator
|
|
remember: do not simply copy m_path_begin
|
|
and m_path_end because they point to
|
|
the memory of other.m_path_list!
|
|
*****************************************/
|
|
path_list_iterator& operator=(const path_list_iterator& other);
|
|
};
|
|
|
|
/************************************************
|
|
osl_searchPath
|
|
***********************************************/
|
|
|
|
sal_Bool SAL_CALL osl_searchPath(
|
|
const rtl_uString* pustrFilePath,
|
|
const rtl_uString* pustrSearchPathList,
|
|
rtl_uString** ppustrPathFound)
|
|
{
|
|
OSL_PRECOND(pustrFilePath && pustrSearchPathList && ppustrPathFound, "osl_searchPath: Invalid parameter");
|
|
|
|
bool bfound = false;
|
|
rtl::OUString fp(const_cast<rtl_uString*>(pustrFilePath));
|
|
rtl::OUString pl = rtl::OUString(const_cast<rtl_uString*>(pustrSearchPathList));
|
|
path_list_iterator pli(pl);
|
|
|
|
while (!pli.done())
|
|
{
|
|
rtl::OUString p = pli.get_current_item();
|
|
osl::systemPathEnsureSeparator(p);
|
|
p += fp;
|
|
|
|
if (osl::access(p, F_OK) > -1)
|
|
{
|
|
bfound = true;
|
|
rtl_uString_assign(ppustrPathFound, p.pData);
|
|
break;
|
|
}
|
|
pli.next();
|
|
}
|
|
return bfound;
|
|
}
|