| /////////////////////////////////////////////////////////////////////////// |
| // |
| // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas |
| // Digital Ltd. LLC |
| // |
| // All rights reserved. |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are |
| // met: |
| // * Redistributions of source code must retain the above copyright |
| // notice, this list of conditions and the following disclaimer. |
| // * Redistributions in binary form must reproduce the above |
| // copyright notice, this list of conditions and the following disclaimer |
| // in the documentation and/or other materials provided with the |
| // distribution. |
| // * Neither the name of Industrial Light & Magic nor the names of |
| // its contributors may be used to endorse or promote products derived |
| // from this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| // |
| /////////////////////////////////////////////////////////////////////////// |
| |
| |
| |
| #ifndef INCLUDED_IMF_ATTRIBUTE_H |
| #define INCLUDED_IMF_ATTRIBUTE_H |
| |
| //----------------------------------------------------------------------------- |
| // |
| // class Attribute |
| // |
| //----------------------------------------------------------------------------- |
| |
| #include "IexBaseExc.h" |
| #include <ImfIO.h> |
| #include <ImfXdr.h> |
| |
| |
| namespace Imf { |
| |
| |
| class Attribute |
| { |
| public: |
| |
| //--------------------------- |
| // Constructor and destructor |
| //--------------------------- |
| |
| Attribute (); |
| virtual ~Attribute (); |
| |
| |
| //------------------------------- |
| // Get this attribute's type name |
| //------------------------------- |
| |
| virtual const char * typeName () const = 0; |
| |
| |
| //------------------------------ |
| // Make a copy of this attribute |
| //------------------------------ |
| |
| virtual Attribute * copy () const = 0; |
| |
| |
| //---------------------------------------- |
| // Type-specific attribute I/O and copying |
| //---------------------------------------- |
| |
| virtual void writeValueTo (OStream &os, |
| int version) const = 0; |
| |
| virtual void readValueFrom (IStream &is, |
| int size, |
| int version) = 0; |
| |
| virtual void copyValueFrom (const Attribute &other) = 0; |
| |
| |
| //------------------ |
| // Attribute factory |
| //------------------ |
| |
| static Attribute * newAttribute (const char typeName[]); |
| |
| |
| //----------------------------------------------------------- |
| // Test if a given attribute type has already been registered |
| //----------------------------------------------------------- |
| |
| static bool knownType (const char typeName[]); |
| |
| |
| protected: |
| |
| //-------------------------------------------------- |
| // Register an attribute type so that newAttribute() |
| // knows how to make objects of this type. |
| //-------------------------------------------------- |
| |
| static void registerAttributeType (const char typeName[], |
| Attribute *(*newAttribute)()); |
| |
| //------------------------------------------------------ |
| // Un-register an attribute type so that newAttribute() |
| // no longer knows how to make objects of this type (for |
| // debugging only). |
| //------------------------------------------------------ |
| |
| static void unRegisterAttributeType (const char typeName[]); |
| }; |
| |
| |
| //------------------------------------------------- |
| // Class template for attributes of a specific type |
| //------------------------------------------------- |
| |
| template <class T> |
| class TypedAttribute: public Attribute |
| { |
| public: |
| |
| //---------------------------- |
| // Constructors and destructor |
| //------------_--------------- |
| |
| TypedAttribute (); |
| TypedAttribute (const T &value); |
| TypedAttribute (const TypedAttribute<T> &other); |
| virtual ~TypedAttribute (); |
| |
| |
| //-------------------------------- |
| // Access to the attribute's value |
| //-------------------------------- |
| |
| T & value (); |
| const T & value () const; |
| |
| |
| //-------------------------------- |
| // Get this attribute's type name. |
| //-------------------------------- |
| |
| virtual const char * typeName () const; |
| |
| |
| //--------------------------------------------------------- |
| // Static version of typeName() |
| // This function must be specialized for each value type T. |
| //--------------------------------------------------------- |
| |
| static const char * staticTypeName (); |
| |
| |
| //--------------------- |
| // Make a new attribute |
| //--------------------- |
| |
| static Attribute * makeNewAttribute (); |
| |
| |
| //------------------------------ |
| // Make a copy of this attribute |
| //------------------------------ |
| |
| virtual Attribute * copy () const; |
| |
| |
| //----------------------------------------------------------------- |
| // Type-specific attribute I/O and copying. |
| // Depending on type T, these functions may have to be specialized. |
| //----------------------------------------------------------------- |
| |
| virtual void writeValueTo (OStream &os, |
| int version) const; |
| |
| virtual void readValueFrom (IStream &is, |
| int size, |
| int version); |
| |
| virtual void copyValueFrom (const Attribute &other); |
| |
| |
| //------------------------------------------------------------ |
| // Dynamic casts that throw exceptions instead of returning 0. |
| //------------------------------------------------------------ |
| |
| static TypedAttribute * cast (Attribute *attribute); |
| static const TypedAttribute * cast (const Attribute *attribute); |
| static TypedAttribute & cast (Attribute &attribute); |
| static const TypedAttribute & cast (const Attribute &attribute); |
| |
| |
| //--------------------------------------------------------------- |
| // Register this attribute type so that Attribute::newAttribute() |
| // knows how to make objects of this type. |
| // |
| // Note that this function is not thread-safe because it modifies |
| // a global variable in the IlmIlm library. A thread in a multi- |
| // threaded program may call registerAttributeType() only when no |
| // other thread is accessing any functions or classes in the |
| // IlmImf library. |
| // |
| //--------------------------------------------------------------- |
| |
| static void registerAttributeType (); |
| |
| |
| //----------------------------------------------------- |
| // Un-register this attribute type (for debugging only) |
| //----------------------------------------------------- |
| |
| static void unRegisterAttributeType (); |
| |
| |
| private: |
| |
| T _value; |
| }; |
| |
| |
| //------------------------------------ |
| // Implementation of TypedAttribute<T> |
| //------------------------------------ |
| |
| template <class T> |
| TypedAttribute<T>::TypedAttribute (): _value (T()) |
| { |
| // empty |
| } |
| |
| |
| template <class T> |
| TypedAttribute<T>::TypedAttribute (const T &value): _value (value) |
| { |
| // empty |
| } |
| |
| |
| template <class T> |
| TypedAttribute<T>::TypedAttribute (const TypedAttribute<T> &other): |
| _value () |
| { |
| copyValueFrom (other); |
| } |
| |
| |
| template <class T> |
| TypedAttribute<T>::~TypedAttribute () |
| { |
| // empty |
| } |
| |
| |
| template <class T> |
| inline T & |
| TypedAttribute<T>::value () |
| { |
| return _value; |
| } |
| |
| |
| template <class T> |
| inline const T & |
| TypedAttribute<T>::value () const |
| { |
| return _value; |
| } |
| |
| |
| template <class T> |
| const char * |
| TypedAttribute<T>::typeName () const |
| { |
| return staticTypeName(); |
| } |
| |
| |
| template <class T> |
| Attribute * |
| TypedAttribute<T>::makeNewAttribute () |
| { |
| return new TypedAttribute<T>(); |
| } |
| |
| |
| template <class T> |
| Attribute * |
| TypedAttribute<T>::copy () const |
| { |
| Attribute * attribute = new TypedAttribute<T>(); |
| attribute->copyValueFrom (*this); |
| return attribute; |
| } |
| |
| |
| template <class T> |
| void |
| TypedAttribute<T>::writeValueTo (OStream &os, int version) const |
| { |
| Xdr::write <StreamIO> (os, _value); |
| } |
| |
| |
| template <class T> |
| void |
| TypedAttribute<T>::readValueFrom (IStream &is, int size, int version) |
| { |
| Xdr::read <StreamIO> (is, _value); |
| } |
| |
| |
| template <class T> |
| void |
| TypedAttribute<T>::copyValueFrom (const Attribute &other) |
| { |
| _value = cast(other)._value; |
| } |
| |
| |
| template <class T> |
| TypedAttribute<T> * |
| TypedAttribute<T>::cast (Attribute *attribute) |
| { |
| TypedAttribute<T> *t = |
| dynamic_cast <TypedAttribute<T> *> (attribute); |
| |
| if (t == 0) |
| throw Iex::TypeExc ("Unexpected attribute type."); |
| |
| return t; |
| } |
| |
| |
| template <class T> |
| const TypedAttribute<T> * |
| TypedAttribute<T>::cast (const Attribute *attribute) |
| { |
| const TypedAttribute<T> *t = |
| dynamic_cast <const TypedAttribute<T> *> (attribute); |
| |
| if (t == 0) |
| throw Iex::TypeExc ("Unexpected attribute type."); |
| |
| return t; |
| } |
| |
| |
| template <class T> |
| inline TypedAttribute<T> & |
| TypedAttribute<T>::cast (Attribute &attribute) |
| { |
| return *cast (&attribute); |
| } |
| |
| |
| template <class T> |
| inline const TypedAttribute<T> & |
| TypedAttribute<T>::cast (const Attribute &attribute) |
| { |
| return *cast (&attribute); |
| } |
| |
| |
| template <class T> |
| inline void |
| TypedAttribute<T>::registerAttributeType () |
| { |
| Attribute::registerAttributeType (staticTypeName(), makeNewAttribute); |
| } |
| |
| |
| template <class T> |
| inline void |
| TypedAttribute<T>::unRegisterAttributeType () |
| { |
| Attribute::unRegisterAttributeType (staticTypeName()); |
| } |
| |
| |
| } // namespace Imf |
| |
| #if defined(OPENEXR_DLL) && defined(_MSC_VER) |
| // Tell MS VC++ to disable "non dll-interface class used as base |
| // for dll-interface class" and "no suitable definition provided |
| // for explicit template" |
| #pragma warning (disable : 4275 4661) |
| |
| #if defined (ILMIMF_EXPORTS) |
| #define IMF_EXPIMP_TEMPLATE |
| #else |
| #define IMF_EXPIMP_TEMPLATE extern |
| #endif |
| |
| IMF_EXPIMP_TEMPLATE template class Imf::TypedAttribute<float>; |
| IMF_EXPIMP_TEMPLATE template class Imf::TypedAttribute<double>; |
| |
| #pragma warning(default : 4251) |
| #undef EXTERN_TEMPLATE |
| #endif |
| |
| // Metrowerks compiler wants the .cpp file inlined, too |
| #ifdef __MWERKS__ |
| #include <ImfAttribute.cpp> |
| #endif |
| |
| #endif |