aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/QPDF_json.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libqpdf/QPDF_json.cc')
-rw-r--r--libqpdf/QPDF_json.cc168
1 files changed, 71 insertions, 97 deletions
diff --git a/libqpdf/QPDF_json.cc b/libqpdf/QPDF_json.cc
index 8326e6a5..b06b70c9 100644
--- a/libqpdf/QPDF_json.cc
+++ b/libqpdf/QPDF_json.cc
@@ -1,12 +1,14 @@
#include <qpdf/QPDF.hh>
#include <qpdf/FileInputSource.hh>
+#include <qpdf/JSON_writer.hh>
#include <qpdf/Pl_Base64.hh>
#include <qpdf/Pl_StdioFile.hh>
#include <qpdf/QIntC.hh>
#include <qpdf/QPDFObject_private.hh>
#include <qpdf/QPDFValue.hh>
#include <qpdf/QPDF_Null.hh>
+#include <qpdf/QPDF_Stream.hh>
#include <qpdf/QTC.hh>
#include <qpdf/QUtil.hh>
#include <algorithm>
@@ -442,7 +444,9 @@ void
QPDF::JSONReactor::replaceObject(QPDFObjectHandle&& replacement, JSON const& value)
{
if (replacement.isIndirect()) {
- error(replacement.getParsedOffset(), "the value of an object may not be an indirect object reference");
+ error(
+ replacement.getParsedOffset(),
+ "the value of an object may not be an indirect object reference");
return;
}
auto& tos = stack.back();
@@ -828,45 +832,20 @@ QPDF::importJSON(std::shared_ptr<InputSource> is, bool must_be_complete)
}
void
-QPDF::writeJSONStream(
+writeJSONStreamFile(
int version,
- Pipeline* p,
- bool& first,
- std::string const& key,
- QPDFObjectHandle& obj,
+ JSON::Writer& jw,
+ QPDF_Stream& stream,
+ int id,
qpdf_stream_decode_level_e decode_level,
- qpdf_json_stream_data_e json_stream_data,
std::string const& file_prefix)
{
- Pipeline* stream_p = nullptr;
- FILE* f = nullptr;
- std::shared_ptr<Pl_StdioFile> f_pl;
- std::string filename;
- if (json_stream_data == qpdf_sj_file) {
- filename = file_prefix + "-" + std::to_string(obj.getObjectID());
- f = QUtil::safe_fopen(filename.c_str(), "wb");
- f_pl = std::make_shared<Pl_StdioFile>("stream data", f);
- stream_p = f_pl.get();
- }
- auto j = JSON::makeDictionary();
- j.addDictionaryMember(
- "stream", obj.getStreamJSON(version, json_stream_data, decode_level, stream_p, filename));
-
- JSON::writeDictionaryItem(p, first, key, j, 3);
- if (f) {
- f_pl->finish();
- f_pl = nullptr;
- fclose(f);
- }
-}
-
-void
-QPDF::writeJSONObject(
- int version, Pipeline* p, bool& first, std::string const& key, QPDFObjectHandle& obj)
-{
- auto j = JSON::makeDictionary();
- j.addDictionaryMember("value", obj.getJSON(version, true));
- JSON::writeDictionaryItem(p, first, key, j, 3);
+ auto filename = file_prefix + "-" + std::to_string(id);
+ auto* f = QUtil::safe_fopen(filename.c_str(), "wb");
+ Pl_StdioFile f_pl{"stream data", f};
+ stream.writeStreamJSON(version, jw, qpdf_sj_file, decode_level, &f_pl, filename);
+ f_pl.finish();
+ fclose(f);
}
void
@@ -893,80 +872,75 @@ QPDF::writeJSON(
std::string const& file_prefix,
std::set<std::string> wanted_objects)
{
- int const depth_outer = 1;
- int const depth_top = 1;
- int const depth_qpdf = 2;
- int const depth_qpdf_inner = 3;
-
if (version != 2) {
throw std::runtime_error("QPDF::writeJSON: only version 2 is supported");
}
- bool first = true;
+ JSON::Writer jw{p, 4};
if (complete) {
- JSON::writeDictionaryOpen(p, first, depth_outer);
- } else {
- first = first_key;
- }
- JSON::writeDictionaryKey(p, first, "qpdf", depth_top);
- bool first_qpdf = true;
- JSON::writeArrayOpen(p, first_qpdf, depth_top);
- JSON::writeNext(p, first_qpdf, depth_qpdf);
- bool first_qpdf_inner = true;
- JSON::writeDictionaryOpen(p, first_qpdf_inner, depth_qpdf);
- JSON::writeDictionaryItem(
- p, first_qpdf_inner, "jsonversion", JSON::makeInt(version), depth_qpdf_inner);
- JSON::writeDictionaryItem(
- p, first_qpdf_inner, "pdfversion", JSON::makeString(getPDFVersion()), depth_qpdf_inner);
- JSON::writeDictionaryItem(
- p,
- first_qpdf_inner,
- "pushedinheritedpageresources",
- JSON::makeBool(everPushedInheritedAttributesToPages()),
- depth_qpdf_inner);
- JSON::writeDictionaryItem(
- p,
- first_qpdf_inner,
- "calledgetallpages",
- JSON::makeBool(everCalledGetAllPages()),
- depth_qpdf_inner);
- JSON::writeDictionaryItem(
- p,
- first_qpdf_inner,
- "maxobjectid",
- JSON::makeInt(QIntC::to_longlong(getObjectCount())),
- depth_qpdf_inner);
- JSON::writeDictionaryClose(p, first_qpdf_inner, depth_qpdf);
- JSON::writeNext(p, first_qpdf, depth_qpdf);
- JSON::writeDictionaryOpen(p, first_qpdf_inner, depth_qpdf);
+ jw << "{";
+ } else if (!first_key) {
+ jw << ",";
+ }
+ first_key = false;
+
+ /* clang-format off */
+ jw << "\n"
+ " \"qpdf\": [\n"
+ " {\n"
+ " \"jsonversion\": " << std::to_string(version) << ",\n"
+ " \"pdfversion\": \"" << getPDFVersion() << "\",\n"
+ " \"pushedinheritedpageresources\": " << (everPushedInheritedAttributesToPages() ? "true" : "false") << ",\n"
+ " \"calledgetallpages\": " << (everCalledGetAllPages() ? "true" : "false") << ",\n"
+ " \"maxobjectid\": " << std::to_string(getObjectCount()) << "\n"
+ " },\n"
+ " {";
+ /* clang-format on */
+
bool all_objects = wanted_objects.empty();
+ bool first = true;
for (auto& obj: getAllObjects()) {
- std::string key = "obj:" + obj.unparse();
+ auto const og = obj.getObjGen();
+ std::string key = "obj:" + og.unparse(' ') + " R";
if (all_objects || wanted_objects.count(key)) {
- if (obj.isStream()) {
- writeJSONStream(
- version,
- p,
- first_qpdf_inner,
- key,
- obj,
- decode_level,
- json_stream_data,
- file_prefix);
+ if (first) {
+ jw << "\n \"" << key;
+ first = false;
} else {
- writeJSONObject(version, p, first_qpdf_inner, key, obj);
+ jw << "\n },\n \"" << key;
+ }
+ if (auto* stream = obj.getObjectPtr()->as<QPDF_Stream>()) {
+ jw << "\": {\n \"stream\": ";
+ if (json_stream_data == qpdf_sj_file) {
+ writeJSONStreamFile(
+ version, jw, *stream, og.getObj(), decode_level, file_prefix);
+ } else {
+ stream->writeStreamJSON(
+ version, jw, json_stream_data, decode_level, nullptr, "");
+ }
+ } else {
+ jw << "\": {\n \"value\": ";
+ obj.writeJSON(version, jw, true);
}
}
}
if (all_objects || wanted_objects.count("trailer")) {
- auto trailer = getTrailer();
- writeJSONObject(version, p, first_qpdf_inner, "trailer", trailer);
- }
- JSON::writeDictionaryClose(p, first_qpdf_inner, depth_qpdf);
- JSON::writeArrayClose(p, first_qpdf, depth_top);
+ if (!first) {
+ jw << "\n },";
+ }
+ jw << "\n \"trailer\": {\n \"value\": ";
+ getTrailer().writeJSON(version, jw, true);
+ first = false;
+ }
+ if (!first) {
+ jw << "\n }";
+ }
+ /* clang-format off */
+ jw << "\n"
+ " }\n"
+ " ]";
+ /* clang-format on */
if (complete) {
- JSON::writeDictionaryClose(p, first, 0);
- *p << "\n";
+ jw << "\n}\n";
p->finish();
}
- first_key = false;
}