Coverage Report

Created: 2025-07-16 07:53

/usr/local/include/OpenEXR/ImfAttribute.h
Line
Count
Source
1
//
2
// SPDX-License-Identifier: BSD-3-Clause
3
// Copyright (c) Contributors to the OpenEXR Project.
4
//
5
6
#ifndef INCLUDED_IMF_ATTRIBUTE_H
7
#define INCLUDED_IMF_ATTRIBUTE_H
8
9
//-----------------------------------------------------------------------------
10
//
11
//  class Attribute
12
//
13
//-----------------------------------------------------------------------------
14
15
#include "ImfForward.h"
16
17
#include "ImfIO.h"
18
#include "ImfXdr.h"
19
20
#include "IexBaseExc.h"
21
22
#include <cstring>
23
#include <typeinfo>
24
25
#if defined(_MSC_VER)
26
// suppress warning about non-exported base classes
27
#    pragma warning(push)
28
#    pragma warning(disable : 4251)
29
#    pragma warning(disable : 4275)
30
#endif
31
32
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
33
34
class IMF_EXPORT_TYPE Attribute
35
{
36
public:
37
    //---------------------------
38
    // Constructor and destructor
39
    //---------------------------
40
41
    IMF_EXPORT Attribute ();
42
    IMF_EXPORT virtual ~Attribute ();
43
44
    //-------------------------------
45
    // Get this attribute's type name
46
    //-------------------------------
47
48
    virtual const char* typeName () const = 0;
49
50
    //------------------------------
51
    // Make a copy of this attribute
52
    //------------------------------
53
54
    virtual Attribute* copy () const = 0;
55
56
    //----------------------------------------
57
    // Type-specific attribute I/O and copying
58
    //----------------------------------------
59
60
    virtual void writeValueTo (
61
        OPENEXR_IMF_INTERNAL_NAMESPACE::OStream& os, int version) const = 0;
62
63
    virtual void readValueFrom (
64
        OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is, int size, int version) = 0;
65
66
    virtual void copyValueFrom (const Attribute& other) = 0;
67
68
    //------------------
69
    // Attribute factory
70
    //------------------
71
72
    IMF_EXPORT static Attribute* newAttribute (const char typeName[]);
73
74
    //-----------------------------------------------------------
75
    // Test if a given attribute type has already been registered
76
    //-----------------------------------------------------------
77
78
    IMF_EXPORT static bool knownType (const char typeName[]);
79
80
protected:
81
    //--------------------------------------------------
82
    // Register an attribute type so that newAttribute()
83
    // knows how to make objects of this type.
84
    //--------------------------------------------------
85
    IMF_EXPORT
86
    static void registerAttributeType (
87
        const char typeName[], Attribute* (*newAttribute) ());
88
89
    //------------------------------------------------------
90
    // Un-register an attribute type so that newAttribute()
91
    // no longer knows how to make objects of this type (for
92
    // debugging only).
93
    //------------------------------------------------------
94
    IMF_EXPORT
95
    static void unRegisterAttributeType (const char typeName[]);
96
};
97
98
//-------------------------------------------------
99
// Class template for attributes of a specific type
100
//-------------------------------------------------
101
102
template <class T>
103
class IMF_EXPORT_TEMPLATE_TYPE TypedAttribute : public Attribute
104
{
105
public:
106
    //------------------------------------------------------------
107
    // Constructors and destructor: default behavior. This assumes
108
    // that the type T is copyable/assignable/moveable.
109
    //------------------------------------------------------------
110
111
    TypedAttribute () = default;
112
    TypedAttribute (const T& value);
113
    TypedAttribute (const TypedAttribute<T>& other) = default;
114
    TypedAttribute (TypedAttribute<T>&& other)      = default;
115
    //NB: if we use a default destructor, it wreaks havoc with where the vtable and such end up
116
    //at least under mingw+windows, and since we are providing extern template instantiations
117
    //this will be pretty trim and should reduce code bloat
118
    virtual ~TypedAttribute ();
119
120
    TypedAttribute& operator= (const TypedAttribute<T>& other) = default;
121
    TypedAttribute& operator= (TypedAttribute<T>&& other)      = default;
122
123
    //--------------------------------
124
    // Access to the attribute's value
125
    //--------------------------------
126
127
    T&       value ();
128
    const T& value () const;
129
130
    //--------------------------------
131
    // Get this attribute's type name.
132
    //--------------------------------
133
134
    virtual const char* typeName () const;
135
136
    //---------------------------------------------------------
137
    // Static version of typeName()
138
    // This function must be specialized for each value type T.
139
    //---------------------------------------------------------
140
141
    static const char* staticTypeName ();
142
143
    //---------------------
144
    // Make a new attribute
145
    //---------------------
146
147
    static Attribute* makeNewAttribute ();
148
149
    //------------------------------
150
    // Make a copy of this attribute
151
    //------------------------------
152
153
    virtual Attribute* copy () const;
154
155
    //-----------------------------------------------------------------
156
    // Type-specific attribute I/O and copying.
157
    // Depending on type T, these functions may have to be specialized.
158
    //-----------------------------------------------------------------
159
160
    virtual void writeValueTo (
161
        OPENEXR_IMF_INTERNAL_NAMESPACE::OStream& os, int version) const;
162
163
    virtual void readValueFrom (
164
        OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is, int size, int version);
165
166
    virtual void copyValueFrom (const Attribute& other);
167
168
    //------------------------------------------------------------
169
    // Dynamic casts that throw exceptions instead of returning 0.
170
    //------------------------------------------------------------
171
172
    static TypedAttribute*       cast (Attribute* attribute);
173
    static const TypedAttribute* cast (const Attribute* attribute);
174
    static TypedAttribute&       cast (Attribute& attribute);
175
    static const TypedAttribute& cast (const Attribute& attribute);
176
177
    //---------------------------------------------------------------
178
    // Register this attribute type so that Attribute::newAttribute()
179
    // knows how to make objects of this type.
180
    //
181
    // Note that this function is not thread-safe because it modifies
182
    // a global variable in the IlmIlm library.  A thread in a multi-
183
    // threaded program may call registerAttributeType() only when no
184
    // other thread is accessing any functions or classes in the
185
    // OpenEXR library.
186
    //
187
    //---------------------------------------------------------------
188
189
    static void registerAttributeType ();
190
191
    //-----------------------------------------------------
192
    // Un-register this attribute type (for debugging only)
193
    //-----------------------------------------------------
194
195
    static void unRegisterAttributeType ();
196
197
private:
198
    T _value;
199
};
200
201
//------------------------------------
202
// Implementation of TypedAttribute<T>
203
//------------------------------------
204
205
template <class T>
206
TypedAttribute<T>::TypedAttribute (const T& value)
207
    : Attribute (), _value (value)
