Use anonymous namespaces for file-private classes

This commit is contained in:
Jay Berkenbilt 2022-04-16 13:21:57 -04:00
parent 38edca820e
commit 75fe4f60c3
15 changed files with 435 additions and 362 deletions

View File

@ -6,7 +6,8 @@
qpdf 11.
* Perform code cleanup including some source-compatible but not
binary compatible changes to function signatures.
binary compatible changes to function signatures, use of anonymous
namespaces, and use of "= default" and "= delete" in declarations.
2022-04-09 Jay Berkenbilt <ejb@ql.org>

2
TODO
View File

@ -479,8 +479,6 @@ This is a list of changes to make next time there is an ABI change.
Comments appear in the code prefixed by "ABI". Always Search for ABI
in source and header files to find items not listed here.
* See where anonymous namespaces can be used to keep things private to
a source file. Search for `(class|struct)` in **/*.cc.
* Having QPDFObjectHandle setters return Class& to allow for
use of fluent interfaces. This includes array and dictionary
mutators.

View File

@ -14,12 +14,15 @@
# error "qpdf does not support libjpeg built with BITS_IN_JSAMPLE != 8"
#endif
struct qpdf_jpeg_error_mgr
namespace
{
struct jpeg_error_mgr pub;
jmp_buf jmpbuf;
std::string msg;
};
struct qpdf_jpeg_error_mgr
{
struct jpeg_error_mgr pub;
jmp_buf jmpbuf;
std::string msg;
};
} // namespace
static void
error_handler(j_common_ptr cinfo)
@ -147,13 +150,16 @@ Pl_DCT::finish()
}
}
struct dct_pipeline_dest
namespace
{
struct jpeg_destination_mgr pub; /* public fields */
unsigned char* buffer;
size_t size;
Pipeline* next;
};
struct dct_pipeline_dest
{
struct jpeg_destination_mgr pub; /* public fields */
unsigned char* buffer;
size_t size;
Pipeline* next;
};
} // namespace
static void
init_pipeline_destination(j_compress_ptr)

View File

