diff options
author | Matthew Olsson <matthewcolsson@gmail.com> | 2021-04-30 18:23:17 -0700 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-05-10 10:32:39 +0200 |
commit | a8f5b6aaa3405e4b4eda49888ee9da8572d5473d (patch) | |
tree | e5c95bb185071cda2f81d5802cd67b366533eb2f /Userland/Libraries/LibPDF/Value.h | |
parent | af9a7b13748cc4ccffe6f257c520b2a3b040102b (diff) | |
download | serenity-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.h | 134 |
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()); + } +}; + +} |