mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 19:08: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
|
||||
library/DLL. Use QPDF_DLL_CLASS for all classes whose type
|
||||
information is needed. This is important for exception classes and
|
||||
it seems also for classes that are intended to be subclassed across
|
||||
the shared library boundary.
|
||||
information is needed. This is important for classes that are used
|
||||
as exceptions, subclassed, or tested with dynamic_cast across the
|
||||
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
|
||||
public classes. Remember to use QPDF_DLL on ~Members(). Exception:
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <qpdf/Buffer.hh>
|
||||
#include <qpdf/InputSource.hh>
|
||||
|
||||
class BufferInputSource: public InputSource
|
||||
class QPDF_DLL_CLASS BufferInputSource: public InputSource
|
||||
{
|
||||
public:
|
||||
// If own_memory is true, BufferInputSource will delete the buffer
|
||||
@ -54,7 +54,7 @@ class BufferInputSource: public InputSource
|
||||
virtual void unreadCh(char ch);
|
||||
|
||||
private:
|
||||
class Members
|
||||
class QPDF_DLL_PRIVATE Members
|
||||
{
|
||||
friend class BufferInputSource;
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
||||
|
||||
class FileInputSource;
|
||||
|
||||
class ClosedFileInputSource: public InputSource
|
||||
class QPDF_DLL_CLASS ClosedFileInputSource: public InputSource
|
||||
{
|
||||
public:
|
||||
QPDF_DLL
|
||||
@ -71,7 +71,7 @@ class ClosedFileInputSource: public InputSource
|
||||
void before();
|
||||
void after();
|
||||
|
||||
class Members
|
||||
class QPDF_DLL_PRIVATE Members
|
||||
{
|
||||
friend class ClosedFileInputSource;
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include <qpdf/InputSource.hh>
|
||||
|
||||
class FileInputSource: public InputSource
|
||||
class QPDF_DLL_CLASS FileInputSource: public InputSource
|
||||
{
|
||||
public:
|
||||
QPDF_DLL
|
||||
@ -54,7 +54,7 @@ class FileInputSource: public InputSource
|
||||
FileInputSource(FileInputSource const&) = delete;
|
||||
FileInputSource& operator=(FileInputSource const&) = delete;
|
||||
|
||||
class Members
|
||||
class QPDF_DLL_PRIVATE Members
|
||||
{
|
||||
friend class FileInputSource;
|
||||
|
||||
|
@ -30,6 +30,9 @@
|
||||
#include <stdio.h>
|
||||
#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
|
||||
{
|
||||
public:
|
||||
|
@ -50,6 +50,8 @@
|
||||
#include <memory>
|
||||
#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
|
||||
{
|
||||
public:
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
class Pl_Buffer: public Pipeline
|
||||
class QPDF_DLL_CLASS Pl_Buffer: public Pipeline
|
||||
{
|
||||
public:
|
||||
QPDF_DLL
|
||||
@ -71,7 +71,7 @@ class Pl_Buffer: public Pipeline
|
||||
void getMallocBuffer(unsigned char** buf, size_t* len);
|
||||
|
||||
private:
|
||||
class Members
|
||||
class QPDF_DLL_PRIVATE Members
|
||||
{
|
||||
friend class Pl_Buffer;
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
#include <qpdf/Pipeline.hh>
|
||||
|
||||
class Pl_Concatenate: public Pipeline
|
||||
class QPDF_DLL_CLASS Pl_Concatenate: public Pipeline
|
||||
{
|
||||
public:
|
||||
QPDF_DLL
|
||||
@ -50,7 +50,7 @@ class Pl_Concatenate: public Pipeline
|
||||
void manualFinish();
|
||||
|
||||
private:
|
||||
class Members
|
||||
class QPDF_DLL_PRIVATE Members
|
||||
{
|
||||
friend class Pl_Concatenate;
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include <qpdf/Pipeline.hh>
|
||||
#include <qpdf/Types.h>
|
||||
|
||||
class Pl_Count: public Pipeline
|
||||
class QPDF_DLL_CLASS Pl_Count: public Pipeline
|
||||
{
|
||||
public:
|
||||
QPDF_DLL
|
||||
@ -48,7 +48,7 @@ class Pl_Count: public Pipeline
|
||||
unsigned char getLastChar() const;
|
||||
|
||||
private:
|
||||
class Members
|
||||
class QPDF_DLL_PRIVATE Members
|
||||
{
|
||||
friend class Pl_Count;
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
// definition of size_t.
|
||||
#include <jpeglib.h>
|
||||
|
||||
class Pl_DCT: public Pipeline
|
||||
class QPDF_DLL_CLASS Pl_DCT: public Pipeline
|
||||
{
|
||||
public:
|
||||
// Constructor for decompressing image data
|
||||
@ -75,7 +75,7 @@ class Pl_DCT: public Pipeline
|
||||
|
||||
enum action_e { a_compress, a_decompress };
|
||||
|
||||
class Members
|
||||
class QPDF_DLL_PRIVATE Members
|
||||
{
|
||||
friend class Pl_DCT;
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
#include <qpdf/Pipeline.hh>
|
||||
|
||||
class Pl_Discard: public Pipeline
|
||||
class QPDF_DLL_CLASS Pl_Discard: public Pipeline
|
||||
{
|
||||
public:
|
||||
QPDF_DLL
|
||||
@ -43,7 +43,7 @@ class Pl_Discard: public Pipeline
|
||||
virtual void finish();
|
||||
|
||||
private:
|
||||
class Members
|
||||
class QPDF_DLL_PRIVATE Members
|
||||
{
|
||||
friend class Pl_Discard;
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
class Pl_Flate: public Pipeline
|
||||
class QPDF_DLL_CLASS Pl_Flate: public Pipeline
|
||||
{
|
||||
public:
|
||||
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 warn(char const*, int error_code);
|
||||
|
||||
class Members
|
||||
class QPDF_DLL_PRIVATE Members
|
||||
{
|
||||
friend class Pl_Flate;
|
||||
|
||||
|
@ -41,7 +41,7 @@
|
||||
// QPDFObjectHandle::addTokenFilter. See QPDFObjectHandle.hh for
|
||||
// details.
|
||||
|
||||
class Pl_QPDFTokenizer: public Pipeline
|
||||
class QPDF_DLL_CLASS Pl_QPDFTokenizer: public Pipeline
|
||||
{
|
||||
public:
|
||||
// Whatever pipeline is provided as "next" will be set as the
|
||||
@ -60,7 +60,7 @@ class Pl_QPDFTokenizer: public Pipeline
|
||||
virtual void finish();
|
||||
|
||||
private:
|
||||
class Members
|
||||
class QPDF_DLL_PRIVATE Members
|
||||
{
|
||||
friend class Pl_QPDFTokenizer;
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include <qpdf/Pipeline.hh>
|
||||
|
||||
class Pl_RunLength: public Pipeline
|
||||
class QPDF_DLL_CLASS Pl_RunLength: public Pipeline
|
||||
{
|
||||
public:
|
||||
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 };
|
||||
|
||||
class Members
|
||||
class QPDF_DLL_PRIVATE Members
|
||||
{
|
||||
friend class Pl_RunLength;
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
// This pipeline is reusable.
|
||||
//
|
||||
|
||||
class Pl_StdioFile: public Pipeline
|
||||
class QPDF_DLL_CLASS Pl_StdioFile: public Pipeline
|
||||
{
|
||||
public:
|
||||
// f is externally maintained; this class just writes to and
|
||||
@ -48,7 +48,7 @@ class Pl_StdioFile: public Pipeline
|
||||
virtual void finish();
|
||||
|
||||
private:
|
||||
class Members
|
||||
class QPDF_DLL_PRIVATE Members
|
||||
{
|
||||
friend class Pl_StdioFile;
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <qpdf/QPDF.hh>
|
||||
|
||||
#include <qpdf/BufferInputSource.hh>
|
||||
#include <qpdf/Pl_Buffer.hh>
|
||||
#include <qpdf/Pl_Discard.hh>
|
||||
#include <qpdf/Pl_Flate.hh>
|
||||
@ -2314,8 +2315,9 @@ test_60(QPDF& pdf, char const* arg2)
|
||||
static void
|
||||
test_61(QPDF& pdf, char const* arg2)
|
||||
{
|
||||
// Test to make sure exceptions can be caught properly across
|
||||
// shared library boundaries.
|
||||
// Test to make sure type information is passed across shared
|
||||
// library boundaries. This includes exception handling, dynamic
|
||||
// cast, and subclassing.
|
||||
pdf.setAttemptRecovery(false);
|
||||
pdf.setSuppressWarnings(true);
|
||||
try {
|
||||
@ -2338,6 +2340,17 @@ test_61(QPDF& pdf, char const* arg2)
|
||||
} catch (std::runtime_error const&) {
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user