aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README-maintainer3
-rw-r--r--TODO26
-rw-r--r--include/qpdf/Buffer.hh28
-rw-r--r--include/qpdf/BufferInputSource.hh23
-rw-r--r--include/qpdf/FileInputSource.hh21
-rw-r--r--include/qpdf/InputSource.hh17
-rw-r--r--include/qpdf/Pipeline.hh18
-rw-r--r--include/qpdf/Pl_Buffer.hh22
-rw-r--r--include/qpdf/Pl_Concatenate.hh16
-rw-r--r--include/qpdf/Pl_Count.hh23
-rw-r--r--include/qpdf/Pl_DCT.hh36
-rw-r--r--include/qpdf/Pl_Discard.hh16
-rw-r--r--include/qpdf/Pl_Flate.hh25
-rw-r--r--include/qpdf/Pl_RunLength.hh23
-rw-r--r--include/qpdf/Pl_StdioFile.hh17
-rw-r--r--include/qpdf/QPDFExc.hh5
-rw-r--r--include/qpdf/QPDFObjGen.hh3
-rw-r--r--include/qpdf/QPDFSystemError.hh5
-rw-r--r--include/qpdf/QPDFXRefEntry.hh2
-rw-r--r--libqpdf/Buffer.cc82
-rw-r--r--libqpdf/BufferInputSource.cc82
-rw-r--r--libqpdf/FileInputSource.cc65
-rw-r--r--libqpdf/InputSource.cc7
-rw-r--r--libqpdf/Pipeline.cc15
-rw-r--r--libqpdf/Pl_Buffer.cc60
-rw-r--r--libqpdf/Pl_Concatenate.cc8
-rw-r--r--libqpdf/Pl_Count.cc21
-rw-r--r--libqpdf/Pl_DCT.cc57
-rw-r--r--libqpdf/Pl_Discard.cc8
-rw-r--r--libqpdf/Pl_Flate.cc66
-rw-r--r--libqpdf/Pl_RunLength.cc97
-rw-r--r--libqpdf/Pl_StdioFile.cc15
-rw-r--r--libtests/buffer.cc30
-rw-r--r--libtests/qtest/buffer/buffer.out2
34 files changed, 623 insertions, 321 deletions
diff --git a/README-maintainer b/README-maintainer
index 3bb2b659..94e6514b 100644
--- a/README-maintainer
+++ b/README-maintainer
@@ -70,6 +70,9 @@ CODING RULES
it seems also for classes that are intended to be subclassed across
the shared library boundary.
+* Put private member variables in PointerHolder<Members> for all
+ public classes. Remember to use QPDF_DLL on ~Members().
+
RELEASE PREPARATION
* Each year, update copyright notices. Just do a case-insensitive
diff --git a/TODO b/TODO
index d32d21d7..dd41430c 100644
--- a/TODO
+++ b/TODO
@@ -1,32 +1,6 @@
Next ABI
========
- * Check all classes that don't use the Members pattern and see if
- they should be converted. Most of the pipeline classes should be
- converted.
-
- Buffer.hh
- BufferInputSource.hh
- FileInputSource.hh
- InputSource.hh
- Pl_Buffer.hh
- Pl_Concatenate.hh
- Pl_Count.hh
- Pl_DCT.hh
- Pl_Discard.hh
- Pl_Flate.hh
- Pl_RunLength.hh
- Pl_StdioFile.hh
- QPDFExc.hh
- QPDFObjGen.hh
- QPDFSystemError.hh
- QPDFXRefEntry.hh
-
- * Pl_Buffer's internal structure is not right for what it does. It
- was modified for greater efficiency, but it was done in a way that
- preserved binary compatibility, so the implementation is a bit
- convoluted.
-
* Check all overloaded methods to see if any can be eliminated by
using defaulted arguments. See ../misc/find-overloaded-functions.pl
(not in source repo)
diff --git a/include/qpdf/Buffer.hh b/include/qpdf/Buffer.hh
index bb9a3eb9..8145f41a 100644
--- a/include/qpdf/Buffer.hh
+++ b/include/qpdf/Buffer.hh
@@ -23,7 +23,8 @@
#define BUFFER_HH
#include <qpdf/DLL.h>
-#include <cstring> // for size_t
+#include <qpdf/PointerHolder.hh>
+#include <stddef.h>
class Buffer
{
@@ -46,8 +47,6 @@ class Buffer
QPDF_DLL
Buffer& operator=(Buffer const&);
QPDF_DLL
- ~Buffer();
- QPDF_DLL
size_t getSize() const;
QPDF_DLL
unsigned char const* getBuffer() const;
@@ -55,13 +54,26 @@ class Buffer
unsigned char* getBuffer();
private:
- void init(size_t size, unsigned char* buf, bool own_memory);
+ class Members
+ {
+ friend class Buffer;
+
+ public:
+ QPDF_DLL
+ ~Members();
+
+ private:
+ Members(size_t size, unsigned char* buf, bool own_memory);
+ Members(Members const&);
+
+ bool own_memory;
+ size_t size;
+ unsigned char* buf;
+ };
+
void copy(Buffer const&);
- void destroy();
- bool own_memory;
- size_t size;
- unsigned char* buf;
+ PointerHolder<Members> m;
};
#endif // BUFFER_HH
diff --git a/include/qpdf/BufferInputSource.hh b/include/qpdf/BufferInputSource.hh
index 51bb98f9..90263335 100644
--- a/include/qpdf/BufferInputSource.hh
+++ b/include/qpdf/BufferInputSource.hh
@@ -56,10 +56,25 @@ class BufferInputSource: public InputSource
private:
qpdf_offset_t const bufSizeAsOffset() const;
- bool own_memory;
- std::string description;
- Buffer* buf;
- qpdf_offset_t cur_offset;
+ class Members
+ {
+ friend class BufferInputSource;
+
+ public:
+ QPDF_DLL
+ ~Members();
+
+ private:
+ Members(bool own_memory, std::string const& description, Buffer* buf);
+ Members(Members const&);
+
+ bool own_memory;
+ std::string description;
+ Buffer* buf;
+ qpdf_offset_t cur_offset;
+ };
+
+ PointerHolder<Members> m;
};
#endif // QPDF_BUFFERINPUTSOURCE_HH
diff --git a/include/qpdf/FileInputSource.hh b/include/qpdf/FileInputSource.hh
index 0845f241..1bf2a2de 100644
--- a/include/qpdf/FileInputSource.hh
+++ b/include/qpdf/FileInputSource.hh
@@ -54,11 +54,24 @@ class FileInputSource: public InputSource
FileInputSource(FileInputSource const&);
FileInputSource& operator=(FileInputSource const&);
- void destroy();
+ class Members
+ {
+ friend class FileInputSource;
- bool close_file;
- std::string filename;
- FILE* file;
+ public:
+ QPDF_DLL
+ ~Members();
+
+ private:
+ Members(bool close_file);
+ Members(Members const&);
+
+ bool close_file;
+ std::string filename;
+ FILE* file;
+ };
+
+ PointerHolder<Members> m;
};
#endif // QPDF_FILEINPUTSOURCE_HH
diff --git a/include/qpdf/InputSource.hh b/include/qpdf/InputSource.hh
index 3d0d9aaf..db48fcba 100644
--- a/include/qpdf/InputSource.hh
+++ b/include/qpdf/InputSource.hh
@@ -24,6 +24,7 @@
#include <qpdf/DLL.h>
#include <qpdf/Types.h>
+#include <qpdf/PointerHolder.hh>
#include <stdio.h>
#include <string>
@@ -86,6 +87,22 @@ class QPDF_DLL_CLASS InputSource
protected:
qpdf_offset_t last_offset;
+
+ private:
+ class Members
+ {
+ friend class InputSource;
+
+ public:
+ QPDF_DLL
+ ~Members();
+
+ private:
+ Members();
+ Members(Members const&);
+ };
+
+ PointerHolder<Members> m;
};
#endif // QPDF_INPUTSOURCE_HH
diff --git a/include/qpdf/Pipeline.hh b/include/qpdf/Pipeline.hh
index a5440a27..36a25df0 100644
--- a/include/qpdf/Pipeline.hh
+++ b/include/qpdf/Pipeline.hh
@@ -45,6 +45,7 @@
#define PIPELINE_HH
#include <qpdf/DLL.h>
+#include <qpdf/PointerHolder.hh>
#include <string>
class QPDF_DLL_CLASS Pipeline
@@ -79,7 +80,22 @@ class QPDF_DLL_CLASS Pipeline
Pipeline(Pipeline const&);
Pipeline& operator=(Pipeline const&);
- Pipeline* next;
+ class Members
+ {
+ friend class Pipeline;
+
+ public:
+ QPDF_DLL
+ ~Members();
+
+ private:
+ Members(Pipeline* next);
+ Members(Members const&);
+
+ Pipeline* next;
+ };
+
+ PointerHolder<Members> m;
};
#endif // PIPELINE_HH
diff --git a/include/qpdf/Pl_Buffer.hh b/include/qpdf/Pl_Buffer.hh
index 5eb143b2..0afa6c69 100644
--- a/include/qpdf/Pl_Buffer.hh
+++ b/include/qpdf/Pl_Buffer.hh
@@ -36,7 +36,6 @@
#include <qpdf/Pipeline.hh>
#include <qpdf/PointerHolder.hh>
#include <qpdf/Buffer.hh>
-#include <list>
class Pl_Buffer: public Pipeline
{
@@ -57,9 +56,24 @@ class Pl_Buffer: public Pipeline
Buffer* getBuffer();
private:
- bool ready;
- std::list<PointerHolder<Buffer> > data;
- size_t total_size;
+ class Members
+ {
+ friend class Pl_Buffer;
+
+ public:
+ QPDF_DLL
+ ~Members();
+
+ private:
+ Members();
+ Members(Members const&);
+
+ bool ready;
+ PointerHolder<Buffer> data;
+ size_t total_size;
+ };
+
+ PointerHolder<Members> m;
};
#endif // PL_BUFFER_HH
diff --git a/include/qpdf/Pl_Concatenate.hh b/include/qpdf/Pl_Concatenate.hh
index 26e5849e..135a9899 100644
--- a/include/qpdf/Pl_Concatenate.hh
+++ b/include/qpdf/Pl_Concatenate.hh
@@ -48,6 +48,22 @@ class Pl_Concatenate: public Pipeline
// the pipeline.
QPDF_DLL
void manualFinish();
+
+ private:
+ class Members
+ {
+ friend class Pl_Concatenate;
+
+ public:
+ QPDF_DLL
+ ~Members();
+
+ private:
+ Members();
+ Members(Members const&);
+ };
+
+ PointerHolder<Members> m;
};
#endif // PL_CONCATENATE_HH
diff --git a/include/qpdf/Pl_Count.hh b/include/qpdf/Pl_Count.hh
index 0b021d9a..aa281c5c 100644
--- a/include/qpdf/Pl_Count.hh
+++ b/include/qpdf/Pl_Count.hh
@@ -48,10 +48,25 @@ class Pl_Count: public Pipeline
unsigned char getLastChar() const;
private:
- // Must be qpdf_offset_t, not size_t, to handle writing more than
- // size_t can handle.
- qpdf_offset_t count;
- unsigned char last_char;
+ class Members
+ {
+ friend class Pl_Count;
+
+ public:
+ QPDF_DLL
+ ~Members();
+
+ private:
+ Members();
+ Members(Members const&);
+
+ // Must be qpdf_offset_t, not size_t, to handle writing more than
+ // size_t can handle.
+ qpdf_offset_t count;
+ unsigned char last_char;
+ };
+
+ PointerHolder<Members> m;
};
#endif // PL_COUNT_HH
diff --git a/include/qpdf/Pl_DCT.hh b/include/qpdf/Pl_DCT.hh
index 1827fa80..57a52cb4 100644
--- a/include/qpdf/Pl_DCT.hh
+++ b/include/qpdf/Pl_DCT.hh
@@ -68,17 +68,37 @@ class Pl_DCT: public Pipeline
enum action_e { a_compress, a_decompress };
- action_e action;
- Pl_Buffer buf;
+ class Members
+ {
+ friend class Pl_DCT;
+
+ public:
+ QPDF_DLL
+ ~Members();
- // Used for compression
- JDIMENSION image_width;
- JDIMENSION image_height;
- int components;
- J_COLOR_SPACE color_space;
+ private:
+ Members(action_e action,
+ char const* buf_description,
+ JDIMENSION image_width = 0,
+ JDIMENSION image_height = 0,
+ int components = 1,
+ J_COLOR_SPACE color_space = JCS_GRAYSCALE,
+ CompressConfig* config_callback = 0);
+ Members(Members const&);
- CompressConfig* config_callback;
+ action_e action;
+ Pl_Buffer buf;
+
+ // Used for compression
+ JDIMENSION image_width;
+ JDIMENSION image_height;
+ int components;
+ J_COLOR_SPACE color_space;
+
+ CompressConfig* config_callback;
+ };
+ PointerHolder<Members> m;
};
#endif // PL_DCT_HH
diff --git a/include/qpdf/Pl_Discard.hh b/include/qpdf/Pl_Discard.hh
index 129431b2..3130ef45 100644
--- a/include/qpdf/Pl_Discard.hh
+++ b/include/qpdf/Pl_Discard.hh
@@ -41,6 +41,22 @@ class Pl_Discard: public Pipeline
virtual void write(unsigned char*, size_t);
QPDF_DLL
virtual void finish();
+
+ private:
+ class Members
+ {
+ friend class Pl_Discard;
+
+ public:
+ QPDF_DLL
+ ~Members();
+
+ private:
+ Members();
+ Members(Members const&);
+ };
+
+ PointerHolder<Members> m;
};
#endif // PL_DISCARD_HH
diff --git a/include/qpdf/Pl_Flate.hh b/include/qpdf/Pl_Flate.hh
index 923b33a8..2884ecc5 100644
--- a/include/qpdf/Pl_Flate.hh
+++ b/include/qpdf/Pl_Flate.hh
@@ -46,11 +46,26 @@ class Pl_Flate: public Pipeline
void handleData(unsigned char* data, size_t len, int flush);
void checkError(char const* prefix, int error_code);
- unsigned char* outbuf;
- size_t out_bufsize;
- action_e action;
- bool initialized;
- void* zdata;
+ class Members
+ {
+ friend class Pl_Flate;
+
+ public:
+ QPDF_DLL
+ ~Members();
+
+ private:
+ Members(size_t out_bufsize, action_e action);
+ Members(Members const&);
+
+ unsigned char* outbuf;
+ size_t out_bufsize;
+ action_e action;
+ bool initialized;
+ void* zdata;
+ };
+
+ PointerHolder<Members> m;
};
#endif // PL_FLATE_HH
diff --git a/include/qpdf/Pl_RunLength.hh b/include/qpdf/Pl_RunLength.hh
index b8e696b6..a579ceea 100644
--- a/include/qpdf/Pl_RunLength.hh
+++ b/include/qpdf/Pl_RunLength.hh
@@ -47,10 +47,25 @@ class Pl_RunLength: public Pipeline
enum state_e { st_top, st_copying, st_run };
- action_e action;
- state_e state;
- unsigned char buf[128];
- unsigned int length;
+ class Members
+ {
+ friend class Pl_RunLength;
+
+ public:
+ QPDF_DLL
+ ~Members();
+
+ private:
+ Members(action_e);
+ Members(Members const&);
+
+ action_e action;
+ state_e state;
+ unsigned char buf[128];
+ unsigned int length;
+ };
+
+ PointerHolder<Members> m;
};
#endif // PL_RUNLENGTH_HH
diff --git a/include/qpdf/Pl_StdioFile.hh b/include/qpdf/Pl_StdioFile.hh
index fd228333..83d7faf2 100644
--- a/include/qpdf/Pl_StdioFile.hh
+++ b/include/qpdf/Pl_StdioFile.hh
@@ -48,7 +48,22 @@ class Pl_StdioFile: public Pipeline
virtual void finish();
private:
- FILE* file;
+ class Members
+ {
+ friend class Pl_StdioFile;
+
+ public:
+ QPDF_DLL
+ ~Members();
+
+ private:
+ Members(FILE*);
+ Members(Members const&);
+
+ FILE* file;
+ };
+
+ PointerHolder<Members> m;
};
#endif // PL_STDIOFILE_HH
diff --git a/include/qpdf/QPDFExc.hh b/include/qpdf/QPDFExc.hh
index 188ede29..4cabd7a9 100644
--- a/include/qpdf/QPDFExc.hh
+++ b/include/qpdf/QPDFExc.hh
@@ -24,8 +24,8 @@
#include <qpdf/DLL.h>
#include <qpdf/Types.h>
-
#include <qpdf/Constants.h>
+
#include <string>
#include <stdexcept>
@@ -70,6 +70,9 @@ class QPDF_DLL_CLASS QPDFExc: public std::runtime_error
qpdf_offset_t offset,
std::string const& message);
+ // This class does not use the Members pattern to avoid needless
+ // memory allocations during exception handling.
+
qpdf_error_code_e error_code;
std::string filename;
std::string object;
diff --git a/include/qpdf/QPDFObjGen.hh b/include/qpdf/QPDFObjGen.hh
index 81c45d9f..9b61c78d 100644
--- a/include/qpdf/QPDFObjGen.hh
+++ b/include/qpdf/QPDFObjGen.hh
@@ -44,6 +44,9 @@ class QPDFObjGen
int getGen() const;
private:
+ // This class does not use the Members pattern to avoid a memory
+ // allocation for every one of these. A lot of these get created
+ // and destroyed.
int obj;
int gen;
};
diff --git a/include/qpdf/QPDFSystemError.hh b/include/qpdf/QPDFSystemError.hh
index e8ea09eb..4ecd01d6 100644
--- a/include/qpdf/QPDFSystemError.hh
+++ b/include/qpdf/QPDFSystemError.hh
@@ -24,8 +24,8 @@
#include <qpdf/DLL.h>
#include <qpdf/Types.h>
-
#include <qpdf/Constants.h>
+
#include <string>
#include <stdexcept>
@@ -51,6 +51,9 @@ class QPDF_DLL_CLASS QPDFSystemError: public std::runtime_error
static std::string createWhat(std::string const& description,
int system_errno);
+ // This class does not use the Members pattern to avoid needless
+ // memory allocations during exception handling.
+
std::string description;
int system_errno;
};
diff --git a/include/qpdf/QPDFXRefEntry.hh b/include/qpdf/QPDFXRefEntry.hh
index ee3cf746..59b6a23f 100644
--- a/include/qpdf/QPDFXRefEntry.hh
+++ b/include/qpdf/QPDFXRefEntry.hh
@@ -49,6 +49,8 @@ class QPDFXRefEntry
int getObjStreamIndex() const; // only for type 2
private:
+ // This class does not use the Members pattern to avoid a memory
+ // allocation for every one of these. A lot of these get created.
int type;
qpdf_offset_t field1;
int field2;
diff --git a/libqpdf/Buffer.cc b/libqpdf/Buffer.cc
index 94e69a56..a15f73e8 100644
--- a/libqpdf/Buffer.cc
+++ b/libqpdf/Buffer.cc
@@ -1,53 +1,55 @@
#include <qpdf/Buffer.hh>
-#include <string.h>
+#include <cstring>
-Buffer::Buffer()
+Buffer::Members::Members(size_t size, unsigned char* buf, bool own_memory) :
+ own_memory(own_memory),
+ size(size),
+ buf(0)
{
- init(0, 0, true);
+ if (own_memory)
+ {
+ this->buf = (size ? new unsigned char[size] : 0);
+ }
+ else
+ {
+ this->buf = buf;
+ }
}
-Buffer::Buffer(size_t size)
+Buffer::Members::~Members()
{
- init(size, 0, true);
+ if (this->own_memory)
+ {
+ delete [] this->buf;
+ }
}
-Buffer::Buffer(unsigned char* buf, size_t size)
+Buffer::Buffer() :
+ m(new Members(0, 0, true))
{
- init(size, buf, false);
}
-Buffer::Buffer(Buffer const& rhs)
+Buffer::Buffer(size_t size) :
+ m(new Members(size, 0, true))
{
- init(0, 0, true);
- copy(rhs);
}
-Buffer&
-Buffer::operator=(Buffer const& rhs)
+Buffer::Buffer(unsigned char* buf, size_t size) :
+ m(new Members(size, buf, false))
{
- copy(rhs);
- return *this;
}
-Buffer::~Buffer()
+Buffer::Buffer(Buffer const& rhs)
{
- destroy();
+ copy(rhs);
}
-void
-Buffer::init(size_t size, unsigned char* buf, bool own_memory)
+Buffer&
+Buffer::operator=(Buffer const& rhs)
{
- this->own_memory = own_memory;
- this->size = size;
- if (own_memory)
- {
- this->buf = (size ? new unsigned char[size] : 0);
- }
- else
- {
- this->buf = buf;
- }
+ copy(rhs);
+ return *this;
}
void
@@ -55,40 +57,28 @@ Buffer::copy(Buffer const& rhs)
{
if (this != &rhs)
{
- this->destroy();
- this->init(rhs.size, 0, true);
- if (this->size)
+ this->m = new Members(rhs.m->size, 0, true);
+ if (this->m->size)
{
- memcpy(this->buf, rhs.buf, this->size);
+ memcpy(this->m->buf, rhs.m->buf, this->m->size);
}
}
}
-void
-Buffer::destroy()
-{
- if (this->own_memory)
- {
- delete [] this->buf;
- }
- this->size = 0;
- this->buf = 0;
-}
-
size_t
Buffer::getSize() const
{
- return this->size;
+ return this->m->size;
}
unsigned char const*
Buffer::getBuffer() const
{
- return this->buf;
+ return this->m->buf;
}
unsigned char*
Buffer::getBuffer()
{
- return this->buf;
+ return this->m->buf;
}
diff --git a/libqpdf/BufferInputSource.cc b/libqpdf/BufferInputSource.cc
index 1bf61bbd..23bad5f0 100644
--- a/libqpdf/BufferInputSource.cc
+++ b/libqpdf/BufferInputSource.cc
@@ -4,8 +4,9 @@
#include <stdexcept>
#include <algorithm>
-BufferInputSource::BufferInputSource(std::string const& description,
- Buffer* buf, bool own_memory) :
+BufferInputSource::Members::Members(bool own_memory,
+ std::string const& description,
+ Buffer* buf) :
own_memory(own_memory),
description(description),
buf(buf),
@@ -13,70 +14,77 @@ BufferInputSource::BufferInputSource(std::string const& description,
{
}
+BufferInputSource::Members::~Members()
+{
+}
+
+BufferInputSource::BufferInputSource(std::string const& description,
+ Buffer* buf, bool own_memory) :
+ m(new Members(own_memory, description, buf))
+{
+}
+
BufferInputSource::BufferInputSource(std::string const& description,
std::string const& contents) :
- own_memory(true),
- description(description),
- buf(0),
- cur_offset(0)
+ m(new Members(true, description, 0))
{
- this->buf = new Buffer(contents.length());
- unsigned char* bp = buf->getBuffer();
+ this->m->buf = new Buffer(contents.length());
+ unsigned char* bp = this->m->buf->getBuffer();
memcpy(bp, contents.c_str(), contents.length());
}
BufferInputSource::~BufferInputSource()
{
- if (own_memory)
+ if (this->m->own_memory)
{
- delete this->buf;
+ delete this->m->buf;
}
}
qpdf_offset_t const
BufferInputSource::bufSizeAsOffset() const
{
- return QIntC::to_offset(this->buf->getSize());
+ return QIntC::to_offset(this->m->buf->getSize());
}
qpdf_offset_t
BufferInputSource::findAndSkipNextEOL()
{
- if (this->cur_offset < 0)
+ if (this->m->cur_offset < 0)
{
throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0");
}
qpdf_offset_t end_pos = bufSizeAsOffset();
- if (this->cur_offset >= end_pos)
+ if (this->m->cur_offset >= end_pos)
{
this->last_offset = end_pos;
- this->cur_offset = end_pos;
+ this->m->cur_offset = end_pos;
return end_pos;
}
qpdf_offset_t result = 0;
- size_t len = QIntC::to_size(end_pos - this->cur_offset);
- unsigned char const* buffer = this->buf->getBuffer();
+ size_t len = QIntC::to_size(end_pos - this->m->cur_offset);
+ unsigned char const* buffer = this->m->buf->getBuffer();
- void* start = const_cast<unsigned char*>(buffer) + this->cur_offset;
+ void* start = const_cast<unsigned char*>(buffer) + this->m->cur_offset;
unsigned char* p1 = static_cast<unsigned char*>(memchr(start, '\r', len));
unsigned char* p2 = static_cast<unsigned char*>(memchr(start, '\n', len));
unsigned char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2;
if (p)
{
result = p - buffer;
- this->cur_offset = result + 1;
+ this->m->cur_offset = result + 1;
++p;
- while ((this->cur_offset < end_pos) &&
+ while ((this->m->cur_offset < end_pos) &&
((*p == '\r') || (*p == '\n')))
{
++p;
- ++this->cur_offset;
+ ++this->m->cur_offset;
}
}
else
{
- this->cur_offset = end_pos;
+ this->m->cur_offset = end_pos;
result = end_pos;
}
return result;
@@ -85,13 +93,13 @@ BufferInputSource::findAndSkipNextEOL()
std::string const&
BufferInputSource::getName() const
{
- return this->description;
+ return this->m->description;
}
qpdf_offset_t
BufferInputSource::tell()
{
- return this->cur_offset;
+ return this->m->cur_offset;
}
void
@@ -100,15 +108,15 @@ BufferInputSource::seek(qpdf_offset_t offset, int whence)
switch (whence)
{
case SEEK_SET:
- this->cur_offset = offset;
+ this->m->cur_offset = offset;
break;
case SEEK_END:
- this->cur_offset = bufSizeAsOffset() + offset;
+ this->m->cur_offset = bufSizeAsOffset() + offset;
break;
case SEEK_CUR:
- this->cur_offset += offset;
+ this->m->cur_offset += offset;
break;
default:
@@ -117,46 +125,46 @@ BufferInputSource::seek(qpdf_offset_t offset, int whence)
break;
}
- if (this->cur_offset < 0)
+ if (this->m->cur_offset < 0)
{
throw std::runtime_error(
- this->description + ": seek before beginning of buffer");
+ this->m->description + ": seek before beginning of buffer");
}
}
void
BufferInputSource::rewind()
{
- this->cur_offset = 0;
+ this->m->cur_offset = 0;
}
size_t
BufferInputSource::read(char* buffer, size_t length)
{
- if (this->cur_offset < 0)
+ if (this->m->cur_offset < 0)
{
throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0");
}
qpdf_offset_t end_pos = bufSizeAsOffset();
- if (this->cur_offset >= end_pos)
+ if (this->m->cur_offset >= end_pos)
{
this->last_offset = end_pos;
return 0;
}
- this->last_offset = this->cur_offset;
+ this->last_offset = this->m->cur_offset;
size_t len = std::min(
- QIntC::to_size(end_pos - this->cur_offset), length);
- memcpy(buffer, buf->getBuffer() + this->cur_offset, len);
- this->cur_offset += QIntC::to_offset(len);
+ QIntC::to_size(end_pos - this->m->cur_offset), length);
+ memcpy(buffer, this->m->buf->getBuffer() + this->m->cur_offset, len);
+ this->m->cur_offset += QIntC::to_offset(len);
return len;
}
void
BufferInputSource::unreadCh(char ch)
{
- if (this->cur_offset > 0)
+ if (this->m->cur_offset > 0)
{
- --this->cur_offset;
+ --this->m->cur_offset;
}
}
diff --git a/libqpdf/FileInputSource.cc b/libqpdf/FileInputSource.cc
index d0f3c8ef..cd8feda4 100644
--- a/libqpdf/FileInputSource.cc
+++ b/libqpdf/FileInputSource.cc
@@ -4,45 +4,45 @@
#include <qpdf/QPDFExc.hh>
#include <algorithm>
-FileInputSource::FileInputSource() :
- close_file(false),
+FileInputSource::Members::Members(bool close_file) :
+ close_file(close_file),
file(0)
{
}
+FileInputSource::Members::~Members()
+{
+ if (this->file && this->close_file)
+ {
+ fclose(this->file);
+ }
+}
+
+FileInputSource::FileInputSource() :
+ m(new Members(false))
+{
+}
+
void
FileInputSource::setFilename(char const* filename)
{
- destroy();
- this->filename = filename;
- this->close_file = true;
- this->file = QUtil::safe_fopen(this->filename.c_str(), "rb");
+ this->m = new Members(true);
+ this->m->filename = filename;
+ this->m->file = QUtil::safe_fopen(filename, "rb");
}
void
FileInputSource::setFile(
char const* description, FILE* filep, bool close_file)
{
- destroy();
- this->filename = description;
- this->close_file = close_file;
- this->file = filep;
+ this->m = new Members(close_file);
+ this->m->filename = description;
+ this->m->file = filep;
this->seek(0, SEEK_SET);
}
FileInputSource::~FileInputSource()
{
- destroy();
-}
-
-void
-FileInputSource::destroy()
-{
- if (this->file && this->close_file)
- {
- fclose(this->file);
- this->file = 0;
- }
}
qpdf_offset_t
@@ -53,7 +53,7 @@ FileInputSource::findAndSkipNextEOL()
char buf[10240];
while (! done)
{
- qpdf_offset_t cur_offset = QUtil::tell(this->file);
+ qpdf_offset_t cur_offset = QUtil::tell(this->m->file);
size_t len = this->read(buf, sizeof(buf));
if (len == 0)
{
@@ -93,41 +93,42 @@ FileInputSource::findAndSkipNextEOL()
std::string const&
FileInputSource::getName() const
{
- return this->filename;
+ return this->m->filename;
}
qpdf_offset_t
FileInputSource::tell()
{
- return QUtil::tell(this->file);
+ return QUtil::tell(this->m->file);
}
void
FileInputSource::seek(qpdf_offset_t offset, int whence)
{
- QUtil::os_wrapper(std::string("seek to ") + this->filename + ", offset " +
+ QUtil::os_wrapper(std::string("seek to ") +
+ this->m->filename + ", offset " +
QUtil::int_to_string(offset) + " (" +
QUtil::int_to_string(whence) + ")",
- QUtil::seek(this->file, offset, whence));
+ QUtil::seek(this->m->file, offset, whence));
}
void
FileInputSource::rewind()
{
- ::rewind(this->file);
+ ::rewind(this->m->file);
}
size_t
FileInputSource::read(char* buffer, size_t length)
{
this->last_offset = this->tell();
- size_t len = fread(buffer, 1, length, this->file);
+ size_t len = fread(buffer, 1, length, this->m->file);
if (len == 0)
{
- if (ferror(this->file))
+ if (ferror(this->m->file))
{
throw QPDFExc(qpdf_e_system,
- this->filename, "",
+ this->m->filename, "",
this->last_offset,
std::string("read ") +
QUtil::uint_to_string(length) + " bytes");
@@ -144,6 +145,6 @@ FileInputSource::read(char* buffer, size_t length)
void
FileInputSource::unreadCh(char ch)
{
- QUtil::os_wrapper(this->filename + ": unread character",
- ungetc(static_cast<unsigned char>(ch), this->file));
+ QUtil::os_wrapper(this->m->filename + ": unread character",
+ ungetc(static_cast<unsigned char>(ch), this->m->file));
}
diff --git a/libqpdf/InputSource.cc b/libqpdf/InputSource.cc
index ca363566..a0e81a7a 100644
--- a/libqpdf/InputSource.cc
+++ b/libqpdf/InputSource.cc
@@ -5,6 +5,13 @@
#include <qpdf/PointerHolder.hh>
#include <qpdf/QIntC.hh>
+InputSource::Members::Members()
+{
+}
+
+InputSource::Members::~Members()
+{
+}
void
InputSource::setLastOffset(qpdf_offset_t offset)
diff --git a/libqpdf/Pipeline.cc b/libqpdf/Pipeline.cc
index b80b2d67..bcd48e46 100644
--- a/libqpdf/Pipeline.cc
+++ b/libqpdf/Pipeline.cc
@@ -1,9 +1,18 @@
#include <qpdf/Pipeline.hh>
#include <stdexcept>
+Pipeline::Members::Members(Pipeline* next) :
+ next(next)
+{
+}
+
+Pipeline::Members::~Members()
+{
+}
+
Pipeline::Pipeline(char const* identifier, Pipeline* next) :
identifier(identifier),
- next(next)
+ m(new Members(next))
{
}
@@ -14,11 +23,11 @@ Pipeline::~Pipeline()
Pipeline*
Pipeline::getNext(bool allow_null)
{
- if ((next == 0) && (! allow_null))
+ if ((this->m->next == 0) && (! allow_null))
{
throw std::logic_error(
this->identifier +
": Pipeline::getNext() called on pipeline with no next");
}
- return this->next;
+ return this->m->next;
}
diff --git a/libqpdf/Pl_Buffer.cc b/libqpdf/Pl_Buffer.cc
index d11959f4..70d906ea 100644
--- a/libqpdf/Pl_Buffer.cc
+++ b/libqpdf/Pl_Buffer.cc
@@ -4,13 +4,22 @@
#include <assert.h>
#include <string.h>
-Pl_Buffer::Pl_Buffer(char const* identifier, Pipeline* next) :
- Pipeline(identifier, next),
+Pl_Buffer::Members::Members() :
ready(true),
total_size(0)
{
}
+Pl_Buffer::Members::~Members()
+{
+}
+
+Pl_Buffer::Pl_Buffer(char const* identifier, Pipeline* next) :
+ Pipeline(identifier, next),
+ m(new Members())
+{
+}
+
Pl_Buffer::~Pl_Buffer()
{
}
@@ -18,32 +27,25 @@ Pl_Buffer::~Pl_Buffer()
void
Pl_Buffer::write(unsigned char* buf, size_t len)
{
- PointerHolder<Buffer> cur_buf;
- size_t cur_size = 0;
- if (! this->data.empty())
+ if (this->m->data.getPointer() == 0)
{
- cur_buf = this->data.back();
- cur_size = cur_buf->getSize();
+ this->m->data = new Buffer(len);
}
- size_t left = cur_size - this->total_size;
+ size_t cur_size = this->m->data->getSize();
+ size_t left = cur_size - this->m->total_size;
if (left < len)
{
- size_t new_size = std::max(this->total_size + len, 2 * cur_size);
- Buffer* b = new Buffer(new_size);
- if (cur_buf.getPointer())
- {
- memcpy(b->getBuffer(), cur_buf->getBuffer(), this->total_size);
- }
- this->data.clear();
- cur_buf = b;
- this->data.push_back(cur_buf);
+ size_t new_size = std::max(this->m->total_size + len, 2 * cur_size);
+ PointerHolder<Buffer> b = new Buffer(new_size);
+ memcpy(b->getBuffer(), this->m->data->getBuffer(), this->m->total_size);
+ this->m->data = b;
}
if (len)
{
- memcpy(cur_buf->getBuffer() + this->total_size, buf, len);
- this->total_size += len;
+ memcpy(this->m->data->getBuffer() + this->m->total_size, buf, len);
+ this->m->total_size += len;
}
- this->ready = false;
+ this->m->ready = false;
if (getNext(true))
{
@@ -54,7 +56,7 @@ Pl_Buffer::write(unsigned char* buf, size_t len)
void
Pl_Buffer::finish()
{
- this->ready = true;
+ this->m->ready = true;
if (getNext(true))
{
getNext()->finish();
@@ -64,21 +66,17 @@ Pl_Buffer::finish()
Buffer*
Pl_Buffer::getBuffer()
{
- if (! this->ready)
+ if (! this->m->ready)
{
throw std::logic_error("Pl_Buffer::getBuffer() called when not ready");
}
- Buffer* b = new Buffer(this->total_size);
- unsigned char* p = b->getBuffer();
- if (! this->data.empty())
+ Buffer* b = new Buffer(this->m->total_size);
+ if (this->m->total_size > 0)
{
- PointerHolder<Buffer> bp = this->data.back();
- this->data.clear();
- memcpy(p, bp->getBuffer(), this->total_size);
+ unsigned char* p = b->getBuffer();
+ memcpy(p, this->m->data->getBuffer(), this->m->total_size);
}
- this->total_size = 0;
- this->ready = false;
-
+ this->m = new Members();
return b;
}
diff --git a/libqpdf/Pl_Concatenate.cc b/libqpdf/Pl_Concatenate.cc
index 8d48de60..7ad8e546 100644
--- a/libqpdf/Pl_Concatenate.cc
+++ b/libqpdf/Pl_Concatenate.cc
@@ -1,5 +1,13 @@
#include <qpdf/Pl_Concatenate.hh>
+Pl_Concatenate::Members::Members()
+{
+}
+
+Pl_Concatenate::Members::~Members()
+{
+}
+
Pl_Concatenate::Pl_Concatenate(char const* identifier, Pipeline* next) :
Pipeline(identifier, next)
{
diff --git a/libqpdf/Pl_Count.cc b/libqpdf/Pl_Count.cc
index b4b13640..8077092a 100644
--- a/libqpdf/Pl_Count.cc
+++ b/libqpdf/Pl_Count.cc
@@ -1,13 +1,22 @@
#include <qpdf/Pl_Count.hh>
#include <qpdf/QIntC.hh>
-Pl_Count::Pl_Count(char const* identifier, Pipeline* next) :
- Pipeline(identifier, next),
+Pl_Count::Members::Members() :
count(0),
last_char('\0')
{
}
+Pl_Count::Members::~Members()
+{
+}
+
+Pl_Count::Pl_Count(char const* identifier, Pipeline* next) :
+ Pipeline(identifier, next),
+ m(new Members())
+{
+}
+
Pl_Count::~Pl_Count()
{
}
@@ -17,9 +26,9 @@ Pl_Count::write(unsigned char* buf, size_t len)
{
if (len)
{
- this->count += QIntC::to_offset(len);
+ this->m->count += QIntC::to_offset(len);
getNext()->write(buf, len);
- this->last_char = buf[len - 1];
+ this->m->last_char = buf[len - 1];
}
}
@@ -32,11 +41,11 @@ Pl_Count::finish()
qpdf_offset_t
Pl_Count::getCount() const
{
- return this->count;
+ return this->m->count;
}
unsigned char
Pl_Count::getLastChar() const
{
- return this->last_char;
+ return this->m->last_char;
}
diff --git a/libqpdf/Pl_DCT.cc b/libqpdf/Pl_DCT.cc
index 4da068cb..de7e1a5e 100644
--- a/libqpdf/Pl_DCT.cc
+++ b/libqpdf/Pl_DCT.cc
@@ -31,10 +31,30 @@ error_handler(j_common_ptr cinfo)
longjmp(jerr->jmpbuf, 1);
}
+Pl_DCT::Members::Members(action_e action,
+ char const* buf_description,
+ JDIMENSION image_width,
+ JDIMENSION image_height,
+ int components,
+ J_COLOR_SPACE color_space,
+ CompressConfig* config_callback) :
+ action(action),
+ buf(buf_description),
+ image_width(image_width),
+ image_height(image_height),
+ components(components),
+ color_space(color_space),
+ config_callback(config_callback)
+{
+}
+
+Pl_DCT::Members::~Members()
+{
+}
+
Pl_DCT::Pl_DCT(char const* identifier, Pipeline* next) :
Pipeline(identifier, next),
- action(a_decompress),
- buf("DCT compressed image")
+ m(new Members(a_decompress, "DCT compressed image"))
{
}
@@ -45,13 +65,8 @@ Pl_DCT::Pl_DCT(char const* identifier, Pipeline* next,
J_COLOR_SPACE color_space,
CompressConfig* config_callback) :
Pipeline(identifier, next),
- action(a_compress),
- buf("DCT uncompressed image"),
- image_width(image_width),
- image_height(image_height),
- components(components),
- color_space(color_space),
- config_callback(config_callback)
+ m(new Members(a_compress, "DCT uncompressed image",
+ image_width, image_height, components, color_space, config_callback))
{
}
@@ -62,18 +77,18 @@ Pl_DCT::~Pl_DCT()
void
Pl_DCT::write(unsigned char* data, size_t len)
{
- this->buf.write(data, len);
+ this->m->buf.write(data, len);
}
void
Pl_DCT::finish()
{
- this->buf.finish();
+ this->m->buf.finish();
// Using a PointerHolder<Buffer> here and passing it into compress
// and decompress causes a memory leak with setjmp/longjmp. Just
// use a pointer and delete it.
- Buffer* b = this->buf.getBuffer();
+ Buffer* b = this->m->buf.getBuffer();
if (b->getSize() == 0)
{
// Special case: empty data will never succeed and probably
@@ -99,7 +114,7 @@ Pl_DCT::finish()
{
try
{
- if (this->action == a_compress)
+ if (this->m->action == a_compress)
{
compress(reinterpret_cast<void*>(&cinfo_compress), b);
}
@@ -123,11 +138,11 @@ Pl_DCT::finish()
}
delete b;
- if (this->action == a_compress)
+ if (this->m->action == a_compress)
{
jpeg_destroy_compress(&cinfo_compress);
}
- if (this->action == a_decompress)
+ if (this->m->action == a_decompress)
{
jpeg_destroy_decompress(&cinfo_decompress);
}
@@ -272,14 +287,14 @@ Pl_DCT::compress(void* cinfo_p, Buffer* b)
unsigned char* outbuffer = outbuffer_ph.getPointer();
jpeg_pipeline_dest(cinfo, outbuffer, BUF_SIZE, this->getNext());
- cinfo->image_width = this->image_width;
- cinfo->image_height = this->image_height;
- cinfo->input_components = this->components;
- cinfo->in_color_space = this->color_space;
+ cinfo->image_width = this->m->image_width;
+ cinfo->image_height = this->m->image_height;
+ cinfo->input_components = this->m->components;
+ cinfo->in_color_space = this->m->color_space;
jpeg_set_defaults(cinfo);
- if (this->config_callback)
+ if (this->m->config_callback)
{
- this->config_callback->apply(cinfo);
+ this->m->config_callback->apply(cinfo);
}
jpeg_start_compress(cinfo, TRUE);
diff --git a/libqpdf/Pl_Discard.cc b/libqpdf/Pl_Discard.cc
index 34d49f3a..f2ba561f 100644
--- a/libqpdf/Pl_Discard.cc
+++ b/libqpdf/Pl_Discard.cc
@@ -2,6 +2,14 @@
// Exercised in md5 test suite
+Pl_Discard::Members::Members()
+{
+}
+
+Pl_Discard::Members::~Members()
+{
+}
+
Pl_Discard::Pl_Discard() :
Pipeline("discard", 0)
{
diff --git a/libqpdf/Pl_Flate.cc b/libqpdf/Pl_Flate.cc
index 67e02d2d..c42d3c28 100644
--- a/libqpdf/Pl_Flate.cc
+++ b/libqpdf/Pl_Flate.cc
@@ -6,12 +6,12 @@
#include <qpdf/QUtil.hh>
#include <qpdf/QIntC.hh>
-Pl_Flate::Pl_Flate(char const* identifier, Pipeline* next,
- action_e action, unsigned int out_bufsize_int) :
- Pipeline(identifier, next),
- out_bufsize(QIntC::to_size(out_bufsize_int)),
+Pl_Flate::Members::Members(size_t out_bufsize,
+ action_e action) :
+ out_bufsize(out_bufsize),
action(action),
- initialized(false)
+ initialized(false),
+ zdata(0)
{
this->outbuf = new unsigned char[out_bufsize];
// Indirect through zdata to reach the z_stream so we don't have
@@ -38,7 +38,7 @@ Pl_Flate::Pl_Flate(char const* identifier, Pipeline* next,
zstream.avail_out = QIntC::to_uint(out_bufsize);
}
-Pl_Flate::~Pl_Flate()
+Pl_Flate::Members::~Members()
{
delete [] this->outbuf;
this->outbuf = 0;
@@ -60,10 +60,21 @@ Pl_Flate::~Pl_Flate()
this->zdata = 0;
}
+Pl_Flate::Pl_Flate(char const* identifier, Pipeline* next,
+ action_e action, unsigned int out_bufsize_int) :
+ Pipeline(identifier, next),
+ m(new Members(QIntC::to_size(out_bufsize_int), action))
+{
+}
+
+Pl_Flate::~Pl_Flate()
+{
+}
+
void
Pl_Flate::write(unsigned char* data, size_t len)
{
- if (this->outbuf == 0)
+ if (this->m->outbuf == 0)
{
throw std::logic_error(
this->identifier +
@@ -79,7 +90,7 @@ Pl_Flate::write(unsigned char* data, size_t len)
{
size_t bytes = (bytes_left >= max_bytes ? max_bytes : bytes_left);
handleData(buf, bytes,
- (action == a_inflate ? Z_SYNC_FLUSH : Z_NO_FLUSH));
+ (this->m->action == a_inflate ? Z_SYNC_FLUSH : Z_NO_FLUSH));
bytes_left -= bytes;
buf += bytes;
}
@@ -94,11 +105,11 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush)
"Pl_Flate: zlib doesn't support data"
" blocks larger than int");
}
- z_stream& zstream = *(static_cast<z_stream*>(this->zdata));
+ z_stream& zstream = *(static_cast<z_stream*>(this->m->zdata));
zstream.next_in = data;
zstream.avail_in = QIntC::to_uint(len);
- if (! this->initialized)
+ if (! this->m->initialized)
{
int err = Z_OK;
@@ -109,7 +120,7 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wold-style-cast"
#endif
- if (this->action == a_deflate)
+ if (this->m->action == a_deflate)
{
err = deflateInit(&zstream, Z_DEFAULT_COMPRESSION);
}
@@ -123,7 +134,7 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush)
#endif
checkError("Init", err);
- this->initialized = true;
+ this->m->initialized = true;
}
int err = Z_OK;
@@ -131,7 +142,7 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush)
bool done = false;
while (! done)
{
- if (action == a_deflate)
+ if (this->m->action == a_deflate)
{
err = deflate(&zstream, flush);
}
@@ -139,7 +150,7 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush)
{
err = inflate(&zstream, flush);
}
- if ((action == a_inflate) && (err != Z_OK) && zstream.msg &&
+ if ((this->m->action == a_inflate) && (err != Z_OK) && zstream.msg &&
(strcmp(zstream.msg, "incorrect data check") == 0))
{
// Other PDF readers ignore this specific error. Combining
@@ -172,12 +183,12 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush)
done = true;
}
uLong ready =
- QIntC::to_ulong(this->out_bufsize - zstream.avail_out);
+ QIntC::to_ulong(this->m->out_bufsize - zstream.avail_out);
if (ready > 0)
{
- this->getNext()->write(this->outbuf, ready);
- zstream.next_out = this->outbuf;
- zstream.avail_out = QIntC::to_uint(this->out_bufsize);
+ this->getNext()->write(this->m->outbuf, ready);
+ zstream.next_out = this->m->outbuf;
+ zstream.avail_out = QIntC::to_uint(this->m->out_bufsize);
}
}
break;
@@ -194,16 +205,16 @@ Pl_Flate::finish()
{
try
{
- if (this->outbuf)
+ if (this->m->outbuf)
{
- if (this->initialized)
+ if (this->m->initialized)
{
- z_stream& zstream = *(static_cast<z_stream*>(this->zdata));
+ z_stream& zstream = *(static_cast<z_stream*>(this->m->zdata));
unsigned char buf[1];
buf[0] = '\0';
handleData(buf, 0, Z_FINISH);
int err = Z_OK;
- if (action == a_deflate)
+ if (this->m->action == a_deflate)
{
err = deflateEnd(&zstream);
}
@@ -211,12 +222,12 @@ Pl_Flate::finish()
{
err = inflateEnd(&zstream);
}
- this->initialized = false;
+ this->m->initialized = false;
checkError("End", err);
}
- delete [] this->outbuf;
- this->outbuf = 0;
+ delete [] this->m->outbuf;
+ this->m->outbuf = 0;
}
}
catch (std::exception& e)
@@ -230,10 +241,11 @@ Pl_Flate::finish()
void
Pl_Flate::checkError(char const* prefix, int error_code)
{
- z_stream& zstream = *(static_cast<z_stream*>(this->zdata));
+ z_stream& zstream = *(static_cast<z_stream*>(this->m->zdata));
if (error_code != Z_OK)
{
- char const* action_str = (action == a_deflate ? "deflate" : "inflate");
+ char const* action_str =
+ (this->m->action == a_deflate ? "deflate" : "inflate");
std::string msg =
this->identifier + ": " + action_str + ": " + prefix + ": ";
diff --git a/libqpdf/Pl_RunLength.cc b/libqpdf/Pl_RunLength.cc
index 3e3abd98..ed3b7576 100644
--- a/libqpdf/Pl_RunLength.cc
+++ b/libqpdf/Pl_RunLength.cc
@@ -3,15 +3,24 @@
#include <qpdf/QUtil.hh>
#include <qpdf/QTC.hh>
-Pl_RunLength::Pl_RunLength(char const* identifier, Pipeline* next,
- action_e action) :
- Pipeline(identifier, next),
+Pl_RunLength::Members::Members(action_e action) :
action(action),
state(st_top),
length(0)
{
}
+Pl_RunLength::Members::~Members()
+{
+}
+
+Pl_RunLength::Pl_RunLength(char const* identifier, Pipeline* next,
+ action_e action) :
+ Pipeline(identifier, next),
+ m(new Members(action))
+{
+}
+
Pl_RunLength::~Pl_RunLength()
{
}
@@ -19,7 +28,7 @@ Pl_RunLength::~Pl_RunLength()
void
Pl_RunLength::write(unsigned char* data, size_t len)
{
- if (this->action == a_encode)
+ if (this->m->action == a_encode)
{
encode(data, len);
}
@@ -34,41 +43,41 @@ Pl_RunLength::encode(unsigned char* data, size_t len)
{
for (size_t i = 0; i < len; ++i)
{
- if ((this->state == st_top) != (this->length <= 1))
+ if ((this->m->state == st_top) != (this->m->length <= 1))
{
throw std::logic_error(
"Pl_RunLength::encode: state/length inconsistency");
}
unsigned char ch = data[i];
- if ((this->length > 0) &&
- ((this->state == st_copying) || (this->length < 128)) &&
- (ch == this->buf[this->length-1]))
+ if ((this->m->length > 0) &&
+ ((this->m->state == st_copying) || (this->m->length < 128)) &&
+ (ch == this->m->buf[this->m->length-1]))
{
QTC::TC("libtests", "Pl_RunLength: switch to run",
- (this->length == 128) ? 0 : 1);
- if (this->state == st_copying)
+ (this->m->length == 128) ? 0 : 1);
+ if (this->m->state == st_copying)
{
- --this->length;
+ --this->m->length;
flush_encode();
- this->buf[0] = ch;
- this->length = 1;
+ this->m->buf[0] = ch;
+ this->m->length = 1;
}
- this->state = st_run;
- this->buf[this->length] = ch;
- ++this->length;
+ this->m->state = st_run;
+ this->m->buf[this->m->length] = ch;
+ ++this->m->length;
}
else
{
- if ((this->length == 128) || (this->state == st_run))
+ if ((this->m->length == 128) || (this->m->state == st_run))
{
flush_encode();
}
- else if (this->length > 0)
+ else if (this->m->length > 0)
{
- this->state = st_copying;
+ this->m->state = st_copying;
}
- this->buf[this->length] = ch;
- ++this->length;
+ this->m->buf[this->m->length] = ch;
+ ++this->m->length;
}
}
}
@@ -79,20 +88,20 @@ Pl_RunLength::decode(unsigned char* data, size_t len)
for (size_t i = 0; i < len; ++i)
{
unsigned char ch = data[i];
- switch (this->state)
+ switch (this->m->state)
{
case st_top:
if (ch < 128)
{
// length represents remaining number of bytes to copy
- this->length = 1U + ch;
- this->state = st_copying;
+ this->m->length = 1U + ch;
+ this->m->state = st_copying;
}
else if (ch > 128)
{
// length represents number of copies of next byte
- this->length = 257U - ch;
- this->state = st_run;
+ this->m->length = 257U - ch;
+ this->m->state = st_run;
}
else // ch == 128
{
@@ -102,18 +111,18 @@ Pl_RunLength::decode(unsigned char* data, size_t len)
case st_copying:
this->getNext()->write(&ch, 1);
- if (--this->length == 0)
+ if (--this->m->length == 0)
{
- this->state = st_top;
+ this->m->state = st_top;
}
break;
case st_run:
- for (unsigned int j = 0; j < this->length; ++j)
+ for (unsigned int j = 0; j < this->m->length; ++j)
{
this->getNext()->write(&ch, 1);
}
- this->state = st_top;
+ this->m->state = st_top;
break;
}
}
@@ -122,36 +131,36 @@ Pl_RunLength::decode(unsigned char* data, size_t len)
void
Pl_RunLength::flush_encode()
{
- if (this->length == 128)
+ if (this->m->length == 128)
{
QTC::TC("libtests", "Pl_RunLength flush full buffer",
- (this->state == st_copying ? 0 :
- this->state == st_run ? 1 :
+ (this->m->state == st_copying ? 0 :
+ this->m->state == st_run ? 1 :
-1));
}
- if (this->length == 0)
+ if (this->m->length == 0)
{
QTC::TC("libtests", "Pl_RunLength flush empty buffer");
}
- if (this->state == st_run)
+ if (this->m->state == st_run)
{
- if ((this->length < 2) || (this->length > 128))
+ if ((this->m->length < 2) || (this->m->length > 128))
{
throw std::logic_error(
"Pl_RunLength: invalid length in flush_encode for run");
}
- unsigned char ch = static_cast<unsigned char>(257 - this->length);
+ unsigned char ch = static_cast<unsigned char>(257 - this->m->length);
this->getNext()->write(&ch, 1);
- this->getNext()->write(&this->buf[0], 1);
+ this->getNext()->write(&this->m->buf[0], 1);
}
- else if (this->length > 0)
+ else if (this->m->length > 0)
{
- unsigned char ch = static_cast<unsigned char>(this->length - 1);
+ unsigned char ch = static_cast<unsigned char>(this->m->length - 1);
this->getNext()->write(&ch, 1);
- this->getNext()->write(this->buf, this->length);
+ this->getNext()->write(this->m->buf, this->m->length);
}
- this->state = st_top;
- this->length = 0;
+ this->m->state = st_top;
+ this->m->length = 0;
}
void
@@ -161,7 +170,7 @@ Pl_RunLength::finish()
// data, which means the stream was terminated early, but we will
// just ignore this case since this is the only sensible thing to
// do.
- if (this->action == a_encode)
+ if (this->m->action == a_encode)
{
flush_encode();
unsigned char ch = 128;
diff --git a/libqpdf/Pl_StdioFile.cc b/libqpdf/Pl_StdioFile.cc
index 4d3cba60..253e36a1 100644
--- a/libqpdf/Pl_StdioFile.cc
+++ b/libqpdf/Pl_StdioFile.cc
@@ -4,9 +4,18 @@
#include <stdexcept>
#include <errno.h>
+Pl_StdioFile::Members::Members(FILE* f) :
+ file(f)
+{
+}
+
+Pl_StdioFile::Members::~Members()
+{
+}
+
Pl_StdioFile::Pl_StdioFile(char const* identifier, FILE* f) :
Pipeline(identifier, 0),
- file(f)
+ m(new Members(f))
{
}
@@ -20,7 +29,7 @@ Pl_StdioFile::write(unsigned char* buf, size_t len)
size_t so_far = 0;
while (len > 0)
{
- so_far = fwrite(buf, 1, len, this->file);
+ so_far = fwrite(buf, 1, len, this->m->file);
if (so_far == 0)
{
QUtil::throw_system_error(
@@ -37,7 +46,7 @@ Pl_StdioFile::write(unsigned char* buf, size_t len)
void
Pl_StdioFile::finish()
{
- if ((fflush(this->file) == -1) &&
+ if ((fflush(this->m->file) == -1) &&
(errno == EBADF))
{
throw std::logic_error(
diff --git a/libtests/buffer.cc b/libtests/buffer.cc
index 4713f554..bd28746f 100644
--- a/libtests/buffer.cc
+++ b/libtests/buffer.cc
@@ -5,6 +5,7 @@
#include <stdlib.h>
#include <stdexcept>
#include <iostream>
+#include <cassert>
static unsigned char* uc(char const* s)
{
@@ -13,6 +14,25 @@ static unsigned char* uc(char const* s)
int main()
{
+ {
+ // Test that buffers can be copied by value.
+ Buffer bc1(2);
+ unsigned char* bc1p = bc1.getBuffer();
+ bc1p[0] = 'Q';
+ bc1p[1] = 'W';
+ Buffer bc2(bc1);
+ bc1p[0] = 'R';
+ unsigned char* bc2p = bc2.getBuffer();
+ assert(bc2p != bc1p);
+ assert(bc2p[0] == 'Q');
+ assert(bc2p[1] == 'W');
+ bc2 = bc1;
+ bc2p = bc2.getBuffer();
+ assert(bc2p != bc1p);
+ assert(bc2p[0] == 'R');
+ assert(bc2p[1] == 'W');
+ }
+
try
{
Pl_Discard discard;
@@ -68,6 +88,16 @@ int main()
b = bp3.getBuffer();
std::cout << "size: " << b->getSize() << std::endl;
delete b;
+ // Should be able to call getBuffer again and get an empty buffer
+ b = bp3.getBuffer();
+ std::cout << "size: " << b->getSize() << std::endl;
+ delete b;
+ // Also can write 0 and do it.
+ bp3.write(uc(""), 0);
+ bp3.finish();
+ b = bp3.getBuffer();
+ std::cout << "size: " << b->getSize() << std::endl;
+ delete b;
}
catch (std::exception& e)
{
diff --git a/libtests/qtest/buffer/buffer.out b/libtests/qtest/buffer/buffer.out
index c1bf24cf..e1e404b1 100644
--- a/libtests/qtest/buffer/buffer.out
+++ b/libtests/qtest/buffer/buffer.out
@@ -9,4 +9,6 @@ Pl_Buffer::getBuffer() called when not ready
size: 9
data: mooquack
size: 0
+size: 0
+size: 0
done