Commit 79f6b4823b95b65290a045a59fdd4a8d9b302708

Authored by Jay Berkenbilt
1 parent 864a546a

Convert remaining public classes to use Members pattern

Have classes contain only a single private member of type
PointerHolder<Members>. This makes it safe to change the structure of
the Members class without breaking binary compatibility. Many of the
classes already follow this pattern quite successfully. This brings in
the rest of the class that are part of the public API.
README-maintainer
@@ -70,6 +70,9 @@ CODING RULES @@ -70,6 +70,9 @@ CODING RULES
70 it seems also for classes that are intended to be subclassed across 70 it seems also for classes that are intended to be subclassed across
71 the shared library boundary. 71 the shared library boundary.
72 72
  73 +* Put private member variables in PointerHolder<Members> for all
  74 + public classes. Remember to use QPDF_DLL on ~Members().
  75 +
73 RELEASE PREPARATION 76 RELEASE PREPARATION
74 77
75 * Each year, update copyright notices. Just do a case-insensitive 78 * Each year, update copyright notices. Just do a case-insensitive
1 Next ABI 1 Next ABI
2 ======== 2 ========
3 3
4 - * Check all classes that don't use the Members pattern and see if  
5 - they should be converted. Most of the pipeline classes should be  
6 - converted.  
7 -  
8 - Buffer.hh  
9 - BufferInputSource.hh  
10 - FileInputSource.hh  
11 - InputSource.hh  
12 - Pl_Buffer.hh  
13 - Pl_Concatenate.hh  
14 - Pl_Count.hh  
15 - Pl_DCT.hh  
16 - Pl_Discard.hh  
17 - Pl_Flate.hh  
18 - Pl_RunLength.hh  
19 - Pl_StdioFile.hh  
20 - QPDFExc.hh  
21 - QPDFObjGen.hh  
22 - QPDFSystemError.hh  
23 - QPDFXRefEntry.hh  
24 -  
25 - * Pl_Buffer's internal structure is not right for what it does. It  
26 - was modified for greater efficiency, but it was done in a way that  
27 - preserved binary compatibility, so the implementation is a bit  
28 - convoluted.  
29 -  
30 * Check all overloaded methods to see if any can be eliminated by 4 * Check all overloaded methods to see if any can be eliminated by
31 using defaulted arguments. See ../misc/find-overloaded-functions.pl 5 using defaulted arguments. See ../misc/find-overloaded-functions.pl
32 (not in source repo) 6 (not in source repo)
include/qpdf/Buffer.hh
@@ -23,7 +23,8 @@ @@ -23,7 +23,8 @@
23 #define BUFFER_HH 23 #define BUFFER_HH
24 24
25 #include <qpdf/DLL.h> 25 #include <qpdf/DLL.h>
26 -#include <cstring> // for size_t 26 +#include <qpdf/PointerHolder.hh>
  27 +#include <stddef.h>
27 28
28 class Buffer 29 class Buffer
29 { 30 {
@@ -46,8 +47,6 @@ class Buffer @@ -46,8 +47,6 @@ class Buffer
46 QPDF_DLL 47 QPDF_DLL
47 Buffer& operator=(Buffer const&); 48 Buffer& operator=(Buffer const&);
48 QPDF_DLL 49 QPDF_DLL
49 - ~Buffer();  
50 - QPDF_DLL  
51 size_t getSize() const; 50 size_t getSize() const;
52 QPDF_DLL 51 QPDF_DLL
53 unsigned char const* getBuffer() const; 52 unsigned char const* getBuffer() const;
@@ -55,13 +54,26 @@ class Buffer @@ -55,13 +54,26 @@ class Buffer
55 unsigned char* getBuffer(); 54 unsigned char* getBuffer();
56 55
57 private: 56 private:
58 - void init(size_t size, unsigned char* buf, bool own_memory); 57 + class Members
  58 + {
  59 + friend class Buffer;
  60 +
  61 + public:
  62 + QPDF_DLL
  63 + ~Members();
  64 +
  65 + private:
  66 + Members(size_t size, unsigned char* buf, bool own_memory);
  67 + Members(Members const&);
  68 +
  69 + bool own_memory;
  70 + size_t size;
  71 + unsigned char* buf;
  72 + };
  73 +
59 void copy(Buffer const&); 74 void copy(Buffer const&);
60 - void destroy();  
61 75
62 - bool own_memory;  
63 - size_t size;  
64 - unsigned char* buf; 76 + PointerHolder<Members> m;
65 }; 77 };
66 78
67 #endif // BUFFER_HH 79 #endif // BUFFER_HH
include/qpdf/BufferInputSource.hh
@@ -56,10 +56,25 @@ class BufferInputSource: public InputSource @@ -56,10 +56,25 @@ class BufferInputSource: public InputSource
56 private: 56 private:
57 qpdf_offset_t const bufSizeAsOffset() const; 57 qpdf_offset_t const bufSizeAsOffset() const;
58 58
59 - bool own_memory;  
60 - std::string description;  
61 - Buffer* buf;  
62 - qpdf_offset_t cur_offset; 59 + class Members
  60 + {
  61 + friend class BufferInputSource;
  62 +
  63 + public:
  64 + QPDF_DLL
  65 + ~Members();
  66 +
  67 + private:
  68 + Members(bool own_memory, std::string const& description, Buffer* buf);
  69 + Members(Members const&);
  70 +
  71 + bool own_memory;
  72 + std::string description;
  73 + Buffer* buf;
  74 + qpdf_offset_t cur_offset;
  75 + };
  76 +
  77 + PointerHolder<Members> m;
63 }; 78 };
64 79
65 #endif // QPDF_BUFFERINPUTSOURCE_HH 80 #endif // QPDF_BUFFERINPUTSOURCE_HH
include/qpdf/FileInputSource.hh
@@ -54,11 +54,24 @@ class FileInputSource: public InputSource @@ -54,11 +54,24 @@ class FileInputSource: public InputSource
54 FileInputSource(FileInputSource const&); 54 FileInputSource(FileInputSource const&);
55 FileInputSource& operator=(FileInputSource const&); 55 FileInputSource& operator=(FileInputSource const&);
56 56
57 - void destroy(); 57 + class Members
  58 + {
  59 + friend class FileInputSource;
58 60
59 - bool close_file;  
60 - std::string filename;  
61 - FILE* file; 61 + public:
  62 + QPDF_DLL
  63 + ~Members();
  64 +
  65 + private:
  66 + Members(bool close_file);
  67 + Members(Members const&);
  68 +
  69 + bool close_file;
  70 + std::string filename;
  71 + FILE* file;
  72 + };
  73 +
  74 + PointerHolder<Members> m;
62 }; 75 };
63 76
64 #endif // QPDF_FILEINPUTSOURCE_HH 77 #endif // QPDF_FILEINPUTSOURCE_HH
include/qpdf/InputSource.hh
@@ -24,6 +24,7 @@ @@ -24,6 +24,7 @@
24 24
25 #include <qpdf/DLL.h> 25 #include <qpdf/DLL.h>
26 #include <qpdf/Types.h> 26 #include <qpdf/Types.h>
  27 +#include <qpdf/PointerHolder.hh>
27 #include <stdio.h> 28 #include <stdio.h>
28 #include <string> 29 #include <string>
29 30
@@ -86,6 +87,22 @@ class QPDF_DLL_CLASS InputSource @@ -86,6 +87,22 @@ class QPDF_DLL_CLASS InputSource
86 87
87 protected: 88 protected:
88 qpdf_offset_t last_offset; 89 qpdf_offset_t last_offset;
  90 +
  91 + private:
  92 + class Members
  93 + {
  94 + friend class InputSource;
  95 +
  96 + public:
  97 + QPDF_DLL
  98 + ~Members();
  99 +
  100 + private:
  101 + Members();
  102 + Members(Members const&);
  103 + };
  104 +
  105 + PointerHolder<Members> m;
89 }; 106 };
90 107
91 #endif // QPDF_INPUTSOURCE_HH 108 #endif // QPDF_INPUTSOURCE_HH
include/qpdf/Pipeline.hh
@@ -45,6 +45,7 @@ @@ -45,6 +45,7 @@
45 #define PIPELINE_HH 45 #define PIPELINE_HH
46 46
47 #include <qpdf/DLL.h> 47 #include <qpdf/DLL.h>
  48 +#include <qpdf/PointerHolder.hh>
48 #include <string> 49 #include <string>
49 50
50 class QPDF_DLL_CLASS Pipeline 51 class QPDF_DLL_CLASS Pipeline
@@ -79,7 +80,22 @@ class QPDF_DLL_CLASS Pipeline @@ -79,7 +80,22 @@ class QPDF_DLL_CLASS Pipeline
79 Pipeline(Pipeline const&); 80 Pipeline(Pipeline const&);
80 Pipeline& operator=(Pipeline const&); 81 Pipeline& operator=(Pipeline const&);
81 82
82 - Pipeline* next; 83 + class Members
  84 + {
  85 + friend class Pipeline;
  86 +
  87 + public:
  88 + QPDF_DLL
  89 + ~Members();
  90 +
  91 + private:
  92 + Members(Pipeline* next);
  93 + Members(Members const&);
  94 +
  95 + Pipeline* next;
  96 + };
  97 +
  98 + PointerHolder<Members> m;