@ -50,60 +50,64 @@ static char const* EMPTY_PDF = (
"110\n"
"%%EOF\n");
class InvalidInputSource: public InputSource
namespace
{
public:
virtual ~InvalidInputSource() = default;
virtual qpdf_offset_t
findAndSkipNextEOL() override
class InvalidInputSource: public InputSource
{
throwException();
return 0;
}
virtual std::string const&
getName() const override
{
static std::string name("closed input source");
return name;
}
virtual qpdf_offset_t
tell() override
{
throwException();
return 0;
}
virtual void
seek(qpdf_offset_t offset, int whence) override
{
throwException();
}
virtual void
rewind() override
{
throwException();
}
virtual size_t
read(char* buffer, size_t length) override
{
throwException();
return 0;
}
virtual void
unreadCh(char ch) override
{
throwException();
}
public:
virtual ~InvalidInputSource() = default;
virtual qpdf_offset_t
findAndSkipNextEOL() override
{
throwException();
return 0;
}
virtual std::string const&
getName() const override
{
static std::string name("closed input source");
return name;
}
virtual qpdf_offset_t
tell() override
{
throwException();
return 0;
}
virtual void
seek(qpdf_offset_t offset, int whence) override
{
throwException();
}
virtual void
rewind() override
{
throwException();
}
virtual size_t
read(char* buffer, size_t length) override
{
throwException();
return 0;
}
virtual void
unreadCh(char ch) override
{
throwException();
}
private:
void
throwException()
{
throw std::logic_error(
"QPDF operation attempted on a QPDF object with no input source."
" QPDF operations are invalid before processFile (or another"
" process method) or after closeInputSource");
}
};
private:
void
throwException()
{
throw std::logic_error(
"QPDF operation attempted on a QPDF object with no input "
"source."
" QPDF operations are invalid before processFile (or another"
" process method) or after closeInputSource");
}
};
} // namespace
QPDF::ForeignStreamData::ForeignStreamData(
std::shared_ptr<EncryptionParameters> encp,

View File

@ -543,20 +543,25 @@ QPDFAcroFormDocumentHelper::adjustInheritedFields(
}
}
class ResourceReplacer: public QPDFObjectHandle::TokenFilter
namespace
{
public:
ResourceReplacer(
std::map<std::string, std::map<std::string, std::string>> const& dr_map,
std::map<std::string, std::map<std::string, std::set<size_t>>> const&
rnames);
virtual ~ResourceReplacer() = default;
virtual void handleToken(QPDFTokenizer::Token const&) override;
class ResourceReplacer: public QPDFObjectHandle::TokenFilter
{
public:
ResourceReplacer(
std::map<std::string, std::map<std::string, std::string>> const&
dr_map,
std::map<
std::string,
std::map<std::string, std::set<size_t>>> const& rnames);
virtual ~ResourceReplacer() = default;
virtual void handleToken(QPDFTokenizer::Token const&) override;
private:
size_t offset;
std::map<std::string, std::map<size_t, std::string>> to_replace;
};
private:
size_t offset;
std::map<std::string, std::map<size_t, std::string>> to_replace;
};
} // namespace
ResourceReplacer::ResourceReplacer(
std::map<std::string, std::map<std::string, std::string>> const& dr_map,

View File

@ -508,29 +508,32 @@ QPDFFormFieldObjectHelper::generateAppearance(QPDFAnnotationObjectHelper& aoh)
}
}
class ValueSetter: public QPDFObjectHandle::TokenFilter
namespace
{
public:
ValueSetter(
std::string const& DA,
std::string const& V,
std::vector<std::string> const& opt,
double tf,
QPDFObjectHandle::Rectangle const& bbox);
virtual ~ValueSetter() = default;
virtual void handleToken(QPDFTokenizer::Token const&);
virtual void handleEOF();
void writeAppearance();
class ValueSetter: public QPDFObjectHandle::TokenFilter
{
public:
ValueSetter(
std::string const& DA,
std::string const& V,
std::vector<std::string> const& opt,
double tf,
QPDFObjectHandle::Rectangle const& bbox);
virtual ~ValueSetter() = default;
virtual void handleToken(QPDFTokenizer::Token const&);
virtual void handleEOF();
void writeAppearance();
private:
std::string DA;
std::string V;
std::vector<std::string> opt;
double tf;
QPDFObjectHandle::Rectangle bbox;
enum { st_top, st_bmc, st_emc, st_end } state;
bool replaced;
};
private:
std::string DA;
std::string V;
std::vector<std::string> opt;
double tf;
QPDFObjectHandle::Rectangle bbox;
enum { st_top, st_bmc, st_emc, st_end } state;
bool replaced;
};
} // namespace
ValueSetter::ValueSetter(
std::string const& DA,
@ -701,27 +704,30 @@ ValueSetter::writeAppearance()
write("ET\nQ\nEMC");
}
class TfFinder: public QPDFObjectHandle::TokenFilter
namespace
{
public:
TfFinder();
virtual ~TfFinder()
class TfFinder: public QPDFObjectHandle::TokenFilter
{
}
virtual void handleToken(QPDFTokenizer::Token const&);
double getTf();
std::string getFontName();
std::string getDA();
public:
TfFinder();
virtual ~TfFinder()
{
}
virtual void handleToken(QPDFTokenizer::Token const&);
double getTf();
std::string getFontName();
std::string getDA();
private:
double tf;
int tf_idx;
std::string font_name;
double last_num;
int last_num_idx;
std::string last_name;
std::vector<std::string> DA;
};
private:
double tf;
int tf_idx;
std::string font_name;
double last_num;
int last_num_idx;
std::string last_name;
std::vector<std::string> DA;
};
} // namespace
TfFinder::TfFinder() :
tf(11.0),

View File

