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

📄 cpl_string.cpp

📁 mitab,读取MapInfo的地图文件
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/**********************************************************************
 * $Id: cpl_string.cpp 10646 2007-01-18 02:38:10Z warmerdam $
 *
 * Name:     cpl_string.cpp
 * Project:  CPL - Common Portability Library
 * Purpose:  String and Stringlist manipulation functions.
 * Author:   Daniel Morissette, danmo@videotron.ca
 *
 **********************************************************************
 * Copyright (c) 1998, Daniel Morissette
 *
 * 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.
 **********************************************************************
 *
 * Independent Security Audit 2003/04/04 Andrey Kiselev:
 *   Completed audit of this module. All functions may be used without buffer
 *   overflows and stack corruptions with any kind of input data strings with
 *   except of CPLSPrintf() and CSLAppendPrintf() (see note below).
 * 
 * Security Audit 2003/03/28 warmerda:
 *   Completed security audit.  I believe that this module may be safely used 
 *   to parse tokenize arbitrary input strings, assemble arbitrary sets of
 *   names values into string lists, unescape and escape text even if provided
 *   by a potentially hostile source.   
 *
 *   CPLSPrintf() and CSLAppendPrintf() may not be safely invoked on 
 *   arbitrary length inputs since it has a fixed size output buffer on system 
 *   without vsnprintf(). 
 *
 **********************************************************************/

#include "cpl_string.h"
#include "cpl_vsi.h"

#if defined(WIN32CE)
#  include <wce_errno.h>
#  include <wce_string.h>
#endif

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

/*=====================================================================
                    StringList manipulation functions.
 =====================================================================*/

/**********************************************************************
 *                       CSLAddString()
 *
 * Append a string to a StringList and return a pointer to the modified
 * StringList.
 * If the input StringList is NULL, then a new StringList is created.
 **********************************************************************/
char **CSLAddString(char **papszStrList, const char *pszNewString)
{
    int nItems=0;

    if (pszNewString == NULL)
        return papszStrList;    /* Nothing to do!*/

    /* Allocate room for the new string */
    if (papszStrList == NULL)
        papszStrList = (char**) CPLCalloc(2,sizeof(char*));
    else
    {
        nItems = CSLCount(papszStrList);
        papszStrList = (char**)CPLRealloc(papszStrList, 
                                          (nItems+2)*sizeof(char*));
    }

    /* Copy the string in the list */
    papszStrList[nItems] = CPLStrdup(pszNewString);
    papszStrList[nItems+1] = NULL;

    return papszStrList;
}

/**********************************************************************
 *                       CSLCount()
 *
 * Return the number of lines in a Stringlist.
 **********************************************************************/
int CSLCount(char **papszStrList)
{
    int nItems=0;

    if (papszStrList)
    {
        while(*papszStrList != NULL)
        {
            nItems++;
            papszStrList++;
        }
    }

    return nItems;
}


/************************************************************************/
/*                            CSLGetField()                             */
/*                                                                      */
/*      Fetches the indicated field, being careful not to crash if      */
/*      the field doesn't exist within this string list.  The           */
/*      returned pointer should not be freed, and doesn't               */
/*      necessarily last long.                                          */
/************************************************************************/

const char * CSLGetField( char ** papszStrList, int iField )

{
    int         i;

    if( papszStrList == NULL || iField < 0 )
        return( "" );

    for( i = 0; i < iField+1; i++ )
    {
        if( papszStrList[i] == NULL )
            return "";
    }

    return( papszStrList[iField] );
}

/**********************************************************************
 *                       CSLDestroy()
 *
 * Free all memory used by a StringList.
 **********************************************************************/
void CPL_STDCALL CSLDestroy(char **papszStrList)
{
    char **papszPtr;

    if (papszStrList)
    {
        papszPtr = papszStrList;
        while(*papszPtr != NULL)
        {
            CPLFree(*papszPtr);
            papszPtr++;
        }

        CPLFree(papszStrList);
    }
}


/**********************************************************************
 *                       CSLDuplicate()
 *
 * Allocate and return a copy of a StringList.
 **********************************************************************/
char    **CSLDuplicate(char **papszStrList)
{
    char **papszNewList, **papszSrc, **papszDst;
    int  nLines;

    nLines = CSLCount(papszStrList);

    if (nLines == 0)
        return NULL;

    papszNewList = (char **)CPLMalloc((nLines+1)*sizeof(char*));
    papszSrc = papszStrList;
    papszDst = papszNewList;

    while(*papszSrc != NULL)
    {
        *papszDst = CPLStrdup(*papszSrc);

        papszSrc++;
        papszDst++;
    }
    *papszDst = NULL;

    return papszNewList;
}

/************************************************************************/
/*                               CSLMerge                               */
/************************************************************************/

/**
 * \brief Merge two lists.
 *
 * The two lists are merged, ensuring that if any keys appear in both
 * that the value from the second (papszOverride) list take precidence.
 *
 * @param papszOrig the original list, being modified.
 * @param papszOverride the list of items being merged in.  This list
 * is unaltered and remains owned by the caller.
 *
 * @return updated list.
 */

