⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpl_path.cpp

📁 mitab,读取MapInfo的地图文件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**********************************************************************
 * $Id: cpl_path.cpp 10646 2007-01-18 02:38:10Z warmerdam $
 *
 * Project:  CPL - Common Portability Library
 * Purpose:  Portable filename/path parsing, and forming ala "Glob API".
 * Author:   Frank Warmerdam, warmerda@home.com
 *
 **********************************************************************
 * Copyright (c) 1999, Frank Warmerdam
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 * DEALINGS IN THE SOFTWARE.
 ****************************************************************************/

#include "cpl_conv.h"
#include "cpl_string.h"
#include "cpl_multiproc.h"

CPL_CVSID("$Id: cpl_path.cpp 10646 2007-01-18 02:38:10Z warmerdam $");


/* should be size of larged possible filename */
#define CPL_PATH_BUF_SIZE 2048

#if defined(WIN32) || defined(WIN32CE)
#define SEP_CHAR '\\'
#define SEP_STRING "\\"
#else
#define SEP_CHAR '/'
#define SEP_STRING "/"
#endif

/************************************************************************/
/*                         CPLGetStaticResult()                         */
/************************************************************************/

static char *CPLGetStaticResult()

{
    char *pszStaticResult = (char *) CPLGetTLS( CTLS_PATHBUF );
    if( pszStaticResult == NULL )
    {
        pszStaticResult = (char *) CPLMalloc(CPL_PATH_BUF_SIZE);
        CPLSetTLS( CTLS_PATHBUF, pszStaticResult, TRUE );
    }

    return pszStaticResult;
}


/************************************************************************/
/*                        CPLFindFilenameStart()                        */
/************************************************************************/

static int CPLFindFilenameStart( const char * pszFilename )

{
    size_t  iFileStart;

    for( iFileStart = strlen(pszFilename);
         iFileStart > 0
             && pszFilename[iFileStart-1] != '/'
             && pszFilename[iFileStart-1] != '\\';
         iFileStart-- ) {}

    return (int)iFileStart;
}

/************************************************************************/
/*                             CPLGetPath()                             */
/************************************************************************/

/**
 * Extract directory path portion of filename.
 *
 * Returns a string containing the directory path portion of the passed
 * filename.  If there is no path in the passed filename an empty string
 * will be returned (not NULL).
 *
 * <pre>
 * CPLGetPath( "abc/def.xyz" ) == "abc"
 * CPLGetPath( "/abc/def/" ) == "/abc/def"
 * CPLGetPath( "/" ) == "/"
 * CPLGetPath( "/abc/def" ) == "/abc"
 * CPLGetPath( "abc" ) == ""
 * </pre>
 *
 * @param pszFilename the filename potentially including a path.
 *
 *  @return Path in an internal string which must not be freed.  The string
 * may be destroyed by the next CPL filename handling call.  The returned
 * will generally not contain a trailing path separator.
 */

const char *CPLGetPath( const char *pszFilename )

{
    int         iFileStart = CPLFindFilenameStart(pszFilename);
    char       *pszStaticResult = CPLGetStaticResult();

    CPLAssert( iFileStart < CPL_PATH_BUF_SIZE );

    if( iFileStart == 0 )
    {
        strcpy( pszStaticResult, "" );
        return pszStaticResult;
    }

    strncpy( pszStaticResult, pszFilename, iFileStart );
    pszStaticResult[iFileStart] = '\0';

    if( iFileStart > 1
        && (pszStaticResult[iFileStart-1] == '/'
            || pszStaticResult[iFileStart-1] == '\\') )
        pszStaticResult[iFileStart-1] = '\0';

    return pszStaticResult;
}

/************************************************************************/
/*                             CPLGetDirname()                          */
/************************************************************************/

