aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/qpdf/QPDFObjectHandle.hh25
-rw-r--r--libqpdf/QPDFObjectHandle.cc132
-rw-r--r--qpdf/qtest/qpdf.test6
-rw-r--r--qpdf/test_driver.cc97
4 files changed, 257 insertions, 3 deletions
diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh
index c632574e..855c14c2 100644
--- a/include/qpdf/QPDFObjectHandle.hh
+++ b/include/qpdf/QPDFObjectHandle.hh
@@ -678,6 +678,8 @@ class QPDFObjectHandle
// Methods for bool objects
QPDF_DLL
bool getBoolValue();
+ QPDF_DLL
+ bool getValueAsBool(bool&);
// Methods for integer objects. Note: if an integer value is too
// big (too far away from zero in either direction) to fit in the
@@ -688,29 +690,46 @@ class QPDFObjectHandle
QPDF_DLL
long long getIntValue();
QPDF_DLL
+ bool getValueAsInt(long long&);
+ QPDF_DLL
int getIntValueAsInt();
QPDF_DLL
+ bool getValueAsInt(int&);
+ QPDF_DLL
unsigned long long getUIntValue();
QPDF_DLL
+ bool getValueAsUInt(unsigned long long&);
+ QPDF_DLL
unsigned int getUIntValueAsUInt();
+ QPDF_DLL
+ bool getValueAsUInt(unsigned int&);
// Methods for real objects
QPDF_DLL
std::string getRealValue();
+ QPDF_DLL
+ bool getValueAsReal(std::string&);
// Methods that work for both integer and real objects
QPDF_DLL
bool isNumber();
QPDF_DLL
double getNumericValue();
+ QPDF_DLL
+ bool getValueAsNumber(double&);
// Methods for name objects; see also name and array objects
QPDF_DLL
std::string getName();
+ QPDF_DLL
+ bool getValueAsName(std::string&);
// Methods for string objects
QPDF_DLL
std::string getStringValue();
+ QPDF_DLL
+ bool getValueAsString(std::string&);
+
// If a string starts with the UTF-16 marker, it is converted from
// UTF-16 to UTF-8. Otherwise, it is treated as a string encoded
// with PDF Doc Encoding. PDF Doc Encoding is identical to
@@ -720,12 +739,18 @@ class QPDFObjectHandle
// unmapped.
QPDF_DLL
std::string getUTF8Value();
+ QPDF_DLL
+ bool getValueAsUTF8(std::string&);
// Methods for content stream objects
QPDF_DLL
std::string getOperatorValue();
QPDF_DLL
+ bool getValueAsOperator(std::string&);
+ QPDF_DLL
std::string getInlineImageValue();
+ QPDF_DLL
+ bool getValueAsInlineImage(std::string&);
// Methods for array objects; see also name and array objects.
diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc
index 0bcd816b..d754448f 100644
--- a/libqpdf/QPDFObjectHandle.cc
+++ b/libqpdf/QPDFObjectHandle.cc
@@ -392,6 +392,17 @@ QPDFObjectHandle::getNumericValue()
}
bool
+QPDFObjectHandle::getValueAsNumber(double& value)
+{
+ if (! isNumber())
+ {
+ return false;
+ }
+ value = getNumericValue();
+ return true;
+}
+
+bool
QPDFObjectHandle::isName()
{
if (! this->initialized)
@@ -536,6 +547,17 @@ QPDFObjectHandle::getBoolValue()
}
}
+bool
+QPDFObjectHandle::getValueAsBool(bool& value)
+{
+ if (! isBool())
+ {
+ return false;
+ }
+ value = dynamic_cast<QPDF_Bool*>(obj.get())->getVal();
+ return true;
+}
+
// Integer accessors
long long
@@ -553,6 +575,17 @@ QPDFObjectHandle::getIntValue()
}
}
+bool
+QPDFObjectHandle::getValueAsInt(long long& value)
+{
+ if (! isInteger())
+ {
+ return false;
+ }
+ value = dynamic_cast<QPDF_Integer*>(obj.get())->getVal();
+ return true;
+}
+
int
QPDFObjectHandle::getIntValueAsInt()
{
@@ -581,6 +614,17 @@ QPDFObjectHandle::getIntValueAsInt()
return result;
}
+bool
+QPDFObjectHandle::getValueAsInt(int& value)
+{
+ if (! isInteger())
+ {
+ return false;
+ }
+ value = getIntValueAsInt();
+ return true;
+}
+
unsigned long long
QPDFObjectHandle::getUIntValue()
{
@@ -600,6 +644,17 @@ QPDFObjectHandle::getUIntValue()
return result;
}
+bool
+QPDFObjectHandle::getValueAsUInt(unsigned long long& value)
+{
+ if (! isInteger())
+ {
+ return false;
+ }
+ value = getUIntValue();
+ return true;
+}
+
unsigned int
QPDFObjectHandle::getUIntValueAsUInt()
{
@@ -629,6 +684,17 @@ QPDFObjectHandle::getUIntValueAsUInt()
return result;
}
+bool
+QPDFObjectHandle::getValueAsUInt(unsigned int& value)
+{
+ if (! isInteger())
+ {
+ return false;
+ }
+ value = getUIntValueAsUInt();
+ return true;
+}
+
// Real accessors
std::string
@@ -646,6 +712,17 @@ QPDFObjectHandle::getRealValue()
}
}
+bool
+QPDFObjectHandle::getValueAsReal(std::string& value)
+{
+ if (! isReal())
+ {
+ return false;
+ }
+ value = dynamic_cast<QPDF_Real*>(obj.get())->getVal();
+ return true;
+}
+
// Name accessors
std::string
@@ -663,6 +740,17 @@ QPDFObjectHandle::getName()
}
}
+bool
+QPDFObjectHandle::getValueAsName(std::string& value)
+{
+ if (! isName())
+ {
+ return false;
+ }
+ value = dynamic_cast<QPDF_Name*>(obj.get())->getName();
+ return true;
+}
+
// String accessors
std::string
@@ -680,6 +768,17 @@ QPDFObjectHandle::getStringValue()
}
}
+bool
+QPDFObjectHandle::getValueAsString(std::string& value)
+{
+ if (! isString())
+ {
+ return false;
+ }
+ value = dynamic_cast<QPDF_String*>(obj.get())->getVal();
+ return true;
+}
+
std::string
QPDFObjectHandle::getUTF8Value()
{
@@ -695,6 +794,17 @@ QPDFObjectHandle::getUTF8Value()
}
}
+bool
+QPDFObjectHandle::getValueAsUTF8(std::string& value)
+{
+ if (! isString())
+ {
+ return false;
+ }
+ value = dynamic_cast<QPDF_String*>(obj.get())->getUTF8Val();
+ return true;
+}
+
// Operator and Inline Image accessors
std::string
@@ -712,6 +822,17 @@ QPDFObjectHandle::getOperatorValue()
}
}
+bool
+QPDFObjectHandle::getValueAsOperator(std::string& value)
+{
+ if (! isOperator())
+ {
+ return false;
+ }
+ value = dynamic_cast<QPDF_Operator*>(obj.get())->getVal();
+ return true;
+}
+
std::string
QPDFObjectHandle::getInlineImageValue()
{
@@ -727,6 +848,17 @@ QPDFObjectHandle::getInlineImageValue()
}
}
+bool
+QPDFObjectHandle::getValueAsInlineImage(std::string& value)
+{
+ if (! isInlineImage())
+ {
+ return false;
+ }
+ value = dynamic_cast<QPDF_InlineImage*>(obj.get())->getVal();
+ return true;
+}
+
// Array accessors
QPDFObjectHandle::QPDFArrayItems
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index 58d4102f..bf386168 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -3285,7 +3285,7 @@ my @badfiles = ("not a PDF file", # 1
"startxref to space then eof", # 38
);
-$n_tests += @badfiles + 7;
+$n_tests += @badfiles + 8;
# Test 6 contains errors in the free table consistency, but we no
# longer have any consistency check for this since it is not important
@@ -3341,6 +3341,10 @@ $td->runtest("integer type checks",
{$td->COMMAND => "test_driver 62 minimal.pdf"},
{$td->STRING => "test 62 done\n", $td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
+$td->runtest("getValueAs... accessor checks",
+ {$td->COMMAND => "test_driver 85 -"},
+ {$td->STRING => "test 85 done\n", $td->EXIT_STATUS => 0},
+ $td->NORMALIZE_NEWLINES);
show_ntests();
# ----------
diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc
index 6381d731..8d28184b 100644
--- a/qpdf/test_driver.cc
+++ b/qpdf/test_driver.cc
@@ -3220,6 +3220,99 @@ static void test_84(QPDF& pdf, char const* arg2)
}
}
+static void test_85(QPDF& pdf, char const* arg2)
+{
+ // Test QPDFObjectHandle::getValueAs... accessors
+
+ auto oh_b = QPDFObjectHandle::newBool(false);
+ auto oh_i = QPDFObjectHandle::newInteger(1);
+ auto oh_i_maxplus =
+ QPDFObjectHandle::newInteger(QIntC::to_longlong(INT_MAX) + 1LL);
+ auto oh_i_umaxplus =
+ QPDFObjectHandle::newInteger(QIntC::to_longlong(UINT_MAX) + 1LL);
+ auto oh_i_minminus =
+ QPDFObjectHandle::newInteger(QIntC::to_longlong(INT_MIN) - 1LL);
+ auto oh_i_neg = QPDFObjectHandle::newInteger(-1);
+ auto oh_r = QPDFObjectHandle::newReal("42.0");
+ auto oh_n = QPDFObjectHandle::newName("/Test");
+ auto oh_s = QPDFObjectHandle::newString("/Test");
+ auto oh_o = QPDFObjectHandle::newOperator("/Test");
+ auto oh_ii = QPDFObjectHandle::newInlineImage("/Test");
+
+ bool b = true;
+ assert(oh_b.getValueAsBool(b));
+ assert(! b);
+ assert(! oh_i.getValueAsBool(b));
+ assert(! b);
+ long long li = 0LL;
+ assert(oh_i.getValueAsInt(li));
+ assert(li == 1LL);
+ assert(! oh_b.getValueAsInt(li));
+ assert(li == 1LL);
+ int i = 0;
+ assert(oh_i.getValueAsInt(i));
+ assert(i == 1);
+ assert(! oh_b.getValueAsInt(i));
+ assert(i == 1);
+ assert(oh_i_maxplus.getValueAsInt(i));
+ assert(i == INT_MAX);
+ assert(oh_i_minminus.getValueAsInt(i));
+ assert(i == INT_MIN);
+ unsigned long long uli = 0U;
+ assert(oh_i.getValueAsUInt(uli));
+ assert(uli == 1u);
+ assert(! oh_b.getValueAsUInt(uli));
+ assert(uli == 1u);
+ assert(oh_i_neg.getValueAsUInt(uli));
+ assert(uli == 0u);
+ unsigned int ui = 0U;
+ assert(oh_i.getValueAsUInt(ui));
+ assert(ui == 1u);
+ assert(! oh_b.getValueAsUInt(ui));
+ assert(ui == 1u);
+ assert(oh_i_neg.getValueAsUInt(ui));
+ assert(ui == 0u);
+ assert(oh_i_umaxplus.getValueAsUInt(ui));
+ assert(ui == UINT_MAX);
+ std::string s = "0";
+ assert(oh_r.getValueAsReal(s));
+ assert(s == "42.0");
+ assert(! oh_i.getValueAsReal(s));
+ assert(s == "42.0");
+ double num = 0.0;
+ assert(oh_i.getValueAsNumber(num));
+ assert(abs(num - 1.0) < 1e-100);
+ assert(oh_r.getValueAsNumber(num));
+ assert(abs(num - 42.0) < 1e-100);
+ assert(! oh_b.getValueAsNumber(num));
+ assert(abs(num - 42.0) < 1e-100);
+ s = "";
+ assert(oh_n.getValueAsName(s));
+ assert(s == "/Test") ;
+ assert(! oh_r.getValueAsName(s));
+ assert(s == "/Test");
+ s = "";
+ assert(oh_s.getValueAsUTF8(s));
+ assert(s == "/Test");
+ assert(! oh_r.getValueAsUTF8(s));
+ assert(s == "/Test");
+ s = "";
+ assert(oh_s.getValueAsUTF8(s));
+ assert(s == "/Test");
+ assert(! oh_r.getValueAsUTF8(s));
+ assert(s == "/Test");
+ s = "";
+ assert(oh_o.getValueAsOperator(s));
+ assert(s == "/Test");
+ assert(! oh_r.getValueAsOperator(s));
+ assert(s == "/Test");
+ s = "";
+ assert(oh_ii.getValueAsInlineImage(s));
+ assert(s == "/Test");
+ assert(! oh_r.getValueAsInlineImage(s));
+ assert(s == "/Test");
+}
+
void runtest(int n, char const* filename1, char const* arg2)
{
// Most tests here are crafted to work on specific files. Look at
@@ -3286,7 +3379,7 @@ void runtest(int n, char const* filename1, char const* arg2)
pdf.processMemoryFile((std::string(filename1) + ".pdf").c_str(),
p, size);
}
- else if ((n == 61) || (n == 81) || (n == 83) || (n == 84))
+ else if ((n == 61) || (n == 81) || (n == 83) || (n == 84) || (n == 85))
{
// Ignore filename argument entirely
}
@@ -3334,7 +3427,7 @@ void runtest(int n, char const* filename1, char const* arg2)
{72, test_72}, {73, test_73}, {74, test_74}, {75, test_75},
{76, test_76}, {77, test_77}, {78, test_78}, {79, test_79},
{80, test_80}, {81, test_81}, {82, test_82}, {83, test_83},
- {84, test_84},
+ {84, test_84}, {85, test_85},
};
auto fn = test_functions.find(n);