summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibPDF/Object.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Libraries/LibPDF/Object.cpp')
-rw-r--r--Userland/Libraries/LibPDF/Object.cpp116
1 files changed, 116 insertions, 0 deletions
diff --git a/Userland/Libraries/LibPDF/Object.cpp b/Userland/Libraries/LibPDF/Object.cpp
new file mode 100644
index 0000000000..4fca01a497
--- /dev/null
+++ b/Userland/Libraries/LibPDF/Object.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2021, Matthew Olsson <mattco@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <AK/Hex.h>
+#include <LibPDF/Object.h>
+
+namespace PDF {
+
+static void append_indent(StringBuilder& builder, int indent)
+{
+ for (int i = 0; i < indent; i++)
+ builder.append(" ");
+}
+
+String StringObject::to_string(int) const
+{
+ if (is_binary())
+ return String::formatted("<{}>", encode_hex(string().bytes()).to_uppercase());
+ return String::formatted("({})", string());
+}
+
+String NameObject::to_string(int) const
+{
+ StringBuilder builder;
+ builder.appendff("/{}", this->name());
+ return builder.to_string();
+}
+
+String ArrayObject::to_string(int indent) const
+{
+ StringBuilder builder;
+ builder.append("[\n");
+ bool first = true;
+
+ for (auto& element : elements()) {
+ if (!first)
+ builder.append(",\n");
+ first = false;
+ append_indent(builder, indent + 1);
+ builder.appendff("{}", element.to_string(indent));
+ }
+
+ builder.append('\n');
+ append_indent(builder, indent);
+ builder.append(']');
+ return builder.to_string();
+}
+
+String DictObject::to_string(int indent) const
+{
+ StringBuilder builder;
+ builder.append("<<\n");
+ bool first = true;
+
+ for (auto& [key, value] : map()) {
+ if (!first)
+ builder.append(",\n");
+ first = false;
+ append_indent(builder, indent + 1);
+ builder.appendff("/{} ", key);
+ builder.appendff("{}", value.to_string(indent + 1));
+ }
+
+ builder.append('\n');
+ append_indent(builder, indent);
+ builder.append(">>");
+ return builder.to_string();
+}
+
+String StreamObject::to_string(int indent) const
+{
+ StringBuilder builder;
+ builder.append("stream\n");
+ append_indent(builder, indent);
+ builder.appendff("{}\n", dict()->to_string(indent + 1));
+ append_indent(builder, indent + 1);
+
+ auto string = encode_hex(bytes());
+ while (true) {
+ if (string.length() > 60) {
+ builder.appendff("{}\n", string.substring(0, 60));
+ append_indent(builder, indent);
+ string = string.substring(60);
+ continue;
+ }
+
+ builder.appendff("{}\n", string);
+ break;
+ }
+
+ append_indent(builder, indent);
+ builder.append("endstream");
+ return builder.to_string();
+}
+
+String IndirectValue::to_string(int indent) const
+{
+ StringBuilder builder;
+ builder.appendff("{} {} obj\n", index(), generation_index());
+ append_indent(builder, indent + 1);
+ builder.append(value().to_string(indent + 1));
+ builder.append('\n');
+ append_indent(builder, indent);
+ builder.append("endobj");
+ return builder.to_string();
+}
+
+String IndirectValueRef::to_string(int) const
+{
+ return String::formatted("{} {} R", index(), generation_index());
+}
+
+}