?? cpl_conv.cpp
字號:
{
bWarned = TRUE;
CPLDebug( "CPL", "CPLFGets() correcting for DOS text mode translation seek problem." );
}
chCheck = fgetc( fp );
}
}
return pszBuffer;
}
/************************************************************************/
/* CPLReadLineBuffer() */
/* */
/* Fetch readline buffer, and ensure it is the desired size, */
/* reallocating if needed. Manages TLS (thread local storage) */
/* issues for the buffer. */
/************************************************************************/
static char *CPLReadLineBuffer( int nRequiredSize )
{
/* -------------------------------------------------------------------- */
/* A required size of -1 means the buffer should be freed. */
/* -------------------------------------------------------------------- */
if( nRequiredSize == -1 )
{
if( CPLGetTLS( CTLS_RLBUFFERINFO ) != NULL )
{
CPLFree( CPLGetTLS( CTLS_RLBUFFERINFO ) );
CPLSetTLS( CTLS_RLBUFFERINFO, NULL, FALSE );
}
return NULL;
}
/* -------------------------------------------------------------------- */
/* If the buffer doesn't exist yet, create it. */
/* -------------------------------------------------------------------- */
GUInt32 *pnAlloc = (GUInt32 *) CPLGetTLS( CTLS_RLBUFFERINFO );
if( pnAlloc == NULL )
{
pnAlloc = (GUInt32 *) CPLMalloc(200);
*pnAlloc = 196;
CPLSetTLS( CTLS_RLBUFFERINFO, pnAlloc, TRUE );
}
/* -------------------------------------------------------------------- */
/* If it is too small, grow it bigger. */
/* -------------------------------------------------------------------- */
if( (int) *pnAlloc < nRequiredSize+1 )
{
int nNewSize = nRequiredSize + 4 + 500;
pnAlloc = (GUInt32 *) CPLRealloc(pnAlloc,nNewSize);
if( pnAlloc == NULL )
{
CPLSetTLS( CTLS_RLBUFFERINFO, NULL, FALSE );
return NULL;
}
*pnAlloc = nNewSize - 4;
CPLSetTLS( CTLS_RLBUFFERINFO, pnAlloc, TRUE );
}
return (char *) (pnAlloc+1);
}
/************************************************************************/
/* CPLReadLine() */
/************************************************************************/
/**
* 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 *CPLReadLine( FILE * fp )
{
char *pszRLBuffer = CPLReadLineBuffer(1);
int nReadSoFar = 0;
/* -------------------------------------------------------------------- */
/* Cleanup case. */
/* -------------------------------------------------------------------- */
if( fp == NULL )
{
CPLReadLineBuffer( -1 );
return NULL;
}
/* -------------------------------------------------------------------- */
/* Loop reading chunks of the line till we get to the end of */
/* the line. */
/* -------------------------------------------------------------------- */
int nBytesReadThisTime;
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). */
/* -------------------------------------------------------------------- */
pszRLBuffer = CPLReadLineBuffer( nReadSoFar + 129 );
if( pszRLBuffer == NULL )
return NULL;
/* -------------------------------------------------------------------- */
/* Do the actual read. */
/* -------------------------------------------------------------------- */
if( CPLFGets( pszRLBuffer+nReadSoFar, 128, fp ) == NULL
&& nReadSoFar == 0 )
return NULL;
nBytesReadThisTime = strlen(pszRLBuffer+nReadSoFar);
nReadSoFar += nBytesReadThisTime;
} while( nBytesReadThisTime >= 127
&& pszRLBuffer[nReadSoFar-1] != 13
&& pszRLBuffer[nReadSoFar-1] != 10 );
return( pszRLBuffer );
}
/************************************************************************/
/* CPLReadLineL() */
/************************************************************************/
/**
* Simplified line reading from text file.
*
* Similar to CPLReadLine(), but reading from a large file API handle.
*
* @param fp file pointer opened with VSIFOpenL().
*
* @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 *CPLReadLineL( FILE * fp )
{
/* -------------------------------------------------------------------- */
/* Cleanup case. */
/* -------------------------------------------------------------------- */
if( fp == NULL )
{
CPLReadLineBuffer( -1 );
return NULL;
}
/* -------------------------------------------------------------------- */
/* Loop reading chunks of the line till we get to the end of */
/* the line. */
/* -------------------------------------------------------------------- */
char *pszRLBuffer;
const size_t nChunkSize = 40;
char szChunk[nChunkSize];
size_t nChunkBytesRead = 0;
int nBufLength = 0;
size_t nChunkBytesConsumed = 0;
while( TRUE )
{
/* -------------------------------------------------------------------- */
/* Read a chunk from the input file. */
/* -------------------------------------------------------------------- */
pszRLBuffer = CPLReadLineBuffer( nBufLength + nChunkSize + 1 );
if( nChunkBytesRead == nChunkBytesConsumed + 1 )
{
// case where one character is left over from last read.
szChunk[0] = szChunk[nChunkBytesConsumed];
nChunkBytesConsumed = 0;
nChunkBytesRead = VSIFReadL( szChunk+1, 1, nChunkSize-1, fp ) + 1;
}
else
{
nChunkBytesConsumed = 0;
// fresh read.
nChunkBytesRead = VSIFReadL( szChunk, 1, nChunkSize, fp );
if( nChunkBytesRead == 0 )
{
if( nBufLength == 0 )
return NULL;
else
break;
}
}
/* -------------------------------------------------------------------- */
/* copy over characters watching for end-of-line. */
/* -------------------------------------------------------------------- */
int bBreak = FALSE;
while( nChunkBytesConsumed < nChunkBytesRead-1 && !bBreak )
{
if( (szChunk[nChunkBytesConsumed] == 13
&& szChunk[nChunkBytesConsumed+1] == 10)
|| (szChunk[nChunkBytesConsumed] == 10
&& szChunk[nChunkBytesConsumed+1] == 13) )
{
nChunkBytesConsumed += 2;
bBreak = TRUE;
}
else if( szChunk[nChunkBytesConsumed] == 10
|| szChunk[nChunkBytesConsumed] == 13 )
{
nChunkBytesConsumed += 1;
bBreak = TRUE;
}
else
pszRLBuffer[nBufLength++] = szChunk[nChunkBytesConsumed++];
}
if( bBreak )
break;
/* -------------------------------------------------------------------- */
/* If there is a remaining character and it is not a newline */
/* consume it. If it is a newline, but we are clearly at the */
/* end of the file then consume it. */
/* -------------------------------------------------------------------- */
if( nChunkBytesConsumed == nChunkBytesRead-1
&& nChunkBytesRead < nChunkSize )
{
if( szChunk[nChunkBytesConsumed] == 10
|| szChunk[nChunkBytesConsumed] == 13 )
{
nChunkBytesConsumed++;
break;
}
pszRLBuffer[nBufLength++] = szChunk[nChunkBytesConsumed++];
break;
}
}
/* -------------------------------------------------------------------- */
/* If we have left over bytes after breaking out, seek back to */
/* ensure they remain to be read next time. */
/* -------------------------------------------------------------------- */
if( nChunkBytesConsumed < nChunkBytesRead )
{
size_t nBytesToPush = nChunkBytesRead - nChunkBytesConsumed;
VSIFSeekL( fp, VSIFTellL( fp ) - nBytesToPush, SEEK_SET );
}
pszRLBuffer[nBufLength] = '\0';
return( pszRLBuffer );
}
/************************************************************************/
/* CPLScanString() */
/************************************************************************/
/**
* Scan up to a maximum number of characters from a given string,
* allocate a buffer for a new string and fill it with scanned characters.
*
* @param pszString String containing characters to be scanned. It may be
* terminated with a null character.
*
* @param nMaxLength The maximum number of character to read. Less
* characters will be read if a null character is encountered.
*
* @param bTrimSpaces If TRUE, trim ending spaces from the input string.
* Character considered as empty using isspace(3) function.
*
* @param bNormalize If TRUE, replace ':' symbol with the '_'. It is needed if
* resulting string will be used in CPL dictionaries.
*
* @return Pointer to the resulting string buffer. Caller responsible to free
* this buffer with CPLFree().
*/
char *CPLScanString( const char *pszString, int nMaxLength,
int bTrimSpaces, int bNormalize )
{
char *pszBuffer;
if ( !pszString )
return NULL;
if ( !nMaxLength )
return CPLStrdup( "" );
pszBuffer = (char *)CPLMalloc( nMaxLength + 1 );
if ( !pszBuffer )
return NULL;
strncpy( pszBuffer, pszString, nMaxLength );
pszBuffer[nMaxLength] = '\0';
if ( bTrimSpaces )
{
size_t i = strlen( pszBuffer );
while ( i-- > 0 && isspace(pszBuffer[i]) )
pszBuffer[i] = '\0';
}
if ( bNormalize )
{
size_t i = strlen( pszBuffer );
while ( i-- > 0 )
{
if ( pszBuffer[i] == ':' )
pszBuffer[i] = '_';
}
}
return pszBuffer;
}
/************************************************************************/
/* CPLScanLong() */
/************************************************************************/
/**
* Scan up to a maximum number of characters from a string and convert
* the result to a long.
*
* @param pszString String containing characters to be scanned. It may be
* terminated with a null character.
*
* @param nMaxLength The maximum number of character to consider as part
* of the number. Less characters will be considered if a null character
* is encountered.
*
* @return Long value, converted from its ASCII form.
*/
long CPLScanLong( const char *pszString, int nMaxLength )
{
long iValue;
char *pszValue = (char *)CPLMalloc( nMaxLength + 1);
/* -------------------------------------------------------------------- */
/* Compute string into local buffer, and terminate it. */
/* -------------------------------------------------------------------- */
strncpy( pszValue, pszString, nMaxLength );
pszValue[nMaxLength] = '\0';
/* -------------------------------------------------------------------- */
/* Use atol() to fetch out the result */
/* -------------------------------------------------------------------- */
iValue = atol( pszValue );
CPLFree( pszValue );
return iValue;
}
/************************************************************************/
/* CPLScanULong() */
/************************************************************************/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -