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

void PoDoFo::PdfParser::ReadXRefContents ( pdf_long  lOffset,
bool  bPositionAtEnd = false 
) [protected]

Reads the xref table from a pdf file. If there is no xref table, ReadXRefStreamContents() is called.

Parameters:
lOffsetread the table from this offset
bPositionAtEndif true the xref table is not read, but the file stream is positioned directly after the table, which allows reading a following trailer dictionary.

Definition at line 563 of file PdfParser.cpp.

References PoDoFo::PdfError::AddToCallstack(), PoDoFo::PdfError::DebugMessage(), PoDoFo::PdfRefCountedInputDevice::Device(), PoDoFo::ePdfError_InvalidXRef, PoDoFo::ePdfError_NoNumber, PoDoFo::ePdfError_NoTrailer, PoDoFo::ePdfError_NoXRef, PoDoFo::ePdfError_UnexpectedEOF, PoDoFo::ePdfVersion_1_3, FindToken(), FindToken2(), PoDoFo::PdfTokenizer::GetNextNumber(), PoDoFo::PdfTokenizer::GetNextToken(), PoDoFo::PdfTokenizer::IsNextToken(), PODOFO_RAISE_ERROR, PoDoFo::PdfTokenizer::QuequeToken(), ReadXRefStreamContents(), ReadXRefSubsection(), PoDoFo::PdfRefCountedBuffer::Resize(), PoDoFo::PdfInputDevice::Seek(), and PoDoFo::PdfInputDevice::Tell().

Referenced by ReadDocumentStructure().

{
    long long nFirstObject = 0;
    long long nNumObjects  = 0;

    size_t curPosition = m_device.Device()->Tell();
    m_device.Device()->Seek(0,std::ios_base::end);
    std::streamoff fileSize = m_device.Device()->Tell();
    m_device.Device()->Seek(curPosition,std::ios_base::beg);

    if (lOffset > fileSize)
    { 
        // Invalid "startxref" Peter Petrov 23 December 2008
        FindToken( "startxref", PDF_XREF_BUF );
        lOffset = m_device.Device()->Tell();
        // TODO: hard coded value "4"
        m_buffer.Resize(PDF_XREF_BUF*4);
        FindToken2("xref", PDF_XREF_BUF*4,lOffset);
        m_buffer.Resize(PDF_XREF_BUF);
        lOffset = m_device.Device()->Tell();
        m_nXRefOffset = lOffset;
    }
    else
    {
        m_device.Device()->Seek( lOffset );
    }
    
    if( !this->IsNextToken( "xref" ) )
    {
//      if( m_ePdfVersion < ePdfVersion_1_5 )
//          Ulrich Arnold 19.10.2009, found linearized 1.3-pdf's with trailer-info in xref-stream
        if( m_ePdfVersion < ePdfVersion_1_3 )
        {
            PODOFO_RAISE_ERROR( ePdfError_NoXRef );
        }
        else
        {
            ReadXRefStreamContents( lOffset, bPositionAtEnd );
            return;
        }
    }

    // read all xref subsections
    // OC 13.08.2010: Avoid exception to terminate endless loop
    for( int nXrefSection = 0; ; ++nXrefSection )
    {
        try {

            // OC 13.08.2010: Avoid exception to terminate endless loop
            if ( nXrefSection > 0 )
            {
                // something like PeekNextToken()
                EPdfTokenType eType;
                const char* pszRead;
                bool gotToken = this->GetNextToken( pszRead, &eType );
                if( gotToken )
                {
                    this->QuequeToken( pszRead, eType );
                    if ( strcmp( "trailer", pszRead ) == 0 )
                        break;
                }
            }

            nFirstObject = this->GetNextNumber();
            nNumObjects  = this->GetNextNumber();

#ifdef PODOFO_VERBOSE_DEBUG
            PdfError::DebugMessage("Reading numbers: %lli %lli\n", nFirstObject, nNumObjects );
#endif // PODOFO_VERBOSE_DEBUG

            if( bPositionAtEnd )
            {
#ifdef _WIN32
                        m_device.Device()->Seek( static_cast<std::streamoff>(nNumObjects* PDF_XREF_ENTRY_SIZE), std::ios_base::cur );
#else
                m_device.Device()->Seek( nNumObjects* PDF_XREF_ENTRY_SIZE, std::ios_base::cur );
#endif // _WIN32
                  }
            else
            {
                ReadXRefSubsection( nFirstObject, nNumObjects );
            }
        } catch( PdfError & e ) {
            if( e == ePdfError_NoNumber || e == ePdfError_InvalidXRef || e == ePdfError_UnexpectedEOF ) 
                break;
            else 
            {
                e.AddToCallstack( __FILE__, __LINE__ );
                throw e;
            }
        }
    }

    try {
        ReadNextTrailer();
    } catch( PdfError & e ) {
        if( e != ePdfError_NoTrailer ) 
        {
            e.AddToCallstack( __FILE__, __LINE__ );
            throw e;
        }
    }
}

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