@ -2,32 +2,35 @@
#include <qpdf/NNTree.hh>
class NameTreeDetails: public NNTreeDetails
namespace
{
public:
virtual std::string const&
itemsKey() const override
class NameTreeDetails: public NNTreeDetails
{
static std::string k("/Names");
return k;
}
virtual bool
keyValid(QPDFObjectHandle oh) const override
{
return oh.isString();
}
virtual int
compareKeys(QPDFObjectHandle a, QPDFObjectHandle b) const override
{
if (!(keyValid(a) && keyValid(b))) {
// We don't call this without calling keyValid first
throw std::logic_error("comparing invalid keys");
public:
virtual std::string const&
itemsKey() const override
{
static std::string k("/Names");
return k;
}
auto as = a.getUTF8Value();
auto bs = b.getUTF8Value();
return ((as < bs) ? -1 : (as > bs) ? 1 : 0);
}
};
virtual bool
keyValid(QPDFObjectHandle oh) const override
{
return oh.isString();
}
virtual int
compareKeys(QPDFObjectHandle a, QPDFObjectHandle b) const override
{
if (!(keyValid(a) && keyValid(b))) {
// We don't call this without calling keyValid first
throw std::logic_error("comparing invalid keys");
}
auto as = a.getUTF8Value();
auto bs = b.getUTF8Value();
return ((as < bs) ? -1 : (as > bs) ? 1 : 0);
}
};
} // namespace
static NameTreeDetails name_tree_details;

View File

@ -3,32 +3,35 @@
#include <qpdf/NNTree.hh>
#include <qpdf/QIntC.hh>
class NumberTreeDetails: public NNTreeDetails
namespace
{
public:
virtual std::string const&
itemsKey() const override
class NumberTreeDetails: public NNTreeDetails
{
static std::string k("/Nums");
return k;
}
virtual bool
keyValid(QPDFObjectHandle oh) const override
{
return oh.isInteger();
}
virtual int
compareKeys(QPDFObjectHandle a, QPDFObjectHandle b) const override
{
if (!(keyValid(a) && keyValid(b))) {
// We don't call this without calling keyValid first
throw std::logic_error("comparing invalid keys");
public:
virtual std::string const&
itemsKey() const override
{
static std::string k("/Nums");
return k;
}
auto as = a.getIntValue();
auto bs = b.getIntValue();
return ((as < bs) ? -1 : (as > bs) ? 1 : 0);
}
};
virtual bool
keyValid(QPDFObjectHandle oh) const override
{
return oh.isInteger();
}
virtual int
compareKeys(QPDFObjectHandle a, QPDFObjectHandle b) const override
{
if (!(keyValid(a) && keyValid(b))) {
// We don't call this without calling keyValid first
throw std::logic_error("comparing invalid keys");
}
auto as = a.getIntValue();
auto bs = b.getIntValue();
return ((as < bs) ? -1 : (as > bs) ? 1 : 0);
}
};
} // namespace
static NumberTreeDetails number_tree_details;

View File