83 }; 99 };
84 100
85 #endif // PIPELINE_HH 101 #endif // PIPELINE_HH
include/qpdf/Pl_Buffer.hh
@@ -36,7 +36,6 @@ @@ -36,7 +36,6 @@
36 #include <qpdf/Pipeline.hh> 36 #include <qpdf/Pipeline.hh>
37 #include <qpdf/PointerHolder.hh> 37 #include <qpdf/PointerHolder.hh>
38 #include <qpdf/Buffer.hh> 38 #include <qpdf/Buffer.hh>
39 -#include <list>  
40 39
41 class Pl_Buffer: public Pipeline 40 class Pl_Buffer: public Pipeline
42 { 41 {
@@ -57,9 +56,24 @@ class Pl_Buffer: public Pipeline @@ -57,9 +56,24 @@ class Pl_Buffer: public Pipeline
57 Buffer* getBuffer(); 56 Buffer* getBuffer();
58 57
59 private: 58 private:
60 - bool ready;  
61 - std::list<PointerHolder<Buffer> > data;  
62 - size_t total_size; 59 + class Members
  60 + {
  61 + friend class Pl_Buffer;
  62 +
  63 + public:
  64 + QPDF_DLL
  65 + ~Members();
  66 +
  67 + private:
  68 + Members();
  69 + Members(Members const&);
  70 +
  71 + bool ready;
  72 + PointerHolder<Buffer> data;
  73 + size_t total_size;
  74 + };
  75 +
  76 + PointerHolder<Members> m;
63 }; 77 };
64 78
65 #endif // PL_BUFFER_HH 79 #endif // PL_BUFFER_HH
include/qpdf/Pl_Concatenate.hh
@@ -48,6 +48,22 @@ class Pl_Concatenate: public Pipeline @@ -48,6 +48,22 @@ class Pl_Concatenate: public Pipeline
48 // the pipeline. 48 // the pipeline.
49 QPDF_DLL 49 QPDF_DLL
50 void manualFinish(); 50 void manualFinish();
  51 +
  52 + private:
  53 + class Members
  54 + {
  55 + friend class Pl_Concatenate;
  56 +
  57 + public:
  58 + QPDF_DLL
  59 + ~Members();
  60 +
  61 + private:
  62 + Members();
  63 + Members(Members const&);
  64 + };
  65 +
  66 + PointerHolder<Members> m;
51 }; 67 };
52 68
53 #endif // PL_CONCATENATE_HH 69 #endif // PL_CONCATENATE_HH
include/qpdf/Pl_Count.hh
@@ -48,10 +48,25 @@ class Pl_Count: public Pipeline @@ -48,10 +48,25 @@ class Pl_Count: public Pipeline
48 unsigned char getLastChar() const; 48 unsigned char getLastChar() const;
49 49
50 private: 50 private:
51 - // Must be qpdf_offset_t, not size_t, to handle writing more than  
52 - // size_t can handle.  
53 - qpdf_offset_t count;  
54 - unsigned char last_char; 51 + class Members
  52 + {
  53 + friend class Pl_Count;
  54 +
  55 + public:
  56 + QPDF_DLL
  57 + ~Members();
  58 +
  59 + private:
  60 + Members();
  61 + Members(Members const&);
  62 +
  63 + // Must be qpdf_offset_t, not size_t, to handle writing more than
  64 + // size_t can handle.
  65 + qpdf_offset_t count;
  66 + unsigned char last_char;
  67 + };
  68 +
  69 + PointerHolder<Members> m;
55 }; 70 };
56 71
57 #endif // PL_COUNT_HH 72 #endif // PL_COUNT_HH
include/qpdf/Pl_DCT.hh
@@ -68,17 +68,37 @@ class Pl_DCT: public Pipeline @@ -68,17 +68,37 @@ class Pl_DCT: public Pipeline
68 68
69 enum action_e { a_compress, a_decompress }; 69 enum action_e { a_compress, a_decompress };
70 70
71 - action_e action;  
72 - Pl_Buffer buf; 71 + class Members
  72 + {
  73 + friend class Pl_DCT;
  74 +
  75 + public:
  76 + QPDF_DLL
  77 + ~Members();
73 78
74 - // Used for compression  
75 - JDIMENSION image_width;  
76 - JDIMENSION image_height;  
77 - int components;  
78 - J_COLOR_SPACE color_space; 79 + private:
  80 + Members(action_e action,
  81 + char const* buf_description,
  82 + JDIMENSION image_width = 0,
  83 + JDIMENSION image_height = 0,
  84 + int components = 1,
  85 + J_COLOR_SPACE color_space = JCS_GRAYSCALE,
  86 + CompressConfig* config_callback = 0);
  87 + Members(Members const&);
79 88
80 - CompressConfig* config_callback; 89 + action_e action;
  90 + Pl_Buffer buf;
  91 +
  92 + // Used for compression
  93 + JDIMENSION image_width;
  94 + JDIMENSION image_height;
  95 + int components;
  96 + J_COLOR_SPACE color_space;
  97 +
  98 + CompressConfig* config_callback;
  99 + };
81 100
  101 + PointerHolder<Members> m;
82 }; 102 };
83 103
84 #endif // PL_DCT_HH 104 #endif // PL_DCT_HH
include/qpdf/Pl_Discard.hh
@@ -41,6 +41,22 @@ class Pl_Discard: public Pipeline @@ -41,6 +41,22 @@ class Pl_Discard: public Pipeline
41 virtual void write(unsigned char*, size_t); 41 virtual void write(unsigned char*, size_t);
42 QPDF_DLL 42 QPDF_DLL
43 virtual void finish(); 43 virtual void finish();
  44 +
  45 + private:
  46 + class Members
  47 + {
  48 + friend class Pl_Discard;
  49 +
  50 + public:
  51 + QPDF_DLL
  52 + ~Members();
  53 +
  54 + private:
  55 + Members();
  56 + Members(Members const&);
  57 + };
  58 +
  59 + PointerHolder<Members> m;
44 }; 60 };
45 61
46 #endif // PL_DISCARD_HH 62 #endif // PL_DISCARD_HH
include/qpdf/Pl_Flate.hh
@@ -46,11 +46,26 @@ class Pl_Flate: public Pipeline @@ -46,11 +46,26 @@ class Pl_Flate: public Pipeline
46 void handleData(unsigned char* data, size_t len, int flush); 46 void handleData(unsigned char* data, size_t len, int flush);
47 void checkError(char const* prefix, int error_code); 47 void checkError(char const* prefix, int error_code);
48 48
49 - unsigned char* outbuf;  
50 - size_t out_bufsize;  
51 - action_e action;  
52 - bool initialized;  
53 - void* zdata; 49 + class Members
  50 + {
  51 + friend class Pl_Flate;
  52 +
  53 + public:
  54 + QPDF_DLL
  55 + ~Members();
  56 +
  57 + private:
  58 + Members(size_t out_bufsize, action_e action);
  59 + Members(Members const&);
  60 +
  61 + unsigned char* outbuf;
  62 + size_t out_bufsize;
  63 + action_e action;
  64 + bool initialized;
  65 + void* zdata;
  66 + };
  67 +
  68 + PointerHolder<Members> m;
54 }; 69 };
55 70
56 #endif // PL_FLATE_HH 71 #endif // PL_FLATE_HH
include/qpdf/Pl_RunLength.hh
@@ -47,10 +47,25 @@ class Pl_RunLength: public Pipeline @@ -47,10 +47,25 @@ class Pl_RunLength: public Pipeline
47 47
48 enum state_e { st_top, st_copying, st_run }; 48 enum state_e { st_top, st_copying, st_run };
49 49
50 - action_e action;  
51 - state_e state;  
52 - unsigned char buf[128];  
53 - unsigned int length; 50 + class Members
  51 + {
  52 + friend class Pl_RunLength;
  53 +
  54 + public:
  55 + QPDF_DLL
  56 + ~Members();
  57 +
  58 + private:
  59 + Members(action_e);
  60 + Members(Members const&);
  61 +
  62 + action_e action;
  63 + state_e state;
  64 + unsigned char buf[128];
  65 + unsigned int length;
  66 + };
  67 +
  68 + PointerHolder<Members> m;
54 }; 69 };
55 70
56 #endif // PL_RUNLENGTH_HH 71 #endif // PL_RUNLENGTH_HH
include/qpdf/Pl_StdioFile.hh
@@ -48,7 +48,22 @@ class Pl_StdioFile: public Pipeline @@ -48,7 +48,22 @@ class Pl_StdioFile: public Pipeline
48 virtual void finish(); 48 virtual void finish();
49 49
50 private: 50 private:
51 - FILE* file; 51 + class Members
  52 + {
  53 + friend class Pl_StdioFile;
  54 +
  55 + public:
  56 + QPDF_DLL
  57 + ~Members();
  58 +
  59 + private:
  60 + Members(FILE*);
  61 + Members(Members const&);
  62 +
  63 + FILE* file;
  64 + };
  65 +
  66 + PointerHolder<Members> m;
52 }; 67 };
53 68
54 #endif // PL_STDIOFILE_HH 69 #endif // PL_STDIOFILE_HH
include/qpdf/QPDFExc.hh
@@ -24,8 +24,8 @@ @@ -24,8 +24,8 @@
24 24
25 #include <qpdf/DLL.h> 25 #include <qpdf/DLL.h>
26 #include <qpdf/Types.h> 26 #include <qpdf/Types.h>
27 -  
28 #include <qpdf/Constants.h> 27 #include <qpdf/Constants.h>
  28 +
29 #include <string> 29 #include <string>
30 #include <stdexcept> 30 #include <stdexcept>
31 31
@@ -70,6 +70,9 @@ class QPDF_DLL_CLASS QPDFExc: public std::runtime_error @@ -70,6 +70,9 @@ class QPDF_DLL_CLASS QPDFExc: public std::runtime_error
70 qpdf_offset_t offset, 70 qpdf_offset_t offset,
71 std::string const& message); 71 std::string const& message);
72 72
  73 + // This class does not use the Members pattern to avoid needless
  74 + // memory allocations during exception handling.
  75 +
73 qpdf_error_code_e error_code; 76 qpdf_error_code_e error_code;
74 std::string filename; 77 std::string filename;
75 std::string object; 78 std::string object;
include/qpdf/QPDFObjGen.hh
@@ -44,6 +44,9 @@ class QPDFObjGen @@ -44,6 +44,9 @@ class QPDFObjGen
44 int getGen() const; 44 int getGen() const;
45 45
46 private: 46 private:
  47 + // This class does not use the Members pattern to avoid a memory
  48 + // allocation for every one of these. A lot of these get created
  49 + // and destroyed.
47 int obj; 50 int obj;
48 int gen; 51 int gen;
49 }; 52 };
include/qpdf/QPDFSystemError.hh
@@ -24,8 +24,8 @@ @@ -24,8 +24,8 @@
24 24
25 #include <qpdf/DLL.h> 25 #include <qpdf/DLL.h>
26 #include <qpdf/Types.h> 26 #include <qpdf/Types.h>
27 -  
28 #include <qpdf/Constants.h> 27 #include <qpdf/Constants.h>
  28 +
