Home | History | Annotate | Download | only in IlmImf
      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 
     50 
     51 namespace Imf {
     52 
     53 
     54 class Attribute
     55 {
     56   public:
     57 
     58     //---------------------------
     59     // Constructor and destructor
     60     //---------------------------
     61 
     62     Attribute ();
     63     virtual ~Attribute ();
     64 
     65 
     66     //-------------------------------
     67     // Get this attribute's type name
     68     //-------------------------------
     69 
     70     virtual const char *	typeName () const = 0;
     71 
     72 
     73     //------------------------------
     74     // Make a copy of this attribute
     75     //------------------------------
     76 
     77     virtual Attribute *		copy () const = 0;
     78 
     79 
     80     //----------------------------------------
     81     // Type-specific attribute I/O and copying
     82     //----------------------------------------
     83 
     84     virtual void		writeValueTo (OStream &os,
     85                           int version) const = 0;
     86 
     87     virtual void		readValueFrom (IStream &is,
     88                            int size,
     89                            int version) = 0;
     90 
     91     virtual void		copyValueFrom (const Attribute &other) = 0;
     92 
     93 
     94     //------------------
     95     // Attribute factory
     96     //------------------
     97 
     98     static Attribute *		newAttribute (const char typeName[]);
     99 
    100 
    101     //-----------------------------------------------------------
    102     // Test if a given attribute type has already been registered
    103     //-----------------------------------------------------------
    104 
    105     static bool			knownType (const char typeName[]);
    106 
    107 
    108   protected:
    109 
    110     //--------------------------------------------------
    111     // Register an attribute type so that newAttribute()
    112     // knows how to make objects of this type.
    113     //--------------------------------------------------
    114 
    115     static void		registerAttributeType (const char typeName[],
    116                            Attribute *(*newAttribute)());
    117 
    118     //------------------------------------------------------
    119     // Un-register an attribute type so that newAttribute()
    120     // no longer knows how to make objects of this type (for
    121     // debugging only).
    122     //------------------------------------------------------
    123 
    124     static void		unRegisterAttributeType (const char typeName[]);
    125 };
    126 
    127 
    128 //-------------------------------------------------
    129 // Class template for attributes of a specific type
    130 //-------------------------------------------------
    131 
    132 template <class T>
    133 class TypedAttribute: public Attribute
    134 {
    135   public:
    136 
    137     //----------------------------
    138     // Constructors and destructor
    139     //------------_---------------
    140 
    141     TypedAttribute ();
    142     TypedAttribute (const T &value);
    143     TypedAttribute (const TypedAttribute<T> &other);
    144     virtual ~TypedAttribute ();
    145 
    146 
    147     //--------------------------------
    148     // Access to the attribute's value
    149     //--------------------------------
    150 
    151     T &					value ();
    152     const T &				value () const;
    153 
    154 
    155     //--------------------------------
    156     // Get this attribute's type name.
    157     //--------------------------------
    158 
    159     virtual const char *		typeName () const;
    160 
    161 
    162     //---------------------------------------------------------
    163     // Static version of typeName()
    164     // This function must be specialized for each value type T.
    165     //---------------------------------------------------------
    166 
    167     static const char *			staticTypeName ();
    168 
    169 
    170     //---------------------
    171     // Make a new attribute
    172     //---------------------
    173 
    174     static Attribute *			makeNewAttribute ();
    175 
    176 
    177     //------------------------------
    178     // Make a copy of this attribute
    179     //------------------------------
    180 
    181     virtual Attribute *			copy () const;
    182 
    183 
    184     //-----------------------------------------------------------------
    185     // Type-specific attribute I/O and copying.
    186     // Depending on type T, these functions may have to be specialized.
    187     //-----------------------------------------------------------------
    188 
    189     virtual void		writeValueTo (OStream &os,
    190                           int version) const;
    191 
    192     virtual void		readValueFrom (IStream &is,
    193                            int size,
    194                            int version);
    195 
    196     virtual void		copyValueFrom (const Attribute &other);
    197 
    198 
    199     //------------------------------------------------------------
    200     // Dynamic casts that throw exceptions instead of returning 0.
    201     //------------------------------------------------------------
    202 
    203     static TypedAttribute *		cast (Attribute *attribute);
    204     static const TypedAttribute *	cast (const Attribute *attribute);
    205     static TypedAttribute &		cast (Attribute &attribute);
    206     static const TypedAttribute &	cast (const Attribute &attribute);
    207 
    208 
    209     //---------------------------------------------------------------
    210     // Register this attribute type so that Attribute::newAttribute()
    211     // knows how to make objects of this type.
    212     //
    213     // Note that this function is not thread-safe because it modifies
    214     // a global variable in the IlmIlm library.  A thread in a multi-
    215     // threaded program may call registerAttributeType() only when no
    216     // other thread is accessing any functions or classes in the
    217     // IlmImf library.
    218     //
    219     //---------------------------------------------------------------
    220 
    221     static void				registerAttributeType ();
    222 
    223 
    224     //-----------------------------------------------------
    225     // Un-register this attribute type (for debugging only)
    226     //-----------------------------------------------------
    227 
    228     static void				 unRegisterAttributeType ();
    229 
    230 
    231   private:
    232 
    233     T					_value;
    234 };
    235 
    236 
    237 //------------------------------------
    238 // Implementation of TypedAttribute<T>
    239 //------------------------------------
    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 (OStream &os, int) const
    320 {
    321     Xdr::write <StreamIO> (os, _value);
    322 }
    323 
    324 
    325 template <class T>
    326 void
    327 TypedAttribute<T>::readValueFrom (IStream &is, int, int)
    328 {
    329     Xdr::read <StreamIO> (is, _value);
    330 }
    331 
    332 
    333 template <class T>
    334 void
    335 TypedAttribute<T>::copyValueFrom (const Attribute &other)
    336 {
    337     _value = cast(other)._value;
    338 }
    339 
    340 
    341 template <class T>
    342 TypedAttribute<T> *
    343 TypedAttribute<T>::cast (Attribute *attribute)
    344 {
    345     TypedAttribute<T> *t =
    346     dynamic_cast <TypedAttribute<T> *> (attribute);
    347 
    348     if (t == 0)
    349     throw Iex::TypeExc ("Unexpected attribute type.");
    350 
    351     return t;
    352 }
    353 
    354 
    355 template <class T>
    356 const TypedAttribute<T> *
    357 TypedAttribute<T>::cast (const Attribute *attribute)
    358 {
    359     const TypedAttribute<T> *t =
    360     dynamic_cast <const TypedAttribute<T> *> (attribute);
    361 
    362     if (t == 0)
    363     throw Iex::TypeExc ("Unexpected attribute type.");
    364 
    365     return t;
    366 }
    367 
    368 
    369 template <class T>
    370 inline TypedAttribute<T> &
    371 TypedAttribute<T>::cast (Attribute &attribute)
    372 {
    373     return *cast (&attribute);
    374 }
    375 
    376 
    377 template <class T>
    378 inline const TypedAttribute<T> &
    379 TypedAttribute<T>::cast (const Attribute &attribute)
    380 {
    381     return *cast (&attribute);
    382 }
    383 
    384 
    385 template <class T>
    386 inline void
    387 TypedAttribute<T>::registerAttributeType ()
    388 {
    389     Attribute::registerAttributeType (staticTypeName(), makeNewAttribute);
    390 }
    391 
    392 
    393 template <class T>
    394 inline void
    395 TypedAttribute<T>::unRegisterAttributeType ()
    396 {
    397     Attribute::unRegisterAttributeType (staticTypeName());
    398 }
    399 
    400 
    401 } // namespace Imf
    402 
    403 #if defined(OPENEXR_DLL) && defined(_MSC_VER)
    404     // Tell MS VC++ to disable "non dll-interface class used as base
    405     // for dll-interface class" and "no suitable definition provided
    406     // for explicit template"
    407     #pragma warning (disable : 4275 4661)
    408 
    409     #if defined (ILMIMF_EXPORTS)
    410     #define IMF_EXPIMP_TEMPLATE
    411     #else
    412     #define IMF_EXPIMP_TEMPLATE extern
    413     #endif
    414 
    415     IMF_EXPIMP_TEMPLATE template class Imf::TypedAttribute<float>;
    416     IMF_EXPIMP_TEMPLATE template class Imf::TypedAttribute<double>;
    417 
    418     #pragma warning(default : 4251)
    419     #undef EXTERN_TEMPLATE
    420 #endif
    421 
    422 // Metrowerks compiler wants the .cpp file inlined, too
    423 #ifdef __MWERKS__
    424 #include <ImfAttribute.cpp>
    425 #endif
    426 
    427 #endif
    428