@ -32,9 +32,12 @@
#include <stdexcept>
#include <stdlib.h>
class TerminateParsing
namespace
{
};
class TerminateParsing
{
};
} // namespace
QPDFObjectHandle::StreamDataProvider::StreamDataProvider(bool supports_retry) :
supports_retry(supports_retry)
@ -74,23 +77,26 @@ QPDFObjectHandle::StreamDataProvider::supportsRetry()
return this->supports_retry;
}
class CoalesceProvider: public QPDFObjectHandle::StreamDataProvider
namespace
{
public:
CoalesceProvider(
QPDFObjectHandle containing_page, QPDFObjectHandle old_contents) :
containing_page(containing_page),
old_contents(old_contents)
class CoalesceProvider: public QPDFObjectHandle::StreamDataProvider
{
}
virtual ~CoalesceProvider() = default;
virtual void
provideStreamData(int objid, int generation, Pipeline* pipeline);
public:
CoalesceProvider(
QPDFObjectHandle containing_page, QPDFObjectHandle old_contents) :
containing_page(containing_page),
old_contents(old_contents)
{
}
virtual ~CoalesceProvider() = default;
virtual void
provideStreamData(int objid, int generation, Pipeline* pipeline);
private:
QPDFObjectHandle containing_page;
QPDFObjectHandle old_contents;
};
private:
QPDFObjectHandle containing_page;
QPDFObjectHandle old_contents;
};
} // namespace
void
CoalesceProvider::provideStreamData(int, int, Pipeline* p)
@ -167,18 +173,21 @@ QPDFObjectHandle::ParserCallbacks::terminateParsing()
throw TerminateParsing();
}
class LastChar: public Pipeline
namespace
{
public:
LastChar(Pipeline* next);
virtual ~LastChar() = default;
virtual void write(unsigned char* data, size_t len);
virtual void finish();
unsigned char getLastChar();
class LastChar: public Pipeline
{
public:
LastChar(Pipeline* next);
virtual ~LastChar() = default;
virtual void write(unsigned char* data, size_t len);
virtual void finish();
unsigned char getLastChar();
private:
unsigned char last_char;
};
private:
unsigned char last_char;
};
} // namespace
LastChar::LastChar(Pipeline* next) :
Pipeline("lastchar", next),
@ -293,21 +302,24 @@ QPDFObjectHandle::getTypeName()
}
}
template <class T>
class QPDFObjectTypeAccessor
namespace
{
public:
static bool
check(QPDFObject* o)
template <class T>
class QPDFObjectTypeAccessor
{
return (o && dynamic_cast<T*>(o));
}
static bool
check(QPDFObject const* o)
{
return (o && dynamic_cast<T const*>(o));
}
};
public:
static bool
check(QPDFObject* o)
{
return (o && dynamic_cast<T*>(o));
}
static bool
check(QPDFObject const* o)
{
return (o && dynamic_cast<T const*>(o));
}
};
} // namespace
bool
QPDFObjectHandle::isBool()
@ -1435,40 +1447,46 @@ QPDFObjectHandle::replaceStreamData(
provider, filter, decode_parms);
}
class FunctionProvider: public QPDFObjectHandle::StreamDataProvider
namespace
{
public:
FunctionProvider(std::function<void(Pipeline*)> provider) :
StreamDataProvider(false),
p1(provider),
p2(nullptr)
class FunctionProvider: public QPDFObjectHandle::StreamDataProvider
{
}
FunctionProvider(std::function<bool(Pipeline*, bool, bool)> provider) :
StreamDataProvider(true),
p1(nullptr),
p2(provider)
{
}
public:
FunctionProvider(std::function<void(Pipeline*)> provider) :
StreamDataProvider(false),
p1(provider),
p2(nullptr)
{
}
FunctionProvider(std::function<bool(Pipeline*, bool, bool)> provider) :
StreamDataProvider(true),
p1(nullptr),
p2(provider)
{
}
virtual void
provideStreamData(int, int, Pipeline* pipeline) override
{
p1(pipeline);
}
virtual void
provideStreamData(int, int, Pipeline* pipeline) override
{
p1(pipeline);
}
virtual bool
provideStreamData(
int, int, Pipeline* pipeline, bool suppress_warnings, bool will_retry)
override
{
return p2(pipeline, suppress_warnings, will_retry);
}
virtual bool
provideStreamData(
int,
int,
Pipeline* pipeline,
bool suppress_warnings,
bool will_retry) override
{
return p2(pipeline, suppress_warnings, will_retry);
}
private:
std::function<void(Pipeline*)> p1;
std::function<bool(Pipeline*, bool, bool)> p2;
};
private:
std::function<void(Pipeline*)> p1;
std::function<bool(Pipeline*, bool, bool)> p2;
};
} // namespace
void
QPDFObjectHandle::replaceStreamData(

View File

@ -11,20 +11,23 @@
#include <qpdf/QUtil.hh>
#include <qpdf/ResourceFinder.hh>
class ContentProvider: public QPDFObjectHandle::StreamDataProvider
namespace
{
public:
ContentProvider(QPDFObjectHandle from_page) :
from_page(from_page)
class ContentProvider: public QPDFObjectHandle::StreamDataProvider
{
}
virtual ~ContentProvider() = default;
virtual void
provideStreamData(int objid, int generation, Pipeline* pipeline);
public:
ContentProvider(QPDFObjectHandle from_page) :
from_page(from_page)
{
}
virtual ~ContentProvider() = default;
virtual void
provideStreamData(int objid, int generation, Pipeline* pipeline);
private:
QPDFObjectHandle from_page;
};
private:
QPDFObjectHandle from_page;
};
} // namespace
void
ContentProvider::provideStreamData(int, int, Pipeline* p)
@ -39,23 +42,26 @@ ContentProvider::provideStreamData(int, int, Pipeline* p)
concat.manualFinish();
}
class InlineImageTracker: public QPDFObjectHandle::TokenFilter
namespace
{
public:
InlineImageTracker(QPDF*, size_t min_size, QPDFObjectHandle resources);
virtual ~InlineImageTracker() = default;
virtual void handleToken(QPDFTokenizer::Token const&);
QPDFObjectHandle convertIIDict(QPDFObjectHandle odict);
class InlineImageTracker: public QPDFObjectHandle::TokenFilter
{
public:
InlineImageTracker(QPDF*, size_t min_size, QPDFObjectHandle resources);
virtual ~InlineImageTracker() = default;
virtual void handleToken(QPDFTokenizer::Token const&);
QPDFObjectHandle convertIIDict(QPDFObjectHandle odict);
QPDF* qpdf;
size_t min_size;
QPDFObjectHandle resources;
std::string dict_str;
std::string bi_str;
int min_suffix;
bool any_images;
enum { st_top, st_bi } state;
};
QPDF* qpdf;
size_t min_size;
QPDFObjectHandle resources;
std::string dict_str;
std::string bi_str;
int min_suffix;
bool any_images;
enum { st_top, st_bi } state;
};
} // namespace
InlineImageTracker::InlineImageTracker(
QPDF* qpdf, size_t min_size, QPDFObjectHandle resources) :