29 #include <string> 29 #include <string>
30 #include <stdexcept> 30 #include <stdexcept>
31 31
@@ -51,6 +51,9 @@ class QPDF_DLL_CLASS QPDFSystemError: public std::runtime_error @@ -51,6 +51,9 @@ class QPDF_DLL_CLASS QPDFSystemError: public std::runtime_error
51 static std::string createWhat(std::string const& description, 51 static std::string createWhat(std::string const& description,
52 int system_errno); 52 int system_errno);
53 53
  54 + // This class does not use the Members pattern to avoid needless
  55 + // memory allocations during exception handling.
  56 +
54 std::string description; 57 std::string description;
55 int system_errno; 58 int system_errno;
56 }; 59 };
include/qpdf/QPDFXRefEntry.hh
@@ -49,6 +49,8 @@ class QPDFXRefEntry @@ -49,6 +49,8 @@ class QPDFXRefEntry
49 int getObjStreamIndex() const; // only for type 2 49 int getObjStreamIndex() const; // only for type 2
50 50
51 private: 51 private:
  52 + // This class does not use the Members pattern to avoid a memory
  53 + // allocation for every one of these. A lot of these get created.
52 int type; 54 int type;
53 qpdf_offset_t field1; 55 qpdf_offset_t field1;
54 int field2; 56 int field2;
libqpdf/Buffer.cc
1 #include <qpdf/Buffer.hh> 1 #include <qpdf/Buffer.hh>
2 2
3 -#include <string.h> 3 +#include <cstring>
4 4
5 -Buffer::Buffer() 5 +Buffer::Members::Members(size_t size, unsigned char* buf, bool own_memory) :
  6 + own_memory(own_memory),
  7 + size(size),
  8 + buf(0)
6 { 9 {
7 - init(0, 0, true); 10 + if (own_memory)
  11 + {
  12 + this->buf = (size ? new unsigned char[size] : 0);
  13 + }
  14 + else
  15 + {
  16 + this->buf = buf;
  17 + }
8 } 18 }
9 19
10 -Buffer::Buffer(size_t size) 20 +Buffer::Members::~Members()
11 { 21 {
12 - init(size, 0, true); 22 + if (this->own_memory)
  23 + {
  24 + delete [] this->buf;
  25 + }
13 } 26 }
14 27
15 -Buffer::Buffer(unsigned char* buf, size_t size) 28 +Buffer::Buffer() :
  29 + m(new Members(0, 0, true))
16 { 30 {
17 - init(size, buf, false);  
18 } 31 }
19 32
20 -Buffer::Buffer(Buffer const& rhs) 33 +Buffer::Buffer(size_t size) :
  34 + m(new Members(size, 0, true))
21 { 35 {
22 - init(0, 0, true);  
23 - copy(rhs);  
24 } 36 }
25 37
26 -Buffer&  
27 -Buffer::operator=(Buffer const& rhs) 38 +Buffer::Buffer(unsigned char* buf, size_t size) :
  39 + m(new Members(size, buf, false))
28 { 40 {
29 - copy(rhs);  
30 - return *this;  
31 } 41 }
32 42
33 -Buffer::~Buffer() 43 +Buffer::Buffer(Buffer const& rhs)
34 { 44 {
35 - destroy(); 45 + copy(rhs);
36 } 46 }
37 47
38 -void  
39 -Buffer::init(size_t size, unsigned char* buf, bool own_memory) 48 +Buffer&
  49 +Buffer::operator=(Buffer const& rhs)
40 { 50 {
41 - this->own_memory = own_memory;  
42 - this->size = size;  
43 - if (own_memory)  
44 - {  
45 - this->buf = (size ? new unsigned char[size] : 0);  
46 - }  
47 - else  
48 - {  
49 - this->buf = buf;  
50 - } 51 + copy(rhs);
  52 + return *this;
51 } 53 }
52 54
53 void 55 void
@@ -55,40 +57,28 @@ Buffer::copy(Buffer const&amp; rhs) @@ -55,40 +57,28 @@ Buffer::copy(Buffer const&amp; rhs)
55 { 57 {
56 if (this != &rhs) 58 if (this != &rhs)
57 { 59 {
58 - this->destroy();  
59 - this->init(rhs.size, 0, true);  
60 - if (this->size) 60 + this->m = new Members(rhs.m->size, 0, true);
  61 + if (this->m->size)
61 { 62 {
62 - memcpy(this->buf, rhs.buf, this->size); 63 + memcpy(this->m->buf, rhs.m->buf, this->m->size);
63 } 64 }
64 } 65 }
65 } 66 }
66 67
67 -void  
68 -Buffer::destroy()  
69 -{  
70 - if (this->own_memory)  
71 - {  
72 - delete [] this->buf;  
73 - }  
74 - this->size = 0;  
75 - this->buf = 0;  
76 -}  
77 -  
78 size_t 68 size_t
79 Buffer::getSize() const 69 Buffer::getSize() const
80 { 70 {
81 - return this->size; 71 + return this->m->size;
82 } 72 }
83 73
84 unsigned char const* 74 unsigned char const*
85 Buffer::getBuffer() const 75 Buffer::getBuffer() const
86 { 76 {
87 - return this->buf; 77 + return this->m->buf;
88 } 78 }
89 79
90 unsigned char* 80 unsigned char*
91 Buffer::getBuffer() 81 Buffer::getBuffer()
92 { 82 {
93 - return this->buf; 83 + return this->m->buf;
94 } 84 }
libqpdf/BufferInputSource.cc
@@ -4,8 +4,9 @@ @@ -4,8 +4,9 @@
4 #include <stdexcept> 4 #include <stdexcept>
5 #include <algorithm> 5 #include <algorithm>
6 6
7 -BufferInputSource::BufferInputSource(std::string const& description,  
8 - Buffer* buf, bool own_memory) : 7 +BufferInputSource::Members::Members(bool own_memory,
  8 + std::string const& description,
  9 + Buffer* buf) :