char **CSLMerge( char **papszOrig, char **papszOverride )

{
    int i;

    if( papszOrig == NULL && papszOverride != NULL )
        return CSLDuplicate( papszOverride );
    
    if( papszOverride == NULL )
        return papszOrig;

    for( i = 0; papszOverride[i] != NULL; i++ )
    {
        char *pszKey = NULL;
        const char *pszValue = CPLParseNameValue( papszOverride[i], &pszKey );

        papszOrig = CSLSetNameValue( papszOrig, pszKey, pszValue );
        CPLFree( pszKey );
    }

    return papszOrig;
}

/**********************************************************************
 *                       CSLLoad()
 *
 * Load a test file into a stringlist.
 *
 * Lines are limited in length by the size of the CPLReadLine() buffer.
 **********************************************************************/
char **CSLLoad(const char *pszFname)
{
    FILE        *fp;
    const char  *pszLine;
    char        **papszStrList=NULL;

    fp = VSIFOpenL(pszFname, "rb");

    if (fp)
    {
        while(!VSIFEofL(fp))
        {
            if ( (pszLine = CPLReadLineL(fp)) != NULL )
            {
                papszStrList = CSLAddString(papszStrList, pszLine);
            }
        }

        VSIFCloseL(fp);

        CPLReadLineL( NULL );
    }
    else
    {
        /* Unable to open file */
        CPLError(CE_Failure, CPLE_OpenFailed,
                 "CSLLoad(%s): %s", pszFname, strerror(errno));
    }

    return papszStrList;
}

/**********************************************************************
 *                       CSLSave()
 *
 * Write a stringlist to a text file.
 *
 * Returns the number of lines written, or 0 if the file could not 
 * be written.
 **********************************************************************/
int  CSLSave(char **papszStrList, const char *pszFname)
{
    FILE    *fp;
    int     nLines = 0;

    if (papszStrList)
    {
        if ((fp = VSIFOpen(pszFname, "wt")) != NULL)
        {
            while(*papszStrList != NULL)
            {
                if (VSIFPuts(*papszStrList, fp) == EOF ||
                    VSIFPutc('\n', fp) == EOF)
                {
                    CPLError(CE_Failure, CPLE_FileIO,
                             "CSLSave(%s): %s", pszFname, 
                             strerror(errno));
                    break;  /* A Problem happened... abort */
                }

                nLines++;
                papszStrList++;
            }

            VSIFClose(fp);
        }
        else
        {
            /* Unable to open file */
            CPLError(CE_Failure, CPLE_OpenFailed,
                     "CSLSave(%s): %s", pszFname, strerror(errno));
        }
    }

    return nLines;
}

/**********************************************************************
 *                       CSLPrint()
 *
 * Print a StringList to fpOut.  If fpOut==NULL, then output is sent
 * to stdout.
 *
 * Returns the number of lines printed.
 **********************************************************************/
int  CSLPrint(char **papszStrList, FILE *fpOut)
{
    int     nLines=0;

    if (fpOut == NULL)
        fpOut = stdout;

    if (papszStrList)
    {
        while(*papszStrList != NULL)
        {
            VSIFPrintf(fpOut, "%s\n", *papszStrList);
            nLines++;
            papszStrList++;
        }
    }

    return nLines;
}


/**********************************************************************
 *                       CSLInsertStrings()
 *
 * Copies the contents of a StringList inside another StringList 
 * before the specified line.
 *
 * nInsertAtLineNo is a 0-based line index before which the new strings
 * should be inserted.  If this value is -1 or is larger than the actual 
 * number of strings in the list then the strings are added at the end
 * of the source StringList.
 *
 * Returns the modified StringList.
 **********************************************************************/
char **CSLInsertStrings(char **papszStrList, int nInsertAtLineNo, 
                        char **papszNewLines)
{
    int     i, nSrcLines, nDstLines, nToInsert;
    char    **ppszSrc, **ppszDst;

    if (papszNewLines == NULL ||
        ( nToInsert = CSLCount(papszNewLines) ) == 0)
        return papszStrList;    /* Nothing to do!*/

    nSrcLines = CSLCount(papszStrList);
    nDstLines = nSrcLines + nToInsert;

    /* Allocate room for the new strings */
    papszStrList = (char**)CPLRealloc(papszStrList, 
                                      (nDstLines+1)*sizeof(char*));

    /* Make sure the array is NULL-terminated... it may not be if
     * papszStrList was NULL before Realloc()
     */
    papszStrList[nSrcLines] = NULL;

    /* Make some room in the original list at the specified location 
     * Note that we also have to move the NULL pointer at the end of
     * the source StringList.
     */
    if (nInsertAtLineNo == -1 || nInsertAtLineNo > nSrcLines)
        nInsertAtLineNo = nSrcLines;

    ppszSrc = papszStrList + nSrcLines;
    ppszDst = papszStrList + nDstLines;

    for (i=nSrcLines; i>=nInsertAtLineNo; i--)
    {
        *ppszDst = *ppszSrc;
        ppszDst--;
        ppszSrc--;
    }

    /* Copy the strings to the list */
    ppszSrc = papszNewLines;

⌨️ 快捷键说明

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