/**
 * Extract directory path portion of filename.
 *
 * Returns a string containing the directory path portion of the passed
 * filename.  If there is no path in the passed filename the dot will be
 * returned.  It is the only difference from CPLGetPath().
 *
 * <pre>
 * CPLGetDirname( "abc/def.xyz" ) == "abc"
 * CPLGetDirname( "/abc/def/" ) == "/abc/def"
 * CPLGetDirname( "/" ) == "/"
 * CPLGetDirname( "/abc/def" ) == "/abc"
 * CPLGetDirname( "abc" ) == "."
 * </pre>
 *
 * @param pszFilename the filename potentially including a path.
 *
 * @return Path in an internal string which must not be freed.  The string
 * may be destroyed by the next CPL filename handling call.  The returned
 * will generally not contain a trailing path separator.
 */

const char *CPLGetDirname( const char *pszFilename )

{
    int         iFileStart = CPLFindFilenameStart(pszFilename);
    char       *pszStaticResult = CPLGetStaticResult();

    CPLAssert( iFileStart < CPL_PATH_BUF_SIZE );

    if( iFileStart == 0 )
    {
        strcpy( pszStaticResult, "." );
        return pszStaticResult;
    }

    strncpy( pszStaticResult, pszFilename, iFileStart );
    pszStaticResult[iFileStart] = '\0';

    if( iFileStart > 1
        && (pszStaticResult[iFileStart-1] == '/'
            || pszStaticResult[iFileStart-1] == '\\') )
        pszStaticResult[iFileStart-1] = '\0';

    return pszStaticResult;
}

/************************************************************************/
/*                           CPLGetFilename()                           */
/************************************************************************/

/**
 * Extract non-directory portion of filename.
 *
 * Returns a string containing the bare filename portion of the passed
 * filename.  If there is no filename (passed value ends in trailing directory
 * separator) an empty string is returned.
 *
 * <pre>
 * CPLGetFilename( "abc/def.xyz" ) == "def.xyz"
 * CPLGetFilename( "/abc/def/" ) == ""
 * CPLGetFilename( "abc/def" ) == "def"
 * </pre>
 *
 * @param pszFullFilename the full filename potentially including a path.
 *
 *  @return just the non-directory portion of the path in an internal string
 * which must not be freed.  The string
 * may be destroyed by the next CPL filename handling call.
 */

const char *CPLGetFilename( const char *pszFullFilename )

{
    int iFileStart = CPLFindFilenameStart( pszFullFilename );
    char       *pszStaticResult = CPLGetStaticResult();

    strncpy( pszStaticResult, pszFullFilename + iFileStart, 
             CPL_PATH_BUF_SIZE );
    pszStaticResult[CPL_PATH_BUF_SIZE - 1] = '\0';

    return pszStaticResult;
}

/************************************************************************/
/*                           CPLGetBasename()                           */
/************************************************************************/

/**
 * Extract basename (non-directory, non-extension) portion of filename.
 *
 * Returns a string containing the file basename portion of the passed
 * name.  If there is no basename (passed value ends in trailing directory
 * separator, or filename starts with a dot) an empty string is returned.
 *
 * <pre>
 * CPLGetBasename( "abc/def.xyz" ) == "def"
 * CPLGetBasename( "abc/def" ) == "def"
 * CPLGetBasename( "abc/def/" ) == ""
 * </pre>
 *
 * @param pszFullFilename the full filename potentially including a path.
 *
 * @return just the non-directory, non-extension portion of the path in
 * an internal string which must not be freed.  The string
 * may be destroyed by the next CPL filename handling call.
 */

const char *CPLGetBasename( const char *pszFullFilename )

{
    size_t  iFileStart = CPLFindFilenameStart( pszFullFilename );
    size_t  iExtStart, nLength;
    char    *pszStaticResult = CPLGetStaticResult();

    for( iExtStart = strlen(pszFullFilename);
         iExtStart > iFileStart && pszFullFilename[iExtStart] != '.';
         iExtStart-- ) {}

    if( iExtStart == iFileStart )
        iExtStart = strlen(pszFullFilename);

    nLength = iExtStart - iFileStart;

    CPLAssert( nLength < CPL_PATH_BUF_SIZE );

    strncpy( pszStaticResult, pszFullFilename + iFileStart, nLength );
    pszStaticResult[nLength] = '\0';

    return pszStaticResult;
}


