1///////////////////////////////////////////////////////////////////////////
2//
3// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
4// Digital Ltd. LLC
5//
6// All rights reserved.
7//
8// Redistribution and use in source and binary forms, with or without
9// modification, are permitted provided that the following conditions are
10// met:
11// * Redistributions of source code must retain the above copyright
12// notice, this list of conditions and the following disclaimer.
13// * Redistributions in binary form must reproduce the above
14// copyright notice, this list of conditions and the following disclaimer
15// in the documentation and/or other materials provided with the
16// distribution.
17// * Neither the name of Industrial Light & Magic nor the names of
18// its contributors may be used to endorse or promote products derived
19// from this software without specific prior written permission.
20//
21// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32//
33///////////////////////////////////////////////////////////////////////////
34
35
36
37#ifndef INCLUDED_IMF_ATTRIBUTE_H
38#define INCLUDED_IMF_ATTRIBUTE_H
39
40//-----------------------------------------------------------------------------
41//
42// class Attribute
43//
44//-----------------------------------------------------------------------------
45
46#include "IexBaseExc.h"
47#include "ImfIO.h"
48#include "ImfXdr.h"
49#include "ImfForward.h"
50#include "ImfExport.h"
51#include "ImfNamespace.h"
52
53OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
54
55
56class Attribute
57{
58 public:
59
60 //---------------------------
61 // Constructor and destructor
62 //---------------------------
63
64 IMF_EXPORT
65 Attribute ();
66 IMF_EXPORT
67 virtual ~Attribute ();
68
69
70 //-------------------------------
71 // Get this attribute's type name
72 //-------------------------------
73
74 virtual const char * typeName () const = 0;
75
76
77 //------------------------------
78 // Make a copy of this attribute
79 //------------------------------
80
81 virtual Attribute * copy () const = 0;
82
83
84 //----------------------------------------
85 // Type-specific attribute I/O and copying
86 //----------------------------------------
87
88 virtual void writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
89 int version) const = 0;
90
91 virtual void readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
92 int size,
93 int version) = 0;
94
95 virtual void copyValueFrom (const Attribute &other) = 0;
96
97
98 //------------------
99 // Attribute factory
100 //------------------
101
102 IMF_EXPORT
103 static Attribute * newAttribute (const char typeName[]);
104
105
106 //-----------------------------------------------------------
107 // Test if a given attribute type has already been registered
108 //-----------------------------------------------------------
109
110 IMF_EXPORT
111 static bool knownType (const char typeName[]);
112
113
114 protected:
115
116 //--------------------------------------------------
117 // Register an attribute type so that newAttribute()
118 // knows how to make objects of this type.
119 //--------------------------------------------------
120
121 IMF_EXPORT
122 static void registerAttributeType (const char typeName[],
123 Attribute *(*newAttribute)());
124
125 //------------------------------------------------------
126 // Un-register an attribute type so that newAttribute()
127 // no longer knows how to make objects of this type (for
128 // debugging only).
129 //------------------------------------------------------
130
131 IMF_EXPORT
132 static void unRegisterAttributeType (const char typeName[]);
133};
134
135
136//-------------------------------------------------
137// Class template for attributes of a specific type
138//-------------------------------------------------
139
140template <class T>
141class TypedAttribute: public Attribute
142{
143 public:
144
145 //------------------------------------------------------------
146 // Constructors and destructor: default behavior. This assumes
147 // that the type T is copyable/assignable/moveable.
148 //------------------------------------------------------------
149
150 TypedAttribute () = default;
151 TypedAttribute (const T &value);
152 TypedAttribute (const TypedAttribute<T> &other) = default;
153 TypedAttribute (TypedAttribute<T> &&other) = default;
154
155 virtual ~TypedAttribute () = default;
156
157 TypedAttribute& operator = (const TypedAttribute<T>& other) = default;
158 TypedAttribute& operator = (TypedAttribute<T>&& other) = default;
159
160 //--------------------------------
161 // Access to the attribute's value
162 //--------------------------------
163
164 T & value ();
165 const T & value () const;
166
167
168 //--------------------------------
169 // Get this attribute's type name.
170 //--------------------------------
171
172 virtual const char * typeName () const;
173
174
175 //---------------------------------------------------------
176 // Static version of typeName()
177 // This function must be specialized for each value type T.
178 //---------------------------------------------------------
179
180 static const char * staticTypeName ();
181
182
183 //---------------------
184 // Make a new attribute
185 //---------------------
186
187 static Attribute * makeNewAttribute ();
188
189
190 //------------------------------
191 // Make a copy of this attribute
192 //------------------------------
193
194 virtual Attribute * copy () const;
195
196
197 //-----------------------------------------------------------------
198 // Type-specific attribute I/O and copying.
199 // Depending on type T, these functions may have to be specialized.
200 //-----------------------------------------------------------------
201
202 virtual void writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
203 int version) const;
204
205 virtual void readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
206 int size,
207 int version);
208
209 virtual void copyValueFrom (const Attribute &other);
210
211
212 //------------------------------------------------------------
213 // Dynamic casts that throw exceptions instead of returning 0.
214 //------------------------------------------------------------
215
216 static TypedAttribute * cast (Attribute *attribute);
217 static const TypedAttribute * cast (const Attribute *attribute);
218 static TypedAttribute & cast (Attribute &attribute);
219 static const TypedAttribute & cast (const Attribute &attribute);
220
221
222 //---------------------------------------------------------------
223 // Register this attribute type so that Attribute::newAttribute()
224 // knows how to make objects of this type.
225 //
226 // Note that this function is not thread-safe because it modifies
227 // a global variable in the IlmIlm library. A thread in a multi-
228 // threaded program may call registerAttributeType() only when no
229 // other thread is accessing any functions or classes in the
230 // IlmImf library.
231 //
232 //---------------------------------------------------------------
233
234 static void registerAttributeType ();
235
236
237 //-----------------------------------------------------
238 // Un-register this attribute type (for debugging only)
239 //-----------------------------------------------------
240
241 static void unRegisterAttributeType ();
242
243
244 private:
245
246 T _value;
247};
248
249//------------------------------------
250// Implementation of TypedAttribute<T>
251//------------------------------------
252
253template <class T>
254TypedAttribute<T>::TypedAttribute (const T & value):
255 Attribute (),
256 _value (value)
257{
258 // empty
259}
260
261template <class T>
262inline T &
263TypedAttribute<T>::value ()
264{
265 return _value;
266}
267
268
269template <class T>
270inline const T &
271TypedAttribute<T>::value () const
272{
273 return _value;
274}
275
276
277template <class T>
278const char *
279TypedAttribute<T>::typeName () const
280{
281 return staticTypeName();
282}
283
284
285template <class T>
286Attribute *
287TypedAttribute<T>::makeNewAttribute ()
288{
289 return new TypedAttribute<T>();
290}
291
292
293template <class T>
294Attribute *
295TypedAttribute<T>::copy () const
296{
297 Attribute * attribute = new TypedAttribute<T>();
298 attribute->copyValueFrom (other: *this);
299 return attribute;
300}
301
302
303template <class T>
304void
305TypedAttribute<T>::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
306 int version) const
307{
308 OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, _value);
309}
310
311
312template <class T>
313void
314TypedAttribute<T>::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
315 int size,
316 int version)
317{
318 OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, _value);
319}
320
321
322template <class T>
323void
324TypedAttribute<T>::copyValueFrom (const Attribute &other)
325{
326 _value = cast(other)._value;
327}
328
329
330template <class T>
331TypedAttribute<T> *
332TypedAttribute<T>::cast (Attribute *attribute)
333{
334 TypedAttribute<T> *t =
335 dynamic_cast <TypedAttribute<T> *> (attribute);
336
337 if (t == 0)
338 throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type.");
339
340 return t;
341}
342
343
344template <class T>
345const TypedAttribute<T> *
346TypedAttribute<T>::cast (const Attribute *attribute)
347{
348 const TypedAttribute<T> *t =
349 dynamic_cast <const TypedAttribute<T> *> (attribute);
350
351 if (t == 0)
352 throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type.");
353
354 return t;
355}
356
357
358template <class T>
359inline TypedAttribute<T> &
360TypedAttribute<T>::cast (Attribute &attribute)
361{
362 return *cast (&attribute);
363}
364
365
366template <class T>
367inline const TypedAttribute<T> &
368TypedAttribute<T>::cast (const Attribute &attribute)
369{
370 return *cast (&attribute);
371}
372
373
374template <class T>
375inline void
376TypedAttribute<T>::registerAttributeType ()
377{
378 Attribute::registerAttributeType (typeName: staticTypeName(), newAttribute: makeNewAttribute);
379}
380
381
382template <class T>
383inline void
384TypedAttribute<T>::unRegisterAttributeType ()
385{
386 Attribute::unRegisterAttributeType (typeName: staticTypeName());
387}
388
389
390OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
391
392
393#endif
394

source code of include/OpenEXR/ImfAttribute.h