Commit 60afe4142e4399b12f21aced476df7ef719008b9

Authored by Jay Berkenbilt
1 parent 15269f36

Refactor: separate copyStreamData from replaceForeignIndirectObjects

include/qpdf/QPDF.hh
@@ -1005,6 +1005,8 @@ class QPDF @@ -1005,6 +1005,8 @@ class QPDF
1005 bool top); 1005 bool top);
1006 QPDFObjectHandle replaceForeignIndirectObjects( 1006 QPDFObjectHandle replaceForeignIndirectObjects(
1007 QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top); 1007 QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top);
  1008 + void copyStreamData(
  1009 + QPDFObjectHandle dest_stream, QPDFObjectHandle src_stream);
1008 1010
1009 // Linearization Hint table structures. 1011 // Linearization Hint table structures.
1010 // Naming conventions: 1012 // Naming conventions:
libqpdf/QPDF.cc
@@ -2569,88 +2569,14 @@ QPDF::replaceForeignIndirectObjects( @@ -2569,88 +2569,14 @@ QPDF::replaceForeignIndirectObjects(
2569 QPDFObjectHandle old_dict = foreign.getDict(); 2569 QPDFObjectHandle old_dict = foreign.getDict();
2570 std::set<std::string> keys = old_dict.getKeys(); 2570 std::set<std::string> keys = old_dict.getKeys();
2571 for (std::set<std::string>::iterator iter = keys.begin(); 2571 for (std::set<std::string>::iterator iter = keys.begin();
2572 - iter != keys.end(); ++iter)  
2573 - { 2572 + iter != keys.end(); ++iter)
  2573 + {
2574 dict.replaceKey( 2574 dict.replaceKey(
2575 *iter, 2575 *iter,
2576 replaceForeignIndirectObjects( 2576 replaceForeignIndirectObjects(
2577 old_dict.getKey(*iter), obj_copier, false)); 2577 old_dict.getKey(*iter), obj_copier, false));
2578 - }  
2579 - if (this->m->copied_stream_data_provider == 0)  
2580 - {  
2581 - this->m->copied_stream_data_provider =  
2582 - new CopiedStreamDataProvider(*this);  
2583 - this->m->copied_streams = this->m->copied_stream_data_provider;  
2584 - }  
2585 - QPDFObjGen local_og(result.getObjGen());  
2586 - // Copy information from the foreign stream so we can pipe its  
2587 - // data later without keeping the original QPDF object around.  
2588 - QPDF* foreign_stream_qpdf = foreign.getOwningQPDF();  
2589 - if (! foreign_stream_qpdf)  
2590 - {  
2591 - throw std::logic_error("unable to retrieve owning qpdf"  
2592 - " from foreign stream");  
2593 - }  
2594 - QPDF_Stream* stream =  
2595 - dynamic_cast<QPDF_Stream*>(  
2596 - QPDFObjectHandle::ObjAccessor::getObject(  
2597 - foreign).getPointer());  
2598 - if (! stream)  
2599 - {  
2600 - throw std::logic_error("unable to retrieve underlying"  
2601 - " stream object from foreign stream");  
2602 - }  
2603 - PointerHolder<Buffer> stream_buffer =  
2604 - stream->getStreamDataBuffer();  
2605 - if ((foreign_stream_qpdf->m->immediate_copy_from) &&  
2606 - (stream_buffer.getPointer() == 0))  
2607 - {  
2608 - // Pull the stream data into a buffer before attempting  
2609 - // the copy operation. Do it on the source stream so that  
2610 - // if the source stream is copied multiple times, we don't  
2611 - // have to keep duplicating the memory.  
2612 - QTC::TC("qpdf", "QPDF immediate copy stream data");  
2613 - foreign.replaceStreamData(foreign.getRawStreamData(),  
2614 - old_dict.getKey("/Filter"),  
2615 - old_dict.getKey("/DecodeParms"));  
2616 - stream_buffer = stream->getStreamDataBuffer();  
2617 - }  
2618 - PointerHolder<QPDFObjectHandle::StreamDataProvider> stream_provider =  
2619 - stream->getStreamDataProvider();  
2620 - if (stream_buffer.getPointer())  
2621 - {  
2622 - QTC::TC("qpdf", "QPDF copy foreign stream with buffer");  
2623 - result.replaceStreamData(stream_buffer,  
2624 - dict.getKey("/Filter"),  
2625 - dict.getKey("/DecodeParms"));  
2626 - }  
2627 - else if (stream_provider.getPointer())  
2628 - {  
2629 - // In this case, the remote stream's QPDF must stay in scope.  
2630 - QTC::TC("qpdf", "QPDF copy foreign stream with provider");  
2631 - this->m->copied_stream_data_provider->registerForeignStream(  
2632 - local_og, foreign);  
2633 - result.replaceStreamData(this->m->copied_streams,  
2634 - dict.getKey("/Filter"),  
2635 - dict.getKey("/DecodeParms"));  
2636 - }  
2637 - else  
2638 - {  
2639 - PointerHolder<ForeignStreamData> foreign_stream_data =  
2640 - new ForeignStreamData(  
2641 - foreign_stream_qpdf->m->encp,  
2642 - foreign_stream_qpdf->m->file,  
2643 - foreign.getObjectID(),  
2644 - foreign.getGeneration(),  
2645 - stream->getOffset(),  
2646 - stream->getLength(),  
2647 - dict);  
2648 - this->m->copied_stream_data_provider->registerForeignStream(  
2649 - local_og, foreign_stream_data);  
2650 - result.replaceStreamData(this->m->copied_streams,  
2651 - dict.getKey("/Filter"),  
2652 - dict.getKey("/DecodeParms"));  
2653 } 2578 }
  2579 + copyStreamData(result, foreign);
2654 } 2580 }
2655 else 2581 else
2656 { 2582 {
@@ -2668,6 +2594,88 @@ QPDF::replaceForeignIndirectObjects( @@ -2668,6 +2594,88 @@ QPDF::replaceForeignIndirectObjects(
2668 } 2594 }
2669 2595
2670 void 2596 void
  2597 +QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign)
  2598 +{
  2599 + QPDFObjectHandle dict = result.getDict();
  2600 + QPDFObjectHandle old_dict = foreign.getDict();
  2601 + if (this->m->copied_stream_data_provider == 0)
  2602 + {
  2603 + this->m->copied_stream_data_provider =
  2604 + new CopiedStreamDataProvider(*this);
  2605 + this->m->copied_streams = this->m->copied_stream_data_provider;
  2606 + }
  2607 + QPDFObjGen local_og(result.getObjGen());
  2608 + // Copy information from the foreign stream so we can pipe its
  2609 + // data later without keeping the original QPDF object around.
  2610 + QPDF* foreign_stream_qpdf = foreign.getOwningQPDF();
  2611 + if (! foreign_stream_qpdf)
  2612 + {
  2613 + throw std::logic_error("unable to retrieve owning qpdf"
  2614 + " from foreign stream");
  2615 + }
  2616 + QPDF_Stream* stream =
  2617 + dynamic_cast<QPDF_Stream*>(
  2618 + QPDFObjectHandle::ObjAccessor::getObject(
  2619 + foreign).getPointer());
  2620 + if (! stream)
  2621 + {
  2622 + throw std::logic_error("unable to retrieve underlying"
  2623 + " stream object from foreign stream");
  2624 + }
  2625 + PointerHolder<Buffer> stream_buffer =
  2626 + stream->getStreamDataBuffer();
  2627 + if ((foreign_stream_qpdf->m->immediate_copy_from) &&
  2628 + (stream_buffer.getPointer() == 0))
  2629 + {
  2630 + // Pull the stream data into a buffer before attempting
  2631 + // the copy operation. Do it on the source stream so that
  2632 + // if the source stream is copied multiple times, we don't
  2633 + // have to keep duplicating the memory.
  2634 + QTC::TC("qpdf", "QPDF immediate copy stream data");
  2635 + foreign.replaceStreamData(foreign.getRawStreamData(),
  2636 + old_dict.getKey("/Filter"),
  2637 + old_dict.getKey("/DecodeParms"));
  2638 + stream_buffer = stream->getStreamDataBuffer();
  2639 + }
  2640 + PointerHolder<QPDFObjectHandle::StreamDataProvider> stream_provider =
  2641 + stream->getStreamDataProvider();
  2642 + if (stream_buffer.getPointer())
  2643 + {
  2644 + QTC::TC("qpdf", "QPDF copy foreign stream with buffer");
  2645 + result.replaceStreamData(stream_buffer,
  2646 + dict.getKey("/Filter"),
  2647 + dict.getKey("/DecodeParms"));
  2648 + }
  2649 + else if (stream_provider.getPointer())
  2650 + {
  2651 + // In this case, the remote stream's QPDF must stay in scope.
  2652 + QTC::TC("qpdf", "QPDF copy foreign stream with provider");
  2653 + this->m->copied_stream_data_provider->registerForeignStream(
  2654 + local_og, foreign);
  2655 + result.replaceStreamData(this->m->copied_streams,
  2656 + dict.getKey("/Filter"),
  2657 + dict.getKey("/DecodeParms"));
  2658 + }
  2659 + else
  2660 + {
  2661 + PointerHolder<ForeignStreamData> foreign_stream_data =
  2662 + new ForeignStreamData(
  2663 + foreign_stream_qpdf->m->encp,
  2664 + foreign_stream_qpdf->m->file,
  2665 + foreign.getObjectID(),
  2666 + foreign.getGeneration(),
  2667 + stream->getOffset(),
  2668 + stream->getLength(),
  2669 + dict);
  2670 + this->m->copied_stream_data_provider->registerForeignStream(
  2671 + local_og, foreign_stream_data);
  2672 + result.replaceStreamData(this->m->copied_streams,
  2673 + dict.getKey("/Filter"),
  2674 + dict.getKey("/DecodeParms"));
  2675 + }
  2676 +}
  2677 +
  2678 +void
2671 QPDF::swapObjects(QPDFObjGen const& og1, QPDFObjGen const& og2) 2679 QPDF::swapObjects(QPDFObjGen const& og1, QPDFObjGen const& og2)
2672 { 2680 {
2673 swapObjects(og1.getObj(), og1.getGen(), og2.getObj(), og2.getGen()); 2681 swapObjects(og1.getObj(), og1.getGen(), og2.getObj(), og2.getGen());