/************************************************************************/
/*                           CPLGetExtension()                          */
/************************************************************************/

/**
 * Extract filename extension from full filename.
 *
 * Returns a string containing the extention portion of the passed
 * name.  If there is no extension (the filename has no dot) an empty string
 * is returned.  The returned extension will not include the period.
 *
 * <pre>
 * CPLGetExtension( "abc/def.xyz" ) == "xyz"
 * CPLGetExtension( "abc/def" ) == ""
 * </pre>
 *
 * @param pszFullFilename the full filename potentially including a path.
 *
 * @return just the extension portion of the path in
 * an internal string which must not be freed.  The string
 * may be destroyed by the next CPL filename handling call.
 */

const char *CPLGetExtension( const char *pszFullFilename )

{
    size_t  iFileStart = CPLFindFilenameStart( pszFullFilename );
    size_t  iExtStart;
    char    *pszStaticResult = CPLGetStaticResult();

    for( iExtStart = strlen(pszFullFilename);
         iExtStart > iFileStart && pszFullFilename[iExtStart] != '.';
         iExtStart-- ) {}

    if( iExtStart == iFileStart )
        iExtStart = strlen(pszFullFilename)-1;

    strncpy( pszStaticResult, pszFullFilename+iExtStart+1, CPL_PATH_BUF_SIZE );
    pszStaticResult[CPL_PATH_BUF_SIZE - 1] = '\0';

    return pszStaticResult;
}

/************************************************************************/
/*                         CPLGetCurrentDir()                           */
/************************************************************************/

/**
 * Get the current working directory name.
 *
 * @return a pointer to buffer, containing current working directory path
 * or NULL in case of error.  User is responsible to free that buffer
 * after usage with CPLFree() function.
 * If HAVE_GETCWD macro is not defined, the function returns NULL.
 **/

char *CPLGetCurrentDir()

{
    size_t  nPathMax;
    char    *pszDirPath;

# ifdef _MAX_PATH
    nPathMax = _MAX_PATH;
# elif PATH_MAX
    nPathMax = PATH_MAX;
# else
    nPathMax = 8192;
# endif

    pszDirPath = (char*)CPLMalloc( nPathMax );
    if ( !pszDirPath )
        return NULL;

#ifdef HAVE_GETCWD
    return getcwd( pszDirPath, nPathMax );
#else
    return NULL;
#endif /* HAVE_GETCWD */
}

/************************************************************************/
/*                         CPLResetExtension()                          */
/************************************************************************/

/**
 * Replace the extension with the provided one.
 *
 * @param pszPath the input path, this string is not altered.
 * @param pszExt the new extension to apply to the given path.
 *
 * @return an altered filename with the new extension.    Do not
 * modify or free the returned string.  The string may be destroyed by the
 * next CPL call.
 */

const char *CPLResetExtension( const char *pszPath, const char *pszExt )

{
    char    *pszStaticResult = CPLGetStaticResult();
    size_t  i;

/* -------------------------------------------------------------------- */
/*      First, try and strip off any existing extension.                */
/* -------------------------------------------------------------------- */
    strncpy( pszStaticResult, pszPath, CPL_PATH_BUF_SIZE );
    pszStaticResult[CPL_PATH_BUF_SIZE - 1] = '\0';
    for( i = strlen(pszStaticResult) - 1; i > 0; i-- )
    {
        if( pszStaticResult[i] == '.' )
        {
            pszStaticResult[i] = '\0';
            break;
        }

        if( pszStaticResult[i] == '/' || pszStaticResult[i] == '\\' 
            || pszStaticResult[i] == ':' )
            break;
    }

/* -------------------------------------------------------------------- */
/*      Append the new extension.                                       */
/* -------------------------------------------------------------------- */
    CPLAssert( strlen(pszExt) + 2 < CPL_PATH_BUF_SIZE );
    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -