diff options
-rw-r--r-- | README-maintainer | 11 | ||||
-rw-r--r-- | include/qpdf/BufferInputSource.hh | 4 | ||||
-rw-r--r-- | include/qpdf/ClosedFileInputSource.hh | 4 | ||||
-rw-r--r-- | include/qpdf/FileInputSource.hh | 4 | ||||
-rw-r--r-- | include/qpdf/InputSource.hh | 3 | ||||
-rw-r--r-- | include/qpdf/Pipeline.hh | 2 | ||||
-rw-r--r-- | include/qpdf/Pl_Buffer.hh | 4 | ||||
-rw-r--r-- | include/qpdf/Pl_Concatenate.hh | 4 | ||||
-rw-r--r-- | include/qpdf/Pl_Count.hh | 4 | ||||
-rw-r--r-- | include/qpdf/Pl_DCT.hh | 4 | ||||
-rw-r--r-- | include/qpdf/Pl_Discard.hh | 4 | ||||
-rw-r--r-- | include/qpdf/Pl_Flate.hh | 4 | ||||
-rw-r--r-- | include/qpdf/Pl_QPDFTokenizer.hh | 4 | ||||
-rw-r--r-- | include/qpdf/Pl_RunLength.hh | 4 | ||||
-rw-r--r-- | include/qpdf/Pl_StdioFile.hh | 4 | ||||
-rw-r--r-- | qpdf/test_driver.cc | 17 |
16 files changed, 52 insertions, 29 deletions
diff --git a/README-maintainer b/README-maintainer index 60e7de57..52c10810 100644 --- a/README-maintainer +++ b/README-maintainer @@ -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: diff --git a/include/qpdf/BufferInputSource.hh b/include/qpdf/BufferInputSource.hh index 6fd92e16..53c362a9 100644 --- a/include/qpdf/BufferInputSource.hh +++ b/include/qpdf/BufferInputSource.hh @@ -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; diff --git a/include/qpdf/ClosedFileInputSource.hh b/include/qpdf/ClosedFileInputSource.hh index cbaa9a52..e5142bc1 100644 --- a/include/qpdf/ClosedFileInputSource.hh +++ b/include/qpdf/ClosedFileInputSource.hh @@ -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; diff --git a/include/qpdf/FileInputSource.hh b/include/qpdf/FileInputSource.hh index 000590c3..c3b60265 100644 --- a/include/qpdf/FileInputSource.hh +++ b/include/qpdf/FileInputSource.hh @@ -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; diff --git a/include/qpdf/InputSource.hh b/include/qpdf/InputSource.hh index b53ac0b3..8d46895d 100644 --- a/include/qpdf/InputSource.hh +++ b/include/qpdf/InputSource.hh @@ -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: diff --git a/include/qpdf/Pipeline.hh b/include/qpdf/Pipeline.hh index 3b06b406..2a2f9d3c 100644 --- a/include/qpdf/Pipeline.hh +++ b/include/qpdf/Pipeline.hh @@ -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: diff --git a/include/qpdf/Pl_Buffer.hh b/include/qpdf/Pl_Buffer.hh index 2556e672..f72646f0 100644 --- a/include/qpdf/Pl_Buffer.hh +++ b/include/qpdf/Pl_Buffer.hh @@ -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; diff --git a/include/qpdf/Pl_Concatenate.hh b/include/qpdf/Pl_Concatenate.hh index 806d61ea..702c48e4 100644 --- a/include/qpdf/Pl_Concatenate.hh +++ b/include/qpdf/Pl_Concatenate.hh @@ -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; diff --git a/include/qpdf/Pl_Count.hh b/include/qpdf/Pl_Count.hh index 4b8f441c..8d9bc6b7 100644 --- a/include/qpdf/Pl_Count.hh +++ b/include/qpdf/Pl_Count.hh @@ -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; diff --git a/include/qpdf/Pl_DCT.hh b/include/qpdf/Pl_DCT.hh index 9481fee9..0339afb7 100644 --- a/include/qpdf/Pl_DCT.hh +++ b/include/qpdf/Pl_DCT.hh @@ -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; diff --git a/include/qpdf/Pl_Discard.hh b/include/qpdf/Pl_Discard.hh index 277461d9..051f9fe1 100644 --- a/include/qpdf/Pl_Discard.hh +++ b/include/qpdf/Pl_Discard.hh @@ -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; diff --git a/include/qpdf/Pl_Flate.hh b/include/qpdf/Pl_Flate.hh index 90c0bbde..503c2db8 100644 --- a/include/qpdf/Pl_Flate.hh +++ b/include/qpdf/Pl_Flate.hh @@ -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; diff --git a/include/qpdf/Pl_QPDFTokenizer.hh b/include/qpdf/Pl_QPDFTokenizer.hh index a5ac3ccc..d5b531e2 100644 --- a/include/qpdf/Pl_QPDFTokenizer.hh +++ b/include/qpdf/Pl_QPDFTokenizer.hh @@ -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; diff --git a/include/qpdf/Pl_RunLength.hh b/include/qpdf/Pl_RunLength.hh index e93c5fb6..5becd198 100644 --- a/include/qpdf/Pl_RunLength.hh +++ b/include/qpdf/Pl_RunLength.hh @@ -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; diff --git a/include/qpdf/Pl_StdioFile.hh b/include/qpdf/Pl_StdioFile.hh index ffc7a790..64f4738d 100644 --- a/include/qpdf/Pl_StdioFile.hh +++ b/include/qpdf/Pl_StdioFile.hh @@ -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; diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc index 8a93721f..6e48bb35 100644 --- a/qpdf/test_driver.cc +++ b/qpdf/test_driver.cc @@ -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 |