9 own_memory(own_memory), 10 own_memory(own_memory),
10 description(description), 11 description(description),
11 buf(buf), 12 buf(buf),
@@ -13,70 +14,77 @@ BufferInputSource::BufferInputSource(std::string const&amp; description, @@ -13,70 +14,77 @@ BufferInputSource::BufferInputSource(std::string const&amp; description,
13 { 14 {
14 } 15 }
15 16
  17 +BufferInputSource::Members::~Members()
  18 +{
  19 +}
  20 +
  21 +BufferInputSource::BufferInputSource(std::string const& description,
  22 + Buffer* buf, bool own_memory) :
  23 + m(new Members(own_memory, description, buf))
  24 +{
  25 +}
  26 +
16 BufferInputSource::BufferInputSource(std::string const& description, 27 BufferInputSource::BufferInputSource(std::string const& description,
17 std::string const& contents) : 28 std::string const& contents) :
18 - own_memory(true),  
19 - description(description),  
20 - buf(0),  
21 - cur_offset(0) 29 + m(new Members(true, description, 0))
22 { 30 {
23 - this->buf = new Buffer(contents.length());  
24 - unsigned char* bp = buf->getBuffer(); 31 + this->m->buf = new Buffer(contents.length());
  32 + unsigned char* bp = this->m->buf->getBuffer();
25 memcpy(bp, contents.c_str(), contents.length()); 33 memcpy(bp, contents.c_str(), contents.length());
26 } 34 }
27 35
28 BufferInputSource::~BufferInputSource() 36 BufferInputSource::~BufferInputSource()
29 { 37 {
30 - if (own_memory) 38 + if (this->m->own_memory)
31 { 39 {
32 - delete this->buf; 40 + delete this->m->buf;
33 } 41 }
34 } 42 }
35 43
36 qpdf_offset_t const 44 qpdf_offset_t const
37 BufferInputSource::bufSizeAsOffset() const 45 BufferInputSource::bufSizeAsOffset() const
38 { 46 {
39 - return QIntC::to_offset(this->buf->getSize()); 47 + return QIntC::to_offset(this->m->buf->getSize());
40 } 48 }
41 49
42 qpdf_offset_t 50 qpdf_offset_t
43 BufferInputSource::findAndSkipNextEOL() 51 BufferInputSource::findAndSkipNextEOL()
44 { 52 {
45 - if (this->cur_offset < 0) 53 + if (this->m->cur_offset < 0)
46 { 54 {
47 throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0"); 55 throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0");
48 } 56 }
49 qpdf_offset_t end_pos = bufSizeAsOffset(); 57 qpdf_offset_t end_pos = bufSizeAsOffset();
50 - if (this->cur_offset >= end_pos) 58 + if (this->m->cur_offset >= end_pos)
51 { 59 {
52 this->last_offset = end_pos; 60 this->last_offset = end_pos;
53 - this->cur_offset = end_pos; 61 + this->m->cur_offset = end_pos;
54 return end_pos; 62 return end_pos;
55 } 63 }
56 64
57 qpdf_offset_t result = 0; 65 qpdf_offset_t result = 0;
58 - size_t len = QIntC::to_size(end_pos - this->cur_offset);  
59 - unsigned char const* buffer = this->buf->getBuffer(); 66 + size_t len = QIntC::to_size(end_pos - this->m->cur_offset);
  67 + unsigned char const* buffer = this->m->buf->getBuffer();
60 68
61 - void* start = const_cast<unsigned char*>(buffer) + this->cur_offset; 69 + void* start = const_cast<unsigned char*>(buffer) + this->m->cur_offset;
62 unsigned char* p1 = static_cast<unsigned char*>(memchr(start, '\r', len)); 70 unsigned char* p1 = static_cast<unsigned char*>(memchr(start, '\r', len));
63 unsigned char* p2 = static_cast<unsigned char*>(memchr(start, '\n', len)); 71 unsigned char* p2 = static_cast<unsigned char*>(memchr(start, '\n', len));
64 unsigned char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2; 72 unsigned char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2;
65 if (p) 73 if (p)
66 { 74 {
67 result = p - buffer; 75 result = p - buffer;
68 - this->cur_offset = result + 1; 76 + this->m->cur_offset = result + 1;
69 ++p; 77 ++p;
70 - while ((this->cur_offset < end_pos) && 78 + while ((this->m->cur_offset < end_pos) &&
71 ((*p == '\r') || (*p == '\n'))) 79 ((*p == '\r') || (*p == '\n')))
72 { 80 {
73 ++p; 81 ++p;
74 - ++this->cur_offset; 82 + ++this->m->cur_offset;
75 } 83 }
76 } 84 }
77 else 85 else
78 { 86 {
79 - this->cur_offset = end_pos; 87 + this->m->cur_offset = end_pos;
80 result = end_pos; 88 result = end_pos;
81 } 89 }
82 return result; 90 return result;
@@ -85,13 +93,13 @@ BufferInputSource::findAndSkipNextEOL() @@ -85,13 +93,13 @@ BufferInputSource::findAndSkipNextEOL()
85 std::string const& 93 std::string const&
86 BufferInputSource::getName() const 94 BufferInputSource::getName() const
87 { 95 {
88 - return this->description; 96 + return this->m->description;
89 } 97 }
90 98
91 qpdf_offset_t 99 qpdf_offset_t
92 BufferInputSource::tell() 100 BufferInputSource::tell()
93 { 101 {
94 - return this->cur_offset; 102 + return this->m->cur_offset;
95 } 103 }
96 104
97 void 105 void
@@ -100,15 +108,15 @@ BufferInputSource::seek(qpdf_offset_t offset, int whence) @@ -100,15 +108,15 @@ BufferInputSource::seek(qpdf_offset_t offset, int whence)
100 switch (whence) 108 switch (whence)
101 { 109 {
102 case SEEK_SET: 110 case SEEK_SET:
103 - this->cur_offset = offset; 111 + this->m->cur_offset = offset;
104 break; 112 break;
105 113
106 case SEEK_END: 114 case SEEK_END:
107 - this->cur_offset = bufSizeAsOffset() + offset; 115 + this->m->cur_offset = bufSizeAsOffset() + offset;
108 break; 116 break;
109 117
110 case SEEK_CUR: 118 case SEEK_CUR:
111 - this->cur_offset += offset; 119 + this->m->cur_offset += offset;
112 break; 120 break;
113 121
114 default: 122 default:
@@ -117,46 +125,46 @@ BufferInputSource::seek(qpdf_offset_t offset, int whence) @@ -117,46 +125,46 @@ BufferInputSource::seek(qpdf_offset_t offset, int whence)
117 break; 125 break;
118 } 126 }
119 127
120 - if (this->cur_offset < 0) 128 + if (this->m->cur_offset < 0)
121 { 129 {
122 throw std::runtime_error( 130 throw std::runtime_error(
123 - this->description + ": seek before beginning of buffer"); 131 + this->m->description + ": seek before beginning of buffer");
124 } 132 }
125 } 133 }
126 134
127 void 135 void
128 BufferInputSource::rewind() 136 BufferInputSource::rewind()
129 { 137 {
130 - this->cur_offset = 0; 138 + this->m->cur_offset = 0;
131 } 139 }
132 140
133 size_t 141 size_t
134 BufferInputSource::read(char* buffer, size_t length) 142 BufferInputSource::read(char* buffer, size_t length)
135 { 143 {
136 - if (this->cur_offset < 0) 144 + if (this->m->cur_offset < 0)
137 { 145 {
138 throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0"); 146 throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0");
139 } 147 }
140 qpdf_offset_t end_pos = bufSizeAsOffset(); 148 qpdf_offset_t end_pos = bufSizeAsOffset();
141 - if (this->cur_offset >= end_pos) 149 + if (this->m->cur_offset >= end_pos)
142 { 150 {
143 this->last_offset = end_pos; 151 this->last_offset = end_pos;
144 return 0; 152 return 0;
145 } 153 }
146 154
147 - this->last_offset = this->cur_offset; 155 + this->last_offset = this->m->cur_offset;
148 size_t len = std::min( 156 size_t len = std::min(
149 - QIntC::to_size(end_pos - this->cur_offset), length);  
150 - memcpy(buffer, buf->getBuffer() + this->cur_offset, len);  
151 - this->cur_offset += QIntC::to_offset(len); 157 + QIntC::to_size(end_pos - this->m->cur_offset), length);
  158 + memcpy(buffer, this->m->buf->getBuffer() + this->m->cur_offset, len);
  159 + this->m->cur_offset += QIntC::to_offset(len);
152 return len; 160 return len;
153 } 161 }
154 162
155 void 163 void
156 BufferInputSource::unreadCh(char ch) 164 BufferInputSource::unreadCh(char ch)
157 { 165 {
158 - if (this->cur_offset > 0) 166 + if (this->m->cur_offset > 0)
159 { 167 {
160 - --this->cur_offset; 168 + --this->m->cur_offset;
161 } 169 }
162 } 170 }
libqpdf/FileInputSource.cc
@@ -4,45 +4,45 @@ @@ -4,45 +4,45 @@
4 #include <qpdf/QPDFExc.hh> 4 #include <qpdf/QPDFExc.hh>
5 #include <algorithm> 5 #include <algorithm>
6 6
7 -FileInputSource::FileInputSource() :  
8 - close_file(false), 7 +FileInputSource::Members::Members(bool close_file) :
  8 + close_file(close_file),
9 file(0) 9 file(0)
10 { 10 {
11 } 11 }
12 12
  13 +FileInputSource::Members::~Members()
  14 +{
  15 + if (this->file && this->close_file)
  16 + {
  17 + fclose(this->file);
  18 + }
  19 +}
  20 +
  21 +FileInputSource::FileInputSource() :
  22 + m(new Members(false))
  23 +{
  24 +}
  25 +
