Logo Search packages:      
Sourcecode: libpodofo version File versions  Download package

bool PoDoFo::PdfTokenizer::GetNextToken ( const char *&  pszToken,
EPdfTokenType *  peType = NULL 
) [inherited]

Reads the next token from the current file position ignoring all comments.

Parameters:
[out]pszBufOn true return, set to a pointer to the read token (a NULL-terminated C string). The pointer is to memory owned by PdfTokenizer and must NOT be freed. The contents are invalidated on the next call to GetNextToken(..) and by the destruction of the PdfTokenizer. Undefined on false return.
[out]peTypeOn true return, if not NULL the type of the read token will be stored into this parameter. Undefined on false return.
Returns:
True if a token was read, false if there are no more tokens to read.
See also:
GetBuffer

Definition at line 195 of file PdfTokenizer.cpp.

References PoDoFo::PdfRefCountedInputDevice::Device(), PoDoFo::ePdfError_InvalidHandle, PoDoFo::PdfRefCountedBuffer::GetBuffer(), PoDoFo::PdfInputDevice::GetChar(), PoDoFo::PdfRefCountedBuffer::GetSize(), PoDoFo::PdfTokenizer::IsDelimiter(), PoDoFo::PdfTokenizer::IsWhitespace(), PoDoFo::PdfInputDevice::Look(), and PODOFO_RAISE_ERROR.

Referenced by PoDoFo::PdfTokenizer::DetermineDataType(), PoDoFo::PdfTokenizer::GetNextNumber(), PoDoFo::PdfTokenizer::GetNextVariant(), PoDoFo::PdfTokenizer::IsNextToken(), PoDoFo::PdfParserObject::ParseFileComplete(), PoDoFo::PdfTokenizer::ReadArray(), PoDoFo::PdfTokenizer::ReadDictionary(), PoDoFo::PdfTokenizer::ReadName(), PoDoFo::PdfContentsTokenizer::ReadNext(), PoDoFo::PdfParser::ReadXRefContents(), and TokenizerTest::TestStream().

{
    int  c; 
    long long  counter  = 0;

    // check first if there are quequed tokens and return them first
    if( m_deqQueque.size() )
    {
        TTokenizerPair pair = m_deqQueque.front();
        m_deqQueque.pop_front();

        if( peType )
            *peType = pair.second;

        strcpy( m_buffer.GetBuffer(), pair.first.c_str() );
        pszToken = m_buffer.GetBuffer();
        return true;
    }
    
    if( !m_device.Device() )
    {
        PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
    }

    if( peType )
        *peType = ePdfTokenType_Token;

    while( (c = m_device.Device()->Look()) != EOF
           && counter < static_cast<long long>(m_buffer.GetSize()) )
    {
        // ignore leading whitespaces
        if( !counter && IsWhitespace( c ) )
        {
            // Consume the whitespace character
            c = m_device.Device()->GetChar();
            continue;
        }
        // ignore comments
        else if( c == '%' ) 
        {
            // Consume all characters before the next line break
            do {
                c = m_device.Device()->GetChar();
            } while( c != EOF && c != 0x0A );
            // If we've already read one or more chars of a token, return them, since
            // comments are treated as token-delimiting whitespace. Otherwise keep reading
            // at the start of the next line.
            if (counter)
                break;
        }
        // special handling for << and >> tokens
        else if( !counter && (c == '<' || c == '>' ) )
        {
            if( peType )
                *peType = ePdfTokenType_Delimiter;

            // retrieve c really from stream
            c = m_device.Device()->GetChar();
            m_buffer.GetBuffer()[counter] = c;
            ++counter;

            char n = m_device.Device()->Look();
            // Is n another < or > , ie are we opening/closing a dictionary?
            // If so, consume that character too.
            if( n == c )
            {
                n = m_device.Device()->GetChar();
                m_buffer.GetBuffer()[counter] = n;
                ++counter;
            }
            // `m_buffer' contains one of < , > , << or >> ; we're done .
            break;
        }
        else if( counter && (IsWhitespace( c ) || IsDelimiter( c )) )
        {
            // Next (unconsumed) character is a token-terminating char, so
            // we have a complete token and can return it.
            break;
        }
        else
        {
            // Consume the next character and add it to the token we're building.
            c = m_device.Device()->GetChar();
            m_buffer.GetBuffer()[counter] = c;
            ++counter;

            if( IsDelimiter( c ) )
            {
                // All delimeters except << and >> (handled above) are
                // one-character tokens, so if we hit one we can just return it
                // immediately.
                if( peType )
                    *peType = ePdfTokenType_Delimiter;
                break;
            }
        }
    }

    m_buffer.GetBuffer()[counter] = '\0';


    if( c == EOF && !counter )
    {
        // No characters were read before EOF, so we're out of data.
        // Ensure the buffer points to NULL in case someone fails to check the return value.
        pszToken = 0;
        return false;
    }

    pszToken = m_buffer.GetBuffer();
    return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Generated by  Doxygen 1.6.0   Back to index