?? cpl_conv.cpp
字號:
/******************************************************************************
* $Id: cpl_conv.cpp 12407 2007-10-13 17:33:44Z rouault $
*
* Project: CPL - Common Portability Library
* Purpose: Convenience functions.
* Author: Frank Warmerdam, warmerdam@pobox.com
*
******************************************************************************
* Copyright (c) 1998, 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_vsi.h"
#include "cpl_multiproc.h"
CPL_CVSID("$Id: cpl_conv.cpp 12407 2007-10-13 17:33:44Z rouault $");
#if defined(WIN32CE)
# include "cpl_wince.h"
# include <wce_errno.h>
#endif
static void *hConfigMutex = NULL;
static volatile char **papszConfigOptions = NULL;
static void *hSharedFileMutex = NULL;
static volatile int nSharedFileCount = 0;
static volatile CPLSharedFileInfo *pasSharedFileList = NULL;
/************************************************************************/
/* CPLCalloc() */
/************************************************************************/
/**
* Safe version of calloc().
*
* This function is like the C library calloc(), but raises a CE_Fatal
* error with CPLError() if it fails to allocate the desired memory. It
* should be used for small memory allocations that are unlikely to fail
* and for which the application is unwilling to test for out of memory
* conditions. It uses VSICalloc() to get the memory, so any hooking of
* VSICalloc() will apply to CPLCalloc() as well. CPLFree() or VSIFree()
* can be used free memory allocated by CPLCalloc().
*
* @param nCount number of objects to allocate.
* @param nSize size (in bytes) of object to allocate.
* @return pointer to newly allocated memory, only NULL if nSize * nCount is
* NULL.
*/
void *CPLCalloc( size_t nCount, size_t nSize )
{
void *pReturn;
if( nSize * nCount == 0 )
return NULL;
pReturn = VSICalloc( nCount, nSize );
if( pReturn == NULL )
{
CPLError( CE_Fatal, CPLE_OutOfMemory,
"CPLCalloc(): Out of memory allocating %d bytes.\n",
nSize * nCount );
}
return pReturn;
}
/************************************************************************/
/* CPLMalloc() */
/************************************************************************/
/**
* Safe version of malloc().
*
* This function is like the C library malloc(), but raises a CE_Fatal
* error with CPLError() if it fails to allocate the desired memory. It
* should be used for small memory allocations that are unlikely to fail
* and for which the application is unwilling to test for out of memory
* conditions. It uses VSIMalloc() to get the memory, so any hooking of
* VSIMalloc() will apply to CPLMalloc() as well. CPLFree() or VSIFree()
* can be used free memory allocated by CPLMalloc().
*
* @param nSize size (in bytes) of memory block to allocate.
* @return pointer to newly allocated memory, only NULL if nSize is zero.
*/
void *CPLMalloc( size_t nSize )
{
void *pReturn;
CPLVerifyConfiguration();
if( nSize == 0 )
return NULL;
if( nSize < 0 )
{
CPLError( CE_Failure, CPLE_AppDefined,
"CPLMalloc(%d): Silly size requested.\n",
nSize );
return NULL;
}
pReturn = VSIMalloc( nSize );
if( pReturn == NULL )
{
CPLError( CE_Fatal, CPLE_OutOfMemory,
"CPLMalloc(): Out of memory allocating %d bytes.\n",
nSize );
}
return pReturn;
}
/************************************************************************/
/* CPLRealloc() */
/************************************************************************/
/**
* Safe version of realloc().
*
* This function is like the C library realloc(), but raises a CE_Fatal
* error with CPLError() if it fails to allocate the desired memory. It
* should be used for small memory allocations that are unlikely to fail
* and for which the application is unwilling to test for out of memory
* conditions. It uses VSIRealloc() to get the memory, so any hooking of
* VSIRealloc() will apply to CPLRealloc() as well. CPLFree() or VSIFree()
* can be used free memory allocated by CPLRealloc().
*
* It is also safe to pass NULL in as the existing memory block for
* CPLRealloc(), in which case it uses VSIMalloc() to allocate a new block.
*
* @param pData existing memory block which should be copied to the new block.
* @param nNewSize new size (in bytes) of memory block to allocate.
* @return pointer to allocated memory, only NULL if nNewSize is zero.
*/
void * CPLRealloc( void * pData, size_t nNewSize )
{
void *pReturn;
if ( nNewSize == 0 )
{
VSIFree(pData);
return NULL;
}
if( nNewSize < 0 )
{
CPLError( CE_Failure, CPLE_AppDefined,
"CPLRealloc(%d): Silly size requested.\n",
nNewSize );
return NULL;
}
if( pData == NULL )
pReturn = VSIMalloc( nNewSize );
else
pReturn = VSIRealloc( pData, nNewSize );
if( pReturn == NULL )
{
CPLError( CE_Fatal, CPLE_OutOfMemory,
"CPLRealloc(): Out of memory allocating %d bytes.\n",
nNewSize );
}
return pReturn;
}
/************************************************************************/
/* CPLStrdup() */
/************************************************************************/
/**
* Safe version of strdup() function.
*
* This function is similar to the C library strdup() function, but if
* the memory allocation fails it will issue a CE_Fatal error with
* CPLError() instead of returning NULL. It uses VSIStrdup(), so any
* hooking of that function will apply to CPLStrdup() as well. Memory
* allocated with CPLStrdup() can be freed with CPLFree() or VSIFree().
*
* It is also safe to pass a NULL string into CPLStrdup(). CPLStrdup()
* will allocate and return a zero length string (as opposed to a NULL
* string).
*
* @param pszString input string to be duplicated. May be NULL.
* @return pointer to a newly allocated copy of the string. Free with
* CPLFree() or VSIFree().
*/
char *CPLStrdup( const char * pszString )
{
char *pszReturn;
if( pszString == NULL )
pszString = "";
pszReturn = VSIStrdup( pszString );
if( pszReturn == NULL )
{
CPLError( CE_Fatal, CPLE_OutOfMemory,
"CPLStrdup(): Out of memory allocating %d bytes.\n",
strlen(pszString) );
}
return( pszReturn );
}
/************************************************************************/
/* CPLStrlwr() */
/************************************************************************/
/**
* Convert each characters of the string to lower case.
*
* For example, "ABcdE" will be converted to "abcde".
* This function is locale dependent.
*
* @param pszString input string to be converted.
* @return pointer to the same string, pszString.
*/
char *CPLStrlwr( char *pszString )
{
if (pszString)
{
char *pszTemp = pszString;
while (*pszTemp)
{
*pszTemp = tolower (*pszTemp);
pszTemp++;
}
}
return pszString;
}
/************************************************************************/
/* CPLFGets() */
/* */
/* Note: CR = \r = ASCII 13 */
/* LF = \n = ASCII 10 */
/************************************************************************/
/**
* Reads in at most one less than nBufferSize characters from the fp
* stream and stores them into the buffer pointed to by pszBuffer.
* Reading stops after an EOF or a newline. If a newline is read, it
* is _not_ stored into the buffer. A '\0' is stored after the last
* character in the buffer. All three types of newline terminators
* recognized by the CPLFGets(): single '\r' and '\n' and '\r\n'
* combination.
*
* @param pszBuffer pointer to the targeting character buffer.
* @param nBufferSize maximum size of the string to read (not including
* termonating '\0').
* @param fp file pointer to read from.
* @return pointer to the pszBuffer containing a string read
* from the file or NULL if the error or end of file was encountered.
*/
char *CPLFGets( char *pszBuffer, int nBufferSize, FILE * fp )
{
int nActuallyRead, nOriginalOffset;
if ( nBufferSize == 0 || pszBuffer == NULL || fp == NULL )
return NULL;
/* -------------------------------------------------------------------- */
/* Let the OS level call read what it things is one line. This */
/* will include the newline. On windows, if the file happens */
/* to be in text mode, the CRLF will have been converted to */
/* just the newline (LF). If it is in binary mode it may well */
/* have both. */
/* -------------------------------------------------------------------- */
nOriginalOffset = VSIFTell( fp );
if( VSIFGets( pszBuffer, nBufferSize, fp ) == NULL )
return NULL;
nActuallyRead = strlen(pszBuffer);
if ( nActuallyRead == 0 )
return NULL;
/* -------------------------------------------------------------------- */
/* If we found \r and out buffer is full, it is possible there */
/* is also a pending \n. Check for it. */
/* -------------------------------------------------------------------- */
if( nBufferSize == nActuallyRead+1
&& pszBuffer[nActuallyRead-1] == 13 )
{
int chCheck;
chCheck = fgetc( fp );
if( chCheck != 10 )
{
// unget the character.
VSIFSeek( fp, nOriginalOffset+nActuallyRead, SEEK_SET );
}
}
/* -------------------------------------------------------------------- */
/* Trim off \n, \r or \r\n if it appears at the end. We don't */
/* need to do any "seeking" since we want the newline eaten. */
/* -------------------------------------------------------------------- */
if( nActuallyRead > 1
&& pszBuffer[nActuallyRead-1] == 10
&& pszBuffer[nActuallyRead-2] == 13 )
{
pszBuffer[nActuallyRead-2] = '\0';
}
else if( pszBuffer[nActuallyRead-1] == 10
|| pszBuffer[nActuallyRead-1] == 13 )
{
pszBuffer[nActuallyRead-1] = '\0';
}
/* -------------------------------------------------------------------- */
/* Search within the string for a \r (MacOS convention */
/* apparently), and if we find it we need to trim the string, */
/* and seek back. */
/* -------------------------------------------------------------------- */
char *pszExtraNewline = strchr( pszBuffer, 13 );
if( pszExtraNewline != NULL )
{
int chCheck;
nActuallyRead = pszExtraNewline - pszBuffer + 1;
*pszExtraNewline = '\0';
VSIFSeek( fp, nOriginalOffset + nActuallyRead - 1, SEEK_SET );
/*
* This hackery is necessary to try and find our correct
* spot on win32 systems with text mode line translation going
* on. Sometimes the fseek back overshoots, but it doesn't
* "realize it" till a character has been read. Try to read till
* we get to the right spot and get our CR.
*/
chCheck = fgetc( fp );
while( (chCheck != 13 && chCheck != EOF)
|| VSIFTell(fp) < nOriginalOffset + nActuallyRead )
{
static volatile int bWarned = FALSE;
if( !bWarned )
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -