aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/Pl_MD5.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2015-10-25 16:09:25 +0100
committerJay Berkenbilt <ejb@ql.org>2015-10-31 23:56:42 +0100
commitb8bdef0ad12883d72ced5eb443e6e34a93bbbb91 (patch)
tree473250ef5919bba535743c2381b86c64ebe810a8 /libqpdf/Pl_MD5.cc
parent607c39211224e0d3bc2ab7066f16ff4952851ee9 (diff)
downloadqpdf-b8bdef0ad12883d72ced5eb443e6e34a93bbbb91.tar.zst
Implement deterministic ID
For non-encrypted files, determinstic ID generation uses file contents instead of timestamp and file name. At a small runtime cost, this enables generation of the same /ID if the same inputs are converted in the same way multiple times.
Diffstat (limited to 'libqpdf/Pl_MD5.cc')
-rw-r--r--libqpdf/Pl_MD5.cc61
1 files changed, 41 insertions, 20 deletions
diff --git a/libqpdf/Pl_MD5.cc b/libqpdf/Pl_MD5.cc
index 3a78cb33..0510e50e 100644
--- a/libqpdf/Pl_MD5.cc
+++ b/libqpdf/Pl_MD5.cc
@@ -3,7 +3,9 @@
Pl_MD5::Pl_MD5(char const* identifier, Pipeline* next) :
Pipeline(identifier, next),
- in_progress(false)
+ in_progress(false),
+ enabled(true),
+ persist_across_finish(false)
{
}
@@ -14,24 +16,27 @@ Pl_MD5::~Pl_MD5()
void
Pl_MD5::write(unsigned char* buf, size_t len)
{
- if (! this->in_progress)
+ if (this->enabled)
{
- this->md5.reset();
- this->in_progress = true;
- }
+ if (! this->in_progress)
+ {
+ this->md5.reset();
+ this->in_progress = true;
+ }
- // Write in chunks in case len is too big to fit in an int.
- // Assume int is at least 32 bits.
- static size_t const max_bytes = 1 << 30;
- size_t bytes_left = len;
- unsigned char* data = buf;
- while (bytes_left > 0)
- {
- size_t bytes = (bytes_left >= max_bytes ? max_bytes : bytes_left);
- this->md5.encodeDataIncrementally(
- reinterpret_cast<char*>(data), bytes);
- bytes_left -= bytes;
- data += bytes;
+ // Write in chunks in case len is too big to fit in an int.
+ // Assume int is at least 32 bits.
+ static size_t const max_bytes = 1 << 30;
+ size_t bytes_left = len;
+ unsigned char* data = buf;
+ while (bytes_left > 0)
+ {
+ size_t bytes = (bytes_left >= max_bytes ? max_bytes : bytes_left);
+ this->md5.encodeDataIncrementally(
+ reinterpret_cast<char*>(data), bytes);
+ bytes_left -= bytes;
+ data += bytes;
+ }
}
this->getNext()->write(buf, len);
@@ -41,16 +46,32 @@ void
Pl_MD5::finish()
{
this->getNext()->finish();
- this->in_progress = false;
+ if (! this->persist_across_finish)
+ {
+ this->in_progress = false;
+ }
+}
+
+void
+Pl_MD5::enable(bool enabled)
+{
+ this->enabled = enabled;
+}
+
+void
+Pl_MD5::persistAcrossFinish(bool persist)
+{
+ this->persist_across_finish = persist;
}
std::string
Pl_MD5::getHexDigest()
{
- if (this->in_progress)
+ if (! this->enabled)
{
throw std::logic_error(
- "digest requested for in-progress MD5 Pipeline");
+ "digest requested for a disabled MD5 Pipeline");
}
+ this->in_progress = false;
return this->md5.unparse();
}