bool CUtlInplaceBuffer::InplaceGetLinePtr( char **ppszInBufferPtr, int *pnLineLength ) { Assert( IsText() && !ContainsCRLF() ); int nLineLen = PeekLineLength(); if ( nLineLen <= 1 ) { SeekGet( SEEK_TAIL, 0 ); return false; } -- nLineLen; // because it accounts for putting a terminating null-character char *pszLine = ( char * ) const_cast< void * >( PeekGet() ); SeekGet( SEEK_CURRENT, nLineLen ); // Set the out args if ( ppszInBufferPtr ) *ppszInBufferPtr = pszLine; if ( pnLineLength ) *pnLineLength = nLineLen; return true; }
void CUtlBufferEditor::GetDelimitedString( CUtlCharConversion *pConv, char *pString, int nMaxChars ) { if ( !IsText() || !pConv ) { GetString( pString, nMaxChars ); return; } if (!IsValid()) { *pString = 0; return; } if ( nMaxChars == 0 ) { nMaxChars = INT_MAX; } EatWhiteSpace(); if ( !PeekStringMatch( 0, pConv->GetDelimiter(), pConv->GetDelimiterLength() ) ) return; // Pull off the starting delimiter SeekGet( SEEK_CURRENT, pConv->GetDelimiterLength() ); int nRead = 0; while ( IsValid() ) { if ( PeekStringMatch( 0, pConv->GetDelimiter(), pConv->GetDelimiterLength() ) ) { SeekGet( SEEK_CURRENT, pConv->GetDelimiterLength() ); break; } char c = GetDelimitedCharInternal( pConv ); if ( nRead < nMaxChars ) { pString[nRead] = c; ++nRead; } } if ( nRead >= nMaxChars ) { nRead = nMaxChars - 1; } pString[nRead] = '\0'; }
//----------------------------------------------------------------------------- // Advance the get index until after the particular string is found // Do not eat whitespace before starting. Return false if it failed //----------------------------------------------------------------------------- bool CUtlBufferEditor::GetToken( const char *pToken ) { Assert( pToken ); // Look for the token int nLen = Q_strlen( pToken ); int nSizeToCheck = Size() - TellGet() - m_nOffset; int nGet = TellGet(); do { int nMaxSize = TellMaxPut() - TellGet(); if ( nMaxSize < nSizeToCheck ) { nSizeToCheck = nMaxSize; } if ( nLen > nSizeToCheck ) break; if ( !CheckPeekGet( 0, nSizeToCheck ) ) break; const char *pBufStart = (const char*)PeekGet(); const char *pFoundEnd = Q_strnistr( pBufStart, pToken, nSizeToCheck ); if ( pFoundEnd ) { size_t nOffset = (size_t)pFoundEnd - (size_t)pBufStart; SeekGet( CUtlBufferEditor::SEEK_CURRENT, nOffset + nLen ); return true; } SeekGet( CUtlBufferEditor::SEEK_CURRENT, nSizeToCheck - nLen - 1 ); nSizeToCheck = Size() - (nLen-1); } while ( true ); SeekGet( CUtlBufferEditor::SEEK_HEAD, nGet ); return false; }
//----------------------------------------------------------------------------- // This version of GetString converts \ to \\ and " to \", etc. // It also places " at the beginning and end of the string //----------------------------------------------------------------------------- char CUtlBufferEditor::GetDelimitedCharInternal( CUtlCharConversion *pConv ) { char c = GetChar(); if ( c == pConv->GetEscapeChar() ) { int nLength = pConv->MaxConversionLength(); if ( !CheckArbitraryPeekGet( 0, nLength ) ) return '\0'; c = pConv->FindConversion( (const char *)PeekGet(), &nLength ); SeekGet( SEEK_CURRENT, nLength ); } return c; }
//----------------------------------------------------------------------------- // Reads a null-terminated string //----------------------------------------------------------------------------- void CUtlBufferEditor::GetString( char* pString, int nMaxChars ) { if (!IsValid()) { *pString = 0; return; } if ( nMaxChars == 0 ) { nMaxChars = INT_MAX; } // Remember, this *includes* the null character // It will be 0, however, if the buffer is empty. int nLen = PeekStringLength(); if ( IsText() ) { EatWhiteSpace(); } if ( nLen == 0 ) { *pString = 0; m_Error |= GET_OVERFLOW; return; } // Strip off the terminating NULL if ( nLen <= nMaxChars ) { Get( pString, nLen - 1 ); pString[ nLen - 1 ] = 0; } else { Get( pString, nMaxChars - 1 ); pString[ nMaxChars - 1 ] = 0; SeekGet( SEEK_CURRENT, nLen - 1 - nMaxChars ); } // Read the terminating NULL in binary formats if ( !IsText() ) { VerifyEquals( GetChar(), 0 ); } }
//----------------------------------------------------------------------------- // Reads up to and including the first \n //----------------------------------------------------------------------------- void CUtlBufferEditor::GetLine( char* pLine, int nMaxChars ) { Assert( IsText() && !ContainsCRLF() ); if ( !IsValid() ) { *pLine = 0; return; } if ( nMaxChars == 0 ) { nMaxChars = INT_MAX; } // Remember, this *includes* the null character // It will be 0, however, if the buffer is empty. int nLen = PeekLineLength(); if ( nLen == 0 ) { *pLine = 0; m_Error |= GET_OVERFLOW; return; } // Strip off the terminating NULL if ( nLen <= nMaxChars ) { Get( pLine, nLen - 1 ); pLine[ nLen - 1 ] = 0; } else { Get( pLine, nMaxChars - 1 ); pLine[ nMaxChars - 1 ] = 0; SeekGet( SEEK_CURRENT, nLen - 1 - nMaxChars ); } }
//----------------------------------------------------------------------------- // Parses the next token, given a set of character breaks to stop at //----------------------------------------------------------------------------- int CUtlBufferEditor::ParseToken( characterset_t *pBreaks, char *pTokenBuf, int nMaxLen, bool bParseComments ) { Assert( nMaxLen > 0 ); pTokenBuf[0] = 0; // skip whitespace + comments while ( true ) { if ( !IsValid() ) return -1; EatWhiteSpace(); if ( bParseComments ) { if ( !EatCPPComment() ) break; } else { break; } } char c = GetChar(); // End of buffer if ( c == 0 ) return -1; // handle quoted strings specially if ( c == '\"' ) { int nLen = 0; while( IsValid() ) { c = GetChar(); if ( c == '\"' || !c ) { pTokenBuf[nLen] = 0; return nLen; } pTokenBuf[nLen] = c; if ( ++nLen == nMaxLen ) { pTokenBuf[nLen-1] = 0; return nMaxLen; } } // In this case, we hit the end of the buffer before hitting the end qoute pTokenBuf[nLen] = 0; return nLen; } // parse single characters if ( IN_CHARACTERSET( *pBreaks, c ) ) { pTokenBuf[0] = c; pTokenBuf[1] = 0; return 1; } // parse a regular word int nLen = 0; while ( true ) { pTokenBuf[nLen] = c; if ( ++nLen == nMaxLen ) { pTokenBuf[nLen-1] = 0; return nMaxLen; } c = GetChar(); if ( !IsValid() ) break; if ( IN_CHARACTERSET( *pBreaks, c ) || c == '\"' || c <= ' ' ) { SeekGet( SEEK_CURRENT, -1 ); break; } } pTokenBuf[nLen] = 0; return nLen; }
//----------------------------------------------------------------------------- // (For text buffers only) // Parse a token from the buffer: // Grab all text that lies between a starting delimiter + ending delimiter // (skipping whitespace that leads + trails both delimiters). // Note the delimiter checks are case-insensitive. // If successful, the get index is advanced and the function returns true, // otherwise the index is not advanced and the function returns false. //----------------------------------------------------------------------------- bool CUtlBufferEditor::ParseToken( const char *pStartingDelim, const char *pEndingDelim, char* pString, int nMaxLen ) { int nCharsToCopy = 0; int nCurrentGet = 0; size_t nEndingDelimLen; // Starting delimiter is optional char emptyBuf = '\0'; if ( !pStartingDelim ) { pStartingDelim = &emptyBuf; } // Ending delimiter is not Assert( pEndingDelim && pEndingDelim[0] ); nEndingDelimLen = Q_strlen( pEndingDelim ); int nStartGet = TellGet(); char nCurrChar; int nTokenStart = -1; EatWhiteSpace( ); while ( *pStartingDelim ) { nCurrChar = *pStartingDelim++; if ( !isspace((unsigned char)nCurrChar) ) { if ( tolower( GetChar() ) != tolower( nCurrChar ) ) goto parseFailed; } else { EatWhiteSpace(); } } EatWhiteSpace(); nTokenStart = TellGet(); if ( !GetToken( pEndingDelim ) ) goto parseFailed; nCurrentGet = TellGet(); nCharsToCopy = (nCurrentGet - nEndingDelimLen) - nTokenStart; if ( nCharsToCopy >= nMaxLen ) { nCharsToCopy = nMaxLen - 1; } if ( nCharsToCopy > 0 ) { SeekGet( CUtlBufferEditor::SEEK_HEAD, nTokenStart ); Get( pString, nCharsToCopy ); if ( !IsValid() ) goto parseFailed; // Eat trailing whitespace for ( ; nCharsToCopy > 0; --nCharsToCopy ) { if ( !isspace( (unsigned char)pString[ nCharsToCopy-1 ] ) ) break; } } pString[ nCharsToCopy ] = '\0'; // Advance the Get index SeekGet( CUtlBufferEditor::SEEK_HEAD, nCurrentGet ); return true; parseFailed: // Revert the get index SeekGet( SEEK_HEAD, nStartGet ); pString[0] = '\0'; return false; }