mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-23 03:18:59 +00:00
Use QPDF_DLL_CLASS with Pipeline and InputSource subclasses
This enables RTTI so we can use dynamic_cast on them across the shared object boundary.
This commit is contained in:
parent
90cfe80bac
commit
5525c93124
@ -156,9 +156,14 @@ CODING RULES
|
|||||||
|
|
||||||
* Use QPDF_DLL on all methods that are to be exported in the shared
|
* Use QPDF_DLL on all methods that are to be exported in the shared
|
||||||
library/DLL. Use QPDF_DLL_CLASS for all classes whose type
|
library/DLL. Use QPDF_DLL_CLASS for all classes whose type
|
||||||
information is needed. This is important for exception classes and
|
information is needed. This is important for classes that are used
|
||||||
it seems also for classes that are intended to be subclassed across
|
as exceptions, subclassed, or tested with dynamic_cast across the
|
||||||
the shared library boundary.
|
the shared object boundary (or "shared library boundary" -- we may
|
||||||
|
use either term in comments and documentation). In particular,
|
||||||
|
anything new derived from Pipeline or InputSource should be marked
|
||||||
|
with QPDF_DLL_CLASS, but we don't need to do it for QPDFObjectHelper
|
||||||
|
or QPDFDocumentHelper subclasses since there's no reason to use
|
||||||
|
dynamic_cast with those.
|
||||||
|
|
||||||
* Put private member variables in std::shared_ptr<Members> for all
|
* Put private member variables in std::shared_ptr<Members> for all
|
||||||
public classes. Remember to use QPDF_DLL on ~Members(). Exception:
|
public classes. Remember to use QPDF_DLL on ~Members(). Exception:
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include <qpdf/Buffer.hh>
|
#include <qpdf/Buffer.hh>
|
||||||
#include <qpdf/InputSource.hh>
|
#include <qpdf/InputSource.hh>
|
||||||
|
|
||||||
class BufferInputSource: public InputSource
|
class QPDF_DLL_CLASS BufferInputSource: public InputSource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// If own_memory is true, BufferInputSource will delete the buffer
|
// If own_memory is true, BufferInputSource will delete the buffer
|
||||||
@ -54,7 +54,7 @@ class BufferInputSource: public InputSource
|
|||||||
virtual void unreadCh(char ch);
|
virtual void unreadCh(char ch);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Members
|
class QPDF_DLL_PRIVATE Members
|
||||||
{
|
{
|
||||||
friend class BufferInputSource;
|
friend class BufferInputSource;
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
class FileInputSource;
|
class FileInputSource;
|
||||||
|
|
||||||
class ClosedFileInputSource: public InputSource
|
class QPDF_DLL_CLASS ClosedFileInputSource: public InputSource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
@ -71,7 +71,7 @@ class ClosedFileInputSource: public InputSource
|
|||||||
void before();
|
void before();
|
||||||
void after();
|
void after();
|
||||||
|
|
||||||
class Members
|
class QPDF_DLL_PRIVATE Members
|
||||||
{
|
{
|
||||||
friend class ClosedFileInputSource;
|
friend class ClosedFileInputSource;
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#include <qpdf/InputSource.hh>
|
#include <qpdf/InputSource.hh>
|
||||||
|
|
||||||
class FileInputSource: public InputSource
|
class QPDF_DLL_CLASS FileInputSource: public InputSource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
@ -54,7 +54,7 @@ class FileInputSource: public InputSource
|
|||||||
FileInputSource(FileInputSource const&) = delete;
|
FileInputSource(FileInputSource const&) = delete;
|
||||||
FileInputSource& operator=(FileInputSource const&) = delete;
|
FileInputSource& operator=(FileInputSource const&) = delete;
|
||||||
|
|
||||||
class Members
|
class QPDF_DLL_PRIVATE Members
|
||||||
{
|
{
|
||||||
friend class FileInputSource;
|
friend class FileInputSource;
|
||||||
|
|
||||||
|
@ -30,6 +30,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
// Remember to use QPDF_DLL_CLASS on anything derived from InputSource
|
||||||
|
// so it will work with dynamic_cast across the shared object
|
||||||
|
// boundary.
|
||||||
class QPDF_DLL_CLASS InputSource
|
class QPDF_DLL_CLASS InputSource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -50,6 +50,8 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
// Remember to use QPDF_DLL_CLASS on anything derived from Pipeline so
|
||||||
|
// it will work with dynamic_cast across the shared object boundary.
|
||||||
class QPDF_DLL_CLASS Pipeline
|
class QPDF_DLL_CLASS Pipeline
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class Pl_Buffer: public Pipeline
|
class QPDF_DLL_CLASS Pl_Buffer: public Pipeline
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
@ -71,7 +71,7 @@ class Pl_Buffer: public Pipeline
|
|||||||
void getMallocBuffer(unsigned char** buf, size_t* len);
|
void getMallocBuffer(unsigned char** buf, size_t* len);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Members
|
class QPDF_DLL_PRIVATE Members
|
||||||
{
|
{
|
||||||
friend class Pl_Buffer;
|
friend class Pl_Buffer;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#include <qpdf/Pipeline.hh>
|
#include <qpdf/Pipeline.hh>
|
||||||
|
|
||||||
class Pl_Concatenate: public Pipeline
|
class QPDF_DLL_CLASS Pl_Concatenate: public Pipeline
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
@ -50,7 +50,7 @@ class Pl_Concatenate: public Pipeline
|
|||||||
void manualFinish();
|
void manualFinish();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Members
|
class QPDF_DLL_PRIVATE Members
|
||||||
{
|
{
|
||||||
friend class Pl_Concatenate;
|
friend class Pl_Concatenate;
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#include <qpdf/Pipeline.hh>
|
#include <qpdf/Pipeline.hh>
|
||||||
#include <qpdf/Types.h>
|
#include <qpdf/Types.h>
|
||||||
|
|
||||||
class Pl_Count: public Pipeline
|
class QPDF_DLL_CLASS Pl_Count: public Pipeline
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
@ -48,7 +48,7 @@ class Pl_Count: public Pipeline
|
|||||||
unsigned char getLastChar() const;
|
unsigned char getLastChar() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Members
|
class QPDF_DLL_PRIVATE Members
|
||||||
{
|
{
|
||||||
friend class Pl_Count;
|
friend class Pl_Count;
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
// definition of size_t.
|
// definition of size_t.
|
||||||
#include <jpeglib.h>
|
#include <jpeglib.h>
|
||||||
|
|
||||||
class Pl_DCT: public Pipeline
|
class QPDF_DLL_CLASS Pl_DCT: public Pipeline
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Constructor for decompressing image data
|
// Constructor for decompressing image data
|
||||||
@ -75,7 +75,7 @@ class Pl_DCT: public Pipeline
|
|||||||
|
|
||||||
enum action_e { a_compress, a_decompress };
|
enum action_e { a_compress, a_decompress };
|
||||||
|
|
||||||
class Members
|
class QPDF_DLL_PRIVATE Members
|
||||||
{
|
{
|
||||||
friend class Pl_DCT;
|
friend class Pl_DCT;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#include <qpdf/Pipeline.hh>
|
#include <qpdf/Pipeline.hh>
|
||||||
|
|
||||||
class Pl_Discard: public Pipeline
|
class QPDF_DLL_CLASS Pl_Discard: public Pipeline
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QPDF_DLL
|
QPDF_DLL
|
||||||
@ -43,7 +43,7 @@ class Pl_Discard: public Pipeline
|
|||||||
virtual void finish();
|
virtual void finish();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Members
|
class QPDF_DLL_PRIVATE Members
|
||||||
{
|
{
|
||||||
friend class Pl_Discard;
|
friend class Pl_Discard;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class Pl_Flate: public Pipeline
|
class QPDF_DLL_CLASS Pl_Flate: public Pipeline
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static unsigned int const def_bufsize = 65536;
|
static unsigned int const def_bufsize = 65536;
|
||||||
@ -65,7 +65,7 @@ class Pl_Flate: public Pipeline
|
|||||||
void checkError(char const* prefix, int error_code);
|
void checkError(char const* prefix, int error_code);
|
||||||
void warn(char const*, int error_code);
|
void warn(char const*, int error_code);
|
||||||
|
|
||||||
class Members
|
class QPDF_DLL_PRIVATE Members
|
||||||
{
|
{
|
||||||
friend class Pl_Flate;
|
friend class Pl_Flate;
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
// QPDFObjectHandle::addTokenFilter. See QPDFObjectHandle.hh for
|
// QPDFObjectHandle::addTokenFilter. See QPDFObjectHandle.hh for
|
||||||
// details.
|
// details.
|
||||||
|
|
||||||
class Pl_QPDFTokenizer: public Pipeline
|
class QPDF_DLL_CLASS Pl_QPDFTokenizer: public Pipeline
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Whatever pipeline is provided as "next" will be set as the
|
// Whatever pipeline is provided as "next" will be set as the
|
||||||
@ -60,7 +60,7 @@ class Pl_QPDFTokenizer: public Pipeline
|
|||||||
virtual void finish();
|
virtual void finish();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Members
|
class QPDF_DLL_PRIVATE Members
|
||||||
{
|
{
|
||||||
friend class Pl_QPDFTokenizer;
|
friend class Pl_QPDFTokenizer;
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#include <qpdf/Pipeline.hh>
|
#include <qpdf/Pipeline.hh>
|
||||||
|
|
||||||
class Pl_RunLength: public Pipeline
|
class QPDF_DLL_CLASS Pl_RunLength: public Pipeline
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum action_e { a_encode, a_decode };
|
enum action_e { a_encode, a_decode };
|
||||||
@ -46,7 +46,7 @@ class Pl_RunLength: public Pipeline
|
|||||||
|
|
||||||
enum state_e { st_top, st_copying, st_run };
|
enum state_e { st_top, st_copying, st_run };
|
||||||
|
|
||||||
class Members
|
class QPDF_DLL_PRIVATE Members
|
||||||
{
|
{
|
||||||
friend class Pl_RunLength;
|
friend class Pl_RunLength;
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
// This pipeline is reusable.
|
// This pipeline is reusable.
|
||||||
//
|
//
|
||||||
|
|
||||||
class Pl_StdioFile: public Pipeline
|
class QPDF_DLL_CLASS Pl_StdioFile: public Pipeline
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// f is externally maintained; this class just writes to and
|
// f is externally maintained; this class just writes to and
|
||||||
@ -48,7 +48,7 @@ class Pl_StdioFile: public Pipeline
|
|||||||
virtual void finish();
|
virtual void finish();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Members
|
class QPDF_DLL_PRIVATE Members
|
||||||
{
|
{
|
||||||
friend class Pl_StdioFile;
|
friend class Pl_StdioFile;
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <qpdf/QPDF.hh>
|
#include <qpdf/QPDF.hh>
|
||||||
|
|
||||||
|
#include <qpdf/BufferInputSource.hh>
|
||||||
#include <qpdf/Pl_Buffer.hh>
|
#include <qpdf/Pl_Buffer.hh>
|
||||||
#include <qpdf/Pl_Discard.hh>
|
#include <qpdf/Pl_Discard.hh>
|
||||||
#include <qpdf/Pl_Flate.hh>
|
#include <qpdf/Pl_Flate.hh>
|
||||||
@ -2314,8 +2315,9 @@ test_60(QPDF& pdf, char const* arg2)
|
|||||||
static void
|
static void
|
||||||
test_61(QPDF& pdf, char const* arg2)
|
test_61(QPDF& pdf, char const* arg2)
|
||||||
{
|
{
|
||||||
// Test to make sure exceptions can be caught properly across
|
// Test to make sure type information is passed across shared
|
||||||
// shared library boundaries.
|
// library boundaries. This includes exception handling, dynamic
|
||||||
|
// cast, and subclassing.
|
||||||
pdf.setAttemptRecovery(false);
|
pdf.setAttemptRecovery(false);
|
||||||
pdf.setSuppressWarnings(true);
|
pdf.setSuppressWarnings(true);
|
||||||
try {
|
try {
|
||||||
@ -2338,6 +2340,17 @@ test_61(QPDF& pdf, char const* arg2)
|
|||||||
} catch (std::runtime_error const&) {
|
} catch (std::runtime_error const&) {
|
||||||
std::cout << "Caught runtime_error as expected" << std::endl;
|
std::cout << "Caught runtime_error as expected" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Spot check RTTI for dynamic cast. We intend to have pipelines
|
||||||
|
// and input sources be testable, but adding comprehensive tests
|
||||||
|
// for everything doesn't add value as it wouldn't catch
|
||||||
|
// forgetting QPDF_DLL_CLASS on a new subclass.
|
||||||
|
BufferInputSource b("x", "y");
|
||||||
|
InputSource* is = &b;
|
||||||
|
assert(dynamic_cast<BufferInputSource*>(is) != nullptr);
|
||||||
|
Pl_Discard pd;
|
||||||
|
Pipeline* p = &pd;
|
||||||
|
assert(dynamic_cast<Pl_Discard*>(p) != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user