📄 ugk_string.cpp
字号:
// ugk_string.cpp/////////////////////////////////////////////////////////////////////////////#include <errno.h>#include "ugk_string.h"#include "ugk_errhandle.h"#include "ugk_memopr.h"#include "ugkglobal.h"char *UGKStrdup( const char * pszString ){ char *pszReturn; if( pszString == NULL ) pszString = ""; pszReturn = strdup( pszString ); if( pszReturn == NULL ) { UGKError( ET_Fatal, UGKErr_OutOfMemory, "UGKStrdup(): Out of memory allocating %d bytes.\n", strlen(pszString) ); } return( pszReturn );}void FreeStrList(char **papszStrList){ char **papszPtr; if (papszStrList) { papszPtr = papszStrList; while(*papszPtr != NULL) { UGK_Free(*papszPtr); papszPtr++; } UGK_Free(papszStrList); }}/********************************************************************** * CountOfList() * * Return the number of lines in a Stringlist. **********************************************************************/int CountOfList(char **papszStrList){ int nItems=0; if (papszStrList) { while(*papszStrList != NULL) { nItems++; papszStrList++; } } return nItems;}/********************************************************************** * DuplicateList() * * Allocate and return a copy of a StringList. **********************************************************************/char **DuplicateList(char **papszStrList){ char **papszNewList, **papszSrc, **papszDst; int nLines; nLines = CountOfList(papszStrList); if (nLines == 0) return NULL; papszNewList = (char **)UGK_Malloc((nLines+1)*sizeof(char*)); papszSrc = papszStrList; papszDst = papszNewList; while(*papszSrc != NULL) { *papszDst = UGKStrdup(*papszSrc); papszSrc++; papszDst++; } *papszDst = NULL; return papszNewList;}/************************************************************************//* FindStrInList() *//* *//* Find a string within a string list. The string must match *//* the full length, but the comparison is case insensitive. *//* Return -1 on failure. *//************************************************************************/int FindStrInList( char ** papszList, const char * pszTarget ){ int i; if( papszList == NULL ) return -1; for( i = 0; papszList[i] != NULL; i++ ) { if( EQUAL(papszList[i],pszTarget)) return i; } return -1;}/********************************************************************** * AddStringToList() * * 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 **AddStringToList(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**) UGK_Calloc(2,sizeof(char*)); else { nItems = CountOfList(papszStrList); papszStrList = (char**)UGK_Realloc(papszStrList, (nItems+2)*sizeof(char*)); } /* Copy the string in the list */ papszStrList[nItems] = UGKStrdup(pszNewString); papszStrList[nItems+1] = NULL; return papszStrList;}/************************************************************************//* GetStrFromList() *//* *//* 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 * GetStrFromList( 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] );}/********************************************************************** * LoadFileToList() * * Load a test file into a stringlist. * * Lines are limited in length by the size of the CPLReadLine() buffer. **********************************************************************/char **LoadFileToList(const char *pszFname){ FILE *fp; const char *pszLine; char **papszStrList=NULL; fp = fopen(pszFname, "rb"); if (fp) { while(!feof(fp)) { if ( (pszLine = ReadLineFromTxt(fp)) != NULL ) { papszStrList = AddStringToList(papszStrList, pszLine); } } fclose(fp); ReadLineFromTxt( NULL ); } else { /* Unable to open file */ ; } return papszStrList;}/************************************************************************//* ReadLineFromTxt() *//************************************************************************//** * Simplified line reading from text file. * * Read a line of text from the given file handle, taking care * to capture CR and/or LF and strip off ... equivelent of * DKReadLine(). Pointer to an internal buffer is returned. * The application shouldn't free it, or depend on it's value * past the next call to CPLReadLine(). * * Note that CPLReadLine() uses VSIFGets(), so any hooking of VSI file * services should apply to CPLReadLine() as well. * * CPLReadLine() maintains an internal buffer, which will appear as a * single block memory leak in some circumstances. CPLReadLine() may * be called with a NULL FILE * at any time to free this working buffer. * * @param fp file pointer opened with VSIFOpen(). * * @return pointer to an internal buffer containing a line of text read * from the file or NULL if the end of file was encountered. */const char *ReadLineFromTxt( FILE * fp ){ static char *pszRLBuffer = NULL; static int nRLBufferSize = 0; int nReadSoFar = 0;/* -------------------------------------------------------------------- *//* Cleanup case. *//* -------------------------------------------------------------------- */ if( fp == NULL ) { UGK_Free( pszRLBuffer ); pszRLBuffer = NULL; nRLBufferSize = 0; return NULL; }/* -------------------------------------------------------------------- *//* Loop reading chunks of the line till we get to the end of *//* the line. *//* -------------------------------------------------------------------- */ do {/* -------------------------------------------------------------------- *//* Grow the working buffer if we have it nearly full. Fail out *//* of read line if we can't reallocate it big enough (for *//* instance for a _very large_ file with no newlines). *//* -------------------------------------------------------------------- */ if( nRLBufferSize-nReadSoFar < 128 ) { nRLBufferSize = nRLBufferSize*2 + 128; pszRLBuffer = (char *) UGK_Realloc(pszRLBuffer, nRLBufferSize); if( pszRLBuffer == NULL ) { nRLBufferSize = 0; return NULL; } }/* -------------------------------------------------------------------- *//* Do the actual read. *//* -------------------------------------------------------------------- */ if( GetsFromFile( pszRLBuffer+nReadSoFar, nRLBufferSize-nReadSoFar, fp ) == NULL ) { UGK_Free( pszRLBuffer ); pszRLBuffer = NULL; nRLBufferSize = 0; return NULL; } nReadSoFar = strlen(pszRLBuffer); } while( nReadSoFar == nRLBufferSize - 1 && pszRLBuffer[nRLBufferSize-2] != 13 && pszRLBuffer[nRLBufferSize-2] != 10 ); return( pszRLBuffer );}/********************************************************************** * SaveStringToTxt() * * Write a stringlist to a text file. * * Returns the number of lines written, or 0 if the file could not * be written. **********************************************************************/int SaveStringToTxt(char **papszStrList, const char *pszFname){ FILE *fp; int nLines = 0; if (papszStrList) { if ((fp = fopen(pszFname, "wt")) != NULL) { while(*papszStrList != NULL) { if (fputs(*papszStrList, fp) == EOF || fputc('\n', fp) == EOF) { UGKError(ET_Failure, UGKErr_FileIO, "CSLSave(%s): %s", pszFname, strerror(errno)); break; /* A Problem happened... abort */ } nLines++; papszStrList++; } fclose(fp); } else { /* Unable to open file */ UGKError(ET_Failure, UGKErr_OpenFailed, "CSLSave(%s): %s", pszFname, strerror(errno)); } } return nLines;}/********************************************************************** * RemoveStringsFromList() * * 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 **RemoveStringsFromList(char **papszStrList, int nFirstLineToDelete, int nNumToRemove, char ***ppapszRetStrings){ int i, nSrcLines, nDstLines; char **ppszSrc, **ppszDst; nSrcLines = CountOfList(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) { FreeStrList(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++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -