void PdfXRef::Write( PdfOutputDevice* pDevice ) { PdfXRef::TCIVecXRefBlock it = m_vecBlocks.begin(); PdfXRef::TCIVecXRefItems itItems; PdfXRef::TCIVecReferences itFree; const PdfReference* pNextFree = NULL; pdf_objnum nFirst = 0; pdf_uint32 nCount = 0; MergeBlocks(); m_offset = pDevice->Tell(); this->BeginWrite( pDevice ); while( it != m_vecBlocks.end() ) { nCount = (*it).m_nCount; nFirst = (*it).m_nFirst; itFree = (*it).freeItems.begin(); itItems = (*it).items.begin(); if( nFirst == 1 ) { --nFirst; ++nCount; } // when there is only one, then we need to start with 0 and the bogus object... this->WriteSubSection( pDevice, nFirst, nCount ); if( !nFirst ) { const PdfReference* pFirstFree = this->GetFirstFreeObject( it, itFree ); this->WriteXRefEntry( pDevice, pFirstFree ? pFirstFree->ObjectNumber() : 0, EMPTY_OBJECT_OFFSET, 'f' ); } while( itItems != (*it).items.end() ) { // check if there is a free object at the current position while( itFree != (*it).freeItems.end() && *itFree < (*itItems).reference ) { pdf_gennum nGen = (*itFree).GenerationNumber(); // get a pointer to the next free object pNextFree = this->GetNextFreeObject( it, itFree ); // write free object this->WriteXRefEntry( pDevice, pNextFree ? pNextFree->ObjectNumber() : 0, nGen, 'f' ); ++itFree; } this->WriteXRefEntry( pDevice, (*itItems).offset, (*itItems).reference.GenerationNumber(), 'n', (*itItems).reference.ObjectNumber() ); ++itItems; } // Check if there are any free objects left! while( itFree != (*it).freeItems.end() ) { pdf_gennum nGen = (*itFree).GenerationNumber(); // get a pointer to the next free object pNextFree = this->GetNextFreeObject( it, itFree ); // write free object this->WriteXRefEntry( pDevice, pNextFree ? pNextFree->ObjectNumber() : 0, nGen, 'f' ); ++itFree; } ++it; } this->EndWrite( pDevice ); }
Pass::Status BlockMergePass::Process() { // Process all entry point functions. ProcessFunction pfn = [this](Function* fp) { return MergeBlocks(fp); }; bool modified = context()->ProcessEntryPointCallTree(pfn); return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange; }