void PdfImmediateWriter::Finish()
{
    // write all objects which are still in RAM
    this->FinishLastObject();

    // setup encrypt dictionary
    if( m_pEncrypt )
    {
        // Add our own Encryption dictionary
        m_pEncryptObj = m_vecObjects->CreateObject();
        m_pEncrypt->CreateEncryptionDictionary( m_pEncryptObj->GetDictionary() );
    }

    this->WritePdfObjects( m_pDevice, *m_pParent, m_pXRef );

    // write the XRef
    pdf_long lXRefOffset = m_pDevice->Tell();
    m_pXRef->Write( m_pDevice );
            
    // XRef streams contain the trailer in the XRef
    if( !m_bXRefStream ) 
    {
        PdfObject trailer;
        
        // if we have a dummy offset we write also a prev entry to the trailer
        FillTrailerObject( &trailer, m_pXRef->GetSize(), false, false );
        
        m_pDevice->Print("trailer\n");
        trailer.WriteObject( m_pDevice, this->GetWriteMode(), NULL );
    }
    
    m_pDevice->Print( "startxref\n%li\n%%%%EOF\n", lXRefOffset );
    m_pDevice->Flush();

    // we are done now
    m_pParent->Detach( this );
    m_pParent = NULL;
}
Exemplo n.º 2
0
void PdfSigIncWriter::Write( PdfOutputDevice* pDevice, pdf_int64 prevOffset)
{
    //CreateFileIdentifier( m_identifier, m_pTrailer );
    if( m_pTrailer->GetDictionary().HasKey( "ID" ) ) {
       PdfObject *idObj =  m_pTrailer->GetDictionary().GetKey("ID");
       
       TCIVariantList it = idObj->GetArray().begin();
		 while( it != idObj->GetArray().end() ) {
			if( (*it).GetDataType() == ePdfDataType_HexString ) {
				 PdfVariant var = (*it);
             m_identifier = var.GetString();
			}
				
			++it;
		}
    } else {
       PdfDate   date;
       PdfString dateString;
       PdfObject*      pInfo;
       PdfOutputDevice length;

       date.ToString( dateString );

       pInfo = new PdfObject();
       pInfo->GetDictionary().AddKey( "CreationDate", dateString );
       pInfo->GetDictionary().AddKey( "Creator", PdfString("PoDoFo") );
       pInfo->GetDictionary().AddKey( "Producer", PdfString("PoDoFo") );
       
      pInfo->GetDictionary().AddKey( "Location", PdfString("SOMEFILENAME") );

      pInfo->WriteObject( &length, ePdfWriteMode_Clean, NULL );

      char *pBuffer = static_cast<char*>(podofo_calloc( length.GetLength(), sizeof(char) ));
      if( !pBuffer )  {
        delete pInfo;
        PODOFO_RAISE_ERROR( ePdfError_OutOfMemory );
      } 

      PdfOutputDevice device( pBuffer, length.GetLength() );
      pInfo->WriteObject( &device, ePdfWriteMode_Clean, NULL );

      // calculate the MD5 Sum
      m_identifier = PdfEncryptMD5Base::GetMD5String( reinterpret_cast<unsigned char*>(pBuffer),
                                           static_cast<unsigned int>(length.GetLength()) );
      podofo_free( pBuffer );

      delete pInfo;
    }

    if( !pDevice )
    {
        PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
    }

    // setup encrypt dictionary
    if( m_pEncrypt )
    {
        m_pEncrypt->GenerateEncryptionKey( m_identifier );

        // Add our own Encryption dictionary
        m_pEncryptObj = m_vecObjects->CreateObject();
        m_pEncrypt->CreateEncryptionDictionary( m_pEncryptObj->GetDictionary() );
    }

    if( GetLinearized() ) 
    {
        this->WriteLinearized( pDevice );
    }
    else
    {
        PdfXRef* pXRef = m_bXRefStream ? new PdfXRefStream( m_vecObjects, this ) : new PdfXRef();

        try {
//            WritePdfHeader  ( pDevice );
            WritePdfObjects ( pDevice, *m_vecObjects, pXRef );
            pXRef->SetFirstEmptyBlock();

            pXRef->Write( pDevice );
            
            // XRef streams contain the trailer in the XRef
            if( !m_bXRefStream ) 
            {
                PdfObject  trailer;
                
                // if we have a dummy offset we write also a prev entry to the trailer
                FillTrailerObject( &trailer, pXRef->GetSize(), false, false );

                PdfObject prevOffsetObj(prevOffset);
                trailer.GetDictionary().AddKey( "Prev", prevOffsetObj);
                pDevice->Print("trailer\n");
                trailer.WriteObject( pDevice, ePdfWriteMode_Clean, NULL ); // Do not encrypt the trailer dicionary!!!
            }
            
            pDevice->Print( "startxref\n%li\n%%%%EOF\n", pXRef->GetOffset());
            delete pXRef;
        } catch( PdfError & e ) {
            // Make sure pXRef is always deleted
            delete pXRef;
            e.AddToCallstack( __FILE__, __LINE__ );
            throw e;
        }
    }
}