View File

@ -20,22 +20,25 @@ is_delimiter(char ch)
return (strchr(" \t\n\v\f\r()<>[]{}/%", ch) != 0);
}
class QPDFWordTokenFinder: public InputSource::Finder
namespace
{
public:
QPDFWordTokenFinder(
std::shared_ptr<InputSource> is, std::string const& str) :
is(is),
str(str)
class QPDFWordTokenFinder: public InputSource::Finder
{
}
virtual ~QPDFWordTokenFinder() = default;
virtual bool check();
public:
QPDFWordTokenFinder(
std::shared_ptr<InputSource> is, std::string const& str) :
is(is),
str(str)
{
}
virtual ~QPDFWordTokenFinder() = default;
virtual bool check();
private:
std::shared_ptr<InputSource> is;
std::string str;
};
private:
std::shared_ptr<InputSource> is;
std::string str;
};
} // namespace
bool
QPDFWordTokenFinder::check()

View File

@ -19,38 +19,42 @@
#include <stdexcept>
class SF_Crypt: public QPDFStreamFilter
namespace
{
public:
SF_Crypt() = default;
virtual ~SF_Crypt() = default;
virtual bool
setDecodeParms(QPDFObjectHandle decode_parms)
class SF_Crypt: public QPDFStreamFilter
{
if (decode_parms.isNull()) {
return true;
}
bool filterable = true;
for (auto const& key : decode_parms.getKeys()) {
if (((key == "/Type") || (key == "/Name")) &&
((!decode_parms.hasKey("/Type")) ||
decode_parms.isDictionaryOfType("/CryptFilterDecodeParms"))) {
// we handle this in decryptStream
} else {
filterable = false;
public:
SF_Crypt() = default;
virtual ~SF_Crypt() = default;
virtual bool
setDecodeParms(QPDFObjectHandle decode_parms)
{
if (decode_parms.isNull()) {
return true;
}
bool filterable = true;
for (auto const& key : decode_parms.getKeys()) {
if (((key == "/Type") || (key == "/Name")) &&
((!decode_parms.hasKey("/Type")) ||
decode_parms.isDictionaryOfType(
"/CryptFilterDecodeParms"))) {
// we handle this in decryptStream
} else {
filterable = false;
}
}
return filterable;
}
return filterable;
}
virtual Pipeline*
getDecodePipeline(Pipeline*)
{
// Not used -- handled by pipeStreamData
return nullptr;
}
};
virtual Pipeline*
getDecodePipeline(Pipeline*)
{
// Not used -- handled by pipeStreamData
return nullptr;
}
};
} // namespace
std::map<std::string, std::string> QPDF_Stream::filter_abbreviations = {
// The PDF specification provides these filter abbreviations for

View File

@ -251,22 +251,25 @@ static unsigned short mac_roman_to_unicode[] = {
0x02c7, // 0xff
};
class FileCloser
namespace
{
public:
FileCloser(FILE* f) :
f(f)
class FileCloser
{
}
public:
FileCloser(FILE* f) :
f(f)
{
}
~FileCloser()
{
fclose(f);
}
~FileCloser()
{
fclose(f);
}
private:
FILE* f;
};
private:
FILE* f;
};
} // namespace
template <typename T>
static std::string
@ -1052,17 +1055,20 @@ QUtil::toUTF16(unsigned long uval)
// Random data support
class RandomDataProviderProvider
namespace
{
public:
RandomDataProviderProvider();
void setProvider(RandomDataProvider*);
RandomDataProvider* getProvider();
class RandomDataProviderProvider
{
public:
RandomDataProviderProvider();
void setProvider(RandomDataProvider*);
RandomDataProvider* getProvider();
private:
RandomDataProvider* default_provider;
RandomDataProvider* current_provider;
};
private:
RandomDataProvider* default_provider;
RandomDataProvider* current_provider;
};
} // namespace
RandomDataProviderProvider::RandomDataProviderProvider() :
default_provider(CryptoRandomDataProvider::getInstance()),

