mirror of
https://github.com/qpdf/qpdf.git
synced 2024-09-21 17:49:08 +00:00
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.
This commit is contained in:
parent
864a546af6
commit
79f6b4823b
@ -70,6 +70,9 @@ CODING RULES
|
|||||||
it seems also for classes that are intended to be subclassed across
|
it seems also for classes that are intended to be subclassed across
|
||||||
the shared library boundary.
|
the shared library boundary.
|
||||||
|
|
||||||
|
* Put private member variables in PointerHolder<Members> for all
|
||||||
|
public classes. Remember to use QPDF_DLL on ~Members().
|
||||||
|
|
||||||
RELEASE PREPARATION
|
RELEASE PREPARATION
|
||||||
|
|
||||||
* Each year, update copyright notices. Just do a case-insensitive
|
* Each year, update copyright notices. Just do a case-insensitive
|
||||||
|
26
TODO
26
TODO
@ -1,32 +1,6 @@
|
|||||||
Next ABI
|
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
|
* Check all overloaded methods to see if any can be eliminated by
|
||||||
using defaulted arguments. See ../misc/find-overloaded-functions.pl
|
using defaulted arguments. See ../misc/find-overloaded-functions.pl
|
||||||
(not in source repo)
|
(not in source repo)
|
||||||
|
@ -23,7 +23,8 @@
|
|||||||
#define BUFFER_HH
|
#define BUFFER_HH
|
||||||
|
|
||||||
#include <qpdf/DLL.h>
|
#include <qpdf/DLL.h>
|
||||||
#include <cstring> // for size_t
|
#include <qpdf/PointerHolder.hh>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
class Buffer
|
class Buffer
|
||||||
{
|
{
|
||||||
@ -46,8 +47,6 @@ class Buffer
|
|||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
Buffer& operator=(Buffer const&);
|
Buffer& operator=(Buffer const&);
|
||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
~Buffer();
|
|
||||||
QPDF_DLL
|
|
||||||
size_t getSize() const;
|
size_t getSize() const;
|
||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
unsigned char const* getBuffer() const;
|
unsigned char const* getBuffer() const;
|
||||||
@ -55,13 +54,26 @@ class Buffer
|
|||||||
unsigned char* getBuffer();
|
unsigned char* getBuffer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init(size_t size, unsigned char* buf, bool own_memory);
|
class Members
|
||||||
void copy(Buffer const&);
|
{
|
||||||
void destroy();
|
friend class Buffer;
|
||||||
|
|
||||||
bool own_memory;
|
public:
|
||||||
size_t size;
|
QPDF_DLL
|
||||||
unsigned char* buf;
|
~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&);
|
||||||
|
|
||||||
|
PointerHolder<Members> m;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BUFFER_HH
|
#endif // BUFFER_HH
|
||||||
|
@ -56,10 +56,25 @@ class BufferInputSource: public InputSource
|
|||||||
private:
|
private:
|
||||||
qpdf_offset_t const bufSizeAsOffset() const;
|
qpdf_offset_t const bufSizeAsOffset() const;
|
||||||
|
|
||||||
bool own_memory;
|
class Members
|
||||||
std::string description;
|
{
|
||||||
Buffer* buf;
|
friend class BufferInputSource;
|
||||||
qpdf_offset_t cur_offset;
|
|
||||||
|
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
|
#endif // QPDF_BUFFERINPUTSOURCE_HH
|
||||||
|
@ -54,11 +54,24 @@ class FileInputSource: public InputSource
|
|||||||
FileInputSource(FileInputSource const&);
|
FileInputSource(FileInputSource const&);
|
||||||
FileInputSource& operator=(FileInputSource const&);
|
FileInputSource& operator=(FileInputSource const&);
|
||||||
|
|
||||||
void destroy();
|
class Members
|
||||||
|
{
|
||||||
|
friend class FileInputSource;
|
||||||
|
|
||||||
bool close_file;
|
public:
|
||||||
std::string filename;
|
QPDF_DLL
|
||||||
FILE* file;
|
~Members();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Members(bool close_file);
|
||||||
|
Members(Members const&);
|
||||||
|
|
||||||
|
bool close_file;
|
||||||
|
std::string filename;
|
||||||
|
FILE* file;
|
||||||
|
};
|
||||||
|
|
||||||
|
PointerHolder<Members> m;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QPDF_FILEINPUTSOURCE_HH
|
#endif // QPDF_FILEINPUTSOURCE_HH
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include <qpdf/DLL.h>
|
#include <qpdf/DLL.h>
|
||||||
#include <qpdf/Types.h>
|
#include <qpdf/Types.h>
|
||||||
|
#include <qpdf/PointerHolder.hh>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -86,6 +87,22 @@ class QPDF_DLL_CLASS InputSource
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
qpdf_offset_t last_offset;
|
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
|
#endif // QPDF_INPUTSOURCE_HH
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#define PIPELINE_HH
|
#define PIPELINE_HH
|
||||||
|
|
||||||
#include <qpdf/DLL.h>
|
#include <qpdf/DLL.h>
|
||||||
|
#include <qpdf/PointerHolder.hh>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class QPDF_DLL_CLASS Pipeline
|
class QPDF_DLL_CLASS Pipeline
|
||||||
@ -79,7 +80,22 @@ class QPDF_DLL_CLASS Pipeline
|
|||||||
Pipeline(Pipeline const&);
|
Pipeline(Pipeline const&);
|
||||||
Pipeline& operator=(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
|
#endif // PIPELINE_HH
|
||||||
|
@ -36,7 +36,6 @@
|
|||||||
#include <qpdf/Pipeline.hh>
|
#include <qpdf/Pipeline.hh>
|
||||||
#include <qpdf/PointerHolder.hh>
|
#include <qpdf/PointerHolder.hh>
|
||||||
#include <qpdf/Buffer.hh>
|
#include <qpdf/Buffer.hh>
|
||||||
#include <list>
|
|
||||||
|
|
||||||
class Pl_Buffer: public Pipeline
|
class Pl_Buffer: public Pipeline
|
||||||
{
|
{
|
||||||
@ -57,9 +56,24 @@ class Pl_Buffer: public Pipeline
|
|||||||
Buffer* getBuffer();
|
Buffer* getBuffer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool ready;
|
class Members
|
||||||
std::list<PointerHolder<Buffer> > data;
|
{
|
||||||
size_t total_size;
|
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
|
#endif // PL_BUFFER_HH
|
||||||
|
@ -48,6 +48,22 @@ class Pl_Concatenate: public Pipeline
|
|||||||
// the pipeline.
|
// the pipeline.
|
||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
void manualFinish();
|
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
|
#endif // PL_CONCATENATE_HH
|
||||||
|
@ -48,10 +48,25 @@ class Pl_Count: public Pipeline
|
|||||||
unsigned char getLastChar() const;
|
unsigned char getLastChar() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Must be qpdf_offset_t, not size_t, to handle writing more than
|
class Members
|
||||||
// size_t can handle.
|
{
|
||||||
qpdf_offset_t count;
|
friend class Pl_Count;
|
||||||
unsigned char last_char;
|
|
||||||
|
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
|
#endif // PL_COUNT_HH
|
||||||
|
@ -68,17 +68,37 @@ class Pl_DCT: public Pipeline
|
|||||||
|
|
||||||
enum action_e { a_compress, a_decompress };
|
enum action_e { a_compress, a_decompress };
|
||||||
|
|
||||||
action_e action;
|
class Members
|
||||||
Pl_Buffer buf;
|
{
|
||||||
|
friend class Pl_DCT;
|
||||||
|
|
||||||
// Used for compression
|
public:
|
||||||
JDIMENSION image_width;
|
QPDF_DLL
|
||||||
JDIMENSION image_height;
|
~Members();
|
||||||
int components;
|
|
||||||
J_COLOR_SPACE color_space;
|
|
||||||
|
|
||||||
CompressConfig* config_callback;
|
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&);
|
||||||
|
|
||||||
|
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
|
#endif // PL_DCT_HH
|
||||||
|
@ -41,6 +41,22 @@ class Pl_Discard: public Pipeline
|
|||||||
virtual void write(unsigned char*, size_t);
|
virtual void write(unsigned char*, size_t);
|
||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
virtual void finish();
|
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
|
#endif // PL_DISCARD_HH
|
||||||
|
@ -46,11 +46,26 @@ class Pl_Flate: public Pipeline
|
|||||||
void handleData(unsigned char* data, size_t len, int flush);
|
void handleData(unsigned char* data, size_t len, int flush);
|
||||||
void checkError(char const* prefix, int error_code);
|
void checkError(char const* prefix, int error_code);
|
||||||
|
|
||||||
unsigned char* outbuf;
|
class Members
|
||||||
size_t out_bufsize;
|
{
|
||||||
action_e action;
|
friend class Pl_Flate;
|
||||||
bool initialized;
|
|
||||||
void* zdata;
|
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
|
#endif // PL_FLATE_HH
|
||||||
|
@ -47,10 +47,25 @@ class Pl_RunLength: public Pipeline
|
|||||||
|
|
||||||
enum state_e { st_top, st_copying, st_run };
|
enum state_e { st_top, st_copying, st_run };
|
||||||
|
|
||||||
action_e action;
|
class Members
|
||||||
state_e state;
|
{
|
||||||
unsigned char buf[128];
|
friend class Pl_RunLength;
|
||||||
unsigned int length;
|
|
||||||
|
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
|
#endif // PL_RUNLENGTH_HH
|
||||||
|
@ -48,7 +48,22 @@ class Pl_StdioFile: public Pipeline
|
|||||||
virtual void finish();
|
virtual void finish();
|
||||||
|
|
||||||
private:
|
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
|
#endif // PL_STDIOFILE_HH
|
||||||
|
@ -24,8 +24,8 @@
|
|||||||
|
|
||||||
#include <qpdf/DLL.h>
|
#include <qpdf/DLL.h>
|
||||||
#include <qpdf/Types.h>
|
#include <qpdf/Types.h>
|
||||||
|
|
||||||
#include <qpdf/Constants.h>
|
#include <qpdf/Constants.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
@ -70,6 +70,9 @@ class QPDF_DLL_CLASS QPDFExc: public std::runtime_error
|
|||||||
qpdf_offset_t offset,
|
qpdf_offset_t offset,
|
||||||
std::string const& message);
|
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;
|
qpdf_error_code_e error_code;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
std::string object;
|
std::string object;
|
||||||
|
@ -44,6 +44,9 @@ class QPDFObjGen
|
|||||||
int getGen() const;
|
int getGen() const;
|
||||||
|
|
||||||
private:
|
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 obj;
|
||||||
int gen;
|
int gen;
|
||||||
};
|
};
|
||||||
|
@ -24,8 +24,8 @@
|
|||||||
|
|
||||||
#include <qpdf/DLL.h>
|
#include <qpdf/DLL.h>
|
||||||
#include <qpdf/Types.h>
|
#include <qpdf/Types.h>
|
||||||
|
|
||||||
#include <qpdf/Constants.h>
|
#include <qpdf/Constants.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
@ -51,6 +51,9 @@ class QPDF_DLL_CLASS QPDFSystemError: public std::runtime_error
|
|||||||
static std::string createWhat(std::string const& description,
|
static std::string createWhat(std::string const& description,
|
||||||
int system_errno);
|
int system_errno);
|
||||||
|
|
||||||
|
// This class does not use the Members pattern to avoid needless
|
||||||
|
// memory allocations during exception handling.
|
||||||
|
|
||||||
std::string description;
|
std::string description;
|
||||||
int system_errno;
|
int system_errno;
|
||||||
};
|
};
|
||||||
|
@ -49,6 +49,8 @@ class QPDFXRefEntry
|
|||||||
int getObjStreamIndex() const; // only for type 2
|
int getObjStreamIndex() const; // only for type 2
|
||||||
|
|
||||||
private:
|
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;
|
int type;
|
||||||
qpdf_offset_t field1;
|
qpdf_offset_t field1;
|
||||||
int field2;
|
int field2;
|
||||||
|
@ -1,45 +1,12 @@
|
|||||||
#include <qpdf/Buffer.hh>
|
#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);
|
|
||||||
}
|
|
||||||
|
|
||||||
Buffer::Buffer(size_t size)
|
|
||||||
{
|
|
||||||
init(size, 0, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Buffer::Buffer(unsigned char* buf, size_t size)
|
|
||||||
{
|
|
||||||
init(size, buf, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
Buffer::Buffer(Buffer const& rhs)
|
|
||||||
{
|
|
||||||
init(0, 0, true);
|
|
||||||
copy(rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
Buffer&
|
|
||||||
Buffer::operator=(Buffer const& rhs)
|
|
||||||
{
|
|
||||||
copy(rhs);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Buffer::~Buffer()
|
|
||||||
{
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Buffer::init(size_t size, unsigned char* buf, bool own_memory)
|
|
||||||
{
|
|
||||||
this->own_memory = own_memory;
|
|
||||||
this->size = size;
|
|
||||||
if (own_memory)
|
if (own_memory)
|
||||||
{
|
{
|
||||||
this->buf = (size ? new unsigned char[size] : 0);
|
this->buf = (size ? new unsigned char[size] : 0);
|
||||||
@ -50,45 +17,68 @@ Buffer::init(size_t size, unsigned char* buf, bool own_memory)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
Buffer::Members::~Members()
|
||||||
Buffer::copy(Buffer const& rhs)
|
|
||||||
{
|
|
||||||
if (this != &rhs)
|
|
||||||
{
|
|
||||||
this->destroy();
|
|
||||||
this->init(rhs.size, 0, true);
|
|
||||||
if (this->size)
|
|
||||||
{
|
|
||||||
memcpy(this->buf, rhs.buf, this->size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Buffer::destroy()
|
|
||||||
{
|
{
|
||||||
if (this->own_memory)
|
if (this->own_memory)
|
||||||
{
|
{
|
||||||
delete [] this->buf;
|
delete [] this->buf;
|
||||||
}
|
}
|
||||||
this->size = 0;
|
}
|
||||||
this->buf = 0;
|
|
||||||
|
Buffer::Buffer() :
|
||||||
|
m(new Members(0, 0, true))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer::Buffer(size_t size) :
|
||||||
|
m(new Members(size, 0, true))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer::Buffer(unsigned char* buf, size_t size) :
|
||||||
|
m(new Members(size, buf, false))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer::Buffer(Buffer const& rhs)
|
||||||
|
{
|
||||||
|
copy(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer&
|
||||||
|
Buffer::operator=(Buffer const& rhs)
|
||||||
|
{
|
||||||
|
copy(rhs);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Buffer::copy(Buffer const& rhs)
|
||||||
|
{
|
||||||
|
if (this != &rhs)
|
||||||
|
{
|
||||||
|
this->m = new Members(rhs.m->size, 0, true);
|
||||||
|
if (this->m->size)
|
||||||
|
{
|
||||||
|
memcpy(this->m->buf, rhs.m->buf, this->m->size);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
Buffer::getSize() const
|
Buffer::getSize() const
|
||||||
{
|
{
|
||||||
return this->size;
|
return this->m->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char const*
|
unsigned char const*
|
||||||
Buffer::getBuffer() const
|
Buffer::getBuffer() const
|
||||||
{
|
{
|
||||||
return this->buf;
|
return this->m->buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char*
|
unsigned char*
|
||||||
Buffer::getBuffer()
|
Buffer::getBuffer()
|
||||||
{
|
{
|
||||||
return this->buf;
|
return this->m->buf;
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,9 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
BufferInputSource::BufferInputSource(std::string const& description,
|
BufferInputSource::Members::Members(bool own_memory,
|
||||||
Buffer* buf, bool own_memory) :
|
std::string const& description,
|
||||||
|
Buffer* buf) :
|
||||||
own_memory(own_memory),
|
own_memory(own_memory),
|
||||||
description(description),
|
description(description),
|
||||||
buf(buf),
|
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,
|
BufferInputSource::BufferInputSource(std::string const& description,
|
||||||
std::string const& contents) :
|
std::string const& contents) :
|
||||||
own_memory(true),
|
m(new Members(true, description, 0))
|
||||||
description(description),
|
|
||||||
buf(0),
|
|
||||||
cur_offset(0)
|
|
||||||
{
|
{
|
||||||
this->buf = new Buffer(contents.length());
|
this->m->buf = new Buffer(contents.length());
|
||||||
unsigned char* bp = buf->getBuffer();
|
unsigned char* bp = this->m->buf->getBuffer();
|
||||||
memcpy(bp, contents.c_str(), contents.length());
|
memcpy(bp, contents.c_str(), contents.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferInputSource::~BufferInputSource()
|
BufferInputSource::~BufferInputSource()
|
||||||
{
|
{
|
||||||
if (own_memory)
|
if (this->m->own_memory)
|
||||||
{
|
{
|
||||||
delete this->buf;
|
delete this->m->buf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qpdf_offset_t const
|
qpdf_offset_t const
|
||||||
BufferInputSource::bufSizeAsOffset() const
|
BufferInputSource::bufSizeAsOffset() const
|
||||||
{
|
{
|
||||||
return QIntC::to_offset(this->buf->getSize());
|
return QIntC::to_offset(this->m->buf->getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
qpdf_offset_t
|
qpdf_offset_t
|
||||||
BufferInputSource::findAndSkipNextEOL()
|
BufferInputSource::findAndSkipNextEOL()
|
||||||
{
|
{
|
||||||
if (this->cur_offset < 0)
|
if (this->m->cur_offset < 0)
|
||||||
{
|
{
|
||||||
throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0");
|
throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0");
|
||||||
}
|
}
|
||||||
qpdf_offset_t end_pos = bufSizeAsOffset();
|
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->last_offset = end_pos;
|
||||||
this->cur_offset = end_pos;
|
this->m->cur_offset = end_pos;
|
||||||
return end_pos;
|
return end_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
qpdf_offset_t result = 0;
|
qpdf_offset_t result = 0;
|
||||||
size_t len = QIntC::to_size(end_pos - this->cur_offset);
|
size_t len = QIntC::to_size(end_pos - this->m->cur_offset);
|
||||||
unsigned char const* buffer = this->buf->getBuffer();
|
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* p1 = static_cast<unsigned char*>(memchr(start, '\r', len));
|
||||||
unsigned char* p2 = static_cast<unsigned char*>(memchr(start, '\n', len));
|
unsigned char* p2 = static_cast<unsigned char*>(memchr(start, '\n', len));
|
||||||
unsigned char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2;
|
unsigned char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2;
|
||||||
if (p)
|
if (p)
|
||||||
{
|
{
|
||||||
result = p - buffer;
|
result = p - buffer;
|
||||||
this->cur_offset = result + 1;
|
this->m->cur_offset = result + 1;
|
||||||
++p;
|
++p;
|
||||||
while ((this->cur_offset < end_pos) &&
|
while ((this->m->cur_offset < end_pos) &&
|
||||||
((*p == '\r') || (*p == '\n')))
|
((*p == '\r') || (*p == '\n')))
|
||||||
{
|
{
|
||||||
++p;
|
++p;
|
||||||
++this->cur_offset;
|
++this->m->cur_offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this->cur_offset = end_pos;
|
this->m->cur_offset = end_pos;
|
||||||
result = end_pos;
|
result = end_pos;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -85,13 +93,13 @@ BufferInputSource::findAndSkipNextEOL()
|
|||||||
std::string const&
|
std::string const&
|
||||||
BufferInputSource::getName() const
|
BufferInputSource::getName() const
|
||||||
{
|
{
|
||||||
return this->description;
|
return this->m->description;
|
||||||
}
|
}
|
||||||
|
|
||||||
qpdf_offset_t
|
qpdf_offset_t
|
||||||
BufferInputSource::tell()
|
BufferInputSource::tell()
|
||||||
{
|
{
|
||||||
return this->cur_offset;
|
return this->m->cur_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -100,15 +108,15 @@ BufferInputSource::seek(qpdf_offset_t offset, int whence)
|
|||||||
switch (whence)
|
switch (whence)
|
||||||
{
|
{
|
||||||
case SEEK_SET:
|
case SEEK_SET:
|
||||||
this->cur_offset = offset;
|
this->m->cur_offset = offset;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SEEK_END:
|
case SEEK_END:
|
||||||
this->cur_offset = bufSizeAsOffset() + offset;
|
this->m->cur_offset = bufSizeAsOffset() + offset;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SEEK_CUR:
|
case SEEK_CUR:
|
||||||
this->cur_offset += offset;
|
this->m->cur_offset += offset;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -117,46 +125,46 @@ BufferInputSource::seek(qpdf_offset_t offset, int whence)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->cur_offset < 0)
|
if (this->m->cur_offset < 0)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
this->description + ": seek before beginning of buffer");
|
this->m->description + ": seek before beginning of buffer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BufferInputSource::rewind()
|
BufferInputSource::rewind()
|
||||||
{
|
{
|
||||||
this->cur_offset = 0;
|
this->m->cur_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
BufferInputSource::read(char* buffer, size_t length)
|
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");
|
throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0");
|
||||||
}
|
}
|
||||||
qpdf_offset_t end_pos = bufSizeAsOffset();
|
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->last_offset = end_pos;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->last_offset = this->cur_offset;
|
this->last_offset = this->m->cur_offset;
|
||||||
size_t len = std::min(
|
size_t len = std::min(
|
||||||
QIntC::to_size(end_pos - this->cur_offset), length);
|
QIntC::to_size(end_pos - this->m->cur_offset), length);
|
||||||
memcpy(buffer, buf->getBuffer() + this->cur_offset, len);
|
memcpy(buffer, this->m->buf->getBuffer() + this->m->cur_offset, len);
|
||||||
this->cur_offset += QIntC::to_offset(len);
|
this->m->cur_offset += QIntC::to_offset(len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BufferInputSource::unreadCh(char ch)
|
BufferInputSource::unreadCh(char ch)
|
||||||
{
|
{
|
||||||
if (this->cur_offset > 0)
|
if (this->m->cur_offset > 0)
|
||||||
{
|
{
|
||||||
--this->cur_offset;
|
--this->m->cur_offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,45 +4,45 @@
|
|||||||
#include <qpdf/QPDFExc.hh>
|
#include <qpdf/QPDFExc.hh>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
FileInputSource::FileInputSource() :
|
FileInputSource::Members::Members(bool close_file) :
|
||||||
close_file(false),
|
close_file(close_file),
|
||||||
file(0)
|
file(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FileInputSource::Members::~Members()
|
||||||
|
{
|
||||||
|
if (this->file && this->close_file)
|
||||||
|
{
|
||||||
|
fclose(this->file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileInputSource::FileInputSource() :
|
||||||
|
m(new Members(false))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FileInputSource::setFilename(char const* filename)
|
FileInputSource::setFilename(char const* filename)
|
||||||
{
|
{
|
||||||
destroy();
|
this->m = new Members(true);
|
||||||
this->filename = filename;
|
this->m->filename = filename;
|
||||||
this->close_file = true;
|
this->m->file = QUtil::safe_fopen(filename, "rb");
|
||||||
this->file = QUtil::safe_fopen(this->filename.c_str(), "rb");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FileInputSource::setFile(
|
FileInputSource::setFile(
|
||||||
char const* description, FILE* filep, bool close_file)
|
char const* description, FILE* filep, bool close_file)
|
||||||
{
|
{
|
||||||
destroy();
|
this->m = new Members(close_file);
|
||||||
this->filename = description;
|
this->m->filename = description;
|
||||||
this->close_file = close_file;
|
this->m->file = filep;
|
||||||
this->file = filep;
|
|
||||||
this->seek(0, SEEK_SET);
|
this->seek(0, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInputSource::~FileInputSource()
|
FileInputSource::~FileInputSource()
|
||||||
{
|
{
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
FileInputSource::destroy()
|
|
||||||
{
|
|
||||||
if (this->file && this->close_file)
|
|
||||||
{
|
|
||||||
fclose(this->file);
|
|
||||||
this->file = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qpdf_offset_t
|
qpdf_offset_t
|
||||||
@ -53,7 +53,7 @@ FileInputSource::findAndSkipNextEOL()
|
|||||||
char buf[10240];
|
char buf[10240];
|
||||||
while (! done)
|
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));
|
size_t len = this->read(buf, sizeof(buf));
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
{
|
{
|
||||||
@ -93,41 +93,42 @@ FileInputSource::findAndSkipNextEOL()
|
|||||||
std::string const&
|
std::string const&
|
||||||
FileInputSource::getName() const
|
FileInputSource::getName() const
|
||||||
{
|
{
|
||||||
return this->filename;
|
return this->m->filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
qpdf_offset_t
|
qpdf_offset_t
|
||||||
FileInputSource::tell()
|
FileInputSource::tell()
|
||||||
{
|
{
|
||||||
return QUtil::tell(this->file);
|
return QUtil::tell(this->m->file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FileInputSource::seek(qpdf_offset_t offset, int whence)
|
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(offset) + " (" +
|
||||||
QUtil::int_to_string(whence) + ")",
|
QUtil::int_to_string(whence) + ")",
|
||||||
QUtil::seek(this->file, offset, whence));
|
QUtil::seek(this->m->file, offset, whence));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FileInputSource::rewind()
|
FileInputSource::rewind()
|
||||||
{
|
{
|
||||||
::rewind(this->file);
|
::rewind(this->m->file);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
FileInputSource::read(char* buffer, size_t length)
|
FileInputSource::read(char* buffer, size_t length)
|
||||||
{
|
{
|
||||||
this->last_offset = this->tell();
|
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 (len == 0)
|
||||||
{
|
{
|
||||||
if (ferror(this->file))
|
if (ferror(this->m->file))
|
||||||
{
|
{
|
||||||
throw QPDFExc(qpdf_e_system,
|
throw QPDFExc(qpdf_e_system,
|
||||||
this->filename, "",
|
this->m->filename, "",
|
||||||
this->last_offset,
|
this->last_offset,
|
||||||
std::string("read ") +
|
std::string("read ") +
|
||||||
QUtil::uint_to_string(length) + " bytes");
|
QUtil::uint_to_string(length) + " bytes");
|
||||||
@ -144,6 +145,6 @@ FileInputSource::read(char* buffer, size_t length)
|
|||||||
void
|
void
|
||||||
FileInputSource::unreadCh(char ch)
|
FileInputSource::unreadCh(char ch)
|
||||||
{
|
{
|
||||||
QUtil::os_wrapper(this->filename + ": unread character",
|
QUtil::os_wrapper(this->m->filename + ": unread character",
|
||||||
ungetc(static_cast<unsigned char>(ch), this->file));
|
ungetc(static_cast<unsigned char>(ch), this->m->file));
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,13 @@
|
|||||||
#include <qpdf/PointerHolder.hh>
|
#include <qpdf/PointerHolder.hh>
|
||||||
#include <qpdf/QIntC.hh>
|
#include <qpdf/QIntC.hh>
|
||||||
|
|
||||||
|
InputSource::Members::Members()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
InputSource::Members::~Members()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
InputSource::setLastOffset(qpdf_offset_t offset)
|
InputSource::setLastOffset(qpdf_offset_t offset)
|
||||||
|
@ -1,9 +1,18 @@
|
|||||||
#include <qpdf/Pipeline.hh>
|
#include <qpdf/Pipeline.hh>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
Pipeline::Members::Members(Pipeline* next) :
|
||||||
|
next(next)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Pipeline::Members::~Members()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Pipeline::Pipeline(char const* identifier, Pipeline* next) :
|
Pipeline::Pipeline(char const* identifier, Pipeline* next) :
|
||||||
identifier(identifier),
|
identifier(identifier),
|
||||||
next(next)
|
m(new Members(next))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14,11 +23,11 @@ Pipeline::~Pipeline()
|
|||||||
Pipeline*
|
Pipeline*
|
||||||
Pipeline::getNext(bool allow_null)
|
Pipeline::getNext(bool allow_null)
|
||||||
{
|
{
|
||||||
if ((next == 0) && (! allow_null))
|
if ((this->m->next == 0) && (! allow_null))
|
||||||
{
|
{
|
||||||
throw std::logic_error(
|
throw std::logic_error(
|
||||||
this->identifier +
|
this->identifier +
|
||||||
": Pipeline::getNext() called on pipeline with no next");
|
": Pipeline::getNext() called on pipeline with no next");
|
||||||
}
|
}
|
||||||
return this->next;
|
return this->m->next;
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,22 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
Pl_Buffer::Pl_Buffer(char const* identifier, Pipeline* next) :
|
Pl_Buffer::Members::Members() :
|
||||||
Pipeline(identifier, next),
|
|
||||||
ready(true),
|
ready(true),
|
||||||
total_size(0)
|
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()
|
Pl_Buffer::~Pl_Buffer()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -18,32 +27,25 @@ Pl_Buffer::~Pl_Buffer()
|
|||||||
void
|
void
|
||||||
Pl_Buffer::write(unsigned char* buf, size_t len)
|
Pl_Buffer::write(unsigned char* buf, size_t len)
|
||||||
{
|
{
|
||||||
PointerHolder<Buffer> cur_buf;
|
if (this->m->data.getPointer() == 0)
|
||||||
size_t cur_size = 0;
|
|
||||||
if (! this->data.empty())
|
|
||||||
{
|
{
|
||||||
cur_buf = this->data.back();
|
this->m->data = new Buffer(len);
|
||||||
cur_size = cur_buf->getSize();
|
|
||||||
}
|
}
|
||||||
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)
|
if (left < len)
|
||||||
{
|
{
|
||||||
size_t new_size = std::max(this->total_size + len, 2 * cur_size);
|
size_t new_size = std::max(this->m->total_size + len, 2 * cur_size);
|
||||||
Buffer* b = new Buffer(new_size);
|
PointerHolder<Buffer> b = new Buffer(new_size);
|
||||||
if (cur_buf.getPointer())
|
memcpy(b->getBuffer(), this->m->data->getBuffer(), this->m->total_size);
|
||||||
{
|
this->m->data = b;
|
||||||
memcpy(b->getBuffer(), cur_buf->getBuffer(), this->total_size);
|
|
||||||
}
|
|
||||||
this->data.clear();
|
|
||||||
cur_buf = b;
|
|
||||||
this->data.push_back(cur_buf);
|
|
||||||
}
|
}
|
||||||
if (len)
|
if (len)
|
||||||
{
|
{
|
||||||
memcpy(cur_buf->getBuffer() + this->total_size, buf, len);
|
memcpy(this->m->data->getBuffer() + this->m->total_size, buf, len);
|
||||||
this->total_size += len;
|
this->m->total_size += len;
|
||||||
}
|
}
|
||||||
this->ready = false;
|
this->m->ready = false;
|
||||||
|
|
||||||
if (getNext(true))
|
if (getNext(true))
|
||||||
{
|
{
|
||||||
@ -54,7 +56,7 @@ Pl_Buffer::write(unsigned char* buf, size_t len)
|
|||||||
void
|
void
|
||||||
Pl_Buffer::finish()
|
Pl_Buffer::finish()
|
||||||
{
|
{
|
||||||
this->ready = true;
|
this->m->ready = true;
|
||||||
if (getNext(true))
|
if (getNext(true))
|
||||||
{
|
{
|
||||||
getNext()->finish();
|
getNext()->finish();
|
||||||
@ -64,21 +66,17 @@ Pl_Buffer::finish()
|
|||||||
Buffer*
|
Buffer*
|
||||||
Pl_Buffer::getBuffer()
|
Pl_Buffer::getBuffer()
|
||||||
{
|
{
|
||||||
if (! this->ready)
|
if (! this->m->ready)
|
||||||
{
|
{
|
||||||
throw std::logic_error("Pl_Buffer::getBuffer() called when not ready");
|
throw std::logic_error("Pl_Buffer::getBuffer() called when not ready");
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer* b = new Buffer(this->total_size);
|
Buffer* b = new Buffer(this->m->total_size);
|
||||||
unsigned char* p = b->getBuffer();
|
if (this->m->total_size > 0)
|
||||||
if (! this->data.empty())
|
|
||||||
{
|
{
|
||||||
PointerHolder<Buffer> bp = this->data.back();
|
unsigned char* p = b->getBuffer();
|
||||||
this->data.clear();
|
memcpy(p, this->m->data->getBuffer(), this->m->total_size);
|
||||||
memcpy(p, bp->getBuffer(), this->total_size);
|
|
||||||
}
|
}
|
||||||
this->total_size = 0;
|
this->m = new Members();
|
||||||
this->ready = false;
|
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
#include <qpdf/Pl_Concatenate.hh>
|
#include <qpdf/Pl_Concatenate.hh>
|
||||||
|
|
||||||
|
Pl_Concatenate::Members::Members()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Pl_Concatenate::Members::~Members()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Pl_Concatenate::Pl_Concatenate(char const* identifier, Pipeline* next) :
|
Pl_Concatenate::Pl_Concatenate(char const* identifier, Pipeline* next) :
|
||||||
Pipeline(identifier, next)
|
Pipeline(identifier, next)
|
||||||
{
|
{
|
||||||
|
@ -1,13 +1,22 @@
|
|||||||
#include <qpdf/Pl_Count.hh>
|
#include <qpdf/Pl_Count.hh>
|
||||||
#include <qpdf/QIntC.hh>
|
#include <qpdf/QIntC.hh>
|
||||||
|
|
||||||
Pl_Count::Pl_Count(char const* identifier, Pipeline* next) :
|
Pl_Count::Members::Members() :
|
||||||
Pipeline(identifier, next),
|
|
||||||
count(0),
|
count(0),
|
||||||
last_char('\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()
|
Pl_Count::~Pl_Count()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -17,9 +26,9 @@ Pl_Count::write(unsigned char* buf, size_t len)
|
|||||||
{
|
{
|
||||||
if (len)
|
if (len)
|
||||||
{
|
{
|
||||||
this->count += QIntC::to_offset(len);
|
this->m->count += QIntC::to_offset(len);
|
||||||
getNext()->write(buf, 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
|
qpdf_offset_t
|
||||||
Pl_Count::getCount() const
|
Pl_Count::getCount() const
|
||||||
{
|
{
|
||||||
return this->count;
|
return this->m->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char
|
unsigned char
|
||||||
Pl_Count::getLastChar() const
|
Pl_Count::getLastChar() const
|
||||||
{
|
{
|
||||||
return this->last_char;
|
return this->m->last_char;
|
||||||
}
|
}
|
||||||
|
@ -31,10 +31,30 @@ error_handler(j_common_ptr cinfo)
|
|||||||
longjmp(jerr->jmpbuf, 1);
|
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) :
|
Pl_DCT::Pl_DCT(char const* identifier, Pipeline* next) :
|
||||||
Pipeline(identifier, next),
|
Pipeline(identifier, next),
|
||||||
action(a_decompress),
|
m(new Members(a_decompress, "DCT compressed image"))
|
||||||
buf("DCT compressed image")
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,13 +65,8 @@ Pl_DCT::Pl_DCT(char const* identifier, Pipeline* next,
|
|||||||
J_COLOR_SPACE color_space,
|
J_COLOR_SPACE color_space,
|
||||||
CompressConfig* config_callback) :
|
CompressConfig* config_callback) :
|
||||||
Pipeline(identifier, next),
|
Pipeline(identifier, next),
|
||||||
action(a_compress),
|
m(new Members(a_compress, "DCT uncompressed image",
|
||||||
buf("DCT uncompressed image"),
|
image_width, image_height, components, color_space, config_callback))
|
||||||
image_width(image_width),
|
|
||||||
image_height(image_height),
|
|
||||||
components(components),
|
|
||||||
color_space(color_space),
|
|
||||||
config_callback(config_callback)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,18 +77,18 @@ Pl_DCT::~Pl_DCT()
|
|||||||
void
|
void
|
||||||
Pl_DCT::write(unsigned char* data, size_t len)
|
Pl_DCT::write(unsigned char* data, size_t len)
|
||||||
{
|
{
|
||||||
this->buf.write(data, len);
|
this->m->buf.write(data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Pl_DCT::finish()
|
Pl_DCT::finish()
|
||||||
{
|
{
|
||||||
this->buf.finish();
|
this->m->buf.finish();
|
||||||
|
|
||||||
// Using a PointerHolder<Buffer> here and passing it into compress
|
// Using a PointerHolder<Buffer> here and passing it into compress
|
||||||
// and decompress causes a memory leak with setjmp/longjmp. Just
|
// and decompress causes a memory leak with setjmp/longjmp. Just
|
||||||
// use a pointer and delete it.
|
// use a pointer and delete it.
|
||||||
Buffer* b = this->buf.getBuffer();
|
Buffer* b = this->m->buf.getBuffer();
|
||||||
if (b->getSize() == 0)
|
if (b->getSize() == 0)
|
||||||
{
|
{
|
||||||
// Special case: empty data will never succeed and probably
|
// Special case: empty data will never succeed and probably
|
||||||
@ -99,7 +114,7 @@ Pl_DCT::finish()
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (this->action == a_compress)
|
if (this->m->action == a_compress)
|
||||||
{
|
{
|
||||||
compress(reinterpret_cast<void*>(&cinfo_compress), b);
|
compress(reinterpret_cast<void*>(&cinfo_compress), b);
|
||||||
}
|
}
|
||||||
@ -123,11 +138,11 @@ Pl_DCT::finish()
|
|||||||
}
|
}
|
||||||
delete b;
|
delete b;
|
||||||
|
|
||||||
if (this->action == a_compress)
|
if (this->m->action == a_compress)
|
||||||
{
|
{
|
||||||
jpeg_destroy_compress(&cinfo_compress);
|
jpeg_destroy_compress(&cinfo_compress);
|
||||||
}
|
}
|
||||||
if (this->action == a_decompress)
|
if (this->m->action == a_decompress)
|
||||||
{
|
{
|
||||||
jpeg_destroy_decompress(&cinfo_decompress);
|
jpeg_destroy_decompress(&cinfo_decompress);
|
||||||
}
|
}
|
||||||
@ -272,14 +287,14 @@ Pl_DCT::compress(void* cinfo_p, Buffer* b)
|
|||||||
unsigned char* outbuffer = outbuffer_ph.getPointer();
|
unsigned char* outbuffer = outbuffer_ph.getPointer();
|
||||||
jpeg_pipeline_dest(cinfo, outbuffer, BUF_SIZE, this->getNext());
|
jpeg_pipeline_dest(cinfo, outbuffer, BUF_SIZE, this->getNext());
|
||||||
|
|
||||||
cinfo->image_width = this->image_width;
|
cinfo->image_width = this->m->image_width;
|
||||||
cinfo->image_height = this->image_height;
|
cinfo->image_height = this->m->image_height;
|
||||||
cinfo->input_components = this->components;
|
cinfo->input_components = this->m->components;
|
||||||
cinfo->in_color_space = this->color_space;
|
cinfo->in_color_space = this->m->color_space;
|
||||||
jpeg_set_defaults(cinfo);
|
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);
|
jpeg_start_compress(cinfo, TRUE);
|
||||||
|
@ -2,6 +2,14 @@
|
|||||||
|
|
||||||
// Exercised in md5 test suite
|
// Exercised in md5 test suite
|
||||||
|
|
||||||
|
Pl_Discard::Members::Members()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Pl_Discard::Members::~Members()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Pl_Discard::Pl_Discard() :
|
Pl_Discard::Pl_Discard() :
|
||||||
Pipeline("discard", 0)
|
Pipeline("discard", 0)
|
||||||
{
|
{
|
||||||
|
@ -6,12 +6,12 @@
|
|||||||
#include <qpdf/QUtil.hh>
|
#include <qpdf/QUtil.hh>
|
||||||
#include <qpdf/QIntC.hh>
|
#include <qpdf/QIntC.hh>
|
||||||
|
|
||||||
Pl_Flate::Pl_Flate(char const* identifier, Pipeline* next,
|
Pl_Flate::Members::Members(size_t out_bufsize,
|
||||||
action_e action, unsigned int out_bufsize_int) :
|
action_e action) :
|
||||||
Pipeline(identifier, next),
|
out_bufsize(out_bufsize),
|
||||||
out_bufsize(QIntC::to_size(out_bufsize_int)),
|
|
||||||
action(action),
|
action(action),
|
||||||
initialized(false)
|
initialized(false),
|
||||||
|
zdata(0)
|
||||||
{
|
{
|
||||||
this->outbuf = new unsigned char[out_bufsize];
|
this->outbuf = new unsigned char[out_bufsize];
|
||||||
// Indirect through zdata to reach the z_stream so we don't have
|
// 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);
|
zstream.avail_out = QIntC::to_uint(out_bufsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pl_Flate::~Pl_Flate()
|
Pl_Flate::Members::~Members()
|
||||||
{
|
{
|
||||||
delete [] this->outbuf;
|
delete [] this->outbuf;
|
||||||
this->outbuf = 0;
|
this->outbuf = 0;
|
||||||
@ -60,10 +60,21 @@ Pl_Flate::~Pl_Flate()
|
|||||||
this->zdata = 0;
|
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
|
void
|
||||||
Pl_Flate::write(unsigned char* data, size_t len)
|
Pl_Flate::write(unsigned char* data, size_t len)
|
||||||
{
|
{
|
||||||
if (this->outbuf == 0)
|
if (this->m->outbuf == 0)
|
||||||
{
|
{
|
||||||
throw std::logic_error(
|
throw std::logic_error(
|
||||||
this->identifier +
|
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);
|
size_t bytes = (bytes_left >= max_bytes ? max_bytes : bytes_left);
|
||||||
handleData(buf, bytes,
|
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;
|
bytes_left -= bytes;
|
||||||
buf += 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"
|
"Pl_Flate: zlib doesn't support data"
|
||||||
" blocks larger than int");
|
" 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.next_in = data;
|
||||||
zstream.avail_in = QIntC::to_uint(len);
|
zstream.avail_in = QIntC::to_uint(len);
|
||||||
|
|
||||||
if (! this->initialized)
|
if (! this->m->initialized)
|
||||||
{
|
{
|
||||||
int err = Z_OK;
|
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 push
|
||||||
# pragma GCC diagnostic ignored "-Wold-style-cast"
|
# pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||||
#endif
|
#endif
|
||||||
if (this->action == a_deflate)
|
if (this->m->action == a_deflate)
|
||||||
{
|
{
|
||||||
err = deflateInit(&zstream, Z_DEFAULT_COMPRESSION);
|
err = deflateInit(&zstream, Z_DEFAULT_COMPRESSION);
|
||||||
}
|
}
|
||||||
@ -123,7 +134,7 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
checkError("Init", err);
|
checkError("Init", err);
|
||||||
this->initialized = true;
|
this->m->initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int err = Z_OK;
|
int err = Z_OK;
|
||||||
@ -131,7 +142,7 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush)
|
|||||||
bool done = false;
|
bool done = false;
|
||||||
while (! done)
|
while (! done)
|
||||||
{
|
{
|
||||||
if (action == a_deflate)
|
if (this->m->action == a_deflate)
|
||||||
{
|
{
|
||||||
err = deflate(&zstream, flush);
|
err = deflate(&zstream, flush);
|
||||||
}
|
}
|
||||||
@ -139,7 +150,7 @@ Pl_Flate::handleData(unsigned char* data, size_t len, int flush)
|
|||||||
{
|
{
|
||||||
err = inflate(&zstream, 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))
|
(strcmp(zstream.msg, "incorrect data check") == 0))
|
||||||
{
|
{
|
||||||
// Other PDF readers ignore this specific error. Combining
|
// 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;
|
done = true;
|
||||||
}
|
}
|
||||||
uLong ready =
|
uLong ready =
|
||||||
QIntC::to_ulong(this->out_bufsize - zstream.avail_out);
|
QIntC::to_ulong(this->m->out_bufsize - zstream.avail_out);
|
||||||
if (ready > 0)
|
if (ready > 0)
|
||||||
{
|
{
|
||||||
this->getNext()->write(this->outbuf, ready);
|
this->getNext()->write(this->m->outbuf, ready);
|
||||||
zstream.next_out = this->outbuf;
|
zstream.next_out = this->m->outbuf;
|
||||||
zstream.avail_out = QIntC::to_uint(this->out_bufsize);
|
zstream.avail_out = QIntC::to_uint(this->m->out_bufsize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -194,16 +205,16 @@ Pl_Flate::finish()
|
|||||||
{
|
{
|
||||||
try
|
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];
|
unsigned char buf[1];
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
handleData(buf, 0, Z_FINISH);
|
handleData(buf, 0, Z_FINISH);
|
||||||
int err = Z_OK;
|
int err = Z_OK;
|
||||||
if (action == a_deflate)
|
if (this->m->action == a_deflate)
|
||||||
{
|
{
|
||||||
err = deflateEnd(&zstream);
|
err = deflateEnd(&zstream);
|
||||||
}
|
}
|
||||||
@ -211,12 +222,12 @@ Pl_Flate::finish()
|
|||||||
{
|
{
|
||||||
err = inflateEnd(&zstream);
|
err = inflateEnd(&zstream);
|
||||||
}
|
}
|
||||||
this->initialized = false;
|
this->m->initialized = false;
|
||||||
checkError("End", err);
|
checkError("End", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete [] this->outbuf;
|
delete [] this->m->outbuf;
|
||||||
this->outbuf = 0;
|
this->m->outbuf = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
@ -230,10 +241,11 @@ Pl_Flate::finish()
|
|||||||
void
|
void
|
||||||
Pl_Flate::checkError(char const* prefix, int error_code)
|
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)
|
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 =
|
std::string msg =
|
||||||
this->identifier + ": " + action_str + ": " + prefix + ": ";
|
this->identifier + ": " + action_str + ": " + prefix + ": ";
|
||||||
|
|
||||||
|
@ -3,15 +3,24 @@
|
|||||||
#include <qpdf/QUtil.hh>
|
#include <qpdf/QUtil.hh>
|
||||||
#include <qpdf/QTC.hh>
|
#include <qpdf/QTC.hh>
|
||||||
|
|
||||||
Pl_RunLength::Pl_RunLength(char const* identifier, Pipeline* next,
|
Pl_RunLength::Members::Members(action_e action) :
|
||||||
action_e action) :
|
|
||||||
Pipeline(identifier, next),
|
|
||||||
action(action),
|
action(action),
|
||||||
state(st_top),
|
state(st_top),
|
||||||
length(0)
|
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()
|
Pl_RunLength::~Pl_RunLength()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -19,7 +28,7 @@ Pl_RunLength::~Pl_RunLength()
|
|||||||
void
|
void
|
||||||
Pl_RunLength::write(unsigned char* data, size_t len)
|
Pl_RunLength::write(unsigned char* data, size_t len)
|
||||||
{
|
{
|
||||||
if (this->action == a_encode)
|
if (this->m->action == a_encode)
|
||||||
{
|
{
|
||||||
encode(data, len);
|
encode(data, len);
|
||||||
}
|
}
|
||||||
@ -34,41 +43,41 @@ Pl_RunLength::encode(unsigned char* data, size_t len)
|
|||||||
{
|
{
|
||||||
for (size_t i = 0; i < len; ++i)
|
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(
|
throw std::logic_error(
|
||||||
"Pl_RunLength::encode: state/length inconsistency");
|
"Pl_RunLength::encode: state/length inconsistency");
|
||||||
}
|
}
|
||||||
unsigned char ch = data[i];
|
unsigned char ch = data[i];
|
||||||
if ((this->length > 0) &&
|
if ((this->m->length > 0) &&
|
||||||
((this->state == st_copying) || (this->length < 128)) &&
|
((this->m->state == st_copying) || (this->m->length < 128)) &&
|
||||||
(ch == this->buf[this->length-1]))
|
(ch == this->m->buf[this->m->length-1]))
|
||||||
{
|
{
|
||||||
QTC::TC("libtests", "Pl_RunLength: switch to run",
|
QTC::TC("libtests", "Pl_RunLength: switch to run",
|
||||||
(this->length == 128) ? 0 : 1);
|
(this->m->length == 128) ? 0 : 1);
|
||||||
if (this->state == st_copying)
|
if (this->m->state == st_copying)
|
||||||
{
|
{
|
||||||
--this->length;
|
--this->m->length;
|
||||||
flush_encode();
|
flush_encode();
|
||||||
this->buf[0] = ch;
|
this->m->buf[0] = ch;
|
||||||
this->length = 1;
|
this->m->length = 1;
|
||||||
}
|
}
|
||||||
this->state = st_run;
|
this->m->state = st_run;
|
||||||
this->buf[this->length] = ch;
|
this->m->buf[this->m->length] = ch;
|
||||||
++this->length;
|
++this->m->length;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((this->length == 128) || (this->state == st_run))
|
if ((this->m->length == 128) || (this->m->state == st_run))
|
||||||
{
|
{
|
||||||
flush_encode();
|
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->m->buf[this->m->length] = ch;
|
||||||
++this->length;
|
++this->m->length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,20 +88,20 @@ Pl_RunLength::decode(unsigned char* data, size_t len)
|
|||||||
for (size_t i = 0; i < len; ++i)
|
for (size_t i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
unsigned char ch = data[i];
|
unsigned char ch = data[i];
|
||||||
switch (this->state)
|
switch (this->m->state)
|
||||||
{
|
{
|
||||||
case st_top:
|
case st_top:
|
||||||
if (ch < 128)
|
if (ch < 128)
|
||||||
{
|
{
|
||||||
// length represents remaining number of bytes to copy
|
// length represents remaining number of bytes to copy
|
||||||
this->length = 1U + ch;
|
this->m->length = 1U + ch;
|
||||||
this->state = st_copying;
|
this->m->state = st_copying;
|
||||||
}
|
}
|
||||||
else if (ch > 128)
|
else if (ch > 128)
|
||||||
{
|
{
|
||||||
// length represents number of copies of next byte
|
// length represents number of copies of next byte
|
||||||
this->length = 257U - ch;
|
this->m->length = 257U - ch;
|
||||||
this->state = st_run;
|
this->m->state = st_run;
|
||||||
}
|
}
|
||||||
else // ch == 128
|
else // ch == 128
|
||||||
{
|
{
|
||||||
@ -102,18 +111,18 @@ Pl_RunLength::decode(unsigned char* data, size_t len)
|
|||||||
|
|
||||||
case st_copying:
|
case st_copying:
|
||||||
this->getNext()->write(&ch, 1);
|
this->getNext()->write(&ch, 1);
|
||||||
if (--this->length == 0)
|
if (--this->m->length == 0)
|
||||||
{
|
{
|
||||||
this->state = st_top;
|
this->m->state = st_top;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case st_run:
|
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->getNext()->write(&ch, 1);
|
||||||
}
|
}
|
||||||
this->state = st_top;
|
this->m->state = st_top;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,36 +131,36 @@ Pl_RunLength::decode(unsigned char* data, size_t len)
|
|||||||
void
|
void
|
||||||
Pl_RunLength::flush_encode()
|
Pl_RunLength::flush_encode()
|
||||||
{
|
{
|
||||||
if (this->length == 128)
|
if (this->m->length == 128)
|
||||||
{
|
{
|
||||||
QTC::TC("libtests", "Pl_RunLength flush full buffer",
|
QTC::TC("libtests", "Pl_RunLength flush full buffer",
|
||||||
(this->state == st_copying ? 0 :
|
(this->m->state == st_copying ? 0 :
|
||||||
this->state == st_run ? 1 :
|
this->m->state == st_run ? 1 :
|
||||||
-1));
|
-1));
|
||||||
}
|
}
|
||||||
if (this->length == 0)
|
if (this->m->length == 0)
|
||||||
{
|
{
|
||||||
QTC::TC("libtests", "Pl_RunLength flush empty buffer");
|
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(
|
throw std::logic_error(
|
||||||
"Pl_RunLength: invalid length in flush_encode for run");
|
"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(&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(&ch, 1);
|
||||||
this->getNext()->write(this->buf, this->length);
|
this->getNext()->write(this->m->buf, this->m->length);
|
||||||
}
|
}
|
||||||
this->state = st_top;
|
this->m->state = st_top;
|
||||||
this->length = 0;
|
this->m->length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -161,7 +170,7 @@ Pl_RunLength::finish()
|
|||||||
// data, which means the stream was terminated early, but we will
|
// data, which means the stream was terminated early, but we will
|
||||||
// just ignore this case since this is the only sensible thing to
|
// just ignore this case since this is the only sensible thing to
|
||||||
// do.
|
// do.
|
||||||
if (this->action == a_encode)
|
if (this->m->action == a_encode)
|
||||||
{
|
{
|
||||||
flush_encode();
|
flush_encode();
|
||||||
unsigned char ch = 128;
|
unsigned char ch = 128;
|
||||||
|
@ -4,9 +4,18 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
Pl_StdioFile::Members::Members(FILE* f) :
|
||||||
|
file(f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Pl_StdioFile::Members::~Members()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Pl_StdioFile::Pl_StdioFile(char const* identifier, FILE* f) :
|
Pl_StdioFile::Pl_StdioFile(char const* identifier, FILE* f) :
|
||||||
Pipeline(identifier, 0),
|
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;
|
size_t so_far = 0;
|
||||||
while (len > 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)
|
if (so_far == 0)
|
||||||
{
|
{
|
||||||
QUtil::throw_system_error(
|
QUtil::throw_system_error(
|
||||||
@ -37,7 +46,7 @@ Pl_StdioFile::write(unsigned char* buf, size_t len)
|
|||||||
void
|
void
|
||||||
Pl_StdioFile::finish()
|
Pl_StdioFile::finish()
|
||||||
{
|
{
|
||||||
if ((fflush(this->file) == -1) &&
|
if ((fflush(this->m->file) == -1) &&
|
||||||
(errno == EBADF))
|
(errno == EBADF))
|
||||||
{
|
{
|
||||||
throw std::logic_error(
|
throw std::logic_error(
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
static unsigned char* uc(char const* s)
|
static unsigned char* uc(char const* s)
|
||||||
{
|
{
|
||||||
@ -13,6 +14,25 @@ static unsigned char* uc(char const* s)
|
|||||||
|
|
||||||
int main()
|
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
|
try
|
||||||
{
|
{
|
||||||
Pl_Discard discard;
|
Pl_Discard discard;
|
||||||
@ -68,6 +88,16 @@ int main()
|
|||||||
b = bp3.getBuffer();
|
b = bp3.getBuffer();
|
||||||
std::cout << "size: " << b->getSize() << std::endl;
|
std::cout << "size: " << b->getSize() << std::endl;
|
||||||
delete b;
|
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)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
|
@ -9,4 +9,6 @@ Pl_Buffer::getBuffer() called when not ready
|
|||||||
size: 9
|
size: 9
|
||||||
data: mooquack
|
data: mooquack
|
||||||
size: 0
|
size: 0
|
||||||
|
size: 0
|
||||||
|
size: 0
|
||||||
done
|
done
|
||||||
|
Loading…
Reference in New Issue
Block a user