aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--TODO3
-rw-r--r--examples/pdf-attach-file.cc20
-rw-r--r--examples/pdf-create.cc29
-rw-r--r--examples/pdf-overlay-page.cc3
-rw-r--r--include/qpdf/QPDFObjectHandle.hh13
-rw-r--r--libqpdf/QPDFFormFieldObjectHelper.cc3
-rw-r--r--libqpdf/QPDFJob.cc3
-rw-r--r--libqpdf/QPDFNameTreeObjectHelper.cc3
-rw-r--r--libqpdf/QPDFNumberTreeObjectHelper.cc3
-rw-r--r--libqpdf/QPDFObjectHandle.cc7
-rw-r--r--libqpdf/QPDFPageDocumentHelper.cc3
-rw-r--r--libqpdf/QPDFPageObjectHelper.cc3
-rw-r--r--qpdf/test_driver.cc6
14 files changed, 57 insertions, 48 deletions
diff --git a/ChangeLog b/ChangeLog
index 7b40e1c7..7dd3dead 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2022-02-05 Jay Berkenbilt <ejb@ql.org>
+ * Add a global user-defined string literal "_qpdf" as a shorthand
+ for QPDFObjectHandle::parse, allowing you to create
+ QPDFObjectHandle objects with
+
+ QPDFObjectHandle oh = "<</Some (PDF)>>"_qpdf;
+
* Expose QPDF::emptyPDF to the C API as qpdf_empty_pdf()
* Add comments letting people know that the version string
diff --git a/TODO b/TODO
index 9bbaecc7..26d7ebc8 100644
--- a/TODO
+++ b/TODO
@@ -11,9 +11,6 @@
* QPDFObjectHandle: getValueAsX methods, getKeyIfDict. Plus C API.
-* Add user-defined initializer `QPDFObjectHandle operator ""_qpdf` to
- be like QPDFObjectHandle::parse: `auto oh = "<< /a (b) >>"_qpdf;`
-
* See if this has been done or is trivial with C++11 local static
initializers: Secure random number generation could be made more
efficient by using a local static to ensure a single random device
diff --git a/examples/pdf-attach-file.cc b/examples/pdf-attach-file.cc
index 0c046000..decc742f 100644
--- a/examples/pdf-attach-file.cc
+++ b/examples/pdf-attach-file.cc
@@ -36,16 +36,16 @@ static void process(char const* infilename, char const* password,
QPDF q;
q.processFile(infilename, password);
- // Create an indirect object for the built-in Helvetica font.
+ // Create an indirect object for the built-in Helvetica font. This
+ // uses the qpdf literal syntax introduced in qpdf 10.6.
auto f1 = q.makeIndirectObject(
- QPDFObjectHandle::parse(
- "<<"
- " /Type /Font"
- " /Subtype /Type1"
- " /Name /F1"
- " /BaseFont /Helvetica"
- " /Encoding /WinAnsiEncoding"
- ">>"));
+ "<<"
+ " /Type /Font"
+ " /Subtype /Type1"
+ " /Name /F1"
+ " /BaseFont /Helvetica"
+ " /Encoding /WinAnsiEncoding"
+ ">>"_qpdf);
// Create a resources dictionary with fonts. This uses the new
// parse introduced in qpdf 10.2 that takes a QPDF* and allows
@@ -93,7 +93,7 @@ static void process(char const* infilename, char const* password,
apdict.replaceKey("/Resources", QPDFObjectHandle::newDictionary());
apdict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject"));
apdict.replaceKey("/Subtype", QPDFObjectHandle::newName("/Form"));
- apdict.replaceKey("/BBox", QPDFObjectHandle::parse("[ 0 0 20 20 ]"));
+ apdict.replaceKey("/BBox", "[ 0 0 20 20 ]"_qpdf);
auto annot = q.makeIndirectObject(
QPDFObjectHandle::parse(
&q,
diff --git a/examples/pdf-create.cc b/examples/pdf-create.cc
index 52f02a0d..8d1e8ee6 100644
--- a/examples/pdf-create.cc
+++ b/examples/pdf-create.cc
@@ -182,12 +182,11 @@ void add_page(QPDFPageDocumentHelper& dh, QPDFObjectHandle font,
size_t width = p->getWidth();
size_t height = p->getHeight();
QPDFObjectHandle image = QPDFObjectHandle::newStream(&pdf);
- image.replaceDict(QPDFObjectHandle::parse(
- "<<"
- " /Type /XObject"
- " /Subtype /Image"
- " /BitsPerComponent 8"
- ">>"));
+ image.replaceDict("<<"
+ " /Type /XObject"
+ " /Subtype /Image"
+ " /BitsPerComponent 8"
+ ">>"_qpdf);
QPDFObjectHandle image_dict = image.getDict();
image_dict.replaceKey("/ColorSpace", newName(color_space));
image_dict.replaceKey("/Width", newInteger(width));
@@ -199,8 +198,7 @@ void add_page(QPDFPageDocumentHelper& dh, QPDFObjectHandle font,
QPDFObjectHandle::newNull());
// Create direct objects as needed by the page dictionary.
- QPDFObjectHandle procset = QPDFObjectHandle::parse(
- "[/PDF /Text /ImageC]");
+ QPDFObjectHandle procset = "[/PDF /Text /ImageC]"_qpdf;
QPDFObjectHandle rfont = QPDFObjectHandle::newDictionary();
rfont.replaceKey("/F1", font);
@@ -384,14 +382,13 @@ static void create_pdf(char const* filename)
// Add an indirect object to contain a font descriptor for the
// built-in Helvetica font.
QPDFObjectHandle font = pdf.makeIndirectObject(
- QPDFObjectHandle::parse(
- "<<"
- " /Type /Font"
- " /Subtype /Type1"
- " /Name /F1"
- " /BaseFont /Helvetica"
- " /Encoding /WinAnsiEncoding"
- ">>"));
+ "<<"
+ " /Type /Font"
+ " /Subtype /Type1"
+ " /Name /F1"
+ " /BaseFont /Helvetica"
+ " /Encoding /WinAnsiEncoding"
+ ">>"_qpdf);
std::vector<std::string> color_spaces;
color_spaces.push_back("/DeviceCMYK");
diff --git a/examples/pdf-overlay-page.cc b/examples/pdf-overlay-page.cc
index 1e06c40c..7b8888e4 100644
--- a/examples/pdf-overlay-page.cc
+++ b/examples/pdf-overlay-page.cc
@@ -65,8 +65,7 @@ static void stamp_page(char const* infile,
// Append the content to the page's content. Surround the
// original content with q...Q to the new content from the
// page's original content.
- resources.mergeResources(
- QPDFObjectHandle::parse("<< /XObject << >> >>"));
+ resources.mergeResources("<< /XObject << >> >>"_qpdf);
resources.getKey("/XObject").replaceKey(name, stamp_fo);
ph.addPageContents(
QPDFObjectHandle::newStream(&inpdf, "q\n"), true);
diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh
index 855c14c2..03d7cb0d 100644
--- a/include/qpdf/QPDFObjectHandle.hh
+++ b/include/qpdf/QPDFObjectHandle.hh
@@ -395,7 +395,7 @@ class QPDFObjectHandle
// object syntax (obj gen R) will cause a logic_error exception to
// be thrown. If object_description is provided, it will appear
// in the message of any QPDFExc exception thrown for invalid
- // syntax.
+ // syntax. See also the global `operator ""_qpdf` defined below.
QPDF_DLL
static QPDFObjectHandle parse(std::string const& object_str,
std::string const& object_description = "");
@@ -1450,6 +1450,17 @@ class QPDFObjectHandle
bool reserved;
};
+#ifndef QPDF_NO_QPDF_STRING
+// This is short for QPDFObjectHandle::parse, so you can do
+
+// auto oh = "<< /Key (value) >>"_qpdf;
+
+// If this is causing problems in your code, define
+// QPDF_NO_QPDF_STRING to prevent the declaration from being here.
+QPDF_DLL
+QPDFObjectHandle operator ""_qpdf(char const* v, size_t len);
+#endif // QPDF_NO_QPDF_STRING
+
class QPDFObjectHandle::QPDFDictItems
{
// This class allows C++-style iteration, including range-for
diff --git a/libqpdf/QPDFFormFieldObjectHelper.cc b/libqpdf/QPDFFormFieldObjectHelper.cc
index d6d8f562..2702ebcf 100644
--- a/libqpdf/QPDFFormFieldObjectHelper.cc
+++ b/libqpdf/QPDFFormFieldObjectHelper.cc
@@ -981,8 +981,7 @@ QPDFFormFieldObjectHelper::generateTextAppearance(
AS.getDict().replaceKey("/Resources", resources);
}
// Use mergeResources to force /Font to be local
- resources.mergeResources(
- QPDFObjectHandle::parse("<< /Font << >> >>"));
+ resources.mergeResources("<< /Font << >> >>"_qpdf);
resources.getKey("/Font").replaceKey(font_name, font);
}
diff --git a/libqpdf/QPDFJob.cc b/libqpdf/QPDFJob.cc
index 646692d5..362db7c2 100644
--- a/libqpdf/QPDFJob.cc
+++ b/libqpdf/QPDFJob.cc
@@ -2281,8 +2281,7 @@ QPDFJob::doUnderOverlayForPage(
from_page, cm, dest_afdh, make_afdh(from_page));
if (! new_content.empty())
{
- resources.mergeResources(
- QPDFObjectHandle::parse("<< /XObject << >> >>"));
+ resources.mergeResources("<< /XObject << >> >>"_qpdf);
auto xobject = resources.getKey("/XObject");
if (xobject.isDictionary())
{
diff --git a/libqpdf/QPDFNameTreeObjectHelper.cc b/libqpdf/QPDFNameTreeObjectHelper.cc
index d39a8d86..861e01aa 100644
--- a/libqpdf/QPDFNameTreeObjectHelper.cc
+++ b/libqpdf/QPDFNameTreeObjectHelper.cc
@@ -61,8 +61,7 @@ QPDFNameTreeObjectHelper
QPDFNameTreeObjectHelper::newEmpty(QPDF& qpdf, bool auto_repair)
{
return QPDFNameTreeObjectHelper(
- qpdf.makeIndirectObject(
- QPDFObjectHandle::parse("<< /Names [] >>")), qpdf, auto_repair);
+ qpdf.makeIndirectObject("<< /Names [] >>"_qpdf), qpdf, auto_repair);
}
QPDFNameTreeObjectHelper::iterator::iterator(
diff --git a/libqpdf/QPDFNumberTreeObjectHelper.cc b/libqpdf/QPDFNumberTreeObjectHelper.cc
index a8dba0ef..0f61874d 100644
--- a/libqpdf/QPDFNumberTreeObjectHelper.cc
+++ b/libqpdf/QPDFNumberTreeObjectHelper.cc
@@ -58,8 +58,7 @@ QPDFNumberTreeObjectHelper
QPDFNumberTreeObjectHelper::newEmpty(QPDF& qpdf, bool auto_repair)
{
return QPDFNumberTreeObjectHelper(
- qpdf.makeIndirectObject(
- QPDFObjectHandle::parse("<< /Nums [] >>")), qpdf, auto_repair);
+ qpdf.makeIndirectObject("<< /Nums [] >>"_qpdf), qpdf, auto_repair);
}
QPDFNumberTreeObjectHelper::iterator::iterator(
diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc
index d754448f..2e9bf48b 100644
--- a/libqpdf/QPDFObjectHandle.cc
+++ b/libqpdf/QPDFObjectHandle.cc
@@ -3666,3 +3666,10 @@ QPDFObjectHandle::QPDFArrayItems::end()
{
return iterator(oh, false);
}
+
+QPDFObjectHandle
+operator ""_qpdf(char const* v, size_t len)
+{
+ return QPDFObjectHandle::parse(
+ std::string(v, len), "QPDFObjectHandle literal");
+}
diff --git a/libqpdf/QPDFPageDocumentHelper.cc b/libqpdf/QPDFPageDocumentHelper.cc
index ab9875a9..e76c874f 100644
--- a/libqpdf/QPDFPageDocumentHelper.cc
+++ b/libqpdf/QPDFPageDocumentHelper.cc
@@ -161,8 +161,7 @@ QPDFPageDocumentHelper::flattenAnnotationsForPage(
name, rotate, required_flags, forbidden_flags);
if (! content.empty())
{
- resources.mergeResources(
- QPDFObjectHandle::parse("<< /XObject << >> >>"));
+ resources.mergeResources("<< /XObject << >> >>"_qpdf);
resources.getKey("/XObject").replaceKey(name, as);
++next_fx;
}
diff --git a/libqpdf/QPDFPageObjectHelper.cc b/libqpdf/QPDFPageObjectHelper.cc
index 0dd6d894..ab806c7f 100644
--- a/libqpdf/QPDFPageObjectHelper.cc
+++ b/libqpdf/QPDFPageObjectHelper.cc
@@ -500,8 +500,7 @@ QPDFPageObjectHelper::externalizeInlineImages(size_t min_size, bool shallow)
QPDFObjectHandle resources = getAttribute("/Resources", true);
// Calling mergeResources also ensures that /XObject becomes
// direct and is not shared with other pages.
- resources.mergeResources(
- QPDFObjectHandle::parse("<< /XObject << >> >>"));
+ resources.mergeResources("<< /XObject << >> >>"_qpdf);
InlineImageTracker iit(this->oh.getOwningQPDF(), min_size, resources);
Pl_Buffer b("new page content");
bool filtered = false;
diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc
index 8d28184b..2031313a 100644
--- a/qpdf/test_driver.cc
+++ b/qpdf/test_driver.cc
@@ -1255,10 +1255,8 @@ static void test_31(QPDF& pdf, char const* arg2)
{
// Test object parsing from a string. The input file is not used.
- QPDFObjectHandle o1 =
- QPDFObjectHandle::parse(
- "[/name 16059 3.14159 false\n"
- " << /key true /other [ (string1) (string2) ] >> null]");
+ auto o1 = "[/name 16059 3.14159 false\n"
+ " << /key true /other [ (string1) (string2) ] >> null]"_qpdf;
std::cout << o1.unparse() << std::endl;
QPDFObjectHandle o2 = QPDFObjectHandle::parse(" 12345 \f ");
assert(o2.isInteger() && (o2.getIntValue() == 12345));