Coverage Report

Created: 2025-09-05 06:52

/src/serenity/Userland/Libraries/LibPDF/Object.h
Line
Count
Source (jump to first uncovered line)
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
namespace {
19
20
template<PDF::IsObject T>
21
char const* object_name()
22
0
{
23
0
#    define ENUMERATE_TYPE(class_name, snake_name)  \
24
0
        if constexpr (IsSame<PDF::class_name, T>) { \
25
0
            return #class_name;                     \
26
0
        }
27
0
    ENUMERATE_OBJECT_TYPES(ENUMERATE_TYPE)
28
0
#    undef ENUMERATE_TYPE
29
30
0
    VERIFY_NOT_REACHED();
31
0
}
Unexecuted instantiation: Document.cpp:_ZN12_GLOBAL__N_111object_nameITkN3PDF8IsObjectENS1_12StreamObjectEEEPKcv
Unexecuted instantiation: Document.cpp:_ZN12_GLOBAL__N_111object_nameITkN3PDF8IsObjectENS1_11ArrayObjectEEEPKcv
Unexecuted instantiation: Document.cpp:_ZN12_GLOBAL__N_111object_nameITkN3PDF8IsObjectENS1_10DictObjectEEEPKcv
Unexecuted instantiation: Document.cpp:_ZN12_GLOBAL__N_111object_nameITkN3PDF8IsObjectENS1_10NameObjectEEEPKcv
Unexecuted instantiation: Document.cpp:_ZN12_GLOBAL__N_111object_nameITkN3PDF8IsObjectENS1_12StringObjectEEEPKcv
Unexecuted instantiation: DocumentParser.cpp:_ZN12_GLOBAL__N_111object_nameITkN3PDF8IsObjectENS1_12StreamObjectEEEPKcv
Unexecuted instantiation: DocumentParser.cpp:_ZN12_GLOBAL__N_111object_nameITkN3PDF8IsObjectENS1_10DictObjectEEEPKcv
Unexecuted instantiation: DocumentParser.cpp:_ZN12_GLOBAL__N_111object_nameITkN3PDF8IsObjectENS1_11ArrayObjectEEEPKcv
Unexecuted instantiation: DocumentParser.cpp:_ZN12_GLOBAL__N_111object_nameITkN3PDF8IsObjectENS1_10NameObjectEEEPKcv
Unexecuted instantiation: Encryption.cpp:_ZN12_GLOBAL__N_111object_nameITkN3PDF8IsObjectENS1_12StreamObjectEEEPKcv
Unexecuted instantiation: Encryption.cpp:_ZN12_GLOBAL__N_111object_nameITkN3PDF8IsObjectENS1_12StringObjectEEEPKcv
Unexecuted instantiation: ObjectDerivatives.cpp:_ZN12_GLOBAL__N_111object_nameITkN3PDF8IsObjectENS1_12StringObjectEEEPKcv
Unexecuted instantiation: ObjectDerivatives.cpp:_ZN12_GLOBAL__N_111object_nameITkN3PDF8IsObjectENS1_10NameObjectEEEPKcv
Unexecuted instantiation: ObjectDerivatives.cpp:_ZN12_GLOBAL__N_111object_nameITkN3PDF8IsObjectENS1_11ArrayObjectEEEPKcv
Unexecuted instantiation: ObjectDerivatives.cpp:_ZN12_GLOBAL__N_111object_nameITkN3PDF8IsObjectENS1_10DictObjectEEEPKcv
Unexecuted instantiation: ObjectDerivatives.cpp:_ZN12_GLOBAL__N_111object_nameITkN3PDF8IsObjectENS1_12StreamObjectEEEPKcv
Unexecuted instantiation: ObjectDerivatives.cpp:_ZN12_GLOBAL__N_111object_nameITkN3PDF8IsObjectENS1_13IndirectValueEEEPKcv
Unexecuted instantiation: Parser.cpp:_ZN12_GLOBAL__N_111object_nameITkN3PDF8IsObjectENS1_11ArrayObjectEEEPKcv
Unexecuted instantiation: Parser.cpp:_ZN12_GLOBAL__N_111object_nameITkN3PDF8IsObjectENS1_10DictObjectEEEPKcv
32
33
}
34
#endif
35
36
namespace PDF {
37
38
class Object : public RefCounted<Object> {
39
public:
40
147
    virtual ~Object() = default;
41
42
0
    [[nodiscard]] ALWAYS_INLINE u32 generation_index() const { return m_generation_index; }
43
14
    ALWAYS_INLINE void set_generation_index(u32 generation_index) { m_generation_index = generation_index; }
44
45
    template<IsObject T>
46
    bool is() const
47
    requires(!IsSame<T, Object>)
48
36
    {
49
36
#define ENUMERATE_TYPE(class_name, snake_name) \
50
216
    if constexpr (IsSame<class_name, T>) {     \
51
36
        return is_##snake_name();              \
52
36
    }
53
216
        ENUMERATE_OBJECT_TYPES(ENUMERATE_TYPE)
54
0
#undef ENUMERATE_TYPE
55
56
36
        VERIFY_NOT_REACHED();
57
36
    }
_ZNK3PDF6Object2isITkNS_8IsObjectENS_10DictObjectEEEbvQnt6IsSameIT_S0_E
Line
Count
Source
48
27
    {
49
27
#define ENUMERATE_TYPE(class_name, snake_name) \
50
27
    if constexpr (IsSame<class_name, T>) {     \
51
27
        return is_##snake_name();              \
52
27
    }
53
27
        ENUMERATE_OBJECT_TYPES(ENUMERATE_TYPE)
54
27
#undef ENUMERATE_TYPE
55
56
27
        VERIFY_NOT_REACHED();
57
27
    }
Unexecuted instantiation: _ZNK3PDF6Object2isITkNS_8IsObjectENS_12StreamObjectEEEbvQnt6IsSameIT_S0_E
_ZNK3PDF6Object2isITkNS_8IsObjectENS_11ArrayObjectEEEbvQnt6IsSameIT_S0_E
Line
Count
Source
48
9
    {
49
9
#define ENUMERATE_TYPE(class_name, snake_name) \
50
9
    if constexpr (IsSame<class_name, T>) {     \
51
9
        return is_##snake_name();              \
52
9
    }
53
9
        ENUMERATE_OBJECT_TYPES(ENUMERATE_TYPE)
54
9
#undef ENUMERATE_TYPE
55
56
9
        VERIFY_NOT_REACHED();
57
9
    }
Unexecuted instantiation: _ZNK3PDF6Object2isITkNS_8IsObjectENS_13IndirectValueEEEbvQnt6IsSameIT_S0_E
Unexecuted instantiation: _ZNK3PDF6Object2isITkNS_8IsObjectENS_10NameObjectEEEbvQnt6IsSameIT_S0_E
Unexecuted instantiation: _ZNK3PDF6Object2isITkNS_8IsObjectENS_12StringObjectEEEbvQnt6IsSameIT_S0_E
58
59
    template<IsObject T>
60
    [[nodiscard]] ALWAYS_INLINE NonnullRefPtr<T> cast(
61
#ifdef PDF_DEBUG
62
        SourceLocation loc = SourceLocation::current()
63
#endif
64
            )
65
    requires(!IsSame<T, Object>)
66
22
    {
67
22
#ifdef PDF_DEBUG
68
22
        if (!is<T>()) {
69
0
            dbgln("{} invalid cast from {} to {}", loc, type_name(), object_name<T>());
70
0
            VERIFY_NOT_REACHED();
71
0
        }
72
22
#endif
73
74
22
        return NonnullRefPtr<T>(static_cast<T&>(*this));
75
22
    }
Unexecuted instantiation: _ZN3PDF6Object4castITkNS_8IsObjectENS_12StreamObjectEEEN2AK13NonnullRefPtrIT_EENS3_14SourceLocationEQnt6IsSameIS5_S0_E
_ZN3PDF6Object4castITkNS_8IsObjectENS_11ArrayObjectEEEN2AK13NonnullRefPtrIT_EENS3_14SourceLocationEQnt6IsSameIS5_S0_E
Line
Count
Source
66
9
    {
67
9
#ifdef PDF_DEBUG
68
9
        if (!is<T>()) {
69
0
            dbgln("{} invalid cast from {} to {}", loc, type_name(), object_name<T>());
70
0
            VERIFY_NOT_REACHED();
71
0
        }
72
9
#endif
73
74
9
        return NonnullRefPtr<T>(static_cast<T&>(*this));
75
9
    }
_ZN3PDF6Object4castITkNS_8IsObjectENS_10DictObjectEEEN2AK13NonnullRefPtrIT_EENS3_14SourceLocationEQnt6IsSameIS5_S0_E
Line
Count
Source
66
13
    {
67
13
#ifdef PDF_DEBUG
68
13
        if (!is<T>()) {
69
0
            dbgln("{} invalid cast from {} to {}", loc, type_name(), object_name<T>());
70
0
            VERIFY_NOT_REACHED();
71
0
        }
72
13
#endif
73
74
13
        return NonnullRefPtr<T>(static_cast<T&>(*this));
75
13
    }
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
76
77
    virtual char const* type_name() const = 0;
78
    virtual ByteString to_byte_string(int indent) const = 0;
79
80
protected:
81
#define ENUMERATE_TYPE(_, name)    \
82
    virtual bool is_##name() const \
83
1
    {                              \
84
1
        return false;              \
85
1
    }
Unexecuted instantiation: PDF::Object::is_string() const
Unexecuted instantiation: PDF::Object::is_name() const
Unexecuted instantiation: PDF::Object::is_array() const
PDF::Object::is_dict() const
Line
Count
Source
83
1
    {                              \
84
1
        return false;              \
85
1
    }
Unexecuted instantiation: PDF::Object::is_stream() const
Unexecuted instantiation: PDF::Object::is_indirect_value() const
86
    ENUMERATE_OBJECT_TYPES(ENUMERATE_TYPE)
87
#undef ENUMERATE_TYPE
88
89
private:
90
    u32 m_generation_index { 0 };
91
};
92
93
}
94
95
namespace AK {
96
97
template<PDF::IsObject T>
98
struct Formatter<T> : Formatter<StringView> {
99
    ErrorOr<void> format(FormatBuilder& builder, T const& object)
100
    {
101
        return Formatter<StringView>::format(builder, object.to_byte_string(0));
102
    }
103
};
104
105
template<PDF::IsObject T>
106
struct Formatter<NonnullRefPtr<T>> : Formatter<T> {
107
    ErrorOr<void> format(FormatBuilder& builder, NonnullRefPtr<T> const& object)
108
    {
109
        return Formatter<T>::format(builder, *object);
110
    }
111
};
112
113
}