2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-05-29 00:10:54 +00:00

ClosedFileInputSource: add method to keep file open

During periods of intensive operation on a specific file, this method
can reduce the overhead of repeated open/close operations.
This commit is contained in:
Jay Berkenbilt 2018-08-04 19:50:21 -04:00
parent 7855e18ae2
commit 4f4c627b77
5 changed files with 41 additions and 1 deletions

View File

@ -1,3 +1,10 @@
2018-08-04 Jay Berkenbilt <ejb@ql.org>
* Add ClosedFileInputSource::stayOpen method, enabling a
ClosedFileInputSource to stay open during manually indicated
periods of high activity, thus reducing the overhead of frequent
open/close operations.
2018-06-23 Jay Berkenbilt <ejb@ql.org> 2018-06-23 Jay Berkenbilt <ejb@ql.org>
* 8.1.0: release * 8.1.0: release

View File

@ -55,6 +55,13 @@ class ClosedFileInputSource: public InputSource
QPDF_DLL QPDF_DLL
virtual void unreadCh(char ch); virtual void unreadCh(char ch);
// The file stays open between calls to stayOpen(true) and
// stayOpen(false). You can use this to surround multiple
// operations on a single ClosedFileInputSource to reduce the
// overhead of a separate open/close on each call.
QPDF_DLL
void stayOpen(bool);
private: private:
ClosedFileInputSource(ClosedFileInputSource const&); ClosedFileInputSource(ClosedFileInputSource const&);
ClosedFileInputSource& operator=(ClosedFileInputSource const&); ClosedFileInputSource& operator=(ClosedFileInputSource const&);
@ -76,6 +83,7 @@ class ClosedFileInputSource: public InputSource
std::string filename; std::string filename;
qpdf_offset_t offset; qpdf_offset_t offset;
FileInputSource* fis; FileInputSource* fis;
bool stay_open;
}; };
PointerHolder<Members> m; PointerHolder<Members> m;
}; };

View File

@ -4,7 +4,8 @@
ClosedFileInputSource::Members::Members(char const* filename) : ClosedFileInputSource::Members::Members(char const* filename) :
filename(filename), filename(filename),
offset(0), offset(0),
fis(0) fis(0),
stay_open(false)
{ {
} }
@ -42,6 +43,10 @@ ClosedFileInputSource::after()
{ {
this->last_offset = this->m->fis->getLastOffset(); this->last_offset = this->m->fis->getLastOffset();
this->m->offset = this->m->fis->tell(); this->m->offset = this->m->fis->tell();
if (this->m->stay_open)
{
return;
}
delete this->m->fis; delete this->m->fis;
this->m->fis = 0; this->m->fis = 0;
} }
@ -82,6 +87,10 @@ void
ClosedFileInputSource::rewind() ClosedFileInputSource::rewind()
{ {
this->m->offset = 0; this->m->offset = 0;
if (this->m->fis)
{
this->m->fis->rewind();
}
} }
size_t size_t
@ -101,3 +110,13 @@ ClosedFileInputSource::unreadCh(char ch)
// Don't call after -- the file has to stay open after this // Don't call after -- the file has to stay open after this
// operation. // operation.
} }
void
ClosedFileInputSource::stayOpen(bool val)
{
this->m->stay_open = val;
if ((! val) && this->m->fis)
{
after();
}
}

View File

@ -65,6 +65,11 @@ int main()
std::cout << "testing with ClosedFileInputSource\n"; std::cout << "testing with ClosedFileInputSource\n";
ClosedFileInputSource cf("input"); ClosedFileInputSource cf("input");
do_tests(&cf); do_tests(&cf);
std::cout << "testing with ClosedFileInputSource in stay open mode\n";
ClosedFileInputSource cf2("input");
cf2.stayOpen(true);
do_tests(&cf2);
cf2.stayOpen(false);
std::cout << "testing with FileInputSource\n"; std::cout << "testing with FileInputSource\n";
FileInputSource f; FileInputSource f;
f.setFilename("input"); f.setFilename("input");

View File

@ -1,3 +1,4 @@
testing with ClosedFileInputSource testing with ClosedFileInputSource
testing with ClosedFileInputSource in stay open mode
testing with FileInputSource testing with FileInputSource
all assertions passed all assertions passed