📄 cpl_conv.cpp
字号:
* 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 ) { 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 ) 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]; nChunkBytesRead = VSIFReadL( szChunk+1, 1, nChunkSize-1, fp ) + 1; if( nChunkBytesRead == 1 ) break; } else { // fresh read. nChunkBytesRead = VSIFReadL( szChunk, 1, nChunkSize, fp ); if( nChunkBytesRead == 0 ) break; } /* -------------------------------------------------------------------- *//* copy over characters watching for end-of-line. *//* -------------------------------------------------------------------- */ int bBreak = FALSE; nChunkBytesConsumed = 0; 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++];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -