mirror of
https://github.com/qpdf/qpdf.git
synced 2025-02-02 03:48:24 +00:00
Refactor: separate copyStreamData from replaceForeignIndirectObjects
This commit is contained in:
parent
15269f36d8
commit
60afe4142e
@ -1005,6 +1005,8 @@ class QPDF
|
||||
bool top);
|
||||
QPDFObjectHandle replaceForeignIndirectObjects(
|
||||
QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top);
|
||||
void copyStreamData(
|
||||
QPDFObjectHandle dest_stream, QPDFObjectHandle src_stream);
|
||||
|
||||
// Linearization Hint table structures.
|
||||
// Naming conventions:
|
||||
|
162
libqpdf/QPDF.cc
162
libqpdf/QPDF.cc
@ -2569,88 +2569,14 @@ QPDF::replaceForeignIndirectObjects(
|
||||
QPDFObjectHandle old_dict = foreign.getDict();
|
||||
std::set<std::string> keys = old_dict.getKeys();
|
||||
for (std::set<std::string>::iterator iter = keys.begin();
|
||||
iter != keys.end(); ++iter)
|
||||
{
|
||||
iter != keys.end(); ++iter)
|
||||
{
|
||||
dict.replaceKey(
|
||||
*iter,
|
||||
replaceForeignIndirectObjects(
|
||||
old_dict.getKey(*iter), obj_copier, false));
|
||||
}
|
||||
if (this->m->copied_stream_data_provider == 0)
|
||||
{
|
||||
this->m->copied_stream_data_provider =
|
||||
new CopiedStreamDataProvider(*this);
|
||||
this->m->copied_streams = this->m->copied_stream_data_provider;
|
||||
}
|
||||
QPDFObjGen local_og(result.getObjGen());
|
||||
// Copy information from the foreign stream so we can pipe its
|
||||
// data later without keeping the original QPDF object around.
|
||||
QPDF* foreign_stream_qpdf = foreign.getOwningQPDF();
|
||||
if (! foreign_stream_qpdf)
|
||||
{
|
||||
throw std::logic_error("unable to retrieve owning qpdf"
|
||||
" from foreign stream");
|
||||
}
|
||||
QPDF_Stream* stream =
|
||||
dynamic_cast<QPDF_Stream*>(
|
||||
QPDFObjectHandle::ObjAccessor::getObject(
|
||||
foreign).getPointer());
|
||||
if (! stream)
|
||||
{
|
||||
throw std::logic_error("unable to retrieve underlying"
|
||||
" stream object from foreign stream");
|
||||
}
|
||||
PointerHolder<Buffer> stream_buffer =
|
||||
stream->getStreamDataBuffer();
|
||||
if ((foreign_stream_qpdf->m->immediate_copy_from) &&
|
||||
(stream_buffer.getPointer() == 0))
|
||||
{
|
||||
// Pull the stream data into a buffer before attempting
|
||||
// the copy operation. Do it on the source stream so that
|
||||
// if the source stream is copied multiple times, we don't
|
||||
// have to keep duplicating the memory.
|
||||
QTC::TC("qpdf", "QPDF immediate copy stream data");
|
||||
foreign.replaceStreamData(foreign.getRawStreamData(),
|
||||
old_dict.getKey("/Filter"),
|
||||
old_dict.getKey("/DecodeParms"));
|
||||
stream_buffer = stream->getStreamDataBuffer();
|
||||
}
|
||||
PointerHolder<QPDFObjectHandle::StreamDataProvider> stream_provider =
|
||||
stream->getStreamDataProvider();
|
||||
if (stream_buffer.getPointer())
|
||||
{
|
||||
QTC::TC("qpdf", "QPDF copy foreign stream with buffer");
|
||||
result.replaceStreamData(stream_buffer,
|
||||
dict.getKey("/Filter"),
|
||||
dict.getKey("/DecodeParms"));
|
||||
}
|
||||
else if (stream_provider.getPointer())
|
||||
{
|
||||
// In this case, the remote stream's QPDF must stay in scope.
|
||||
QTC::TC("qpdf", "QPDF copy foreign stream with provider");
|
||||
this->m->copied_stream_data_provider->registerForeignStream(
|
||||
local_og, foreign);
|
||||
result.replaceStreamData(this->m->copied_streams,
|
||||
dict.getKey("/Filter"),
|
||||
dict.getKey("/DecodeParms"));
|
||||
}
|
||||
else
|
||||
{
|
||||
PointerHolder<ForeignStreamData> foreign_stream_data =
|
||||
new ForeignStreamData(
|
||||
foreign_stream_qpdf->m->encp,
|
||||
foreign_stream_qpdf->m->file,
|
||||
foreign.getObjectID(),
|
||||
foreign.getGeneration(),
|
||||
stream->getOffset(),
|
||||
stream->getLength(),
|
||||
dict);
|
||||
this->m->copied_stream_data_provider->registerForeignStream(
|
||||
local_og, foreign_stream_data);
|
||||
result.replaceStreamData(this->m->copied_streams,
|
||||
dict.getKey("/Filter"),
|
||||
dict.getKey("/DecodeParms"));
|
||||
}
|
||||
copyStreamData(result, foreign);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2667,6 +2593,88 @@ QPDF::replaceForeignIndirectObjects(
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign)
|
||||
{
|
||||
QPDFObjectHandle dict = result.getDict();
|
||||
QPDFObjectHandle old_dict = foreign.getDict();
|
||||
if (this->m->copied_stream_data_provider == 0)
|
||||
{
|
||||
this->m->copied_stream_data_provider =
|
||||
new CopiedStreamDataProvider(*this);
|
||||
this->m->copied_streams = this->m->copied_stream_data_provider;
|
||||
}
|
||||
QPDFObjGen local_og(result.getObjGen());
|
||||
// Copy information from the foreign stream so we can pipe its
|
||||
// data later without keeping the original QPDF object around.
|
||||
QPDF* foreign_stream_qpdf = foreign.getOwningQPDF();
|
||||
if (! foreign_stream_qpdf)
|
||||
{
|
||||
throw std::logic_error("unable to retrieve owning qpdf"
|
||||
" from foreign stream");
|
||||
}
|
||||
QPDF_Stream* stream =
|
||||
dynamic_cast<QPDF_Stream*>(
|
||||
QPDFObjectHandle::ObjAccessor::getObject(
|
||||
foreign).getPointer());
|
||||
if (! stream)
|
||||
{
|
||||
throw std::logic_error("unable to retrieve underlying"
|
||||
" stream object from foreign stream");
|
||||
}
|
||||
PointerHolder<Buffer> stream_buffer =
|
||||
stream->getStreamDataBuffer();
|
||||
if ((foreign_stream_qpdf->m->immediate_copy_from) &&
|
||||
(stream_buffer.getPointer() == 0))
|
||||
{
|
||||
// Pull the stream data into a buffer before attempting
|
||||
// the copy operation. Do it on the source stream so that
|
||||
// if the source stream is copied multiple times, we don't
|
||||
// have to keep duplicating the memory.
|
||||
QTC::TC("qpdf", "QPDF immediate copy stream data");
|
||||
foreign.replaceStreamData(foreign.getRawStreamData(),
|
||||
old_dict.getKey("/Filter"),
|
||||
old_dict.getKey("/DecodeParms"));
|
||||
stream_buffer = stream->getStreamDataBuffer();
|
||||
}
|
||||
PointerHolder<QPDFObjectHandle::StreamDataProvider> stream_provider =
|
||||
stream->getStreamDataProvider();
|
||||
if (stream_buffer.getPointer())
|
||||
{
|
||||
QTC::TC("qpdf", "QPDF copy foreign stream with buffer");
|
||||
result.replaceStreamData(stream_buffer,
|
||||
dict.getKey("/Filter"),
|
||||
dict.getKey("/DecodeParms"));
|
||||
}
|
||||
else if (stream_provider.getPointer())
|
||||
{
|
||||
// In this case, the remote stream's QPDF must stay in scope.
|
||||
QTC::TC("qpdf", "QPDF copy foreign stream with provider");
|
||||
this->m->copied_stream_data_provider->registerForeignStream(
|
||||
local_og, foreign);
|
||||
result.replaceStreamData(this->m->copied_streams,
|
||||
dict.getKey("/Filter"),
|
||||
dict.getKey("/DecodeParms"));
|
||||
}
|
||||
else
|
||||
{
|
||||
PointerHolder<ForeignStreamData> foreign_stream_data =
|
||||
new ForeignStreamData(
|
||||
foreign_stream_qpdf->m->encp,
|
||||
foreign_stream_qpdf->m->file,
|
||||
foreign.getObjectID(),
|
||||
foreign.getGeneration(),
|
||||
stream->getOffset(),
|
||||
stream->getLength(),
|
||||
dict);
|
||||
this->m->copied_stream_data_provider->registerForeignStream(
|
||||
local_og, foreign_stream_data);
|
||||
result.replaceStreamData(this->m->copied_streams,
|
||||
dict.getKey("/Filter"),
|
||||
dict.getKey("/DecodeParms"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
QPDF::swapObjects(QPDFObjGen const& og1, QPDFObjGen const& og2)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user