13 void 26 void
14 FileInputSource::setFilename(char const* filename) 27 FileInputSource::setFilename(char const* filename)
15 { 28 {
16 - destroy();  
17 - this->filename = filename;  
18 - this->close_file = true;  
19 - this->file = QUtil::safe_fopen(this->filename.c_str(), "rb"); 29 + this->m = new Members(true);
  30 + this->m->filename = filename;
  31 + this->m->file = QUtil::safe_fopen(filename, "rb");
20 } 32 }
21 33
22 void 34 void
23 FileInputSource::setFile( 35 FileInputSource::setFile(
24 char const* description, FILE* filep, bool close_file) 36 char const* description, FILE* filep, bool close_file)
25 { 37 {
26 - destroy();  
27 - this->filename = description;  
28 - this->close_file = close_file;  
29 - this->file = filep; 38 + this->m = new Members(close_file);
  39 + this->m->filename = description;
  40 + this->m->file = filep;
30 this->seek(0, SEEK_SET); 41 this->seek(0, SEEK_SET);
31 } 42 }
32 43
33 FileInputSource::~FileInputSource() 44 FileInputSource::~FileInputSource()
34 { 45 {
35 - destroy();  
36 -}  
37 -  
38 -void  
39 -FileInputSource::destroy()  
40 -{  
41 - if (this->file && this->close_file)  
42 - {  
43 - fclose(this->file);  
44 - this->file = 0;  
45 - }  
46 } 46 }
47 47
48 qpdf_offset_t 48 qpdf_offset_t
@@ -53,7 +53,7 @@ FileInputSource::findAndSkipNextEOL() @@ -53,7 +53,7 @@ FileInputSource::findAndSkipNextEOL()
53 char buf[10240]; 53 char buf[10240];
54 while (! done) 54 while (! done)
55 { 55 {
56 - qpdf_offset_t cur_offset = QUtil::tell(this->file); 56 + qpdf_offset_t cur_offset = QUtil::tell(this->m->file);
57 size_t len = this->read(buf, sizeof(buf)); 57 size_t len = this->read(buf, sizeof(buf));
58 if (len == 0) 58 if (len == 0)
59 { 59 {
@@ -93,41 +93,42 @@ FileInputSource::findAndSkipNextEOL() @@ -93,41 +93,42 @@ FileInputSource::findAndSkipNextEOL()
93 std::string const& 93 std::string const&
94 FileInputSource::getName() const 94 FileInputSource::getName() const
95 { 95 {
96 - return this->filename; 96 + return this->m->filename;
97 } 97 }
98 98
99 qpdf_offset_t 99 qpdf_offset_t
100 FileInputSource::tell() 100 FileInputSource::tell()
101 { 101 {
102 - return QUtil::tell(this->file); 102 + return QUtil::tell(this->m->file);
103 } 103 }
104 104
105 void 105 void
106 FileInputSource::seek(qpdf_offset_t offset, int whence) 106 FileInputSource::seek(qpdf_offset_t offset, int whence)
107 { 107 {
108 - QUtil::os_wrapper(std::string("seek to ") + this->filename + ", offset " + 108 + QUtil::os_wrapper(std::string("seek to ") +
  109 + this->m->filename + ", offset " +
109 QUtil::int_to_string(offset) + " (" + 110 QUtil::int_to_string(offset) + " (" +
110 QUtil::int_to_string(whence) + ")", 111 QUtil::int_to_string(whence) + ")",
111 - QUtil::seek(this->file, offset, whence)); 112 + QUtil::seek(this->m->file, offset, whence));
112 } 113 }
113 114
114 void 115 void
115 FileInputSource::rewind() 116 FileInputSource::rewind()
116 { 117 {
117 - ::rewind(this->file); 118 + ::rewind(this->m->file);
118 } 119 }
119 120
120 size_t 121 size_t
121 FileInputSource::read(char* buffer, size_t length) 122 FileInputSource::read(char* buffer, size_t length)
122 { 123 {
123 this->last_offset = this->tell(); 124 this->last_offset = this->tell();
124 - size_t len = fread(buffer, 1, length, this->file); 125 + size_t len = fread(buffer, 1, length, this->m->file);
125 if (len == 0) 126 if (len == 0)
126 { 127 {
127 - if (ferror(this->file)) 128 + if (ferror(this->m->file))
128 { 129 {
129 throw QPDFExc(qpdf_e_system, 130 throw QPDFExc(qpdf_e_system,
130 - this->filename, "", 131 + this->m->filename, "",
131 this->last_offset, 132 this->last_offset,
132 std::string("read ") + 133 std::string("read ") +
133 QUtil::uint_to_string(length) + " bytes"); 134 QUtil::uint_to_string(length) + " bytes");
@@ -144,6 +145,6 @@ FileInputSource::read(char* buffer, size_t length) @@ -144,6 +145,6 @@ FileInputSource::read(char* buffer, size_t length)
144 void 145 void
145 FileInputSource::unreadCh(char ch) 146 FileInputSource::unreadCh(char ch)
146 { 147 {
147 - QUtil::os_wrapper(this->filename + ": unread character",  
148 - ungetc(static_cast<unsigned char>(ch), this->file)); 148 + QUtil::os_wrapper(this->m->filename + ": unread character",
  149 + ungetc(static_cast<unsigned char>(ch), this->m->file));
149 } 150 }
libqpdf/InputSource.cc
@@ -5,6 +5,13 @@ @@ -5,6 +5,13 @@
5 #include <qpdf/PointerHolder.hh> 5 #include <qpdf/PointerHolder.hh>
6 #include <qpdf/QIntC.hh> 6 #include <qpdf/QIntC.hh>
7 7
  8 +InputSource::Members::Members()
  9 +{
  10 +}
  11 +
  12 +InputSource::Members::~Members()
  13 +{
  14 +}
8 15
9 void 16 void
10 InputSource::setLastOffset(qpdf_offset_t offset) 17 InputSource::setLastOffset(qpdf_offset_t offset)
libqpdf/Pipeline.cc
1 #include <qpdf/Pipeline.hh> 1 #include <qpdf/Pipeline.hh>
2 #include <stdexcept> 2 #include <stdexcept>
3 3
  4 +Pipeline::Members::Members(Pipeline* next) :
  5 + next(next)
  6 +{
  7 +}
  8 +
  9 +Pipeline::Members::~Members()
  10 +{
  11 +}
  12 +
4 Pipeline::Pipeline(char const* identifier, Pipeline* next) : 13 Pipeline::Pipeline(char const* identifier, Pipeline* next) :
5 identifier(identifier), 14 identifier(identifier),
6 - next(next) 15 + m(new Members(next))
7 { 16 {
8 } 17 }
9 18
@@ -14,11 +23,11 @@ Pipeline::~Pipeline() @@ -14,11 +23,11 @@ Pipeline::~Pipeline()
14 Pipeline* 23 Pipeline*
15 Pipeline::getNext(bool allow_null) 24 Pipeline::getNext(bool allow_null)
16 { 25 {
17 - if ((next == 0) && (! allow_null)) 26 + if ((this->m->next == 0) && (! allow_null))
18 { 27 {
19 throw std::logic_error( 28 throw std::logic_error(
20 this->identifier + 29 this->identifier +
21 ": Pipeline::getNext() called on pipeline with no next"); 30 ": Pipeline::getNext() called on pipeline with no next");
22 } 31 }
23 - return this->next; 32 + return this->m->next;
24 } 33 }
libqpdf/Pl_Buffer.cc
@@ -4,13 +4,22 @@ @@ -4,13 +4,22 @@
4 #include <assert.h> 4 #include <assert.h>
5 #include <string.h> 5 #include <string.h>
6 6
7 -Pl_Buffer::Pl_Buffer(char const* identifier, Pipeline* next) :  
8 - Pipeline(identifier, next), 7 +Pl_Buffer::Members::Members() :
9 ready(true), 8 ready(true),
10 total_size(0) 9 total_size(0)
11 { 10 {
12 } 11 }
13 12
  13 +Pl_Buffer::Members::~Members()
  14 +{
  15 +}
  16 +
  17 +Pl_Buffer::Pl_Buffer(char const* identifier, Pipeline* next) :
  18 + Pipeline(identifier, next),
  19 + m(new Members())
  20 +{
  21 +}
  22 +
14 Pl_Buffer::~Pl_Buffer() 23 Pl_Buffer::~Pl_Buffer()
15 { 24 {
16 } 25 }
@@ -18,32 +27,25 @@ Pl_Buffer::~Pl_Buffer() @@ -18,32 +27,25 @@ Pl_Buffer::~Pl_Buffer()
18 void 27 void
19 Pl_Buffer::write(unsigned char* buf, size_t len) 28 Pl_Buffer::write(unsigned char* buf, size_t len)
20 { 29 {
21 - PointerHolder<Buffer> cur_buf;  
22 - size_t cur_size = 0;  
23 - if (! this->data.empty()) 30 + if (this->m->data.getPointer() == 0)
24 { 31 {
25 - cur_buf = this->data.back();  
26 - cur_size = cur_buf->getSize(); 32 + this->m->data = new Buffer(len);
27 } 33 }
28 - size_t left = cur_size - this->total_size; 34 + size_t cur_size = this->m->data->getSize();
  35 + size_t left = cur_size - this->m->total_size;
29 if (left < len) 36 if (left < len)
30 { 37 {
31 - size_t new_size = std::max(this->total_size + len, 2 * cur_size);  
32 - Buffer* b = new Buffer(new_size);  
33 - if (cur_buf.getPointer())  
34 - {  
35 - memcpy(b->getBuffer(), cur_buf->getBuffer(), this->total_size);  
36 - }  
37 - this->data.clear();  
38 - cur_buf = b;  
39 - this->data.push_back(cur_buf); 38 + size_t new_size = std::max(this->m->total_size + len, 2 * cur_size);
  39 + PointerHolder<Buffer> b = new Buffer(new_size);
  40 + memcpy(b->getBuffer(), this->m->data->getBuffer(), this->m->total_size);
  41 + this->m->data = b;
40 } 42 }
41 if (len) 43 if (len)
42 { 44 {
43 - memcpy(cur_buf->getBuffer() + this->total_size, buf, len);  
44 - this->total_size += len; 45 + memcpy(this->m->data->getBuffer() + this->m->total_size, buf, len);
  46 + this->m->total_size += len;
45 } 47 }
46 - this->ready = false; 48 + this->m->ready = false;
47 49
48 if (getNext(true)) 50 if (getNext(true))
49 { 51 {
@@ -54,7 +56,7 @@ Pl_Buffer::write(unsigned char* buf, size_t len) @@ -54,7 +56,7 @@ Pl_Buffer::write(unsigned char* buf, size_t len)
54 void 56 void
55 Pl_Buffer::finish() 57 Pl_Buffer::finish()
56 { 58 {
57 - this->ready = true; 59 + this->m->ready = true;
58 if (getNext(true)) 60 if (getNext(true))
59 { 61 {
60 getNext()->finish(); 62 getNext()->finish();
@@ -64,21 +66,17 @@ Pl_Buffer::finish() @@ -64,21 +66,17 @@ Pl_Buffer::finish()
64 Buffer* 66 Buffer*
65 Pl_Buffer::getBuffer() 67 Pl_Buffer::getBuffer()
66 { 68 {
67 - if (! this->ready) 69 + if (! this->m->ready)
68 { 70 {
69 throw std::logic_error("Pl_Buffer::getBuffer() called when not ready"); 71 throw std::logic_error("Pl_Buffer::getBuffer() called when not ready");
70 } 72 }
71 73
72 - Buffer* b = new Buffer(this->total_size);  
73 - unsigned char* p = b->getBuffer();  
74 - if (! this->data.empty()) 74 + Buffer* b = new Buffer(this->m->total_size);
  75 + if (this->m->total_size > 0)
75 { 76 {
76 - PointerHolder<Buffer> bp = this->data.back();  
77 - this->data.clear();  
78 - memcpy(p, bp->getBuffer(), this->total_size); 77 + unsigned char* p = b->getBuffer();
  78 + memcpy(p, this->m->data->getBuffer(), this->m->total_size);
79 } 79 }
80 - this->total_size = 0;  
81 - this->ready = false;  
82 - 80 + this->m = new Members();
83 return b; 81 return b;
84 } 82 }
libqpdf/Pl_Concatenate.cc
1 #include <qpdf/Pl_Concatenate.hh> 1 #include <qpdf/Pl_Concatenate.hh>
2 2
  3 +Pl_Concatenate::Members::Members()
  4 +{
  5 +}
  6 +
  7 +Pl_Concatenate::Members::~Members()
  8 +{
  9 +}
  10 +
3 Pl_Concatenate::Pl_Concatenate(char const* identifier, Pipeline* next) : 11 Pl_Concatenate::Pl_Concatenate(char const* identifier, Pipeline* next) :
4 Pipeline(identifier, next) 12 Pipeline(identifier, next)
5 { 13 {
libqpdf/Pl_Count.cc
1 #include <qpdf/Pl_Count.hh> 1 #include <qpdf/Pl_Count.hh>
2 #include <qpdf/QIntC.hh> 2 #include <qpdf/QIntC.hh>
3 3
4 -Pl_Count::Pl_Count(char const* identifier, Pipeline* next) :  
5 - Pipeline(identifier, next), 4 +Pl_Count::Members::Members() :
6 count(0), 5 count(0),
7 last_char('\0') 6 last_char('\0')
8 { 7 {
9 } 8 }
10 9
  10 +Pl_Count::Members::~Members()
  11 +{
  12 +}
  13 +
  14 +Pl_Count::Pl_Count(char const* identifier, Pipeline* next) :
  15 + Pipeline(identifier, next),
  16 + m(new Members())
  17 +{
  18 +}
  19 +
11 Pl_Count::~Pl_Count() 20 Pl_Count::~Pl_Count()
12 { 21 {
13 } 22 }
@@ -17,9 +26,9 @@ Pl_Count::write(unsigned char* buf, size_t len) @@ -17,9 +26,9 @@ Pl_Count::write(unsigned char* buf, size_t len)
17 { 26 {
18 if (len) 27 if (len)
19 { 28 {
20 - this->count += QIntC::to_offset(len); 29 + this->m->count += QIntC::to_offset(len);
21 getNext()->write(buf, len); 30 getNext()->write(buf, len);
22 - this->last_char = buf[len - 1]; 31 + this->m->last_char = buf[len - 1];
23 } 32 }
24 } 33 }
25 34
@@ -32,11 +41,11 @@ Pl_Count::finish() @@ -32,11 +41,11 @@ Pl_Count::finish()
32 qpdf_offset_t 41 qpdf_offset_t
33 Pl_Count::getCount() const 42 Pl_Count::getCount() const
34 { 43 {
35 - return this->count; 44 + return this->m->count;
36 } 45 }
37 46
38 unsigned char 47 unsigned char
39 Pl_Count::getLastChar() const 48 Pl_Count::getLastChar() const
40 { 49 {
41 - return this->last_char; 50 + return this->m->last_char;
42 } 51 }
libqpdf/Pl_DCT.cc
@@ -31,10 +31,30 @@ error_handler(j_common_ptr cinfo) @@ -31,10 +31,30 @@ error_handler(j_common_ptr cinfo)
31 longjmp(jerr->jmpbuf, 1); 31 longjmp(jerr->jmpbuf, 1);
32 } 32 }
33 33
  34 +Pl_DCT::Members::Members(action_e action,
  35 + char const* buf_description,
  36 + JDIMENSION image_width,
  37 + JDIMENSION image_height,
  38 + int components,
  39 + J_COLOR_SPACE color_space,
  40 + CompressConfig* config_callback) :
  41 + action(action),
  42 + buf(buf_description),
  43 + image_width(image_width),
  44 + image_height(image_height),
  45 + components(components),
  46 + color_space(color_space),
  47 + config_callback(config_callback)
  48 +{
  49 +}
  50 +
  51 +Pl_DCT::Members::~Members()
  52 +{
  53 +}
  54 +
34 Pl_DCT::Pl_DCT(char const* identifier, Pipeline* next) : 55 Pl_DCT::Pl_DCT(char const* identifier, Pipeline* next) :
35 Pipeline(identifier, next), 56 Pipeline(identifier, next),
36 - action(a_decompress),  
37 - buf("DCT compressed image") 57 + m(new Members(a_decompress, "DCT compressed image"))
38 { 58 {
39 } 59 }
40 60
@@ -45,13 +65,8 @@ Pl_DCT::Pl_DCT(char const* identifier, Pipeline* next, @@ -45,13 +65,8 @@ Pl_DCT::Pl_DCT(char const* identifier, Pipeline* next,
45 J_COLOR_SPACE color_space, 65 J_COLOR_SPACE color_space,
46 CompressConfig* config_callback) : 66 CompressConfig* config_callback) :
47 Pipeline(identifier, next), 67 Pipeline(identifier, next),
48 - action(a_compress),  
49 - buf("DCT uncompressed image"),  
50 - image_width(image_width),  
51 - image_height(image_height),  
52 - components(components),  
53 - color_space(color_space),  
54 - config_callback(config_callback) 68 + m(new Members(a_compress, "DCT uncompressed image",
  69 + image_width, image_height, components, color_space, config_callback))
55 { 70 {
56 } 71 }
57 72
@@ -62,18 +77,18 @@ Pl_DCT::~Pl_DCT() @@ -62,18 +77,18 @@ Pl_DCT::~Pl_DCT()
62 void 77 void
63 Pl_DCT::write(unsigned char* data, size_t len) 78 Pl_DCT::write(unsigned char* data, size_t len)
64 { 79 {
65 - this->buf.write(data, len); 80 + this->m->buf.write(data, len);
66 } 81 }
67 82
68 void 83 void
69 Pl_DCT::finish() 84 Pl_DCT::finish()
70 { 85 {
71 - this->buf.finish(); 86 + this->m->buf.finish();
72 87
73 // Using a PointerHolder<Buffer> here and passing it into compress 88 // Using a PointerHolder<Buffer> here and passing it into compress
74 // and decompress causes a memory leak with setjmp/longjmp. Just 89 // and decompress causes a memory leak with setjmp/longjmp. Just
75 // use a pointer and delete it. 90 // use a pointer and delete it.
76 - Buffer* b = this->buf.getBuffer(); 91 + Buffer* b = this->m->buf.getBuffer();
77 if (b->getSize() == 0) 92 if (b->getSize() == 0)
78 { 93 {
79 // Special case: empty data will never succeed and probably 94 // Special case: empty data will never succeed and probably
@@ -99,7 +114,7 @@ Pl_DCT::finish() @@ -99,7 +114,7 @@ Pl_DCT::finish()
99 { 114 {
100 try 115 try
101 { 116 {
102 - if (this->action == a_compress) 117 + if (this->m->action == a_compress)
103 { 118 {
104 compress(reinterpret_cast<void*>(&cinfo_compress), b); 119 compress(reinterpret_cast<void*>(&cinfo_compress), b);
105 } 120 }
@@ -123,11 +138,11 @@ Pl_DCT::finish() @@ -123,11 +138,11 @@ Pl_DCT::finish()
123 } 138 }
124 delete b; 139 delete b;
125 140
126 - if (this->action == a_compress) 141 + if (this->m->action == a_compress)
127 { 142 {
128 jpeg_destroy_compress(&cinfo_compress); 143 jpeg_destroy_compress(&cinfo_compress);
129 } 144 }
130 - if (this->action == a_decompress) 145 + if (this->m->action == a_decompress)
131 { 146 {
132 jpeg_destroy_decompress(&cinfo_decompress); 147 jpeg_destroy_decompress(&cinfo_decompress);
133 } 148 }
@@ -272,14 +287,14 @@ Pl_DCT::compress(void* cinfo_p, Buffer* b) @@ -272,14 +287,14 @@ Pl_DCT::compress(void* cinfo_p, Buffer* b)
272 unsigned char* outbuffer = outbuffer_ph.getPointer(); 287 unsigned char* outbuffer = outbuffer_ph.getPointer();
273 jpeg_pipeline_dest(cinfo, outbuffer, BUF_SIZE, this->getNext()); 288 jpeg_pipeline_dest(cinfo, outbuffer, BUF_SIZE, this->getNext());
274 289
275 - cinfo->image_width = this->image_width;  
276 - cinfo->image_height = this->image_height;  
277 - cinfo->input_components = this->components;  
278 - cinfo->in_color_space = this->color_space; 290 + cinfo->image_width = this->m->image_width;
  291 + cinfo->image_height = this->m->image_height;
  292 + cinfo->input_components = this->m->components;
  293 + cinfo->in_color_space = this->m->color_space;
279 jpeg_set_defaults(cinfo); 294 jpeg_set_defaults(cinfo);
280 - if (this->config_callback) 295 + if (this->m->config_callback)
281 { 296 {
282 - this->config_callback->apply(cinfo); 297 + this->m->config_callback->apply(cinfo);
283 } 298 }
284 299
285 jpeg_start_compress(cinfo, TRUE); 300 jpeg_start_compress(cinfo, TRUE);
libqpdf/Pl_Discard.cc
@@ -2,6 +2,14 @@ @@ -2,6 +2,14 @@
2 2
3 // Exercised in md5 test suite 3 // Exercised in md5 test suite
4 4
  5 +Pl_Discard::Members::Members()
  6 +{
  7 +}
  8 +
  9 +Pl_Discard::Members::~Members()
  10 +{
  11 +}
  12 +
5 Pl_Discard::Pl_Discard() : 13 Pl_Discard::Pl_Discard() :
6 Pipeline("discard", 0) 14 Pipeline("discard", 0)
7 { 15 {
libqpdf/Pl_Flate.cc
@@ -6,12 +6,12 @@ @@ -6,12 +6,12 @@
6 #include <qpdf/QUtil.hh> 6 #include <qpdf/QUtil.hh>
7 #include <qpdf/QIntC.hh> 7 #include <qpdf/QIntC.hh>
8 8
9 -Pl_Flate::Pl_Flate(char const* identifier, Pipeline* next,  
10 - action_e action, unsigned int out_bufsize_int) :  
11 - Pipeline(identifier, next),  
12 - out_bufsize(QIntC::to_size(out_bufsize_int)), 9 +Pl_Flate::Members::Members(size_t out_bufsize,
  10 + action_e action) :
  11 + out_bufsize(out_bufsize),
13 action(action), 12 action(action),
14 - initialized(false) 13 + initialized(false),
  14 + zdata(0)
15 { 15 {
16 this->outbuf = new unsigned char[out_bufsize]; 16 this->outbuf = new unsigned char[out_bufsize];
17 // Indirect through zdata to reach the z_stream so we don't have 17 // 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, @@ -38,7 +38,7 @@ Pl_Flate::Pl_Flate(char const* identifier, Pipeline* next,
38 zstream.avail_out = QIntC::to_uint(out_bufsize); 38 zstream.avail_out = QIntC::to_uint(out_bufsize);
39 } 39 }
40 40
41 -Pl_Flate::~Pl_Flate() 41 +Pl_Flate::Members::~Members()
42 { 42 {
43 delete [] this->outbuf; 43 delete [] this->outbuf;
44 this->outbuf = 0; 44 this->outbuf = 0;
@@ -60,10 +60,21 @@ Pl_Flate::~Pl_Flate() @@ -60,10 +60,21 @@ Pl_Flate::~Pl_Flate()
60 this->zdata = 0; 60 this->zdata = 0;
61 } 61 }
62 62
  63 +Pl_Flate::Pl_Flate(char const* identifier, Pipeline* next,
  64 + action_e action, unsigned int out_bufsize_int) :
  65 + Pipeline(identifier, next),
  66 + m(new Members(QIntC::to_size(out_bufsize_int), action))
  67 +{
  68 +}
  69 +
  70 +Pl_Flate::~Pl_Flate()
  71 +{
  72 +}
  73 +
63 void 74 void
64 Pl_Flate::write(unsigned char* data, size_t len) 75 Pl_Flate::write(unsigned char* data, size_t len)
65 { 76 {
66 - if (this->outbuf == 0) 77 + if (this->m->outbuf == 0)
67 { 78 {
68 throw std::logic_error( 79 throw std::logic_error(
69 this->identifier + 80 this->identifier +
@@ -79,7 +90,7 @@ Pl_Flate::write(unsigned char* data, size_t len) @@ -79,7 +90,7 @@ Pl_Flate::write(unsigned char* data, size_t len)
79 { 90 {
80 size_t bytes = (bytes_left >= max_bytes ? max_bytes : bytes_left); 91 size_t bytes = (bytes_left >= max_bytes ? max_bytes : bytes_left);
81 handleData(buf, bytes, 92 handleData(buf, bytes,
82 - (action == a_inflate ? Z_SYNC_FLUSH : Z_NO_FLUSH)); 93 + (this->m->action == a_inflate ? Z_SYNC_FLUSH : Z_NO_FLUSH));
83 bytes_left -= bytes; 94 bytes_left -= bytes;
84 buf += bytes; 95 buf += bytes;
85 } 96 }
@@ -94,11 +105,11 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush) @@ -94,11 +105,11 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush)
94 "Pl_Flate: zlib doesn't support data" 105 "Pl_Flate: zlib doesn't support data"
95 " blocks larger than int"); 106 " blocks larger than int");
96 } 107 }
97 - z_stream& zstream = *(static_cast<z_stream*>(this->zdata)); 108 + z_stream& zstream = *(static_cast<z_stream*>(this->m->zdata));
98 zstream.next_in = data; 109 zstream.next_in = data;
99 zstream.avail_in = QIntC::to_uint(len); 110 zstream.avail_in = QIntC::to_uint(len);
100 111
101 - if (! this->initialized) 112 + if (! this->m->initialized)
102 { 113 {
103 int err = Z_OK; 114 int err = Z_OK;
104 115
@@ -109,7 +120,7 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush) @@ -109,7 +120,7 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush)
109 # pragma GCC diagnostic push 120 # pragma GCC diagnostic push
110 # pragma GCC diagnostic ignored "-Wold-style-cast" 121 # pragma GCC diagnostic ignored "-Wold-style-cast"
111 #endif 122 #endif
112 - if (this->action == a_deflate) 123 + if (this->m->action == a_deflate)
113 { 124 {
114 err = deflateInit(&zstream, Z_DEFAULT_COMPRESSION); 125 err = deflateInit(&zstream, Z_DEFAULT_COMPRESSION);
115 } 126 }
@@ -123,7 +134,7 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush) @@ -123,7 +134,7 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush)
123 #endif 134 #endif
124 135
125 checkError("Init", err); 136 checkError("Init", err);
126 - this->initialized = true; 137 + this->m->initialized = true;
127 } 138 }
128 139
129 int err = Z_OK; 140 int err = Z_OK;
@@ -131,7 +142,7 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush) @@ -131,7 +142,7 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush)
131 bool done = false; 142 bool done = false;
132 while (! done) 143 while (! done)
133 { 144 {
134 - if (action == a_deflate) 145 + if (this->m->action == a_deflate)
135 { 146 {
136 err = deflate(&zstream, flush); 147 err = deflate(&zstream, flush);
137 } 148 }
@@ -139,7 +150,7 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush) @@ -139,7 +150,7 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush)
139 { 150 {
140 err = inflate(&zstream, flush); 151 err = inflate(&zstream, flush);
141 } 152 }
142 - if ((action == a_inflate) && (err != Z_OK) && zstream.msg && 153 + if ((this->m->action == a_inflate) && (err != Z_OK) && zstream.msg &&
143 (strcmp(zstream.msg, "incorrect data check") == 0)) 154 (strcmp(zstream.msg, "incorrect data check") == 0))
144 { 155 {
145 // Other PDF readers ignore this specific error. Combining 156 // Other PDF readers ignore this specific error. Combining
@@ -172,12 +183,12 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush) @@ -172,12 +183,12 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush)
172 done = true; 183 done = true;
173 } 184 }
174 uLong ready = 185 uLong ready =
175 - QIntC::to_ulong(this->out_bufsize - zstream.avail_out); 186 + QIntC::to_ulong(this->m->out_bufsize - zstream.avail_out);
176 if (ready > 0) 187 if (ready > 0)
177 { 188 {
178 - this->getNext()->write(this->outbuf, ready);  
179 - zstream.next_out = this->outbuf;  
180 - zstream.avail_out = QIntC::to_uint(this->out_bufsize); 189 + this->getNext()->write(this->m->outbuf, ready);
  190 + zstream.next_out = this->m->outbuf;
  191 + zstream.avail_out = QIntC::to_uint(this->m->out_bufsize);
181 } 192 }
182 } 193 }
183 break; 194 break;
@@ -194,16 +205,16 @@ Pl_Flate::finish() @@ -194,16 +205,16 @@ Pl_Flate::finish()
194 { 205 {
195 try 206 try
196 { 207 {
197 - if (this->outbuf) 208 + if (this->m->outbuf)
198 { 209 {
199 - if (this->initialized) 210 + if (this->m->initialized)
200 { 211 {
201 - z_stream& zstream = *(static_cast<z_stream*>(this->zdata)); 212 + z_stream& zstream = *(static_cast<z_stream*>(this->m->zdata));
202 unsigned char buf[1]; 213 unsigned char buf[1];
203 buf[0] = '\0'; 214 buf[0] = '\0';
204 handleData(buf, 0, Z_FINISH); 215 handleData(buf, 0, Z_FINISH);
205 int err = Z_OK; 216 int err = Z_OK;
206 - if (action == a_deflate) 217 + if (this->m->action == a_deflate)
207 { 218 {
208 err = deflateEnd(&zstream); 219 err = deflateEnd(&zstream);
209 } 220 }
@@ -211,12 +222,12 @@ Pl_Flate::finish() @@ -211,12 +222,12 @@ Pl_Flate::finish()
211 { 222 {
212 err = inflateEnd(&zstream); 223 err = inflateEnd(&zstream);
213 } 224 }
214 - this->initialized = false; 225 + this->m->initialized = false;
215 checkError("End", err); 226 checkError("End", err);
216 } 227 }
217 228
218 - delete [] this->outbuf;  
219 - this->outbuf = 0; 229 + delete [] this->m->outbuf;
  230 + this->m->outbuf = 0;
220 } 231 }
221 } 232 }
222 catch (std::exception& e) 233 catch (std::exception& e)
@@ -230,10 +241,11 @@ Pl_Flate::finish() @@ -230,10 +241,11 @@ Pl_Flate::finish()
230 void 241 void
231 Pl_Flate::checkError(char const* prefix, int error_code) 242 Pl_Flate::checkError(char const* prefix, int error_code)
232 { 243 {
233 - z_stream& zstream = *(static_cast<z_stream*>(this->zdata)); 244 + z_stream& zstream = *(static_cast<z_stream*>(this->m->zdata));
234 if (error_code != Z_OK) 245 if (error_code != Z_OK)
235 { 246 {
236 - char const* action_str = (action == a_deflate ? "deflate" : "inflate"); 247 + char const* action_str =
  248 + (this->m->action == a_deflate ? "deflate" : "inflate");
237 std::string msg = 249 std::string msg =
238 this->identifier + ": " + action_str + ": " + prefix + ": "; 250 this->identifier + ": " + action_str + ": " + prefix + ": ";
239 251
libqpdf/Pl_RunLength.cc
@@ -3,15 +3,24 @@ @@ -3,15 +3,24 @@
3 #include <qpdf/QUtil.hh> 3 #include <qpdf/QUtil.hh>
4 #include <qpdf/QTC.hh> 4 #include <qpdf/QTC.hh>
5 5
6 -Pl_RunLength::Pl_RunLength(char const* identifier, Pipeline* next,  
7 - action_e action) :  
8 - Pipeline(identifier, next), 6 +Pl_RunLength::Members::Members(action_e action) :
9 action(action), 7 action(action),
10 state(st_top), 8 state(st_top),
11 length(0) 9 length(0)
12 { 10 {
13 } 11 }
14 12
  13 +Pl_RunLength::Members::~Members()
  14 +{
  15 +}
  16 +
  17 +Pl_RunLength::Pl_RunLength(char const* identifier, Pipeline* next,
  18 + action_e action) :
  19 + Pipeline(identifier, next),
  20 + m(new Members(action))
  21 +{
  22 +}
  23 +
15 Pl_RunLength::~Pl_RunLength() 24 Pl_RunLength::~Pl_RunLength()
16 { 25 {
17 } 26 }
@@ -19,7 +28,7 @@ Pl_RunLength::~Pl_RunLength() @@ -19,7 +28,7 @@ Pl_RunLength::~Pl_RunLength()
19 void 28 void
20 Pl_RunLength::write(unsigned char* data, size_t len) 29 Pl_RunLength::write(unsigned char* data, size_t len)
21 { 30 {
22 - if (this->action == a_encode) 31 + if (this->m->action == a_encode)
23 { 32 {
24 encode(data, len); 33 encode(data, len);
25 } 34 }
@@ -34,41 +43,41 @@ Pl_RunLength::encode(unsigned char* data, size_t len) @@ -34,41 +43,41 @@ Pl_RunLength::encode(unsigned char* data, size_t len)
34 { 43 {
35 for (size_t i = 0; i < len; ++i) 44 for (size_t i = 0; i < len; ++i)
36 { 45 {
37 - if ((this->state == st_top) != (this->length <= 1)) 46 + if ((this->m->state == st_top) != (this->m->length <= 1))
38 { 47 {
39 throw std::logic_error( 48 throw std::logic_error(
40 "Pl_RunLength::encode: state/length inconsistency"); 49 "Pl_RunLength::encode: state/length inconsistency");
41 } 50 }
42 unsigned char ch = data[i]; 51 unsigned char ch = data[i];
43 - if ((this->length > 0) &&  
44 - ((this->state == st_copying) || (this->length < 128)) &&  
45 - (ch == this->buf[this->length-1])) 52 + if ((this->m->length > 0) &&
  53 + ((this->m->state == st_copying) || (this->m->length < 128)) &&
  54 + (ch == this->m->buf[this->m->length-1]))
46 { 55 {
47 QTC::TC("libtests", "Pl_RunLength: switch to run", 56 QTC::TC("libtests", "Pl_RunLength: switch to run",
48 - (this->length == 128) ? 0 : 1);  
49 - if (this->state == st_copying) 57 + (this->m->length == 128) ? 0 : 1);
  58 + if (this->m->state == st_copying)
50 { 59 {
51 - --this->length; 60 + --this->m->length;
52 flush_encode(); 61 flush_encode();
53 - this->buf[0] = ch;  
54 - this->length = 1; 62 + this->m->buf[0] = ch;
  63 + this->m->length = 1;
55 } 64 }
56 - this->state = st_run;  
57 - this->buf[this->length] = ch;  
58 - ++this->length; 65 + this->m->state = st_run;
  66 + this->m->buf[this->m->length] = ch;
  67 + ++this->m->length;
59 } 68 }
60 else 69 else
61 { 70 {
62 - if ((this->length == 128) || (this->state == st_run)) 71 + if ((this->m->length == 128) || (this->m->state == st_run))
63 { 72 {
64 flush_encode(); 73 flush_encode();
65 } 74 }
66 - else if (this->length > 0) 75 + else if (this->m->length > 0)
67 { 76 {
68 - this->state = st_copying; 77 + this->m->state = st_copying;
69 } 78 }
70 - this->buf[this->length] = ch;  
71 - ++this->length; 79 + this->m->buf[this->m->length] = ch;
  80 + ++this->m->length;
72 } 81 }
73 } 82 }
74 } 83 }
@@ -79,20 +88,20 @@ Pl_RunLength::decode(unsigned char* data, size_t len) @@ -79,20 +88,20 @@ Pl_RunLength::decode(unsigned char* data, size_t len)
79 for (size_t i = 0; i < len; ++i) 88 for (size_t i = 0; i < len; ++i)
80 { 89 {
81 unsigned char ch = data[i]; 90 unsigned char ch = data[i];
82 - switch (this->state) 91 + switch (this->m->state)
83 { 92 {
84 case st_top: 93 case st_top:
85 if (ch < 128) 94 if (ch < 128)
86 { 95 {
87 // length represents remaining number of bytes to copy 96 // length represents remaining number of bytes to copy
88 - this->length = 1U + ch;  
89 - this->state = st_copying; 97 + this->m->length = 1U + ch;
  98 + this->m->state = st_copying;
90 } 99 }
91 else if (ch > 128) 100 else if (ch > 128)
92 { 101 {
93 // length represents number of copies of next byte 102 // length represents number of copies of next byte
94 - this->length = 257U - ch;  
95 - this->state = st_run; 103 + this->m->length = 257U - ch;
  104 + this->m->state = st_run;
96 } 105 }
97 else // ch == 128 106 else // ch == 128
98 { 107 {
@@ -102,18 +111,18 @@ Pl_RunLength::decode(unsigned char* data, size_t len) @@ -102,18 +111,18 @@ Pl_RunLength::decode(unsigned char* data, size_t len)
102 111
103 case st_copying: 112 case st_copying:
104 this->getNext()->write(&ch, 1); 113 this->getNext()->write(&ch, 1);
105 - if (--this->length == 0) 114 + if (--this->m->length == 0)
106 { 115 {
107 - this->state = st_top; 116 + this->m->state = st_top;
108 } 117 }
109 break; 118 break;
110 119
111 case st_run: 120 case st_run:
112 - for (unsigned int j = 0; j < this->length; ++j) 121 + for (unsigned int j = 0; j < this->m->length; ++j)
113 { 122 {
114 this->getNext()->write(&ch, 1); 123 this->getNext()->write(&ch, 1);
115 } 124 }
116 - this->state = st_top; 125 + this->m->state = st_top;
117 break; 126 break;
118 } 127 }
119 } 128 }
@@ -122,36 +131,36 @@ Pl_RunLength::decode(unsigned char* data, size_t len) @@ -122,36 +131,36 @@ Pl_RunLength::decode(unsigned char* data, size_t len)
122 void 131 void
123 Pl_RunLength::flush_encode() 132 Pl_RunLength::flush_encode()
124 { 133 {
125 - if (this->length == 128) 134 + if (this->m->length == 128)
126 { 135 {
127 QTC::TC("libtests", "Pl_RunLength flush full buffer", 136 QTC::TC("libtests", "Pl_RunLength flush full buffer",
128 - (this->state == st_copying ? 0 :  
129 - this->state == st_run ? 1 : 137 + (this->m->state == st_copying ? 0 :
  138 + this->m->state == st_run ? 1 :
130 -1)); 139 -1));
131 } 140 }
132 - if (this->length == 0) 141 + if (this->m->length == 0)
133 { 142 {
134 QTC::TC("libtests", "Pl_RunLength flush empty buffer"); 143 QTC::TC("libtests", "Pl_RunLength flush empty buffer");
135 } 144 }
136 - if (this->state == st_run) 145 + if (this->m->state == st_run)
137 { 146 {
138 - if ((this->length < 2) || (this->length > 128)) 147 + if ((this->m->length < 2) || (this->m->length > 128))
139 { 148 {
140 throw std::logic_error( 149 throw std::logic_error(
141 "Pl_RunLength: invalid length in flush_encode for run"); 150 "Pl_RunLength: invalid length in flush_encode for run");
142 } 151 }
143 - unsigned char ch = static_cast<unsigned char>(257 - this->length); 152 + unsigned char ch = static_cast<unsigned char>(257 - this->m->length);
144 this->getNext()->write(&ch, 1); 153 this->getNext()->write(&ch, 1);
145 - this->getNext()->write(&this->buf[0], 1); 154 + this->getNext()->write(&this->m->buf[0], 1);
146 } 155 }
147 - else if (this->length > 0) 156 + else if (this->m->length > 0)
148 { 157 {
149 - unsigned char ch = static_cast<unsigned char>(this->length - 1); 158 + unsigned char ch = static_cast<unsigned char>(this->m->length - 1);
150 this->getNext()->write(&ch, 1); 159 this->getNext()->write(&ch, 1);
151 - this->getNext()->write(this->buf, this->length); 160 + this->getNext()->write(this->m->buf, this->m->length);
152 } 161 }
153 - this->state = st_top;  
154 - this->length = 0; 162 + this->m->state = st_top;
  163 + this->m->length = 0;
155 } 164 }
156 165
157 void 166 void
@@ -161,7 +170,7 @@ Pl_RunLength::finish() @@ -161,7 +170,7 @@ Pl_RunLength::finish()
161 // data, which means the stream was terminated early, but we will 170 // data, which means the stream was terminated early, but we will
162 // just ignore this case since this is the only sensible thing to 171 // just ignore this case since this is the only sensible thing to
163 // do. 172 // do.
164 - if (this->action == a_encode) 173 + if (this->m->action == a_encode)
165 { 174 {
166 flush_encode(); 175 flush_encode();
167 unsigned char ch = 128; 176 unsigned char ch = 128;
libqpdf/Pl_StdioFile.cc
@@ -4,9 +4,18 @@ @@ -4,9 +4,18 @@
4 #include <stdexcept> 4 #include <stdexcept>
5 #include <errno.h> 5 #include <errno.h>
6 6
  7 +Pl_StdioFile::Members::Members(FILE* f) :
  8 + file(f)
  9 +{
  10 +}
  11 +
  12 +Pl_StdioFile::Members::~Members()
  13 +{
  14 +}
  15 +
7 Pl_StdioFile::Pl_StdioFile(char const* identifier, FILE* f) : 16 Pl_StdioFile::Pl_StdioFile(char const* identifier, FILE* f) :
8 Pipeline(identifier, 0), 17 Pipeline(identifier, 0),
9 - file(f) 18 + m(new Members(f))
10 { 19 {
11 } 20 }
12 21
@@ -20,7 +29,7 @@ Pl_StdioFile::write(unsigned char* buf, size_t len) @@ -20,7 +29,7 @@ Pl_StdioFile::write(unsigned char* buf, size_t len)
20 size_t so_far = 0; 29 size_t so_far = 0;
21 while (len > 0) 30 while (len > 0)
22 { 31 {
23 - so_far = fwrite(buf, 1, len, this->file); 32 + so_far = fwrite(buf, 1, len, this->m->file);
24 if (so_far == 0) 33 if (so_far == 0)
25 { 34 {
26 QUtil::throw_system_error( 35 QUtil::throw_system_error(
@@ -37,7 +46,7 @@ Pl_StdioFile::write(unsigned char* buf, size_t len) @@ -37,7 +46,7 @@ Pl_StdioFile::write(unsigned char* buf, size_t len)
37 void 46 void
38 Pl_StdioFile::finish() 47 Pl_StdioFile::finish()
39 { 48 {
40 - if ((fflush(this->file) == -1) && 49 + if ((fflush(this->m->file) == -1) &&
41 (errno == EBADF)) 50 (errno == EBADF))
42 { 51 {
43 throw std::logic_error( 52 throw std::logic_error(
libtests/buffer.cc
@@ -5,6 +5,7 @@ @@ -5,6 +5,7 @@
5 #include <stdlib.h> 5 #include <stdlib.h>
6 #include <stdexcept> 6 #include <stdexcept>
7 #include <iostream> 7 #include <iostream>
  8 +#include <cassert>
8 9
9 static unsigned char* uc(char const* s) 10 static unsigned char* uc(char const* s)
10 { 11 {
@@ -13,6 +14,25 @@ static unsigned char* uc(char const* s) @@ -13,6 +14,25 @@ static unsigned char* uc(char const* s)
13 14
14 int main() 15 int main()
15 { 16 {
  17 + {
  18 + // Test that buffers can be copied by value.
  19 + Buffer bc1(2);
  20 + unsigned char* bc1p = bc1.getBuffer();
  21 + bc1p[0] = 'Q';
  22 + bc1p[1] = 'W';
  23 + Buffer bc2(bc1);
  24 + bc1p[0] = 'R';
  25 + unsigned char* bc2p = bc2.getBuffer();
  26 + assert(bc2p != bc1p);
  27 + assert(bc2p[0] == 'Q');
  28 + assert(bc2p[1] == 'W');
  29 + bc2 = bc1;
  30 + bc2p = bc2.getBuffer();
  31 + assert(bc2p != bc1p);
  32 + assert(bc2p[0] == 'R');
  33 + assert(bc2p[1] == 'W');
  34 + }
  35 +
16 try 36 try
17 { 37 {
18 Pl_Discard discard; 38 Pl_Discard discard;
@@ -68,6 +88,16 @@ int main() @@ -68,6 +88,16 @@ int main()
68 b = bp3.getBuffer(); 88 b = bp3.getBuffer();
69 std::cout << "size: " << b->getSize() << std::endl; 89 std::cout << "size: " << b->getSize() << std::endl;
70 delete b; 90 delete b;
  91 + // Should be able to call getBuffer again and get an empty buffer
  92 + b = bp3.getBuffer();
  93 + std::cout << "size: " << b->getSize() << std::endl;
  94 + delete b;
  95 + // Also can write 0 and do it.
  96 + bp3.write(uc(""), 0);
  97 + bp3.finish();
  98 + b = bp3.getBuffer();
  99 + std::cout << "size: " << b->getSize() << std::endl;
  100 + delete b;
71 } 101 }
72 catch (std::exception& e) 102 catch (std::exception& e)
73 { 103 {
libtests/qtest/buffer/buffer.out
@@ -9,4 +9,6 @@ Pl_Buffer::getBuffer() called when not ready @@ -9,4 +9,6 @@ Pl_Buffer::getBuffer() called when not ready
9 size: 9 9 size: 9
10 data: mooquack 10 data: mooquack
11 size: 0 11 size: 0
  12 +size: 0
  13 +size: 0
12 done 14 done