diff --git a/README-maintainer.md b/README-maintainer.md index 5c86cb8..a8328ec 100644 --- a/README-maintainer.md +++ b/README-maintainer.md @@ -886,7 +886,7 @@ still things that could potentially break ABI, such as * Changes to the types of public or protected data members without changing the size -* Changes to the meanings of parameters with changing the signature +* Changes to the meanings of parameters without changing the signature Not breaking ABI/API still requires care. diff --git a/include/qpdf/Buffer.hh b/include/qpdf/Buffer.hh index 928821e..979d57d 100644 --- a/include/qpdf/Buffer.hh +++ b/include/qpdf/Buffer.hh @@ -46,6 +46,9 @@ class Buffer QPDF_DLL Buffer(std::string& content); + Buffer(Buffer const&) = delete; + Buffer& operator=(Buffer const&) = delete; + QPDF_DLL Buffer(Buffer&&) noexcept; QPDF_DLL diff --git a/include/qpdf/ClosedFileInputSource.hh b/include/qpdf/ClosedFileInputSource.hh index b8f58fd..b5d7e33 100644 --- a/include/qpdf/ClosedFileInputSource.hh +++ b/include/qpdf/ClosedFileInputSource.hh @@ -20,22 +20,25 @@ #ifndef QPDF_CLOSEDFILEINPUTSOURCE_HH #define QPDF_CLOSEDFILEINPUTSOURCE_HH -// This is an input source that reads from files, like FileInputSource, except that it opens and -// closes the file surrounding every operation. This decreases efficiency, but it allows many more -// of these to exist at once than the maximum number of open file descriptors. This is used for -// merging large numbers of files. - #include #include class FileInputSource; +// This is an input source that reads from files, like FileInputSource, except that it opens and +// closes the file surrounding every operation. This decreases efficiency, but it allows many more +// of these to exist at once than the maximum number of open file descriptors. This is used for +// merging large numbers of files. class QPDF_DLL_CLASS ClosedFileInputSource: public InputSource { public: QPDF_DLL ClosedFileInputSource(char const* filename); + + ClosedFileInputSource(ClosedFileInputSource const&) = delete; + ClosedFileInputSource& operator=(ClosedFileInputSource const&) = delete; + QPDF_DLL ~ClosedFileInputSource() override; QPDF_DLL @@ -60,9 +63,6 @@ class QPDF_DLL_CLASS ClosedFileInputSource: public InputSource void stayOpen(bool); private: - ClosedFileInputSource(ClosedFileInputSource const&) = delete; - ClosedFileInputSource& operator=(ClosedFileInputSource const&) = delete; - QPDF_DLL_PRIVATE void before(); QPDF_DLL_PRIVATE diff --git a/include/qpdf/FileInputSource.hh b/include/qpdf/FileInputSource.hh index 7613697..dbad8c5 100644 --- a/include/qpdf/FileInputSource.hh +++ b/include/qpdf/FileInputSource.hh @@ -25,8 +25,7 @@ class QPDF_DLL_CLASS FileInputSource: public InputSource { public: - QPDF_DLL - FileInputSource(); + FileInputSource() = default; QPDF_DLL FileInputSource(char const* filename); QPDF_DLL @@ -35,6 +34,10 @@ class QPDF_DLL_CLASS FileInputSource: public InputSource void setFilename(char const* filename); QPDF_DLL void setFile(char const* description, FILE* filep, bool close_file); + + FileInputSource(FileInputSource const&) = delete; + FileInputSource& operator=(FileInputSource const&) = delete; + QPDF_DLL ~FileInputSource() override; QPDF_DLL @@ -53,12 +56,9 @@ class QPDF_DLL_CLASS FileInputSource: public InputSource void unreadCh(char ch) override; private: - FileInputSource(FileInputSource const&) = delete; - FileInputSource& operator=(FileInputSource const&) = delete; - - bool close_file; + bool close_file{false}; std::string filename; - FILE* file; + FILE* file{nullptr}; }; #endif // QPDF_FILEINPUTSOURCE_HH diff --git a/include/qpdf/InputSource.hh b/include/qpdf/InputSource.hh index 37d1303..6bde273 100644 --- a/include/qpdf/InputSource.hh +++ b/include/qpdf/InputSource.hh @@ -32,11 +32,8 @@ class QPDF_DLL_CLASS InputSource { public: - QPDF_DLL - InputSource() - { - } - QPDF_DLL + InputSource() = default; + virtual ~InputSource() = default; class QPDF_DLL_CLASS Finder diff --git a/include/qpdf/JSON.hh b/include/qpdf/JSON.hh index d22ea96..390ee8a 100644 --- a/include/qpdf/JSON.hh +++ b/include/qpdf/JSON.hh @@ -20,15 +20,6 @@ #ifndef JSON_HH #define JSON_HH -// This is a simple JSON serializer and parser, primarily designed for serializing QPDF Objects as -// JSON. While it may work as a general-purpose JSON parser/serializer, there are better options. -// JSON objects contain their data as smart pointers. When one JSON object is added to another, this -// pointer is copied. This means you can create temporary JSON objects on the stack, add them to -// other objects, and let them go out of scope safely. It also means that if a JSON object is added -// in more than one place, all copies share the underlying data. This makes them similar in -// structure and behavior to QPDFObjectHandle and may feel natural within the QPDF codebase, but it -// is also a good reason not to use this as a general-purpose JSON package. - #include #include @@ -43,12 +34,19 @@ class Pipeline; class InputSource; +// This is a simple JSON serializer and parser, primarily designed for serializing QPDF Objects as +// JSON. While it may work as a general-purpose JSON parser/serializer, there are better options. +// JSON objects contain their data as smart pointers. When one JSON object is added to another, this +// pointer is copied. This means you can create temporary JSON objects on the stack, add them to +// other objects, and let them go out of scope safely. It also means that if a JSON object is added +// in more than one place, all copies share the underlying data. This makes them similar in +// structure and behavior to QPDFObjectHandle and may feel natural within the QPDF codebase, but it +// is also a good reason not to use this as a general-purpose JSON package. class JSON { public: static int constexpr LATEST = 2; - QPDF_DLL JSON() = default; QPDF_DLL @@ -147,6 +145,7 @@ class JSON // // - If argument is wrong type, including null, return false // - If argument is right type, return true and initialize the value + QPDF_DLL bool getString(std::string& utf8) const; QPDF_DLL @@ -210,7 +209,6 @@ class JSON class QPDF_DLL_CLASS Reactor { public: - QPDF_DLL virtual ~Reactor() = default; // The start/end methods are called when parsing of a dictionary or array is started or @@ -377,7 +375,6 @@ class JSON friend class JSON; public: - QPDF_DLL ~Members() = default; private: diff --git a/include/qpdf/PDFVersion.hh b/include/qpdf/PDFVersion.hh index d9c9fcd..b137c15 100644 --- a/include/qpdf/PDFVersion.hh +++ b/include/qpdf/PDFVersion.hh @@ -23,18 +23,16 @@ #include #include +// Represent a PDF version. PDF versions are typically major.minor, but PDF 1.7 has several +// extension levels as the ISO 32000 spec was in progress. This class helps with comparison of +// versions. class PDFVersion { public: - // Represent a PDF version. PDF versions are typically major.minor, but PDF 1.7 has several - // extension levels as the ISO 32000 spec was in progress. This class helps with comparison of - // versions. - QPDF_DLL - PDFVersion(); - QPDF_DLL + PDFVersion() = default; PDFVersion(PDFVersion const&) = default; - QPDF_DLL PDFVersion& operator=(PDFVersion const&) = default; + QPDF_DLL PDFVersion(int major, int minor, int extension = 0); QPDF_DLL @@ -59,9 +57,9 @@ class PDFVersion int getExtensionLevel() const; private: - int major_version; - int minor_version; - int extension_level; + int major_version{0}; + int minor_version{0}; + int extension_level{0}; }; #endif // PDFVERSION_HH diff --git a/include/qpdf/Pipeline.hh b/include/qpdf/Pipeline.hh index d3ab189..d818cad 100644 --- a/include/qpdf/Pipeline.hh +++ b/include/qpdf/Pipeline.hh @@ -17,6 +17,14 @@ // License. At your option, you may continue to consider qpdf to be licensed under those terms. // Please see the manual for additional information. +#ifndef PIPELINE_HH +#define PIPELINE_HH + +#include + +#include +#include + // Generalized Pipeline interface. By convention, subclasses of Pipeline are called Pl_Something. // // When an instance of Pipeline is created with a pointer to a next pipeline, that pipeline writes @@ -32,15 +40,7 @@ // Some pipelines are reusable (i.e., you can call write() after calling finish() and can call // finish() multiple times) while others are not. It is up to the caller to use a pipeline // according to its own restrictions. - -#ifndef PIPELINE_HH -#define PIPELINE_HH - -#include - -#include -#include - +// // 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 @@ -49,7 +49,6 @@ class QPDF_DLL_CLASS Pipeline QPDF_DLL Pipeline(char const* identifier, Pipeline* next); - QPDF_DLL virtual ~Pipeline() = default; // Subclasses should implement write and finish to do their jobs and then, if they are not @@ -98,7 +97,7 @@ class QPDF_DLL_CLASS Pipeline protected: QPDF_DLL Pipeline* getNext(bool allow_null = false); - QPDF_DLL + Pipeline* next() const noexcept { diff --git a/include/qpdf/Pl_Buffer.hh b/include/qpdf/Pl_Buffer.hh index 7e275d0..722c8d4 100644 --- a/include/qpdf/Pl_Buffer.hh +++ b/include/qpdf/Pl_Buffer.hh @@ -20,6 +20,12 @@ #ifndef PL_BUFFER_HH #define PL_BUFFER_HH +#include +#include + +#include +#include + // This pipeline accumulates the data passed to it into a memory buffer. Each subsequent use of // this buffer appends to the data accumulated so far. getBuffer() may be called only after calling // finish() and before calling any subsequent write(). At that point, a dynamically allocated @@ -28,13 +34,6 @@ // // For this pipeline, "next" may be null. If a next pointer is provided, this pipeline will also // pass the data through to it. - -#include -#include - -#include -#include - class QPDF_DLL_CLASS Pl_Buffer: public Pipeline { public: @@ -69,23 +68,9 @@ class QPDF_DLL_CLASS Pl_Buffer: public Pipeline std::string getString(); private: - class QPDF_DLL_PRIVATE Members - { - friend class Pl_Buffer; - - public: - QPDF_DLL - ~Members() = default; - - private: - Members() = default; - Members(Members const&) = delete; - - bool ready{true}; - std::string data; - }; + class Members; - std::shared_ptr m; + std::unique_ptr m; }; #endif // PL_BUFFER_HH diff --git a/include/qpdf/Pl_Concatenate.hh b/include/qpdf/Pl_Concatenate.hh index 92d7f44..548765d 100644 --- a/include/qpdf/Pl_Concatenate.hh +++ b/include/qpdf/Pl_Concatenate.hh @@ -20,18 +20,18 @@ #ifndef PL_CONCATENATE_HH #define PL_CONCATENATE_HH +#include + // This pipeline will drop all regular finish calls rather than passing them onto next. To finish // downstream streams, call manualFinish. This makes it possible to pipe multiple streams (e.g. // with QPDFObjectHandle::pipeStreamData) to a downstream like Pl_Flate that can't handle multiple // calls to finish(). - -#include - class QPDF_DLL_CLASS Pl_Concatenate: public Pipeline { public: QPDF_DLL Pl_Concatenate(char const* identifier, Pipeline* next); + QPDF_DLL ~Pl_Concatenate() override; @@ -51,7 +51,6 @@ class QPDF_DLL_CLASS Pl_Concatenate: public Pipeline friend class Pl_Concatenate; public: - QPDF_DLL ~Members() = default; private: @@ -59,7 +58,7 @@ class QPDF_DLL_CLASS Pl_Concatenate: public Pipeline Members(Members const&) = delete; }; - std::shared_ptr m; + std::unique_ptr m{nullptr}; }; #endif // PL_CONCATENATE_HH diff --git a/include/qpdf/Pl_Count.hh b/include/qpdf/Pl_Count.hh index 07c5fe5..076106d 100644 --- a/include/qpdf/Pl_Count.hh +++ b/include/qpdf/Pl_Count.hh @@ -20,11 +20,10 @@ #ifndef PL_COUNT_HH #define PL_COUNT_HH -// This pipeline is reusable; i.e., it is safe to call write() after calling finish(). - #include #include +// This pipeline is reusable; i.e., it is safe to call write() after calling finish(). class QPDF_DLL_CLASS Pl_Count: public Pipeline { public: @@ -45,24 +44,9 @@ class QPDF_DLL_CLASS Pl_Count: public Pipeline unsigned char getLastChar() const; private: - class QPDF_DLL_PRIVATE Members - { - friend class Pl_Count; - - public: - QPDF_DLL - ~Members() = default; - - private: - Members(); - Members(Members const&) = delete; - - // Must be qpdf_offset_t, not size_t, to handle writing more than size_t can handle. - qpdf_offset_t count{0}; - unsigned char last_char{'\0'}; - }; + class Members; - std::shared_ptr m; + std::unique_ptr m; }; #endif // PL_COUNT_HH diff --git a/include/qpdf/Pl_DCT.hh b/include/qpdf/Pl_DCT.hh index 1af9d36..02f4a34 100644 --- a/include/qpdf/Pl_DCT.hh +++ b/include/qpdf/Pl_DCT.hh @@ -89,39 +89,9 @@ class QPDF_DLL_CLASS Pl_DCT: public Pipeline enum action_e { a_compress, a_decompress }; - class QPDF_DLL_PRIVATE Members - { - friend class Pl_DCT; - - public: - QPDF_DLL - ~Members() = default; - Members(Members const&) = delete; - - private: - // For compression - Members( - JDIMENSION image_width, - JDIMENSION image_height, - int components, - J_COLOR_SPACE color_space, - CompressConfig* config_callback); - // For decompression - Members(); - - action_e action; - Pl_Buffer buf; - - // Used for compression - JDIMENSION image_width{0}; - JDIMENSION image_height{0}; - int components{1}; - J_COLOR_SPACE color_space{JCS_GRAYSCALE}; - - CompressConfig* config_callback{nullptr}; - }; + class Members; - std::shared_ptr m; + std::unique_ptr m; }; #endif // PL_DCT_HH diff --git a/include/qpdf/Pl_Discard.hh b/include/qpdf/Pl_Discard.hh index ec6169a..400a2dc 100644 --- a/include/qpdf/Pl_Discard.hh +++ b/include/qpdf/Pl_Discard.hh @@ -20,12 +20,11 @@ #ifndef PL_DISCARD_HH #define PL_DISCARD_HH -// This pipeline discards its output. It is an end-of-line pipeline (with no next). - -// This pipeline is reusable; i.e., it is safe to call write() after calling finish(). - #include +// This pipeline discards its output. It is an end-of-line pipeline (with no next). +// +// This pipeline is reusable; i.e., it is safe to call write() after calling finish(). class QPDF_DLL_CLASS Pl_Discard: public Pipeline { public: @@ -37,22 +36,6 @@ class QPDF_DLL_CLASS Pl_Discard: public Pipeline void write(unsigned char const*, size_t) override; QPDF_DLL void finish() override; - - private: - class QPDF_DLL_PRIVATE Members - { - friend class Pl_Discard; - - public: - QPDF_DLL - ~Members() = default; - - private: - Members() = default; - Members(Members const&) = delete; - }; - - std::shared_ptr m; }; #endif // PL_DISCARD_HH diff --git a/include/qpdf/Pl_Flate.hh b/include/qpdf/Pl_Flate.hh index c7bbeba..800f85f 100644 --- a/include/qpdf/Pl_Flate.hh +++ b/include/qpdf/Pl_Flate.hh @@ -104,11 +104,10 @@ class QPDF_DLL_CLASS Pl_Flate: public Pipeline friend class Pl_Flate; public: - QPDF_DLL + Members(size_t out_bufsize, action_e action); ~Members(); private: - Members(size_t out_bufsize, action_e action); Members(Members const&) = delete; std::shared_ptr outbuf; @@ -121,7 +120,7 @@ class QPDF_DLL_CLASS Pl_Flate: public Pipeline std::unique_ptr zopfli_buf; }; - std::shared_ptr m; + std::unique_ptr m; }; #endif // PL_FLATE_HH diff --git a/include/qpdf/Pl_Function.hh b/include/qpdf/Pl_Function.hh index 3add90d..a0e3ada 100644 --- a/include/qpdf/Pl_Function.hh +++ b/include/qpdf/Pl_Function.hh @@ -62,22 +62,9 @@ class QPDF_DLL_CLASS Pl_Function: public Pipeline void finish() override; private: - class QPDF_DLL_PRIVATE Members - { - friend class Pl_Function; + class Members; - public: - QPDF_DLL - ~Members() = default; - - private: - Members(writer_t); - Members(Members const&) = delete; - - writer_t fn; - }; - - std::shared_ptr m; + std::unique_ptr m; }; #endif // PL_FUNCTION_HH diff --git a/include/qpdf/Pl_OStream.hh b/include/qpdf/Pl_OStream.hh index fbf8b7d..556cc90 100644 --- a/include/qpdf/Pl_OStream.hh +++ b/include/qpdf/Pl_OStream.hh @@ -17,8 +17,6 @@ // License. At your option, you may continue to consider qpdf to be licensed under those terms. // Please see the manual for additional information. -// End-of-line pipeline that simply writes its data to a stdio FILE* object. - #ifndef PL_OSTREAM_HH #define PL_OSTREAM_HH @@ -26,10 +24,9 @@ #include +// End-of-line pipeline that simply writes its data to a stdio FILE* object. // // This pipeline is reusable. -// - class QPDF_DLL_CLASS Pl_OStream: public Pipeline { public: @@ -45,22 +42,9 @@ class QPDF_DLL_CLASS Pl_OStream: public Pipeline void finish() override; private: - class QPDF_DLL_PRIVATE Members - { - friend class Pl_OStream; - - public: - QPDF_DLL - ~Members() = default; - - private: - Members(std::ostream&); - Members(Members const&) = delete; - - std::ostream& os; - }; + class Members; - std::shared_ptr m; + std::unique_ptr m; }; #endif // PL_OSTREAM_HH diff --git a/include/qpdf/Pl_QPDFTokenizer.hh b/include/qpdf/Pl_QPDFTokenizer.hh index b2b77fc..5d3fed1 100644 --- a/include/qpdf/Pl_QPDFTokenizer.hh +++ b/include/qpdf/Pl_QPDFTokenizer.hh @@ -31,11 +31,10 @@ // Tokenize the incoming text using QPDFTokenizer and pass the tokens in turn to a // QPDFObjectHandle::TokenFilter object. All bytes of incoming content will be included in exactly // one token and passed downstream. - +// // This is a very low-level interface for working with token filters. Most code will want to use // QPDFObjectHandle::filterPageContents or QPDFObjectHandle::addTokenFilter. See QPDFObjectHandle.hh // for details. - class QPDF_DLL_CLASS Pl_QPDFTokenizer: public Pipeline { public: @@ -52,23 +51,9 @@ class QPDF_DLL_CLASS Pl_QPDFTokenizer: public Pipeline void finish() override; private: - class QPDF_DLL_PRIVATE Members - { - friend class Pl_QPDFTokenizer; - - public: - QPDF_DLL - ~Members() = default; - - private: - Members(); - Members(Members const&) = delete; + class Members; - QPDFObjectHandle::TokenFilter* filter{nullptr}; - QPDFTokenizer tokenizer; - Pl_Buffer buf; - }; - std::shared_ptr m; + std::unique_ptr m; }; #endif // PL_QPDFTOKENIZER_HH diff --git a/include/qpdf/Pl_RunLength.hh b/include/qpdf/Pl_RunLength.hh index 0c15279..bebc425 100644 --- a/include/qpdf/Pl_RunLength.hh +++ b/include/qpdf/Pl_RunLength.hh @@ -52,26 +52,9 @@ class QPDF_DLL_CLASS Pl_RunLength: public Pipeline enum state_e { st_top, st_copying, st_run }; - class QPDF_DLL_PRIVATE Members - { - friend class Pl_RunLength; + class Members; - public: - QPDF_DLL - ~Members() = default; - - private: - Members(action_e); - Members(Members const&) = delete; - - action_e action; - state_e state{st_top}; - unsigned char buf[128]; - unsigned int length{0}; - std::string out; - }; - - std::shared_ptr m; + std::unique_ptr m; }; #endif // PL_RUNLENGTH_HH diff --git a/include/qpdf/Pl_StdioFile.hh b/include/qpdf/Pl_StdioFile.hh index ba1db9e..47e6fc9 100644 --- a/include/qpdf/Pl_StdioFile.hh +++ b/include/qpdf/Pl_StdioFile.hh @@ -29,7 +29,6 @@ // // This pipeline is reusable. // - class QPDF_DLL_CLASS Pl_StdioFile: public Pipeline { public: @@ -45,22 +44,10 @@ class QPDF_DLL_CLASS Pl_StdioFile: public Pipeline void finish() override; private: - class QPDF_DLL_PRIVATE Members - { - friend class Pl_StdioFile; - - public: - QPDF_DLL - ~Members() = default; - - private: - Members(FILE*); - Members(Members const&) = delete; - - FILE* file; - }; + class Members; + ; - std::shared_ptr m; + std::unique_ptr m; }; #endif // PL_STDIOFILE_HH diff --git a/include/qpdf/Pl_String.hh b/include/qpdf/Pl_String.hh index 64ad8ed..d4666a7 100644 --- a/include/qpdf/Pl_String.hh +++ b/include/qpdf/Pl_String.hh @@ -20,6 +20,10 @@ #ifndef PL_STRING_HH #define PL_STRING_HH +#include + +#include + // This pipeline accumulates the data passed to it into a std::string, a reference to which is // passed in at construction. Each subsequent use of this pipeline appends to the data accumulated // so far. @@ -31,11 +35,6 @@ // this in front of another pipeline to capture data that is written to the other pipeline without // interfering with when finish is called on the other pipeline and without having to put a // Pl_Concatenate after it. - -#include - -#include - class QPDF_DLL_CLASS Pl_String: public Pipeline { public: @@ -50,22 +49,9 @@ class QPDF_DLL_CLASS Pl_String: public Pipeline void finish() override; private: - class QPDF_DLL_PRIVATE Members - { - friend class Pl_String; - - public: - QPDF_DLL - ~Members() = default; - - private: - Members(std::string&); - Members(Members const&) = delete; - - std::string& s; - }; + class Members; - std::shared_ptr m; + std::unique_ptr m; }; #endif // PL_STRING_HH diff --git a/include/qpdf/QPDF.hh b/include/qpdf/QPDF.hh index 528a679..934a8e7 100644 --- a/include/qpdf/QPDF.hh +++ b/include/qpdf/QPDF.hh @@ -1496,13 +1496,11 @@ class QPDF friend class ResolveRecorder; public: - QPDF_DLL - ~Members() = default; - - private: Members(); Members(Members const&) = delete; + ~Members() = default; + private: std::shared_ptr log; unsigned long long unique_id{0}; QPDFTokenizer tokenizer; @@ -1577,7 +1575,7 @@ class QPDF // Keep all member variables inside the Members object, which we dynamically allocate. This // makes it possible to add new private members without breaking binary compatibility. - std::shared_ptr m; + std::unique_ptr m; }; #endif // QPDF_HH diff --git a/include/qpdf/QPDFAcroFormDocumentHelper.hh b/include/qpdf/QPDFAcroFormDocumentHelper.hh index 004578d..248525a 100644 --- a/include/qpdf/QPDFAcroFormDocumentHelper.hh +++ b/include/qpdf/QPDFAcroFormDocumentHelper.hh @@ -20,6 +20,18 @@ #ifndef QPDFACROFORMDOCUMENTHELPER_HH #define QPDFACROFORMDOCUMENTHELPER_HH +#include + +#include + +#include +#include +#include + +#include +#include +#include + // This document helper is intended to help with operations on interactive forms. Here are the key // things to know: @@ -53,25 +65,12 @@ // under "/Fields" in the "/AcroForm" dictionary. In a more complex case, you may have to trace // through various "/Kids" elements in the "/AcroForm" field entry until you find the annotation // dictionary. - -#include - -#include - -#include -#include -#include - -#include -#include -#include - class QPDFAcroFormDocumentHelper: public QPDFDocumentHelper { public: QPDF_DLL QPDFAcroFormDocumentHelper(QPDF&); - QPDF_DLL + ~QPDFAcroFormDocumentHelper() override = default; // This class lazily creates an internal cache of the mapping among form fields, annotations, @@ -232,7 +231,6 @@ class QPDFAcroFormDocumentHelper: public QPDFDocumentHelper friend class QPDFAcroFormDocumentHelper; public: - QPDF_DLL ~Members() = default; private: diff --git a/include/qpdf/QPDFAnnotationObjectHelper.hh b/include/qpdf/QPDFAnnotationObjectHelper.hh index 932488f..7aea177 100644 --- a/include/qpdf/QPDFAnnotationObjectHelper.hh +++ b/include/qpdf/QPDFAnnotationObjectHelper.hh @@ -30,7 +30,7 @@ class QPDFAnnotationObjectHelper: public QPDFObjectHelper public: QPDF_DLL QPDFAnnotationObjectHelper(QPDFObjectHandle); - QPDF_DLL + ~QPDFAnnotationObjectHelper() override = default; // This class provides helper methods for annotations. More functionality will likely be added @@ -92,7 +92,6 @@ class QPDFAnnotationObjectHelper: public QPDFObjectHelper friend class QPDFAnnotationObjectHelper; public: - QPDF_DLL ~Members() = default; private: diff --git a/include/qpdf/QPDFCryptoImpl.hh b/include/qpdf/QPDFCryptoImpl.hh index b2c9ebd..1eddcbd 100644 --- a/include/qpdf/QPDFCryptoImpl.hh +++ b/include/qpdf/QPDFCryptoImpl.hh @@ -32,40 +32,28 @@ // so, provide an implementation of QPDFCryptoImpl, ensure that you // register it by calling QPDFCryptoProvider::registerImpl, and make // it the default by calling QPDFCryptoProvider::setDefaultProvider. - class QPDF_DLL_CLASS QPDFCryptoImpl { public: - QPDF_DLL QPDFCryptoImpl() = default; - QPDF_DLL virtual ~QPDFCryptoImpl() = default; // Random Number Generation - QPDF_DLL virtual void provideRandomData(unsigned char* data, size_t len) = 0; // Hashing typedef unsigned char MD5_Digest[16]; - QPDF_DLL virtual void MD5_init() = 0; - QPDF_DLL virtual void MD5_update(unsigned char const* data, size_t len) = 0; - QPDF_DLL virtual void MD5_finalize() = 0; - QPDF_DLL virtual void MD5_digest(MD5_Digest) = 0; - QPDF_DLL virtual void SHA2_init(int bits) = 0; - QPDF_DLL virtual void SHA2_update(unsigned char const* data, size_t len) = 0; - QPDF_DLL virtual void SHA2_finalize() = 0; - QPDF_DLL virtual std::string SHA2_digest() = 0; // Encryption/Decryption @@ -74,26 +62,20 @@ class QPDF_DLL_CLASS QPDFCryptoImpl // and readers. Search for RC4 in README.md // key_len of -1 means treat key_data as a null-terminated string - QPDF_DLL virtual void RC4_init(unsigned char const* key_data, int key_len = -1) = 0; // out_data = 0 means to encrypt/decrypt in place - QPDF_DLL virtual void RC4_process(unsigned char const* in_data, size_t len, unsigned char* out_data = nullptr) = 0; - QPDF_DLL virtual void RC4_finalize() = 0; static size_t constexpr rijndael_buf_size = 16; - QPDF_DLL virtual void rijndael_init( bool encrypt, unsigned char const* key_data, size_t key_len, bool cbc_mode, unsigned char* cbc_block) = 0; - QPDF_DLL virtual void rijndael_process(unsigned char* in_data, unsigned char* out_data) = 0; - QPDF_DLL virtual void rijndael_finalize() = 0; }; diff --git a/include/qpdf/QPDFCryptoProvider.hh b/include/qpdf/QPDFCryptoProvider.hh index 1f3e891..2f87b99 100644 --- a/include/qpdf/QPDFCryptoProvider.hh +++ b/include/qpdf/QPDFCryptoProvider.hh @@ -31,7 +31,6 @@ // This class is part of qpdf's pluggable crypto provider support. Most users won't need to know or // care about this class, but you can use it if you want to supply your own crypto implementation. // See also comments in QPDFCryptoImpl.hh. - class QPDFCryptoProvider { public: @@ -92,7 +91,6 @@ class QPDFCryptoProvider public: Members() = default; - QPDF_DLL ~Members() = default; private: diff --git a/include/qpdf/QPDFDocumentHelper.hh b/include/qpdf/QPDFDocumentHelper.hh index 63f9677..8b44263 100644 --- a/include/qpdf/QPDFDocumentHelper.hh +++ b/include/qpdf/QPDFDocumentHelper.hh @@ -30,28 +30,24 @@ // the underlying QPDF object unless there is a specific comment in a specific helper method that // says otherwise. The pattern of using helper objects was introduced to allow creation of higher // level helper functions without polluting the public interface of QPDF. - class QPDF_DLL_CLASS QPDFDocumentHelper { public: - QPDF_DLL QPDFDocumentHelper(QPDF& qpdf) : qpdf(qpdf) { } QPDF_DLL virtual ~QPDFDocumentHelper(); - QPDF_DLL QPDF& getQPDF() { - return this->qpdf; + return qpdf; } - QPDF_DLL QPDF const& getQPDF() const { - return this->qpdf; + return qpdf; } protected: diff --git a/include/qpdf/QPDFEFStreamObjectHelper.hh b/include/qpdf/QPDFEFStreamObjectHelper.hh index 36a445b..0998b59 100644 --- a/include/qpdf/QPDFEFStreamObjectHelper.hh +++ b/include/qpdf/QPDFEFStreamObjectHelper.hh @@ -29,13 +29,12 @@ // This class provides a higher level interface around Embedded File Streams, which are discussed in // section 7.11.4 of the ISO-32000 PDF specification. - class QPDFEFStreamObjectHelper: public QPDFObjectHelper { public: QPDF_DLL QPDFEFStreamObjectHelper(QPDFObjectHandle); - QPDF_DLL + ~QPDFEFStreamObjectHelper() override = default; // Date parameters are strings that conform to the PDF spec for date/time strings, which is @@ -98,7 +97,6 @@ class QPDFEFStreamObjectHelper: public QPDFObjectHelper friend class QPDFEFStreamObjectHelper; public: - QPDF_DLL ~Members() = default; private: diff --git a/include/qpdf/QPDFEmbeddedFileDocumentHelper.hh b/include/qpdf/QPDFEmbeddedFileDocumentHelper.hh index 45632b4..f63a491 100644 --- a/include/qpdf/QPDFEmbeddedFileDocumentHelper.hh +++ b/include/qpdf/QPDFEmbeddedFileDocumentHelper.hh @@ -33,13 +33,12 @@ // This class provides a higher level interface around document-level file attachments, also known // as embedded files. These are discussed in sections 7.7.4 and 7.11 of the ISO-32000 PDF // specification. - class QPDFEmbeddedFileDocumentHelper: public QPDFDocumentHelper { public: QPDF_DLL QPDFEmbeddedFileDocumentHelper(QPDF&); - QPDF_DLL + ~QPDFEmbeddedFileDocumentHelper() override = default; QPDF_DLL @@ -73,7 +72,6 @@ class QPDFEmbeddedFileDocumentHelper: public QPDFDocumentHelper friend class QPDFEmbeddedFileDocumentHelper; public: - QPDF_DLL ~Members() = default; private: diff --git a/include/qpdf/QPDFExc.hh b/include/qpdf/QPDFExc.hh index b69c955..787482d 100644 --- a/include/qpdf/QPDFExc.hh +++ b/include/qpdf/QPDFExc.hh @@ -37,7 +37,7 @@ class QPDF_DLL_CLASS QPDFExc: public std::runtime_error std::string const& object, qpdf_offset_t offset, std::string const& message); - QPDF_DLL + ~QPDFExc() noexcept override = default; // To get a complete error string, call what(), provided by std::exception. The accessors below diff --git a/include/qpdf/QPDFFileSpecObjectHelper.hh b/include/qpdf/QPDFFileSpecObjectHelper.hh index 129f995..1999ed2 100644 --- a/include/qpdf/QPDFFileSpecObjectHelper.hh +++ b/include/qpdf/QPDFFileSpecObjectHelper.hh @@ -29,13 +29,12 @@ // This class provides a higher level interface around File Specification dictionaries, which are // discussed in section 7.11 of the ISO-32000 PDF specification. - class QPDFFileSpecObjectHelper: public QPDFObjectHelper { public: QPDF_DLL QPDFFileSpecObjectHelper(QPDFObjectHandle); - QPDF_DLL + ~QPDFFileSpecObjectHelper() override = default; QPDF_DLL @@ -93,7 +92,6 @@ class QPDFFileSpecObjectHelper: public QPDFObjectHelper friend class QPDFFileSpecObjectHelper; public: - QPDF_DLL ~Members() = default; private: diff --git a/include/qpdf/QPDFFormFieldObjectHelper.hh b/include/qpdf/QPDFFormFieldObjectHelper.hh index d1fd597..d77209e 100644 --- a/include/qpdf/QPDFFormFieldObjectHelper.hh +++ b/include/qpdf/QPDFFormFieldObjectHelper.hh @@ -20,9 +20,6 @@ #ifndef QPDFFORMFIELDOBJECTHELPER_HH #define QPDFFORMFIELDOBJECTHELPER_HH -// This object helper helps with form fields for interactive forms. Please see comments in -// QPDFAcroFormDocumentHelper.hh for additional details. - #include #include @@ -30,6 +27,8 @@ class QPDFAnnotationObjectHelper; +// This object helper helps with form fields for interactive forms. Please see comments in +// QPDFAcroFormDocumentHelper.hh for additional details. class QPDFFormFieldObjectHelper: public QPDFObjectHelper { public: @@ -37,7 +36,7 @@ class QPDFFormFieldObjectHelper: public QPDFObjectHelper QPDFFormFieldObjectHelper(); QPDF_DLL QPDFFormFieldObjectHelper(QPDFObjectHandle); - QPDF_DLL + ~QPDFFormFieldObjectHelper() override = default; QPDF_DLL @@ -199,7 +198,6 @@ class QPDFFormFieldObjectHelper: public QPDFObjectHelper friend class QPDFFormFieldObjectHelper; public: - QPDF_DLL ~Members() = default; private: diff --git a/include/qpdf/QPDFLogger.hh b/include/qpdf/QPDFLogger.hh index b494833..3a4f027 100644 --- a/include/qpdf/QPDFLogger.hh +++ b/include/qpdf/QPDFLogger.hh @@ -143,7 +143,6 @@ class QPDFLogger friend class QPDFLogger; public: - QPDF_DLL ~Members(); private: diff --git a/include/qpdf/QPDFMatrix.hh b/include/qpdf/QPDFMatrix.hh index 4dbd9b5..4e5fd39 100644 --- a/include/qpdf/QPDFMatrix.hh +++ b/include/qpdf/QPDFMatrix.hh @@ -31,7 +31,6 @@ // (a, b, c, d, e, f) = │ c d 0 │ // │ e f 1 │ // └ ┘ - class QPDFMatrix { public: @@ -79,12 +78,9 @@ class QPDFMatrix // operator== tests for exact equality, not considering deltas for floating point. QPDF_DLL bool operator==(QPDFMatrix const& rhs) const; + QPDF_DLL - bool - operator!=(QPDFMatrix const& rhs) const - { - return !operator==(rhs); - } + bool operator!=(QPDFMatrix const& rhs) const; double a; double b; diff --git a/include/qpdf/QPDFNameTreeObjectHelper.hh b/include/qpdf/QPDFNameTreeObjectHelper.hh index a4a9a17..9405942 100644 --- a/include/qpdf/QPDFNameTreeObjectHelper.hh +++ b/include/qpdf/QPDFNameTreeObjectHelper.hh @@ -28,16 +28,15 @@ #include -// This is an object helper for name trees. See section 7.9.6 in the PDF spec (ISO 32000) for a -// description of name trees. When looking up items in the name tree, use UTF-8 strings. All names -// are normalized for lookup purposes. - -// See examples/pdf-name-number-tree.cc for a demonstration of using QPDFNameTreeObjectHelper. - class NNTreeImpl; class NNTreeIterator; class NNTreeDetails; +// This is an object helper for name trees. See section 7.9.6 in the PDF spec (ISO 32000) for a +// description of name trees. When looking up items in the name tree, use UTF-8 strings. All names +// are normalized for lookup purposes. +// +// See examples/pdf-name-number-tree.cc for a demonstration of using QPDFNameTreeObjectHelper. class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper { public: @@ -78,7 +77,6 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper bool valid() const; QPDF_DLL iterator& operator++(); - QPDF_DLL iterator operator++(int) { @@ -88,7 +86,6 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper } QPDF_DLL iterator& operator--(); - QPDF_DLL iterator operator--(int) { @@ -102,7 +99,6 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper pointer operator->(); QPDF_DLL bool operator==(iterator const& other) const; - QPDF_DLL bool operator!=(iterator const& other) const { @@ -172,7 +168,6 @@ class QPDF_DLL_CLASS QPDFNameTreeObjectHelper: public QPDFObjectHelper friend class QPDFNameTreeObjectHelper; public: - QPDF_DLL ~Members() = default; private: diff --git a/include/qpdf/QPDFNumberTreeObjectHelper.hh b/include/qpdf/QPDFNumberTreeObjectHelper.hh index da5cb06..3cc7a89 100644 --- a/include/qpdf/QPDFNumberTreeObjectHelper.hh +++ b/include/qpdf/QPDFNumberTreeObjectHelper.hh @@ -27,15 +27,14 @@ #include -// This is an object helper for number trees. See section 7.9.7 in the PDF spec (ISO 32000) for a -// description of number trees. - -// See examples/pdf-name-number-tree.cc for a demonstration of using QPDFNumberTreeObjectHelper. - class NNTreeImpl; class NNTreeIterator; class NNTreeDetails; +// This is an object helper for number trees. See section 7.9.7 in the PDF spec (ISO 32000) for a +// description of number trees. +// +// See examples/pdf-name-number-tree.cc for a demonstration of using QPDFNumberTreeObjectHelper. class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper { public: @@ -93,7 +92,6 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper bool valid() const; QPDF_DLL iterator& operator++(); - QPDF_DLL iterator operator++(int) { @@ -103,7 +101,6 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper } QPDF_DLL iterator& operator--(); - QPDF_DLL iterator operator--(int) { @@ -117,7 +114,6 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper pointer operator->(); QPDF_DLL bool operator==(iterator const& other) const; - QPDF_DLL bool operator!=(iterator const& other) const { @@ -189,7 +185,6 @@ class QPDF_DLL_CLASS QPDFNumberTreeObjectHelper: public QPDFObjectHelper typedef QPDFNumberTreeObjectHelper::numtree_number numtree_number; public: - QPDF_DLL ~Members() = default; private: diff --git a/include/qpdf/QPDFObjGen.hh b/include/qpdf/QPDFObjGen.hh index 5c38665..8bdeea7 100644 --- a/include/qpdf/QPDFObjGen.hh +++ b/include/qpdf/QPDFObjGen.hh @@ -35,57 +35,47 @@ class QPDFObjectHelper; class QPDFObjGen { public: - QPDF_DLL QPDFObjGen() = default; - QPDF_DLL QPDFObjGen(int obj, int gen) : obj(obj), gen(gen) { } - QPDF_DLL bool operator<(QPDFObjGen const& rhs) const { return (obj < rhs.obj) || (obj == rhs.obj && gen < rhs.gen); } - QPDF_DLL bool operator==(QPDFObjGen const& rhs) const { return obj == rhs.obj && gen == rhs.gen; } - QPDF_DLL bool operator!=(QPDFObjGen const& rhs) const { return !(*this == rhs); } - QPDF_DLL int getObj() const { return obj; } - QPDF_DLL int getGen() const { return gen; } - QPDF_DLL bool isIndirect() const { return obj != 0; } - QPDF_DLL std::string unparse(char separator = ',') const { return std::to_string(obj) + separator + std::to_string(gen); } - QPDF_DLL friend std::ostream& operator<<(std::ostream& os, QPDFObjGen og) { @@ -116,7 +106,6 @@ class QPDFObjGen public: // Add 'og' to the set. Return false if 'og' is already present in the set. Attempts to // insert QPDFObjGen(0, 0) are ignored. - QPDF_DLL bool add(QPDFObjGen og) { @@ -129,7 +118,6 @@ class QPDFObjGen return true; } - QPDF_DLL void erase(QPDFObjGen og) { diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh index d3ea1f0..fd4b19d 100644 --- a/include/qpdf/QPDFObjectHandle.hh +++ b/include/qpdf/QPDFObjectHandle.hh @@ -156,9 +156,7 @@ class QPDFObjectHandle final: public qpdf::BaseHandle class QPDF_DLL_CLASS TokenFilter { public: - QPDF_DLL TokenFilter() = default; - QPDF_DLL virtual ~TokenFilter() = default; virtual void handleToken(QPDFTokenizer::Token const&) = 0; QPDF_DLL @@ -196,7 +194,6 @@ class QPDFObjectHandle final: public qpdf::BaseHandle class StringDecrypter { public: - QPDF_DLL virtual ~StringDecrypter() = default; virtual void decryptString(std::string& val) = 0; }; @@ -206,7 +203,6 @@ class QPDFObjectHandle final: public qpdf::BaseHandle class QPDF_DLL_CLASS ParserCallbacks { public: - QPDF_DLL virtual ~ParserCallbacks() = default; // One of the handleObject methods must be overridden. QPDF_DLL @@ -286,18 +282,13 @@ class QPDFObjectHandle final: public qpdf::BaseHandle double f; }; - QPDF_DLL QPDFObjectHandle() = default; - QPDF_DLL QPDFObjectHandle(QPDFObjectHandle const&) = default; - QPDF_DLL QPDFObjectHandle& operator=(QPDFObjectHandle const&) = default; - QPDF_DLL QPDFObjectHandle(QPDFObjectHandle&&) = default; - QPDF_DLL QPDFObjectHandle& operator=(QPDFObjectHandle&&) = default; - [[deprecated("use operator bool()")]] QPDF_DLL inline bool isInitialized() const; + [[deprecated("use operator bool()")]] inline bool isInitialized() const; // This method returns true if the QPDFObjectHandle objects point to exactly the same underlying // object, meaning that changes to one are reflected in the other, or "if you paint one, the @@ -348,7 +339,7 @@ class QPDFObjectHandle final: public qpdf::BaseHandle // This returns true in addition to the query for the specific type for indirect objects. QPDF_DLL - inline bool isIndirect() const; + bool isIndirect() const; // This returns true for indirect objects from a QPDF that has been destroyed. Trying unparse // such an object will throw a logic_error. @@ -1145,9 +1136,9 @@ class QPDFObjectHandle final: public qpdf::BaseHandle QPDF_DLL QPDFObjGen getObjGen() const; QPDF_DLL - inline int getObjectID() const; + int getObjectID() const; QPDF_DLL - inline int getGeneration() const; + int getGeneration() const; QPDF_DLL std::string unparse() const; @@ -1424,11 +1415,9 @@ class QPDFObjectHandle::QPDFDictItems using pointer = T*; using reference = T&; - QPDF_DLL virtual ~iterator() = default; QPDF_DLL iterator& operator++(); - QPDF_DLL iterator operator++(int) { @@ -1438,7 +1427,6 @@ class QPDFObjectHandle::QPDFDictItems } QPDF_DLL iterator& operator--(); - QPDF_DLL iterator operator--(int) { @@ -1452,7 +1440,6 @@ class QPDFObjectHandle::QPDFDictItems pointer operator->(); QPDF_DLL bool operator==(iterator const& other) const; - QPDF_DLL bool operator!=(iterator const& other) const { @@ -1468,7 +1455,6 @@ class QPDFObjectHandle::QPDFDictItems friend class QPDFDictItems::iterator; public: - QPDF_DLL ~Members() = default; private: @@ -1522,11 +1508,9 @@ class QPDFObjectHandle::QPDFArrayItems using pointer = T*; using reference = T&; - QPDF_DLL virtual ~iterator() = default; QPDF_DLL iterator& operator++(); - QPDF_DLL iterator operator++(int) { @@ -1536,7 +1520,6 @@ class QPDFObjectHandle::QPDFArrayItems } QPDF_DLL iterator& operator--(); - QPDF_DLL iterator operator--(int) { @@ -1550,7 +1533,6 @@ class QPDFObjectHandle::QPDFArrayItems pointer operator->(); QPDF_DLL bool operator==(iterator const& other) const; - QPDF_DLL bool operator!=(iterator const& other) const { @@ -1566,7 +1548,6 @@ class QPDFObjectHandle::QPDFArrayItems friend class QPDFArrayItems::iterator; public: - QPDF_DLL ~Members() = default; private: @@ -1607,24 +1588,6 @@ namespace qpdf } // namespace qpdf -inline int -QPDFObjectHandle::getObjectID() const -{ - return getObjGen().getObj(); -} - -inline int -QPDFObjectHandle::getGeneration() const -{ - return getObjGen().getGen(); -} - -inline bool -QPDFObjectHandle::isIndirect() const -{ - return (obj != nullptr) && (getObjectID() != 0); -} - inline bool QPDFObjectHandle::isInitialized() const { diff --git a/include/qpdf/QPDFObjectHelper.hh b/include/qpdf/QPDFObjectHelper.hh index 648b0f7..00f57e3 100644 --- a/include/qpdf/QPDFObjectHelper.hh +++ b/include/qpdf/QPDFObjectHelper.hh @@ -34,20 +34,17 @@ class QPDF_DLL_CLASS QPDFObjectHelper: public qpdf::BaseHandle { public: - QPDF_DLL QPDFObjectHelper(QPDFObjectHandle oh) : qpdf::BaseHandle(oh.getObj()) { } QPDF_DLL virtual ~QPDFObjectHelper(); - QPDF_DLL QPDFObjectHandle getObjectHandle() { return {obj}; } - QPDF_DLL QPDFObjectHandle const getObjectHandle() const { diff --git a/include/qpdf/QPDFOutlineDocumentHelper.hh b/include/qpdf/QPDFOutlineDocumentHelper.hh index 1f152d5..a36b4d5 100644 --- a/include/qpdf/QPDFOutlineDocumentHelper.hh +++ b/include/qpdf/QPDFOutlineDocumentHelper.hh @@ -35,13 +35,12 @@ // section 12.3.3 of the PDF spec (ISO-32000). With the help of QPDFOutlineObjectHelper, the // outlines tree is traversed, and a bidirectional map is made between pages and outlines. See also // QPDFOutlineObjectHelper. - class QPDFOutlineDocumentHelper: public QPDFDocumentHelper { public: QPDF_DLL QPDFOutlineDocumentHelper(QPDF&); - QPDF_DLL + ~QPDFOutlineDocumentHelper() override = default; QPDF_DLL @@ -79,7 +78,6 @@ class QPDFOutlineDocumentHelper: public QPDFDocumentHelper friend class QPDFOutlineDocumentHelper; public: - QPDF_DLL ~Members() = default; private: diff --git a/include/qpdf/QPDFOutlineObjectHelper.hh b/include/qpdf/QPDFOutlineObjectHelper.hh index 3275170..7b39bee 100644 --- a/include/qpdf/QPDFOutlineObjectHelper.hh +++ b/include/qpdf/QPDFOutlineObjectHelper.hh @@ -30,11 +30,9 @@ class QPDFOutlineDocumentHelper; // This is an object helper for outline items. Outlines, also known as bookmarks, are described in // section 12.3.3 of the PDF spec (ISO-32000). See comments below for details. - class QPDFOutlineObjectHelper: public QPDFObjectHelper { public: - QPDF_DLL ~QPDFOutlineObjectHelper() override { // This must be cleared explicitly to avoid circular references that prevent cleanup of @@ -87,7 +85,6 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper }; private: - QPDF_DLL QPDFOutlineObjectHelper(QPDFObjectHandle, QPDFOutlineDocumentHelper&, int); class Members @@ -95,7 +92,6 @@ class QPDFOutlineObjectHelper: public QPDFObjectHelper friend class QPDFOutlineObjectHelper; public: - QPDF_DLL ~Members() = default; private: diff --git a/include/qpdf/QPDFPageDocumentHelper.hh b/include/qpdf/QPDFPageDocumentHelper.hh index 28f691b..bad7e68 100644 --- a/include/qpdf/QPDFPageDocumentHelper.hh +++ b/include/qpdf/QPDFPageDocumentHelper.hh @@ -37,7 +37,7 @@ class QPDFPageDocumentHelper: public QPDFDocumentHelper public: QPDF_DLL QPDFPageDocumentHelper(QPDF&); - QPDF_DLL + ~QPDFPageDocumentHelper() override = default; // Traverse page tree, and return all /Page objects wrapped in QPDFPageObjectHelper objects. @@ -117,7 +117,6 @@ class QPDFPageDocumentHelper: public QPDFDocumentHelper friend class QPDFPageDocumentHelper; public: - QPDF_DLL ~Members() = default; private: diff --git a/include/qpdf/QPDFPageLabelDocumentHelper.hh b/include/qpdf/QPDFPageLabelDocumentHelper.hh index b4596f2..9c63172 100644 --- a/include/qpdf/QPDFPageLabelDocumentHelper.hh +++ b/include/qpdf/QPDFPageLabelDocumentHelper.hh @@ -44,7 +44,7 @@ class QPDFPageLabelDocumentHelper: public QPDFDocumentHelper public: QPDF_DLL QPDFPageLabelDocumentHelper(QPDF&); - QPDF_DLL + ~QPDFPageLabelDocumentHelper() override = default; QPDF_DLL @@ -82,7 +82,6 @@ class QPDFPageLabelDocumentHelper: public QPDFDocumentHelper friend class QPDFPageLabelDocumentHelper; public: - QPDF_DLL ~Members() = default; private: diff --git a/include/qpdf/QPDFPageObjectHelper.hh b/include/qpdf/QPDFPageObjectHelper.hh index 51ad3e6..9df550b 100644 --- a/include/qpdf/QPDFPageObjectHelper.hh +++ b/include/qpdf/QPDFPageObjectHelper.hh @@ -31,15 +31,14 @@ class QPDFAcroFormDocumentHelper; +// This is a helper class for page objects, but as of qpdf 10.1, many of the methods also work +// for form XObjects. When this is the case, it is noted in the comment. class QPDFPageObjectHelper: public QPDFObjectHelper { - // This is a helper class for page objects, but as of qpdf 10.1, many of the methods also work - // for form XObjects. When this is the case, it is noted in the comment. - public: QPDF_DLL QPDFPageObjectHelper(QPDFObjectHandle); - QPDF_DLL + ~QPDFPageObjectHelper() override = default; // PAGE ATTRIBUTES @@ -411,7 +410,6 @@ class QPDFPageObjectHelper: public QPDFObjectHelper friend class QPDFPageObjectHelper; public: - QPDF_DLL ~Members() = default; private: diff --git a/include/qpdf/QPDFStreamFilter.hh b/include/qpdf/QPDFStreamFilter.hh index fe88312..e2c912f 100644 --- a/include/qpdf/QPDFStreamFilter.hh +++ b/include/qpdf/QPDFStreamFilter.hh @@ -27,10 +27,8 @@ class QPDF_DLL_CLASS QPDFStreamFilter { public: - QPDF_DLL QPDFStreamFilter() = default; - QPDF_DLL virtual ~QPDFStreamFilter() = default; // A QPDFStreamFilter class must implement, at a minimum, setDecodeParms() and diff --git a/include/qpdf/QPDFSystemError.hh b/include/qpdf/QPDFSystemError.hh index ca3aa87..90f0cfe 100644 --- a/include/qpdf/QPDFSystemError.hh +++ b/include/qpdf/QPDFSystemError.hh @@ -32,7 +32,7 @@ class QPDF_DLL_CLASS QPDFSystemError: public std::runtime_error public: QPDF_DLL QPDFSystemError(std::string const& description, int system_errno); - QPDF_DLL + ~QPDFSystemError() noexcept override = default; // To get a complete error string, call what(), provided by std::exception. The accessors below diff --git a/include/qpdf/QPDFUsage.hh b/include/qpdf/QPDFUsage.hh index bc52e15..810cc05 100644 --- a/include/qpdf/QPDFUsage.hh +++ b/include/qpdf/QPDFUsage.hh @@ -30,7 +30,6 @@ class QPDF_DLL_CLASS QPDFUsage: public std::runtime_error public: QPDF_DLL QPDFUsage(std::string const& msg); - QPDF_DLL ~QPDFUsage() noexcept override = default; }; diff --git a/include/qpdf/QPDFWriter.hh b/include/qpdf/QPDFWriter.hh index 6b79a7f..5cfb958 100644 --- a/include/qpdf/QPDFWriter.hh +++ b/include/qpdf/QPDFWriter.hh @@ -17,9 +17,6 @@ // License. At your option, you may continue to consider qpdf to be licensed under those terms. // Please see the manual for additional information. -// This class implements a simple writer for saving QPDF objects to new PDF files. See comments -// through the header file for additional details. - #ifndef QPDFWRITER_HH #define QPDFWRITER_HH @@ -51,6 +48,8 @@ class QPDF; class Pl_Count; class Pl_MD5; +// This class implements a simple writer for saving QPDF objects to new PDF files. See comments +// through the header file for additional details. class QPDFWriter { public: @@ -71,7 +70,6 @@ class QPDFWriter QPDF_DLL QPDFWriter(QPDF& pdf, char const* description, FILE* file, bool close_file); - QPDF_DLL ~QPDFWriter() = default; class QPDF_DLL_CLASS ProgressReporter diff --git a/include/qpdf/QPDFXRefEntry.hh b/include/qpdf/QPDFXRefEntry.hh index 9eb07ad..1dc28c7 100644 --- a/include/qpdf/QPDFXRefEntry.hh +++ b/include/qpdf/QPDFXRefEntry.hh @@ -37,14 +37,12 @@ class QPDFXRefEntry QPDF_DLL QPDFXRefEntry(int type, qpdf_offset_t field1, int field2); // Create a type 1 "uncompressed" entry. - QPDF_DLL QPDFXRefEntry(qpdf_offset_t offset) : type(1), field1(offset) { } // Create a type 2 "compressed" entry. - QPDF_DLL QPDFXRefEntry(int stream_number, int index) : type(2), field1(stream_number), diff --git a/include/qpdf/QUtil.hh b/include/qpdf/QUtil.hh index 16e5693..2f0a748 100644 --- a/include/qpdf/QUtil.hh +++ b/include/qpdf/QUtil.hh @@ -190,7 +190,7 @@ namespace QUtil // Returns lower-case hex-encoded version of the char including a leading "#". QPDF_DLL - inline std::string hex_encode_char(char); + std::string hex_encode_char(char); // Returns a string that is the result of decoding the input string. The input string may // consist of mixed case hexadecimal digits. Any characters that are not hexadecimal digits will @@ -202,7 +202,7 @@ namespace QUtil // Decode a single hex digit into a char in the range 0 <= char < 16. Return a char >= 16 if // digit is not a valid hex digit. QPDF_DLL - inline constexpr char hex_decode_char(char digit) noexcept; + char hex_decode_char(char digit); // Set stdin, stdout to binary mode QPDF_DLL @@ -431,16 +431,16 @@ namespace QUtil // These routines help the tokenizer recognize certain character classes without using ctype, // which we avoid because of locale considerations. QPDF_DLL - inline bool is_hex_digit(char); + bool is_hex_digit(char); QPDF_DLL - inline bool is_space(char); + bool is_space(char); QPDF_DLL - inline bool is_digit(char); + bool is_digit(char); QPDF_DLL - inline bool is_number(char const*); + bool is_number(char const*); // This method parses the numeric range syntax used by the qpdf command-line tool. May throw // std::runtime_error. A numeric range is as comma-separated list of groups. A group may be a @@ -489,65 +489,4 @@ namespace QUtil size_t get_max_memory_usage(); }; // namespace QUtil -inline bool -QUtil::is_hex_digit(char ch) -{ - return hex_decode_char(ch) < '\20'; -} - -inline bool -QUtil::is_space(char ch) -{ - return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\v'; -} - -inline bool -QUtil::is_digit(char ch) -{ - return ((ch >= '0') && (ch <= '9')); -} - -inline bool -QUtil::is_number(char const* p) -{ - // ^[\+\-]?(\.\d*|\d+(\.\d*)?)$ - if (!*p) { - return false; - } - if ((*p == '-') || (*p == '+')) { - ++p; - } - bool found_dot = false; - bool found_digit = false; - for (; *p; ++p) { - if (*p == '.') { - if (found_dot) { - // only one dot - return false; - } - found_dot = true; - } else if (QUtil::is_digit(*p)) { - found_digit = true; - } else { - return false; - } - } - return found_digit; -} - -inline std::string -QUtil::hex_encode_char(char c) -{ - static auto constexpr hexchars = "0123456789abcdef"; - return {'#', hexchars[static_cast(c) >> 4], hexchars[c & 0x0f]}; -} - -inline constexpr char -QUtil::hex_decode_char(char digit) noexcept -{ - return digit <= '9' && digit >= '0' - ? char(digit - '0') - : (digit >= 'a' ? char(digit - 'a' + 10) : (digit >= 'A' ? char(digit - 'A' + 10) : '\20')); -} - #endif // QUTIL_HH diff --git a/libqpdf/FileInputSource.cc b/libqpdf/FileInputSource.cc index ec6e84b..ef1522b 100644 --- a/libqpdf/FileInputSource.cc +++ b/libqpdf/FileInputSource.cc @@ -5,12 +5,6 @@ #include #include -FileInputSource::FileInputSource() : - close_file(false), - file(nullptr) -{ -} - FileInputSource::FileInputSource(char const* filename) : close_file(true), filename(filename), diff --git a/libqpdf/JSON.cc b/libqpdf/JSON.cc index 41ea8c1..80bd6c6 100644 --- a/libqpdf/JSON.cc +++ b/libqpdf/JSON.cc @@ -8,9 +8,13 @@ #include #include #include +#include + #include #include +using namespace qpdf; + JSON::Members::Members(std::unique_ptr value) : value(std::move(value)) { @@ -761,7 +765,7 @@ JSONParser::tokenError() QTC::TC("libtests", "JSON parse unexpected sign"); throw std::runtime_error( "JSON: offset " + std::to_string(offset) + ": numeric literal: unexpected sign"); - } else if (QUtil::is_space(*p) || strchr("{}[]:,", *p)) { + } else if (util::is_space(*p) || strchr("{}[]:,", *p)) { QTC::TC("libtests", "JSON parse incomplete number"); throw std::runtime_error( "JSON: offset " + std::to_string(offset) + ": numeric literal: incomplete number"); @@ -1078,7 +1082,7 @@ JSONParser::getToken() case ls_u4: using ui = unsigned int; - if (ui val = ui(QUtil::hex_decode_char(*p)); val < 16) { + if (ui val = ui(util::hex_decode_char(*p)); val < 16) { u_value = 16 * u_value + val; } else { tokenError(); diff --git a/libqpdf/PDFVersion.cc b/libqpdf/PDFVersion.cc index d093b06..fa32895 100644 --- a/libqpdf/PDFVersion.cc +++ b/libqpdf/PDFVersion.cc @@ -2,11 +2,6 @@ #include -PDFVersion::PDFVersion() : - PDFVersion(0, 0, 0) -{ -} - PDFVersion::PDFVersion(int major_version, int minor_version, int extension_level) : major_version(major_version), minor_version(minor_version), diff --git a/libqpdf/Pl_Base64.cc b/libqpdf/Pl_Base64.cc index 4fa4091..afc782b 100644 --- a/libqpdf/Pl_Base64.cc +++ b/libqpdf/Pl_Base64.cc @@ -2,9 +2,13 @@ #include #include +#include + #include #include +using namespace qpdf; + static char to_c(unsigned int ch) { @@ -50,7 +54,7 @@ Pl_Base64::decode(unsigned char const* data, size_t len) { unsigned char const* p = data; while (len > 0) { - if (!QUtil::is_space(to_c(*p))) { + if (!util::is_space(to_c(*p))) { this->buf[this->pos++] = *p; if (this->pos == 4) { flush(); diff --git a/libqpdf/Pl_Buffer.cc b/libqpdf/Pl_Buffer.cc index 86389d6..38fadb3 100644 --- a/libqpdf/Pl_Buffer.cc +++ b/libqpdf/Pl_Buffer.cc @@ -5,16 +5,24 @@ #include #include +class Pl_Buffer::Members +{ + public: + Members() = default; + Members(Members const&) = delete; + + bool ready{true}; + std::string data; +}; + Pl_Buffer::Pl_Buffer(char const* identifier, Pipeline* next) : Pipeline(identifier, next), - m(new Members()) + m(std::make_unique()) { } -Pl_Buffer::~Pl_Buffer() // NOLINT (modernize-use-equals-default) -{ - // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer -} +// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer +Pl_Buffer::~Pl_Buffer() = default; void Pl_Buffer::write(unsigned char const* buf, size_t len) diff --git a/libqpdf/Pl_Concatenate.cc b/libqpdf/Pl_Concatenate.cc index 339c1c5..fa95bea 100644 --- a/libqpdf/Pl_Concatenate.cc +++ b/libqpdf/Pl_Concatenate.cc @@ -10,10 +10,8 @@ Pl_Concatenate::Pl_Concatenate(char const* identifier, Pipeline* next) : } } -Pl_Concatenate::~Pl_Concatenate() // NOLINT (modernize-use-equals-default) -{ - // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer -} +// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer +Pl_Concatenate::~Pl_Concatenate() = default; void Pl_Concatenate::write(unsigned char const* data, size_t len) diff --git a/libqpdf/Pl_Count.cc b/libqpdf/Pl_Count.cc index 912f44e..bca217c 100644 --- a/libqpdf/Pl_Count.cc +++ b/libqpdf/Pl_Count.cc @@ -2,13 +2,21 @@ #include -Pl_Count::Members::Members() +class Pl_Count::Members { -} + public: + Members() = default; + Members(Members const&) = delete; + ~Members() = default; + + // Must be qpdf_offset_t, not size_t, to handle writing more than size_t can handle. + qpdf_offset_t count{0}; + unsigned char last_char{'\0'}; +}; Pl_Count::Pl_Count(char const* identifier, Pipeline* next) : Pipeline(identifier, next), - m(new Members()) + m(std::make_unique()) { if (!next) { throw std::logic_error("Attempt to create Pl_Count with nullptr as next"); diff --git a/libqpdf/Pl_DCT.cc b/libqpdf/Pl_DCT.cc index 047cacb..92af9c9 100644 --- a/libqpdf/Pl_DCT.cc +++ b/libqpdf/Pl_DCT.cc @@ -57,31 +57,52 @@ progress_monitor(j_common_ptr cinfo) } } -Pl_DCT::Members::Members() : - action(a_decompress), - buf("DCT compressed image") +class Pl_DCT::Members { -} + public: + // For compression + Members( + JDIMENSION image_width, + JDIMENSION image_height, + int components, + J_COLOR_SPACE color_space, + CompressConfig* config_callback) : + action(a_compress), + buf("DCT uncompressed image"), + image_width(image_width), + image_height(image_height), + components(components), + color_space(color_space), + config_callback(config_callback) + { + } -Pl_DCT::Members::Members( - JDIMENSION image_width, - JDIMENSION image_height, - int components, - J_COLOR_SPACE color_space, - CompressConfig* config_callback) : - action(a_compress), - buf("DCT uncompressed image"), - image_width(image_width), - image_height(image_height), - components(components), - color_space(color_space), - config_callback(config_callback) -{ -} + // For decompression + Members() : + action(a_decompress), + buf("DCT compressed image") + { + } + + Members(Members const&) = delete; + + ~Members() = default; + + action_e action; + Pl_Buffer buf; + + // Used for compression + JDIMENSION image_width{0}; + JDIMENSION image_height{0}; + int components{1}; + J_COLOR_SPACE color_space{JCS_GRAYSCALE}; + + CompressConfig* config_callback{nullptr}; +}; Pl_DCT::Pl_DCT(char const* identifier, Pipeline* next) : Pipeline(identifier, next), - m(new Members()) + m(std::make_unique()) { if (!next) { throw std::logic_error("Attempt to create Pl_DCT with nullptr as next"); @@ -115,14 +136,13 @@ Pl_DCT::Pl_DCT( J_COLOR_SPACE color_space, CompressConfig* compress_callback) : Pipeline(identifier, next), - m(new Members(image_width, image_height, components, color_space, compress_callback)) + m(std::make_unique( + image_width, image_height, components, color_space, compress_callback)) { } -Pl_DCT::~Pl_DCT() // NOLINT (modernize-use-equals-default) -{ - // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer -} +// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer +Pl_DCT::~Pl_DCT() = default; void Pl_DCT::write(unsigned char const* data, size_t len) diff --git a/libqpdf/Pl_Discard.cc b/libqpdf/Pl_Discard.cc index 643d3e4..60d2d4d 100644 --- a/libqpdf/Pl_Discard.cc +++ b/libqpdf/Pl_Discard.cc @@ -2,15 +2,16 @@ // Exercised in md5 test suite +// Pl_Discard does not use the member pattern as thee is no prospect of it ever requiring data +// members. + Pl_Discard::Pl_Discard() : Pipeline("discard", nullptr) { } -Pl_Discard::~Pl_Discard() // NOLINT (modernize-use-equals-default) -{ - // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer -} +// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer +Pl_Discard::~Pl_Discard() = default; void Pl_Discard::write(unsigned char const* buf, size_t len) diff --git a/libqpdf/Pl_Flate.cc b/libqpdf/Pl_Flate.cc index 724b443..a28a1a3 100644 --- a/libqpdf/Pl_Flate.cc +++ b/libqpdf/Pl_Flate.cc @@ -68,17 +68,15 @@ Pl_Flate::Members::~Members() Pl_Flate::Pl_Flate( char const* identifier, Pipeline* next, action_e action, unsigned int out_bufsize_int) : Pipeline(identifier, next), - m(std::shared_ptr(new Members(QIntC::to_size(out_bufsize_int), action))) + m(std::make_unique(QIntC::to_size(out_bufsize_int), action)) { if (!next) { throw std::logic_error("Attempt to create Pl_Flate with nullptr as next"); } } -Pl_Flate::~Pl_Flate() // NOLINT (modernize-use-equals-default) -{ - // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer -} +// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer +Pl_Flate::~Pl_Flate() = default; unsigned long long Pl_Flate::memory_limit() diff --git a/libqpdf/Pl_Function.cc b/libqpdf/Pl_Function.cc index 3bcef45..7b36ad0 100644 --- a/libqpdf/Pl_Function.cc +++ b/libqpdf/Pl_Function.cc @@ -2,20 +2,28 @@ #include -Pl_Function::Members::Members(writer_t fn) : - fn(fn) +class Pl_Function::Members { -} + public: + Members(writer_t fn) : + fn(fn) + { + } + Members(Members const&) = delete; + ~Members() = default; + + writer_t fn; +}; Pl_Function::Pl_Function(char const* identifier, Pipeline* next, writer_t fn) : Pipeline(identifier, next), - m(new Members(fn)) + m(std::make_unique(fn)) { } Pl_Function::Pl_Function(char const* identifier, Pipeline* next, writer_c_t fn, void* udata) : Pipeline(identifier, next), - m(new Members(nullptr)) + m(std::make_unique(nullptr)) { m->fn = [identifier, fn, udata](unsigned char const* data, size_t len) { int code = fn(data, len, udata); diff --git a/libqpdf/Pl_OStream.cc b/libqpdf/Pl_OStream.cc index 9b1995a..296fd23 100644 --- a/libqpdf/Pl_OStream.cc +++ b/libqpdf/Pl_OStream.cc @@ -2,21 +2,27 @@ #include -Pl_OStream::Members::Members(std::ostream& os) : - os(os) +class Pl_OStream::Members { -} + public: + Members(std::ostream& os) : + os(os) + { + } + Members(Members const&) = delete; + ~Members() = default; + + std::ostream& os; +}; Pl_OStream::Pl_OStream(char const* identifier, std::ostream& os) : Pipeline(identifier, nullptr), - m(new Members(os)) + m(std::make_unique(os)) { } -Pl_OStream::~Pl_OStream() // NOLINT (modernize-use-equals-default) -{ - // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer -} +// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer +Pl_OStream::~Pl_OStream() = default; void Pl_OStream::write(unsigned char const* buf, size_t len) diff --git a/libqpdf/Pl_QPDFTokenizer.cc b/libqpdf/Pl_QPDFTokenizer.cc index 16a4bd0..b60ab78 100644 --- a/libqpdf/Pl_QPDFTokenizer.cc +++ b/libqpdf/Pl_QPDFTokenizer.cc @@ -4,15 +4,22 @@ #include #include -Pl_QPDFTokenizer::Members::Members() : - buf("tokenizer buffer") +class Pl_QPDFTokenizer::Members { -} + public: + Members() = default; + Members(Members const&) = delete; + ~Members() = default; + + QPDFObjectHandle::TokenFilter* filter{nullptr}; + QPDFTokenizer tokenizer; + Pl_Buffer buf{"tokenizer buffer"}; +}; Pl_QPDFTokenizer::Pl_QPDFTokenizer( char const* identifier, QPDFObjectHandle::TokenFilter* filter, Pipeline* next) : Pipeline(identifier, next), - m(new Members) + m(std::make_unique()) { m->filter = filter; QPDFObjectHandle::TokenFilter::PipelineAccessor::setPipeline(m->filter, next); @@ -20,10 +27,8 @@ Pl_QPDFTokenizer::Pl_QPDFTokenizer( m->tokenizer.includeIgnorable(); } -Pl_QPDFTokenizer::~Pl_QPDFTokenizer() // NOLINT (modernize-use-equals-default) -{ - // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer -} +// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer +Pl_QPDFTokenizer::~Pl_QPDFTokenizer() = default; void Pl_QPDFTokenizer::write(unsigned char const* data, size_t len) diff --git a/libqpdf/Pl_RunLength.cc b/libqpdf/Pl_RunLength.cc index 963dbd9..cd269ab 100644 --- a/libqpdf/Pl_RunLength.cc +++ b/libqpdf/Pl_RunLength.cc @@ -8,14 +8,26 @@ namespace unsigned long long memory_limit{0}; } // namespace -Pl_RunLength::Members::Members(action_e action) : - action(action) +class Pl_RunLength::Members { -} + public: + Members(action_e action) : + action(action) + { + } + Members(Members const&) = delete; + ~Members() = default; + + action_e action; + state_e state{st_top}; + unsigned char buf[128]; + unsigned int length{0}; + std::string out; +}; Pl_RunLength::Pl_RunLength(char const* identifier, Pipeline* next, action_e action) : Pipeline(identifier, next), - m(new Members(action)) + m(std::make_unique(action)) { if (!next) { throw std::logic_error("Attempt to create Pl_RunLength with nullptr as next"); diff --git a/libqpdf/Pl_StdioFile.cc b/libqpdf/Pl_StdioFile.cc index 24e1124..a2f500f 100644 --- a/libqpdf/Pl_StdioFile.cc +++ b/libqpdf/Pl_StdioFile.cc @@ -6,21 +6,27 @@ #include #include -Pl_StdioFile::Members::Members(FILE* f) : - file(f) +class Pl_StdioFile::Members { -} + public: + Members(FILE* f) : + file(f) + { + } + Members(Members const&) = delete; + ~Members() = default; + + FILE* file; +}; Pl_StdioFile::Pl_StdioFile(char const* identifier, FILE* f) : Pipeline(identifier, nullptr), - m(new Members(f)) + m(std::make_unique(f)) { } -Pl_StdioFile::~Pl_StdioFile() // NOLINT (modernize-use-equals-default) -{ - // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer -} +// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer +Pl_StdioFile::~Pl_StdioFile() = default; void Pl_StdioFile::write(unsigned char const* buf, size_t len) diff --git a/libqpdf/Pl_String.cc b/libqpdf/Pl_String.cc index c022d5c..dccbf84 100644 --- a/libqpdf/Pl_String.cc +++ b/libqpdf/Pl_String.cc @@ -2,21 +2,27 @@ #include -Pl_String::Members::Members(std::string& s) : - s(s) +class Pl_String::Members { -} + public: + Members(std::string& s) : + s(s) + { + } + Members(Members const&) = delete; + ~Members() = default; + + std::string& s; +}; Pl_String::Pl_String(char const* identifier, Pipeline* next, std::string& s) : Pipeline(identifier, next), - m(new Members(s)) + m(std::make_unique(s)) { } -Pl_String::~Pl_String() // NOLINT (modernize-use-equals-default) -{ - // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer -} +// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer +Pl_String::~Pl_String() = default; void Pl_String::write(unsigned char const* buf, size_t len) diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index 08e877e..7cbc656 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -22,6 +22,9 @@ #include #include #include +#include + +using namespace qpdf; // This must be a fixed value. This API returns a const reference to it, and the C API relies on its // being static as well. @@ -200,7 +203,7 @@ QPDF::Members::Members() : } QPDF::QPDF() : - m(new Members()) + m(std::make_unique()) { m->tokenizer.allowEOF(); // Generate a unique ID. It just has to be unique among all QPDF objects allocated throughout @@ -368,14 +371,14 @@ QPDF::numWarnings() const bool QPDF::validatePDFVersion(char const*& p, std::string& version) { - bool valid = QUtil::is_digit(*p); + bool valid = util::is_digit(*p); if (valid) { - while (QUtil::is_digit(*p)) { + while (util::is_digit(*p)) { version.append(1, *p++); } - if ((*p == '.') && QUtil::is_digit(*(p + 1))) { + if ((*p == '.') && util::is_digit(*(p + 1))) { version.append(1, *p++); - while (QUtil::is_digit(*p)) { + while (util::is_digit(*p)) { version.append(1, *p++); } } else { @@ -709,7 +712,7 @@ QPDF::read_xref(qpdf_offset_t xref_offset) while (!done) { char ch; if (1 == m->file->read(&ch, 1)) { - if (QUtil::is_space(ch)) { + if (util::is_space(ch)) { skipped_space = true; } else { m->file->unreadCh(ch); @@ -724,7 +727,7 @@ QPDF::read_xref(qpdf_offset_t xref_offset) m->file->read(buf, sizeof(buf) - 1); // The PDF spec says xref must be followed by a line terminator, but files exist in the wild // where it is terminated by arbitrary whitespace. - if ((strncmp(buf, "xref", 4) == 0) && QUtil::is_space(buf[4])) { + if ((strncmp(buf, "xref", 4) == 0) && util::is_space(buf[4])) { if (skipped_space) { QTC::TC("qpdf", "QPDF xref skipped space"); warn(damagedPDF("", 0, "extraneous whitespace seen before xref")); @@ -737,8 +740,8 @@ QPDF::read_xref(qpdf_offset_t xref_offset) : (buf[4] == ' ') ? 2 : 9999)); int skip = 4; - // buf is null-terminated, and QUtil::is_space('\0') is false, so this won't overrun. - while (QUtil::is_space(buf[skip])) { + // buf is null-terminated, and util::is_space('\0') is false, so this won't overrun. + while (util::is_space(buf[skip])) { ++skip; } xref_offset = read_xrefTable(xref_offset + skip); @@ -795,37 +798,37 @@ QPDF::parse_xrefFirst(std::string const& line, int& obj, int& num, int& bytes) char const* start = line.c_str(); // Skip zero or more spaces - while (QUtil::is_space(*p)) { + while (util::is_space(*p)) { ++p; } // Require digit - if (!QUtil::is_digit(*p)) { + if (!util::is_digit(*p)) { return false; } // Gather digits std::string obj_str; - while (QUtil::is_digit(*p)) { + while (util::is_digit(*p)) { obj_str.append(1, *p++); } // Require space - if (!QUtil::is_space(*p)) { + if (!util::is_space(*p)) { return false; } // Skip spaces - while (QUtil::is_space(*p)) { + while (util::is_space(*p)) { ++p; } // Require digit - if (!QUtil::is_digit(*p)) { + if (!util::is_digit(*p)) { return false; } // Gather digits std::string num_str; - while (QUtil::is_digit(*p)) { + while (util::is_digit(*p)) { num_str.append(1, *p++); } // Skip any space including line terminators - while (QUtil::is_space(*p)) { + while (util::is_space(*p)) { ++p; } bytes = toI(p - start); @@ -847,51 +850,51 @@ QPDF::read_bad_xrefEntry(qpdf_offset_t& f1, int& f2, char& type) // Skip zero or more spaces. There aren't supposed to be any. bool invalid = false; - while (QUtil::is_space(*p)) { + while (util::is_space(*p)) { ++p; QTC::TC("qpdf", "QPDF ignore first space in xref entry"); invalid = true; } // Require digit - if (!QUtil::is_digit(*p)) { + if (!util::is_digit(*p)) { return false; } // Gather digits std::string f1_str; - while (QUtil::is_digit(*p)) { + while (util::is_digit(*p)) { f1_str.append(1, *p++); } // Require space - if (!QUtil::is_space(*p)) { + if (!util::is_space(*p)) { return false; } - if (QUtil::is_space(*(p + 1))) { + if (util::is_space(*(p + 1))) { QTC::TC("qpdf", "QPDF ignore first extra space in xref entry"); invalid = true; } // Skip spaces - while (QUtil::is_space(*p)) { + while (util::is_space(*p)) { ++p; } // Require digit - if (!QUtil::is_digit(*p)) { + if (!util::is_digit(*p)) { return false; } // Gather digits std::string f2_str; - while (QUtil::is_digit(*p)) { + while (util::is_digit(*p)) { f2_str.append(1, *p++); } // Require space - if (!QUtil::is_space(*p)) { + if (!util::is_space(*p)) { return false; } - if (QUtil::is_space(*(p + 1))) { + if (util::is_space(*(p + 1))) { QTC::TC("qpdf", "QPDF ignore second extra space in xref entry"); invalid = true; } // Skip spaces - while (QUtil::is_space(*p)) { + while (util::is_space(*p)) { ++p; } if ((*p == 'f') || (*p == 'n')) { @@ -938,12 +941,12 @@ QPDF::read_xrefEntry(qpdf_offset_t& f1, int& f2, char& type) ++f1_len; ++p; } - while (QUtil::is_digit(*p) && f1_len++ < 10) { + while (util::is_digit(*p) && f1_len++ < 10) { f1 *= 10; f1 += *p++ - '0'; } // Require space - if (!QUtil::is_space(*p++)) { + if (!util::is_space(*p++)) { // Entry doesn't start with space or digit. // C++20: [[unlikely]] return false; @@ -953,11 +956,11 @@ QPDF::read_xrefEntry(qpdf_offset_t& f1, int& f2, char& type) ++f2_len; ++p; } - while (QUtil::is_digit(*p) && f2_len++ < 5) { + while (util::is_digit(*p) && f2_len++ < 5) { f2 *= 10; f2 += static_cast(*p++ - '0'); } - if (QUtil::is_space(*p++) && (*p == 'f' || *p == 'n')) { + if (util::is_space(*p++) && (*p == 'f' || *p == 'n')) { // C++20: [[likely]] type = *p; // No test for valid line[19]. @@ -1602,7 +1605,7 @@ QPDF::validateStreamLineEnd(QPDFObjectHandle& object, QPDFObjGen og, qpdf_offset } return; } - if (!QUtil::is_space(ch)) { + if (!util::is_space(ch)) { QTC::TC("qpdf", "QPDF stream without newline"); m->file->unreadCh(ch); warn(damagedPDF( diff --git a/libqpdf/QPDFArgParser.cc b/libqpdf/QPDFArgParser.cc index fc8f2ef..c16c18b 100644 --- a/libqpdf/QPDFArgParser.cc +++ b/libqpdf/QPDFArgParser.cc @@ -5,10 +5,13 @@ #include #include #include +#include + #include #include #include +using namespace qpdf; using namespace std::literals; QPDFArgParser::Members::Members(int argc, char const* const argv[], char const* progname_env) : @@ -285,7 +288,7 @@ QPDFArgParser::handleBashArguments() bool append = false; switch (state) { case st_top: - if (QUtil::is_space(ch)) { + if (util::is_space(ch)) { if (!arg.empty()) { m->bash_argv.push_back(QUtil::make_shared_cstr(arg)); arg.clear(); diff --git a/libqpdf/QPDFJob.cc b/libqpdf/QPDFJob.cc index 0aa5609..6b1d6cb 100644 --- a/libqpdf/QPDFJob.cc +++ b/libqpdf/QPDFJob.cc @@ -29,9 +29,12 @@ #include #include #include +#include #include // JOB_SCHEMA_DATA +using namespace qpdf; + namespace { class ImageOptimizer: public QPDFObjectHandle::StreamDataProvider @@ -388,7 +391,7 @@ QPDFJob::parseRotationParameter(std::string const& parameter) if ((first == '+') || (first == '-')) { relative = ((first == '+') ? 1 : -1); angle_str = angle_str.substr(1); - } else if (!QUtil::is_digit(angle_str.at(0))) { + } else if (!util::is_digit(angle_str.at(0))) { angle_str = ""; } } diff --git a/libqpdf/QPDFMatrix.cc b/libqpdf/QPDFMatrix.cc index f38d764..99570d6 100644 --- a/libqpdf/QPDFMatrix.cc +++ b/libqpdf/QPDFMatrix.cc @@ -138,3 +138,9 @@ QPDFMatrix::operator==(QPDFMatrix const& rhs) const (this->a == rhs.a) && (this->b == rhs.b) && (this->c == rhs.c) && (this->d == rhs.d) && (this->e == rhs.e) && (this->f == rhs.f)); } + +bool +QPDFMatrix::operator!=(QPDFMatrix const& rhs) const +{ + return !operator==(rhs); +} diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index ffe2509..13f04fd 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -279,7 +280,7 @@ Name::normalize(std::string const& name) } else if ( ch < 33 || ch == '#' || ch == '/' || ch == '(' || ch == ')' || ch == '{' || ch == '}' || ch == '<' || ch == '>' || ch == '[' || ch == ']' || ch == '%' || ch > 126) { - result += QUtil::hex_encode_char(ch); + result += util::hex_encode_char(ch); } else { result += ch; } @@ -2369,6 +2370,24 @@ QPDFObjectHandle::getObjGen() const return obj ? obj->getObjGen() : QPDFObjGen(); } +int +QPDFObjectHandle::getObjectID() const +{ + return getObjGen().getObj(); +} + +int +QPDFObjectHandle::getGeneration() const +{ + return getObjGen().getGen(); +} + +bool +QPDFObjectHandle::isIndirect() const +{ + return getObjectID() != 0; +} + // Indirect object accessors QPDF* QPDFObjectHandle::getOwningQPDF() const diff --git a/libqpdf/QPDFObjectHelper.cc b/libqpdf/QPDFObjectHelper.cc index cbd54f3..fa2ee22 100644 --- a/libqpdf/QPDFObjectHelper.cc +++ b/libqpdf/QPDFObjectHelper.cc @@ -1,6 +1,4 @@ #include -QPDFObjectHelper::~QPDFObjectHelper() // NOLINT (modernize-use-equals-default) -{ - // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer -} +// Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer +QPDFObjectHelper::~QPDFObjectHelper() = default; diff --git a/libqpdf/QPDFTokenizer.cc b/libqpdf/QPDFTokenizer.cc index 7f7c6d9..00796a2 100644 --- a/libqpdf/QPDFTokenizer.cc +++ b/libqpdf/QPDFTokenizer.cc @@ -8,11 +8,14 @@ #include #include #include +#include #include #include #include +using namespace qpdf; + static inline bool is_delimiter(char ch) { @@ -123,7 +126,7 @@ QPDFTokenizer::includeIgnorable() bool QPDFTokenizer::isSpace(char ch) { - return ((ch == '\0') || QUtil::is_space(ch)); + return (ch == '\0' || util::is_space(ch)); } bool @@ -440,7 +443,7 @@ QPDFTokenizer::inNameHex1(char ch) { this->hex_char = ch; - if (char hval = QUtil::hex_decode_char(ch); hval < '\20') { + if (char hval = util::hex_decode_char(ch); hval < '\20') { this->char_code = int(hval) << 4; this->state = st_name_hex2; } else { @@ -456,7 +459,7 @@ QPDFTokenizer::inNameHex1(char ch) void QPDFTokenizer::inNameHex2(char ch) { - if (char hval = QUtil::hex_decode_char(ch); hval < '\20') { + if (char hval = util::hex_decode_char(ch); hval < '\20') { this->char_code |= int(hval); } else { QTC::TC("qpdf", "QPDFTokenizer bad name 2"); @@ -483,7 +486,7 @@ QPDFTokenizer::inNameHex2(char ch) void QPDFTokenizer::inSign(char ch) { - if (QUtil::is_digit(ch)) { + if (util::is_digit(ch)) { this->state = st_number; } else if (ch == '.') { this->state = st_decimal; @@ -496,7 +499,7 @@ QPDFTokenizer::inSign(char ch) void QPDFTokenizer::inDecimal(char ch) { - if (QUtil::is_digit(ch)) { + if (util::is_digit(ch)) { this->state = st_real; } else { this->state = st_literal; @@ -507,7 +510,7 @@ QPDFTokenizer::inDecimal(char ch) void QPDFTokenizer::inNumber(char ch) { - if (QUtil::is_digit(ch)) { + if (util::is_digit(ch)) { } else if (ch == '.') { this->state = st_real; } else if (isDelimiter(ch)) { @@ -523,7 +526,7 @@ QPDFTokenizer::inNumber(char ch) void QPDFTokenizer::inReal(char ch) { - if (QUtil::is_digit(ch)) { + if (util::is_digit(ch)) { } else if (isDelimiter(ch)) { this->type = tt_real; this->state = st_token_ready; @@ -645,7 +648,7 @@ QPDFTokenizer::inLiteral(char ch) void QPDFTokenizer::inHexstring(char ch) { - if (char hval = QUtil::hex_decode_char(ch); hval < '\20') { + if (char hval = util::hex_decode_char(ch); hval < '\20') { this->char_code = int(hval) << 4; this->state = st_in_hexstring_2nd; @@ -667,7 +670,7 @@ QPDFTokenizer::inHexstring(char ch) void QPDFTokenizer::inHexstring2nd(char ch) { - if (char hval = QUtil::hex_decode_char(ch); hval < '\20') { + if (char hval = util::hex_decode_char(ch); hval < '\20') { this->val += char(this->char_code) | hval; this->state = st_in_hexstring; diff --git a/libqpdf/QPDF_json.cc b/libqpdf/QPDF_json.cc index 288f265..81c5506 100644 --- a/libqpdf/QPDF_json.cc +++ b/libqpdf/QPDF_json.cc @@ -9,9 +9,13 @@ #include #include #include +#include + #include #include +using namespace qpdf; + // This chart shows an example of the state transitions that would occur in parsing a minimal file. // | @@ -67,10 +71,10 @@ is_indirect_object(std::string const& v, int& obj, int& gen) char const* p = v.c_str(); std::string o_str; std::string g_str; - if (!QUtil::is_digit(*p)) { + if (!util::is_digit(*p)) { return false; } - while (QUtil::is_digit(*p)) { + while (util::is_digit(*p)) { o_str.append(1, *p++); } if (*p != ' ') { @@ -79,10 +83,10 @@ is_indirect_object(std::string const& v, int& obj, int& gen) while (*p == ' ') { ++p; } - if (!QUtil::is_digit(*p)) { + if (!util::is_digit(*p)) { return false; } - while (QUtil::is_digit(*p)) { + while (util::is_digit(*p)) { g_str.append(1, *p++); } if (*p != ' ') { @@ -128,7 +132,7 @@ is_binary_string(std::string const& v, std::string& str) str = v.substr(2); int count = 0; for (char c: str) { - if (!QUtil::is_hex_digit(c)) { + if (!util::is_hex_digit(c)) { return false; } ++count; diff --git a/libqpdf/QPDF_linearization.cc b/libqpdf/QPDF_linearization.cc index 703617a..b183c07 100644 --- a/libqpdf/QPDF_linearization.cc +++ b/libqpdf/QPDF_linearization.cc @@ -12,11 +12,14 @@ #include #include #include +#include #include #include #include +using namespace qpdf; + template static void load_vector_int( @@ -105,7 +108,7 @@ QPDF::isLinearized() char* p = buf; while (lindict_obj == -1) { // Find a digit or end of buffer - while (((p - buf) < tbuf_size) && (!QUtil::is_digit(*p))) { + while (((p - buf) < tbuf_size) && (!util::is_digit(*p))) { ++p; } if (p - buf == tbuf_size) { @@ -114,7 +117,7 @@ QPDF::isLinearized() // Seek to the digit. Then skip over digits for a potential // next iteration. m->file->seek(p - buf, SEEK_SET); - while (((p - buf) < tbuf_size) && QUtil::is_digit(*p)) { + while (((p - buf) < tbuf_size) && util::is_digit(*p)) { ++p; } diff --git a/libqpdf/QUtil.cc b/libqpdf/QUtil.cc index e075399..05b53ba 100644 --- a/libqpdf/QUtil.cc +++ b/libqpdf/QUtil.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,8 @@ # include #endif +using namespace qpdf; + // First element is 24 static unsigned short pdf_doc_low_to_unicode[] = { 0x02d8, // 0x18 BREVE @@ -396,7 +399,7 @@ unsigned long long QUtil::string_to_ull(char const* str) { char const* p = str; - while (*p && is_space(*p)) { + while (*p && util::is_space(*p)) { ++p; } if (*p == '-') { @@ -739,7 +742,7 @@ QUtil::hex_decode(std::string const& input) bool first = true; char decoded; for (auto ch: input) { - ch = hex_decode_char(ch); + ch = util::hex_decode_char(ch); if (ch < '\20') { if (first) { decoded = static_cast(ch << 4); @@ -2002,3 +2005,63 @@ QUtil::get_max_memory_usage() return 0; #endif } + +char +QUtil::hex_decode_char(char digit) +{ + return util::hex_decode_char(digit); +} + +std::string +QUtil::hex_encode_char(char c) +{ + return util::hex_encode_char(c); +} + +bool +QUtil::is_number(char const* p) +{ + // No longer used by qpdf. + + // ^[\+\-]?(\.\d*|\d+(\.\d*)?)$ + if (!*p) { + return false; + } + if ((*p == '-') || (*p == '+')) { + ++p; + } + bool found_dot = false; + bool found_digit = false; + for (; *p; ++p) { + if (*p == '.') { + if (found_dot) { + // only one dot + return false; + } + found_dot = true; + } else if (util::is_digit(*p)) { + found_digit = true; + } else { + return false; + } + } + return found_digit; +} + +bool +QUtil::is_space(char c) +{ + return util::is_space(c); +} + +bool +QUtil::is_digit(char c) +{ + return util::is_digit(c); +} + +bool +QUtil::is_hex_digit(char c) +{ + return util::is_hex_digit(c); +} diff --git a/libqpdf/qpdf/Util.hh b/libqpdf/qpdf/Util.hh new file mode 100644 index 0000000..9f6b389 --- /dev/null +++ b/libqpdf/qpdf/Util.hh @@ -0,0 +1,49 @@ +#ifndef UTIL_HH +#define UTIL_HH + +#include + +namespace qpdf::util +{ + // This is a collection of useful utility functions for qpdf internal use. They include inline + // functions, some of which are exposed as regular functions in QUtil. Implementations are in + // QUtil.cc. + + inline constexpr char + hex_decode_char(char digit) + { + return digit <= '9' && digit >= '0' + ? char(digit - '0') + : (digit >= 'a' ? char(digit - 'a' + 10) + : (digit >= 'A' ? char(digit - 'A' + 10) : '\20')); + } + + inline constexpr bool + is_hex_digit(char ch) + { + return hex_decode_char(ch) < '\20'; + } + + inline constexpr bool + is_space(char ch) + { + return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '\f' || ch == '\v'; + } + + inline bool + is_digit(char ch) + { + return (ch >= '0' && ch <= '9'); + } + + // Returns lower-case hex-encoded version of the char including a leading "#". + inline std::string + hex_encode_char(char c) + { + static auto constexpr hexchars = "0123456789abcdef"; + return {'#', hexchars[static_cast(c) >> 4], hexchars[c & 0x0f]}; + } + +} // namespace qpdf::util + +#endif // UTIL_HH diff --git a/qpdf/sizes.cc b/qpdf/sizes.cc index 8bfba99..8ea4e6c 100644 --- a/qpdf/sizes.cc +++ b/qpdf/sizes.cc @@ -108,7 +108,6 @@ main() print_size(QPDFNameTreeObjectHelper::iterator); print_size(QPDFNumberTreeObjectHelper); print_size(QPDFNumberTreeObjectHelper::iterator); - print_size(QPDFObjGen); print_size(QPDFObjectHandle); print_size(QPDFObjectHandle::ParserCallbacks); print_size(QPDFObjectHandle::QPDFArrayItems); @@ -117,6 +116,7 @@ main() print_size(QPDFObjectHandle::QPDFDictItems::iterator); print_size(QPDFObjectHandle::StreamDataProvider); print_size(QPDFObjectHandle::TokenFilter); + print_size(QPDFObjectHelper); print_size(QPDFOutlineDocumentHelper); print_size(QPDFOutlineObjectHelper); print_size(QPDFPageDocumentHelper);