summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibPDF/Value.h
diff options
context:
space:
mode:
authorMatthew Olsson <matthewcolsson@gmail.com>2021-04-30 18:23:17 -0700
committerAndreas Kling <kling@serenityos.org>2021-05-10 10:32:39 +0200
commita8f5b6aaa3405e4b4eda49888ee9da8572d5473d (patch)
treee5c95bb185071cda2f81d5802cd67b366533eb2f /Userland/Libraries/LibPDF/Value.h
parentaf9a7b13748cc4ccffe6f257c520b2a3b040102b (diff)
downloadserenity-a8f5b6aaa3405e4b4eda49888ee9da8572d5473d.zip
LibPDF: Create basic object structure
This commit is the start of LibPDF, and introduces some basic structure objects. This emulates LibJS's Value structure, where Value is a simple class that can contain a pointer to a more complex Object class with more data. All of the basic PDF objects have a representation.
Diffstat (limited to 'Userland/Libraries/LibPDF/Value.h')
-rw-r--r--Userland/Libraries/LibPDF/Value.h134
1 files changed, 134 insertions, 0 deletions
diff --git a/Userland/Libraries/LibPDF/Value.h b/Userland/Libraries/LibPDF/Value.h
new file mode 100644
index 0000000000..6999902bfc
--- /dev/null
+++ b/Userland/Libraries/LibPDF/Value.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2021, Matthew Olsson <mattco@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/Format.h>
+
+namespace PDF {
+
+class Object;
+
+class Value {
+public:
+ Value()
+ : m_type(Type::Null)
+ {
+ }
+
+ Value(bool b)
+ : m_type(Type::Bool)
+ {
+ m_as_bool = b;
+ }
+
+ Value(int i)
+ : m_type(Type::Int)
+ {
+ m_as_int = i;
+ }
+
+ Value(float f)
+ : m_type(Type::Float)
+ {
+ m_as_float = f;
+ }
+
+ template<IsObject T>
+ Value(NonnullRefPtr<T> obj)
+ : m_type(Type::Object)
+ {
+ obj->ref();
+ m_as_object = obj;
+ }
+
+ Value(const Value& other)
+ {
+ *this = other;
+ }
+
+ ~Value();
+
+ Value& operator=(const Value& other);
+
+ [[nodiscard]] ALWAYS_INLINE bool is_null() const { return m_type == Type::Null; }
+ [[nodiscard]] ALWAYS_INLINE bool is_bool() const { return m_type == Type::Bool; }
+ [[nodiscard]] ALWAYS_INLINE bool is_int() const { return m_type == Type::Int; }
+ [[nodiscard]] ALWAYS_INLINE bool is_float() const { return m_type == Type::Float; }
+ [[nodiscard]] ALWAYS_INLINE bool is_number() const { return is_int() || is_float(); }
+
+ [[nodiscard]] ALWAYS_INLINE bool is_object() const { return m_type == Type::Object; }
+
+ [[nodiscard]] ALWAYS_INLINE bool as_bool() const
+ {
+ VERIFY(is_bool());
+ return m_as_bool;
+ }
+
+ [[nodiscard]] ALWAYS_INLINE int as_int() const
+ {
+ VERIFY(is_int());
+ return m_as_int;
+ }
+
+ [[nodiscard]] ALWAYS_INLINE int to_int() const
+ {
+ if (is_int())
+ return as_int();
+ return static_cast<int>(as_float());
+ }
+
+ [[nodiscard]] ALWAYS_INLINE float as_float() const
+ {
+ VERIFY(is_float());
+ return m_as_float;
+ }
+
+ [[nodiscard]] ALWAYS_INLINE float to_float() const
+ {
+ if (is_float())
+ return as_float();
+ return static_cast<float>(as_int());
+ }
+
+ [[nodiscard]] ALWAYS_INLINE NonnullRefPtr<Object> as_object() const { return *m_as_object; }
+
+ [[nodiscard]] ALWAYS_INLINE explicit operator bool() const { return !is_null(); }
+
+ [[nodiscard]] String to_string(int indent = 0) const;
+
+private:
+ enum class Type {
+ Null,
+ Bool,
+ Int,
+ Float,
+ Object,
+ };
+
+ union {
+ bool m_as_bool;
+ int m_as_int;
+ float m_as_float;
+ Object* m_as_object;
+ };
+
+ Type m_type;
+};
+
+}
+
+namespace AK {
+
+template<>
+struct Formatter<PDF::Value> : Formatter<StringView> {
+ void format(FormatBuilder& builder, const PDF::Value& value)
+ {
+ Formatter<StringView>::format(builder, value.to_string());
+ }
+};
+
+}