Coverage Report

Created: 2026-09-14 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibPDF/Object.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2021-2022, Matthew Olsson <mattco@serenityos.org>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#pragma once
8
9
#include <AK/Debug.h>
10
#include <AK/DeprecatedFlyString.h>
11
#include <AK/Format.h>
12
#include <AK/RefCounted.h>
13
#include <AK/SourceLocation.h>
14
#include <LibPDF/Error.h>
15
#include <LibPDF/Forward.h>
16
17
#ifdef PDF_DEBUG
18
template<PDF::IsObject T>
19
char const* object_name()
20
0
{
21
0
#    define ENUMERATE_TYPE(class_name, snake_name)  \
22
0
        if constexpr (IsSame<PDF::class_name, T>) { \
23
0
            return #class_name;                     \
24
0
        }
25
0
    ENUMERATE_OBJECT_TYPES(ENUMERATE_TYPE)
26
0
#    undef ENUMERATE_TYPE
27
28
0
    VERIFY_NOT_REACHED();
29
0
}
Unexecuted instantiation: _Z11object_nameITkN3PDF8IsObjectENS0_12StreamObjectEEPKcv
Unexecuted instantiation: _Z11object_nameITkN3PDF8IsObjectENS0_11ArrayObjectEEPKcv
Unexecuted instantiation: _Z11object_nameITkN3PDF8IsObjectENS0_10DictObjectEEPKcv
Unexecuted instantiation: _Z11object_nameITkN3PDF8IsObjectENS0_10NameObjectEEPKcv
Unexecuted instantiation: _Z11object_nameITkN3PDF8IsObjectENS0_12StringObjectEEPKcv
Unexecuted instantiation: _Z11object_nameITkN3PDF8IsObjectENS0_13IndirectValueEEPKcv
30
#endif
31
32
namespace PDF {
33
34
class Object : public RefCounted<Object> {
35
public:
36
81
    virtual ~Object() = default;
37
38
0
    [[nodiscard]] ALWAYS_INLINE u32 generation_index() const { return m_generation_index; }
39
8
    ALWAYS_INLINE void set_generation_index(u32 generation_index) { m_generation_index = generation_index; }
40
41
    template<IsObject T>
42
    bool is() const
43
    requires(!IsSame<T, Object>)
44
21
    {
45
21
#define ENUMERATE_TYPE(class_name, snake_name) \
46
126
    if constexpr (IsSame<class_name, T>) {     \
47
21
        return is_##snake_name();              \
48
21
    }
49
126
        ENUMERATE_OBJECT_TYPES(ENUMERATE_TYPE)
50
0
#undef ENUMERATE_TYPE
51
52
21
        VERIFY_NOT_REACHED();
53
21
    }
_ZNK3PDF6Object2isITkNS_8IsObjectENS_10DictObjectEEEbvQnt6IsSameIT_S0_E
Line
Count
Source
44
16
    {
45
16
#define ENUMERATE_TYPE(class_name, snake_name) \
46
16
    if constexpr (IsSame<class_name, T>) {     \
47
16
        return is_##snake_name();              \
48
16
    }
49
16
        ENUMERATE_OBJECT_TYPES(ENUMERATE_TYPE)
50
16
#undef ENUMERATE_TYPE
51
52
16
        VERIFY_NOT_REACHED();
53
16
    }
Unexecuted instantiation: _ZNK3PDF6Object2isITkNS_8IsObjectENS_12StreamObjectEEEbvQnt6IsSameIT_S0_E
_ZNK3PDF6Object2isITkNS_8IsObjectENS_11ArrayObjectEEEbvQnt6IsSameIT_S0_E
Line
Count
Source
44
5
    {
45
5
#define ENUMERATE_TYPE(class_name, snake_name) \
46
5
    if constexpr (IsSame<class_name, T>) {     \
47
5
        return is_##snake_name();              \
48
5
    }
49
5
        ENUMERATE_OBJECT_TYPES(ENUMERATE_TYPE)
50
5
#undef ENUMERATE_TYPE
51
52
5
        VERIFY_NOT_REACHED();
53
5
    }
Unexecuted instantiation: _ZNK3PDF6Object2isITkNS_8IsObjectENS_13IndirectValueEEEbvQnt6IsSameIT_S0_E
Unexecuted instantiation: _ZNK3PDF6Object2isITkNS_8IsObjectENS_10NameObjectEEEbvQnt6IsSameIT_S0_E
Unexecuted instantiation: _ZNK3PDF6Object2isITkNS_8IsObjectENS_12StringObjectEEEbvQnt6IsSameIT_S0_E
54
55
    template<IsObject T>
56
    [[nodiscard]] ALWAYS_INLINE NonnullRefPtr<T> cast(
57
#ifdef PDF_DEBUG
58
        SourceLocation loc = SourceLocation::current()
59
#endif
60
            )
61
    requires(!IsSame<T, Object>)
62
13
    {
63
13
#ifdef PDF_DEBUG
64
13
        if (!is<T>()) {
65
0
            dbgln("{} invalid cast from {} to {}", loc, type_name(), object_name<T>());
66
0
            VERIFY_NOT_REACHED();
67
0
        }
68
13
#endif
69
70
13
        return NonnullRefPtr<T>(static_cast<T&>(*this));
71
13
    }
Unexecuted instantiation: _ZN3PDF6Object4castITkNS_8IsObjectENS_12StreamObjectEEEN2AK13NonnullRefPtrIT_EENS3_14SourceLocationEQnt6IsSameIS5_S0_E
_ZN3PDF6Object4castITkNS_8IsObjectENS_11ArrayObjectEEEN2AK13NonnullRefPtrIT_EENS3_14SourceLocationEQnt6IsSameIS5_S0_E
Line
Count
Source
62
5
    {
63
5
#ifdef PDF_DEBUG
64
5
        if (!is<T>()) {
65
0
            dbgln("{} invalid cast from {} to {}", loc, type_name(), object_name<T>());
66
0
            VERIFY_NOT_REACHED();
67
0
        }
68
5
#endif
69
70
5
        return NonnullRefPtr<T>(static_cast<T&>(*this));
71
5
    }
_ZN3PDF6Object4castITkNS_8IsObjectENS_10DictObjectEEEN2AK13NonnullRefPtrIT_EENS3_14SourceLocationEQnt6IsSameIS5_S0_E
Line
Count
Source
62
8
    {
63
8
#ifdef PDF_DEBUG
64
8
        if (!is<T>()) {
65
0
            dbgln("{} invalid cast from {} to {}", loc, type_name(), object_name<T>());
66
0
            VERIFY_NOT_REACHED();
67
0
        }
68
8
#endif
69
70
8
        return NonnullRefPtr<T>(static_cast<T&>(*this));
71
8
    }
Unexecuted instantiation: _ZN3PDF6Object4castITkNS_8IsObjectENS_10NameObjectEEEN2AK13NonnullRefPtrIT_EENS3_14SourceLocationEQnt6IsSameIS5_S0_E
Unexecuted instantiation: _ZN3PDF6Object4castITkNS_8IsObjectENS_12StringObjectEEEN2AK13NonnullRefPtrIT_EENS3_14SourceLocationEQnt6IsSameIS5_S0_E
Unexecuted instantiation: _ZN3PDF6Object4castITkNS_8IsObjectENS_13IndirectValueEEEN2AK13NonnullRefPtrIT_EENS3_14SourceLocationEQnt6IsSameIS5_S0_E
72
73
    virtual char const* type_name() const = 0;
74
    virtual ByteString to_byte_string(int indent) const = 0;
75
76
protected:
77
#define ENUMERATE_TYPE(_, name)    \
78
    virtual bool is_##name() const \
79
0
    {                              \
80
0
        return false;              \
81
0
    }
Unexecuted instantiation: PDF::Object::is_string() const
Unexecuted instantiation: PDF::Object::is_name() const
Unexecuted instantiation: PDF::Object::is_array() const
Unexecuted instantiation: PDF::Object::is_dict() const
Unexecuted instantiation: PDF::Object::is_stream() const
Unexecuted instantiation: PDF::Object::is_indirect_value() const
82
    ENUMERATE_OBJECT_TYPES(ENUMERATE_TYPE)
83
#undef ENUMERATE_TYPE
84
85
private:
86
    u32 m_generation_index { 0 };
87
};
88
89
}
90
91
namespace AK {
92
93
template<PDF::IsObject T>
94
struct Formatter<T> : Formatter<StringView> {
95
    ErrorOr<void> format(FormatBuilder& builder, T const& object)
96
    {
97
        return Formatter<StringView>::format(builder, object.to_byte_string(0));
98
    }
99
};
100
101
template<PDF::IsObject T>
102
struct Formatter<NonnullRefPtr<T>> : Formatter<T> {
103
    ErrorOr<void> format(FormatBuilder& builder, NonnullRefPtr<T> const& object)
104
    {
105
        return Formatter<T>::format(builder, *object);
106
    }
107
};
108
109
}