View File

@ -31,47 +31,54 @@ SecureRandomDataProvider::getInstance()
# ifdef _WIN32
class WindowsCryptProvider
namespace
{
public:
WindowsCryptProvider()
class WindowsCryptProvider
{
if (!CryptAcquireContextW(
&crypt_prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
throw std::runtime_error(
"unable to acquire crypt context: " + getErrorMessage());
public:
WindowsCryptProvider()
{
if (!CryptAcquireContextW(
&crypt_prov,
NULL,
NULL,
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT)) {
throw std::runtime_error(
"unable to acquire crypt context: " + getErrorMessage());
}
}
~WindowsCryptProvider()
{
// Ignore error
CryptReleaseContext(crypt_prov, 0);
}
}
~WindowsCryptProvider()
{
// Ignore error
CryptReleaseContext(crypt_prov, 0);
}
HCRYPTPROV crypt_prov;
HCRYPTPROV crypt_prov;
private:
std::string
getErrorMessage()
{
DWORD errorMessageID = ::GetLastError();
LPSTR messageBuffer = nullptr;
size_t size = FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
errorMessageID,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<LPSTR>(&messageBuffer),
0,
NULL);
std::string message(messageBuffer, size);
LocalFree(messageBuffer);
return (
"error number " + QUtil::int_to_string_base(errorMessageID, 16) +
": " + message);
}
};
private:
std::string
getErrorMessage()
{
DWORD errorMessageID = ::GetLastError();
LPSTR messageBuffer = nullptr;
size_t size = FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
errorMessageID,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<LPSTR>(&messageBuffer),
0,
NULL);
std::string message(messageBuffer, size);
LocalFree(messageBuffer);
return (
"error number " +
QUtil::int_to_string_base(errorMessageID, 16) + ": " + message);
}
};
} // namespace
# endif
void

View File

@ -60,17 +60,20 @@ _qpdf_data::_qpdf_data() :
{
}
class ProgressReporter: public QPDFWriter::ProgressReporter
namespace
{
public:
ProgressReporter(void (*handler)(int, void*), void* data);
virtual ~ProgressReporter() = default;
virtual void reportProgress(int);
class ProgressReporter: public QPDFWriter::ProgressReporter
{
public:
ProgressReporter(void (*handler)(int, void*), void* data);
virtual ~ProgressReporter() = default;
virtual void reportProgress(int);
private:
void (*handler)(int, void*);
void* data;
};
private:
void (*handler)(int, void*);
void* data;
};
} // namespace
ProgressReporter::ProgressReporter(void (*handler)(int, void*), void* data) :
handler(handler),