📄 cpl_string.cpp
字号:
/********************************************************************** * $Id: cpl_string.cpp,v 1.57 2006/11/22 18:17:49 fwarmerdam Exp $ * * 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(). * * $Log: cpl_string.cpp,v $ * Revision 1.57 2006/11/22 18:17:49 fwarmerdam * changed frmt to const char in CPLSPrintf * * Revision 1.56 2006/06/30 14:58:22 dron * Avoid warnings on win/64. * * Revision 1.55 2006/04/12 15:10:40 fwarmerdam * argument to InsertString should be const * * Revision 1.54 2006/02/19 21:54:34 mloskot * [WINCE] Changes related to Windows CE port of CPL. Most changes are #ifdef wrappers. * * Revision 1.53 2005/12/19 20:17:21 fwarmerdam * enable pszValue NULL to delete entry in CSLSetNameValue * * Revision 1.52 2005/12/06 07:33:12 fwarmerdam * fixed support for tokenizing string with trailing delimeter, bug 945 * * Revision 1.51 2005/10/13 01:20:16 fwarmerdam * added CSLMerge() * * Revision 1.50 2005/09/30 19:11:40 fwarmerdam * fixed hextobinary conversion, bug 935 * * Revision 1.49 2005/09/14 19:21:17 fwarmerdam * binary pointer is const in binarytohex * * Revision 1.48 2005/09/13 15:07:23 dron * Initialize counters in CPLHexToBinary(). * * Revision 1.47 2005/09/11 21:09:27 fwarmerdam * use large file API in CSLLoad * * Revision 1.46 2005/09/05 20:19:08 fwarmerdam * fixed binarytohex function * * Revision 1.45 2005/08/31 03:31:15 fwarmerdam * added binarytohex/hextobinary * * Revision 1.44 2005/08/04 19:41:33 fwarmerdam * support setting null value in CSLSetNameValue * * Revision 1.43 2005/05/23 03:59:44 fwarmerdam * make cplsprintf buffer threadlocal * * Revision 1.42 2005/04/04 15:23:31 fwarmerdam * some functions now CPL_STDCALL * * Revision 1.41 2004/09/17 21:26:28 fwarmerdam * Yikes ... CPLEscapeString() was badly broken for BackslashEscapable. * * Revision 1.40 2004/08/16 20:23:46 warmerda * added .csv escaping * * Revision 1.39 2004/07/12 21:50:38 warmerda * Added SQL escaping style * * Revision 1.38 2004/04/23 22:23:32 warmerda * Fixed key memory leak in seldom used CSLSetNameValueSeperator(). * * Revision 1.37 2003/12/02 15:56:47 warmerda * avoid use of CSLAddString() in tokenize, manage list ourselves * * Revision 1.36 2003/08/29 17:32:27 warmerda * Open file in binary mode for CSLLoad() since CPLReadline() works much * better then. * * Revision 1.35 2003/07/17 10:15:40 dron * CSLTestBoolean() added. * * Revision 1.34 2003/05/28 19:22:38 warmerda * fixed docs * * Revision 1.33 2003/05/21 04:20:30 warmerda * avoid warnings * * Revision 1.32 2003/04/04 14:57:38 dron * _vsnprintf() hack moved to the cpl_config.h.vc. * * Revision 1.31 2003/04/04 14:16:07 dron * Use _vsnprintf() in Windows environment. * * Revision 1.30 2003/03/28 05:29:53 warmerda * Fixed buffer overflow risk in escaping code (for XML method). Avoid * use of CPLSPrintf() for name/value list assembly to avoid risk with long * key names or values. Use vsnprintf() in CPLSPrintf() on platforms where it * is available. Security audit complete. * * Revision 1.29 2003/03/27 21:32:08 warmerda * Fixed bug with escaped spaces. * * Revision 1.28 2003/03/11 21:33:02 warmerda * added URL encode/decode support, untested * * Revision 1.27 2003/01/30 19:15:55 warmerda * added some docs * * Revision 1.26 2003/01/14 14:31:16 warmerda * Added "OFF" as a negative response to CSLFetchBoolean(). * * Revision 1.25 2002/10/07 19:35:38 dron * Fixed description for CSLFetchBoolean() * * Revision 1.24 2002/07/12 22:37:05 warmerda * added CSLFetchBoolean * * Revision 1.23 2002/07/09 20:25:25 warmerda * expand tabs * * Revision 1.22 2002/05/28 18:53:43 warmerda * added XML escaping support * * Revision 1.21 2002/04/26 14:55:26 warmerda * Added CPLEscapeString() and CPLUnescapeString() (unescape untested) * * Revision 1.20 2002/03/05 14:26:57 warmerda * expanded tabs * * Revision 1.19 2002/01/16 03:59:27 warmerda * added CPLTokenizeString2 * * Revision 1.18 2001/12/11 22:40:26 warmerda * cleanup CPLReadLine buffer in CSLLoad() * * Revision 1.17 2001/11/07 14:31:16 warmerda * doc fix * * Revision 1.16 2001/07/18 04:00:49 warmerda * added CPL_CVSID * * Revision 1.15 2001/01/19 21:16:41 warmerda * expanded tabs * * Revision 1.14 2000/10/06 15:19:03 warmerda * added CPLSetNameValueSeparator * * Revision 1.13 2000/08/22 17:47:50 warmerda * Fixed declaration of gnCPLSPrintfBuffer. * * Revision 1.12 2000/08/18 21:20:54 svillene * *** empty log message *** * * Revision 1.11 2000/03/30 05:38:48 warmerda * added CPLParseNameValue * * Revision 1.10 1999/06/26 14:05:10 warmerda * Added CSLFindString(). * * Revision 1.9 1999/04/28 02:33:02 danmo * CSLInsertStrings(): make sure papszStrList is NULL-terminated properly * * Revision 1.8 1999/03/12 21:19:49 danmo * Fixed TokenizeStringComplex() vs strings ending with empty token, * and fixed a problem with CSLAdd/SetNameValue() vs empty string list. * * Revision 1.7 1999/03/09 21:29:57 warmerda * Added backslash escaping within string constants for tokenize function. * * Revision 1.6 1999/02/25 04:40:46 danmo * Modif. CSLLoad() to use CPLReadLine() (better handling of newlines) * * Revision 1.5 1999/02/17 01:41:58 warmerda * Added CSLGetField * * Revision 1.4 1998/12/15 19:01:40 warmerda * *** empty log message *** * * Revision 1.3 1998/12/05 23:04:21 warmerda * Use EQUALN() instead of strincmp() which doesn't exist on Linux. * * Revision 1.2 1998/12/04 21:40:42 danmo * Added more Name=Value manipulation fuctions * * Revision 1.1 1998/12/03 18:26:02 warmerda * New * **********************************************************************/#include "cpl_string.h"#include "cpl_vsi.h"#if defined(WIN32CE)# include <wce_errno.h># include <wce_string.h>#endifCPL_CVSID("$Id: cpl_string.cpp,v 1.57 2006/11/22 18:17:49 fwarmerdam 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 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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -