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 | |
53 | OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER |
54 | |
55 | |
56 | class IMF_EXPORT Attribute |
57 | { |
58 | public: |
59 | |
60 | //--------------------------- |
61 | // Constructor and destructor |
62 | //--------------------------- |
63 | |
64 | Attribute (); |
65 | virtual ~Attribute (); |
66 | |
67 | |
68 | //------------------------------- |
69 | // Get this attribute's type name |
70 | //------------------------------- |
71 | |
72 | virtual const char * typeName () const = 0; |
73 | |
74 | |
75 | //------------------------------ |
76 | // Make a copy of this attribute |
77 | //------------------------------ |
78 | |
79 | virtual Attribute * copy () const = 0; |
80 | |
81 | |
82 | //---------------------------------------- |
83 | // Type-specific attribute I/O and copying |
84 | //---------------------------------------- |
85 | |
86 | virtual void writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, |
87 | int version) const = 0; |
88 | |
89 | virtual void readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, |
90 | int size, |
91 | int version) = 0; |
92 | |
93 | virtual void copyValueFrom (const Attribute &other) = 0; |
94 | |
95 | |
96 | //------------------ |
97 | // Attribute factory |
98 | //------------------ |
99 | |
100 | static Attribute * newAttribute (const char typeName[]); |
101 | |
102 | |
103 | //----------------------------------------------------------- |
104 | // Test if a given attribute type has already been registered |
105 | //----------------------------------------------------------- |
106 | |
107 | static bool knownType (const char typeName[]); |
108 | |
109 | |
110 | protected: |
111 | |
112 | //-------------------------------------------------- |
113 | // Register an attribute type so that newAttribute() |
114 | // knows how to make objects of this type. |
115 | //-------------------------------------------------- |
116 | |
117 | static void registerAttributeType (const char typeName[], |
118 | Attribute *(*newAttribute)()); |
119 | |
120 | //------------------------------------------------------ |
121 | // Un-register an attribute type so that newAttribute() |
122 | // no longer knows how to make objects of this type (for |
123 | // debugging only). |
124 | //------------------------------------------------------ |
125 | |
126 | static void unRegisterAttributeType (const char typeName[]); |
127 | }; |
128 | |
129 | |
130 | //------------------------------------------------- |
131 | // Class template for attributes of a specific type |
132 | //------------------------------------------------- |
133 | |
134 | template <class T> |
135 | class TypedAttribute: public Attribute |
136 | { |
137 | public: |
138 | |
139 | //---------------------------- |
140 | // Constructors and destructor |
141 | //------------_--------------- |
142 | |
143 | TypedAttribute (); |
144 | TypedAttribute (const T &value); |
145 | TypedAttribute (const TypedAttribute<T> &other); |
146 | virtual ~TypedAttribute (); |
147 | |
148 | |
149 | //-------------------------------- |
150 | // Access to the attribute's value |
151 | //-------------------------------- |
152 | |
153 | T & value (); |
154 | const T & value () const; |
155 | |
156 | |
157 | //-------------------------------- |
158 | // Get this attribute's type name. |
159 | //-------------------------------- |
160 | |
161 | virtual const char * typeName () const; |
162 | |
163 | |
164 | //--------------------------------------------------------- |
165 | // Static version of typeName() |
166 | // This function must be specialized for each value type T. |
167 | //--------------------------------------------------------- |
168 | |
169 | static const char * staticTypeName (); |
170 | |
171 | |
172 | //--------------------- |
173 | // Make a new attribute |
174 | //--------------------- |
175 | |
176 | static Attribute * makeNewAttribute (); |
177 | |
178 | |
179 | //------------------------------ |
180 | // Make a copy of this attribute |
181 | //------------------------------ |
182 | |
183 | virtual Attribute * copy () const; |
184 | |
185 | |
186 | //----------------------------------------------------------------- |
187 | // Type-specific attribute I/O and copying. |
188 | // Depending on type T, these functions may have to be specialized. |
189 | //----------------------------------------------------------------- |
190 | |
191 | virtual void writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, |
192 | int version) const; |
193 | |
194 | virtual void readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, |
195 | int size, |
196 | int version); |
197 | |
198 | virtual void copyValueFrom (const Attribute &other); |
199 | |
200 | |
201 | //------------------------------------------------------------ |
202 | // Dynamic casts that throw exceptions instead of returning 0. |
203 | //------------------------------------------------------------ |
204 | |
205 | static TypedAttribute * cast (Attribute *attribute); |
206 | static const TypedAttribute * cast (const Attribute *attribute); |
207 | static TypedAttribute & cast (Attribute &attribute); |
208 | static const TypedAttribute & cast (const Attribute &attribute); |
209 | |
210 | |
211 | //--------------------------------------------------------------- |
212 | // Register this attribute type so that Attribute::newAttribute() |
213 | // knows how to make objects of this type. |
214 | // |
215 | // Note that this function is not thread-safe because it modifies |
216 | // a global variable in the IlmIlm library. A thread in a multi- |
217 | // threaded program may call registerAttributeType() only when no |
218 | // other thread is accessing any functions or classes in the |
219 | // IlmImf library. |
220 | // |
221 | //--------------------------------------------------------------- |
222 | |
223 | static void registerAttributeType (); |
224 | |
225 | |
226 | //----------------------------------------------------- |
227 | // Un-register this attribute type (for debugging only) |
228 | //----------------------------------------------------- |
229 | |
230 | static void unRegisterAttributeType (); |
231 | |
232 | |
233 | private: |
234 | |
235 | T _value; |
236 | }; |
237 | |
238 | //------------------------------------ |
239 | // Implementation of TypedAttribute<T> |
240 | //------------------------------------ |
241 | template <class T> |
242 | TypedAttribute<T>::TypedAttribute (): |
243 | Attribute (), |
244 | _value (T()) |
245 | { |
246 | // empty |
247 | } |
248 | |
249 | |
250 | template <class T> |
251 | TypedAttribute<T>::TypedAttribute (const T & value): |
252 | Attribute (), |
253 | _value (value) |
254 | { |
255 | // empty |
256 | } |
257 | |
258 | |
259 | template <class T> |
260 | TypedAttribute<T>::TypedAttribute (const TypedAttribute<T> &other): |
261 | Attribute (other), |
262 | _value () |
263 | { |
264 | copyValueFrom (other); |
265 | } |
266 | |
267 | |
268 | template <class T> |
269 | TypedAttribute<T>::~TypedAttribute () |
270 | { |
271 | // empty |
272 | } |
273 | |
274 | |
275 | template <class T> |
276 | inline T & |
277 | TypedAttribute<T>::value () |
278 | { |
279 | return _value; |
280 | } |
281 | |
282 | |
283 | template <class T> |
284 | inline const T & |
285 | TypedAttribute<T>::value () const |
286 | { |
287 | return _value; |
288 | } |
289 | |
290 | |
291 | template <class T> |
292 | const char * |
293 | TypedAttribute<T>::typeName () const |
294 | { |
295 | return staticTypeName(); |
296 | } |
297 | |
298 | |
299 | template <class T> |
300 | Attribute * |
301 | TypedAttribute<T>::makeNewAttribute () |
302 | { |
303 | return new TypedAttribute<T>(); |
304 | } |
305 | |
306 | |
307 | template <class T> |
308 | Attribute * |
309 | TypedAttribute<T>::copy () const |
310 | { |
311 | Attribute * attribute = new TypedAttribute<T>(); |
312 | attribute->copyValueFrom (*this); |
313 | return attribute; |
314 | } |
315 | |
316 | |
317 | template <class T> |
318 | void |
319 | TypedAttribute<T>::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, |
320 | int version) const |
321 | { |
322 | OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, _value); |
323 | } |
324 | |
325 | |
326 | template <class T> |
327 | void |
328 | TypedAttribute<T>::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, |
329 | int size, |
330 | int version) |
331 | { |
332 | OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, _value); |
333 | } |
334 | |
335 | |
336 | template <class T> |
337 | void |
338 | TypedAttribute<T>::copyValueFrom (const Attribute &other) |
339 | { |
340 | _value = cast(other)._value; |
341 | } |
342 | |
343 | |
344 | template <class T> |
345 | TypedAttribute<T> * |
346 | TypedAttribute<T>::cast (Attribute *attribute) |
347 | { |
348 | TypedAttribute<T> *t = |
349 | dynamic_cast <TypedAttribute<T> *> (attribute); |
350 | |
351 | if (t == 0) |
352 | throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type." ); |
353 | |
354 | return t; |
355 | } |
356 | |
357 | |
358 | template <class T> |
359 | const TypedAttribute<T> * |
360 | TypedAttribute<T>::cast (const Attribute *attribute) |
361 | { |
362 | const TypedAttribute<T> *t = |
363 | dynamic_cast <const TypedAttribute<T> *> (attribute); |
364 | |
365 | if (t == 0) |
366 | throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type." ); |
367 | |
368 | return t; |
369 | } |
370 | |
371 | |
372 | template <class T> |
373 | inline TypedAttribute<T> & |
374 | TypedAttribute<T>::cast (Attribute &attribute) |
375 | { |
376 | return *cast (&attribute); |
377 | } |
378 | |
379 | |
380 | template <class T> |
381 | inline const TypedAttribute<T> & |
382 | TypedAttribute<T>::cast (const Attribute &attribute) |
383 | { |
384 | return *cast (&attribute); |
385 | } |
386 | |
387 | |
388 | template <class T> |
389 | inline void |
390 | TypedAttribute<T>::registerAttributeType () |
391 | { |
392 | Attribute::registerAttributeType (staticTypeName(), makeNewAttribute); |
393 | } |
394 | |
395 | |
396 | template <class T> |
397 | inline void |
398 | TypedAttribute<T>::unRegisterAttributeType () |
399 | { |
400 | Attribute::unRegisterAttributeType (staticTypeName()); |
401 | } |
402 | |
403 | |
404 | OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT |
405 | |
406 | |
407 | #endif |
408 | |