208
{
209
    // empty
210
}
211
212
template <class T> TypedAttribute<T>::~TypedAttribute ()
213
{
214
    // empty
215
}
216
217
template <class T>
218
inline T&
219
TypedAttribute<T>::value ()
220
{
221
    return _value;
222
}
223
224
template <class T>
225
inline const T&
226
TypedAttribute<T>::value () const
227
3.64k
{
228
3.64k
    return _value;
229
3.64k
}
Unexecuted instantiation: Imf_3_3::TypedAttribute<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >::value() const
Imf_3_3::TypedAttribute<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::value() const
Line
Count
Source
227
480
{
228
480
    return _value;
229
480
}
Imf_3_3::TypedAttribute<float>::value() const
Line
Count
Source
227
2.80k
{
228
2.80k
    return _value;
229
2.80k
}
Imf_3_3::TypedAttribute<Imf_3_3::Chromaticities>::value() const
Line
Count
Source
227
358
{
228
358
    return _value;
229
358
}
230
231
template <class T>
232
const char*
233
TypedAttribute<T>::typeName () const
234
{
235
    return staticTypeName ();
236
}
237
238
template <class T>
239
Attribute*
240
TypedAttribute<T>::makeNewAttribute ()
241
{
242
    return new TypedAttribute<T> ();
243
}
244
245
template <class T>
246
Attribute*
247
TypedAttribute<T>::copy () const
248
{
249
    Attribute* attribute = new TypedAttribute<T> ();
250
    attribute->copyValueFrom (*this);
251
    return attribute;
252
}
253
254
template <class T>
255
void
256
TypedAttribute<T>::writeValueTo (
257
    OPENEXR_IMF_INTERNAL_NAMESPACE::OStream& os, int version) const
258
{
259
    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write<
260
        OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, _value);
261
}
262
263
template <class T>
264
void
265
TypedAttribute<T>::readValueFrom (
266
    OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is, int size, int version)
267
{
268
    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read<
269
        OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, _value);
270
}
271
272
template <class T>
273
void
274
TypedAttribute<T>::copyValueFrom (const Attribute& other)
275
{
276
    _value = cast (other)._value;
277
}
278
279
template <class T>
280
TypedAttribute<T>*
281
TypedAttribute<T>::cast (Attribute* attribute)
282
{
283
    TypedAttribute<T>* t = dynamic_cast<TypedAttribute<T>*> (attribute);
284
285
    if (t == 0) throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type.");
286
287
    return t;
288
}
289
290
template <class T>
291
const TypedAttribute<T>*
292
TypedAttribute<T>::cast (const Attribute* attribute)
293
{
294
    const TypedAttribute<T>* t =
295
        dynamic_cast<const TypedAttribute<T>*> (attribute);
296
297
    if (t == 0) throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type.");
298
299
    return t;
300
}
301
302
template <class T>
303
inline TypedAttribute<T>&
304
TypedAttribute<T>::cast (Attribute& attribute)
305
{
306
    return *cast (&attribute);
307
}
308
309
template <class T>
310
inline const TypedAttribute<T>&
311
TypedAttribute<T>::cast (const Attribute& attribute)
312
{
313
    return *cast (&attribute);
314
}
315
316
template <class T>
317
inline void
318
TypedAttribute<T>::registerAttributeType ()
319
{
320
    Attribute::registerAttributeType (staticTypeName (), makeNewAttribute);
321
}
322
323
template <class T>
324
inline void
325
TypedAttribute<T>::unRegisterAttributeType ()
326
{
327
    Attribute::unRegisterAttributeType (staticTypeName ());
328
}
329
330
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
331
332
#if defined(_MSC_VER)
333
#    pragma warning(pop)
334
#endif
335
336
#endif