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

void PoDoFo::PdfParserObject::ParseStream (  ) [protected, inherited]

Starts reading at the file position m_lStreamOffset and interprets all bytes as contents of the objects stream. It is assumed that the dictionary has a valid /Length key already.

Called from DelayedStreamLoadImpl(). Do not call directly.

Definition at line 230 of file PdfParserObject.cpp.

References PoDoFo::PdfEncrypt::CreateEncryptionInputStream(), PoDoFo::PdfVariant::DelayedLoadDone(), PoDoFo::PdfRefCountedInputDevice::Device(), PoDoFo::ePdfError_InvalidHandle, PoDoFo::ePdfError_InvalidStreamLength, PoDoFo::PdfInputDevice::GetChar(), PoDoFo::PdfVariant::GetDataTypeString(), PoDoFo::PdfVariant::GetDictionary_NoDL(), PoDoFo::PdfDictionary::GetKey(), PoDoFo::PdfVariant::GetNumber(), PoDoFo::PdfVecObjects::GetObject(), PoDoFo::PdfVariant::GetReference(), PoDoFo::PdfObject::GetStream_NoDL(), PoDoFo::PdfVariant::IsNumber(), PoDoFo::PdfVariant::IsReference(), PoDoFo::PdfTokenizer::IsWhitespace(), PoDoFo::PdfInputDevice::Look(), PoDoFo::PdfReference::ObjectNumber(), PODOFO_RAISE_ERROR, PODOFO_RAISE_ERROR_INFO, PoDoFo::PdfObject::Reference(), PoDoFo::PdfInputDevice::Seek(), PoDoFo::PdfEncrypt::SetCurrentReference(), PoDoFo::PdfVariant::SetDirty(), PoDoFo::PdfStream::SetRawData(), and PoDoFo::PdfInputDevice::Tell().

Referenced by PoDoFo::PdfParserObject::DelayedStreamLoadImpl().

{
#if defined(PODOFO_EXTRA_CHECKS)
    assert(DelayedLoadDone());
    assert(DelayedStreamLoadInProgress());
    assert(!DelayedStreamLoadDone());
#endif

    long long         lLen  = -1;
    int          c;

    if( !m_device.Device() || !m_pOwner )
    {
        PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
    }

    m_device.Device()->Seek( m_lStreamOffset );

    // From the PDF Reference manual
    // The keyword stream that follows
    // the stream dictionary should be followed by an end-of-line marker consisting of
    // either a carriage return and a line feed or just a line feed, and not by a carriage re-
    // turn alone.
    c = m_device.Device()->Look();
    if( PdfTokenizer::IsWhitespace( c ) )
    {
        c = m_device.Device()->GetChar();

        if( c == '\r' )
        {
            c = m_device.Device()->Look();
            if( c == '\n' )
            {
                c = m_device.Device()->GetChar();
            }
        }
    } 
    
    pdf_long fLoc = m_device.Device()->Tell();  // we need to save this, since loading the Length key could disturb it!

    PdfObject* pObj = this->GetDictionary_NoDL().GetKey( PdfName::KeyLength );  
    if( pObj && pObj->IsNumber() )
    {
        lLen = pObj->GetNumber();   
    }
    else if( pObj && pObj->IsReference() )
    {
        pObj = m_pOwner->GetObject( pObj->GetReference() );
        if( !pObj )
        {
            PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidHandle, "/Length key referenced indirect object that could not be loaded" );
        }

        printf("Reading object %i 0 R with type: %s\n", pObj->Reference().ObjectNumber(), pObj->GetDataTypeString());
        if( !pObj->IsNumber() )
        {
            PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidStreamLength, "/Length key for stream referenced non-number" );
        }

        lLen = pObj->GetNumber();

        // DS: This code makes no sense, 
        //     as empty streams with length 0 are valid, too.
        //if( !lLen )
        //{
        //    PODOFO_RAISE_ERROR( ePdfError_InvalidStreamLength );
        //}

        // we do not use indirect references for the length of the document
        // DS: Even though do not remove the length key,
        //     as 2 or more object might use the same object for key lengths.
        //     Deleting the length object of the first object will make
        //     all other objects non readable.
        //     If you want those length object to be removed,
        //     run the garbage collection of PdfVecObjects over your PDF.
        //delete m_pOwner->RemoveObject( pObj->Reference() );
    }
    else
    {
        PODOFO_RAISE_ERROR( ePdfError_InvalidStreamLength );
    }

    m_device.Device()->Seek( fLoc );      // reset it before reading!
    PdfDeviceInputStream reader( m_device.Device() );
    if( m_pEncrypt )
    {
        m_pEncrypt->SetCurrentReference( m_reference );
        PdfInputStream* pInput = m_pEncrypt->CreateEncryptionInputStream( &reader );
        this->GetStream_NoDL()->SetRawData( pInput, static_cast<pdf_long>(lLen) );
        delete pInput;
    }
    else
        this->GetStream_NoDL()->SetRawData( &reader, static_cast<pdf_long>(lLen) );

    this->SetDirty( false );
    /*
    SAFE_OP( GetNextStringFromFile( ) );
    if( strncmp( m_buffer.Buffer(), "endstream", s_nLenEndStream ) != 0 )
        return ERROR_PDF_MISSING_ENDSTREAM;
    */
}

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