📄 cplstring.cpp
字号:
#include "stdafx.h"#include "CplString.h"#include "CplVsi.h"CPL_CVSID("$Id: cpl_string.cpp,v 1.37 2003/12/02 15:56:47 warmerda Exp $");/*===================================================================== 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 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;}/********************************************************************** * 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 = VSIFOpen(pszFname, "rb"); if (fp) { while(!VSIFEof(fp)) { if ( (pszLine = CPLReadLine(fp)) != NULL ) { papszStrList = CSLAddString(papszStrList, pszLine); } } VSIFClose(fp); CPLReadLine( 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; ppszDst = papszStrList + nInsertAtLineNo; for (; *ppszSrc != NULL; ppszSrc++, ppszDst++) { *ppszDst = CPLStrdup(*ppszSrc); } return papszStrList;}/********************************************************************** * CSLInsertString() * * Insert a string at a given line number inside a StringList * * nInsertAtLineNo is a 0-based line index before which the new string * should be inserted. If this value is -1 or is larger than the actual * number of strings in the list then the string is added at the end * of the source StringList. * * Returns the modified StringList. **********************************************************************/char **CSLInsertString(char **papszStrList, int nInsertAtLineNo, char *pszNewLine){ char *apszList[2]; /* Create a temporary StringList and call CSLInsertStrings() */ apszList[0] = pszNewLine; apszList[1] = NULL; return CSLInsertStrings(papszStrList, nInsertAtLineNo, apszList);}/********************************************************************** * CSLRemoveStrings() * * Remove strings inside a StringList * * nFirstLineToDelete is the 0-based line index of the first line to * remove. If this value is -1 or is larger than the actual * number of strings in list then the nNumToRemove last strings are * removed. * * If ppapszRetStrings != NULL then the deleted strings won't be * free'd, they will be stored in a new StringList and the pointer to * this new list will be returned in *ppapszRetStrings. * * Returns the modified StringList. **********************************************************************/char **CSLRemoveStrings(char **papszStrList, int nFirstLineToDelete, int nNumToRemove, char ***ppapszRetStrings){ int i, nSrcLines, nDstLines; char **ppszSrc, **ppszDst; nSrcLines = CSLCount(papszStrList); nDstLines = nSrcLines - nNumToRemove; if (nNumToRemove < 1 || nSrcLines == 0) return papszStrList; /* Nothing to do!*/ /* If operation will result in an empty StringList then don't waste * time here! */ if (nDstLines < 1) { CSLDestroy(papszStrList); return NULL; } /* Remove lines from the source StringList... * Either free() each line or store them to a new StringList depending on * the caller's choice. */ ppszDst = papszStrList + nFirstLineToDelete; if (ppapszRetStrings == NULL) { /* free() all the strings that will be removed. */ for (i=0; i < nNumToRemove; i++) { CPLFree(*ppszDst); *ppszDst = NULL; } } else { /* Store the strings to remove in a new StringList */ *ppapszRetStrings = (char **)CPLCalloc(nNumToRemove+1, sizeof(char*)); for (i=0; i < nNumToRemove; i++) { (*ppapszRetStrings)[i] = *ppszDst; *ppszDst = NULL; ppszDst++; } } /* Shift down all the lines that follow the lines to remove. */ if (nFirstLineToDelete == -1 || nFirstLineToDelete > nSrcLines) nFirstLineToDelete = nDstLines; ppszSrc = papszStrList + nFirstLineToDelete + nNumToRemove; ppszDst = papszStrList + nFirstLineToDelete; for ( ; *ppszSrc != NULL; ppszSrc++, ppszDst++) { *ppszDst = *ppszSrc; } /* Move the NULL pointer at the end of the StringList */ *ppszDst = *ppszSrc; /* At this point, we could realloc() papszStrList to a smaller size, but * since this array will likely grow again in further operations on the * StringList we'll leave it as it is. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -