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 51namespace Imf { 52 53 54class 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 132template <class T> 133class 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 241template <class T> 242TypedAttribute<T>::TypedAttribute (): _value (T()) 243{ 244 // empty 245} 246 247 248template <class T> 249TypedAttribute<T>::TypedAttribute (const T &value): _value (value) 250{ 251 // empty 252} 253 254 255template <class T> 256TypedAttribute<T>::TypedAttribute (const TypedAttribute<T> &other): 257 _value () 258{ 259 copyValueFrom (other); 260} 261 262 263template <class T> 264TypedAttribute<T>::~TypedAttribute () 265{ 266 // empty 267} 268 269 270template <class T> 271inline T & 272TypedAttribute<T>::value () 273{ 274 return _value; 275} 276 277 278template <class T> 279inline const T & 280TypedAttribute<T>::value () const 281{ 282 return _value; 283} 284 285 286template <class T> 287const char * 288TypedAttribute<T>::typeName () const 289{ 290 return staticTypeName(); 291} 292 293 294template <class T> 295Attribute * 296TypedAttribute<T>::makeNewAttribute () 297{ 298 return new TypedAttribute<T>(); 299} 300 301 302template <class T> 303Attribute * 304TypedAttribute<T>::copy () const 305{ 306 Attribute * attribute = new TypedAttribute<T>(); 307 attribute->copyValueFrom (*this); 308 return attribute; 309} 310 311 312template <class T> 313void 314TypedAttribute<T>::writeValueTo (OStream &os, int version) const 315{ 316 Xdr::write <StreamIO> (os, _value); 317} 318 319 320template <class T> 321void 322TypedAttribute<T>::readValueFrom (IStream &is, int size, int version) 323{ 324 Xdr::read <StreamIO> (is, _value); 325} 326 327 328template <class T> 329void 330TypedAttribute<T>::copyValueFrom (const Attribute &other) 331{ 332 _value = cast(other)._value; 333} 334 335 336template <class T> 337TypedAttribute<T> * 338TypedAttribute<T>::cast (Attribute *attribute) 339{ 340 TypedAttribute<T> *t = 341 dynamic_cast <TypedAttribute<T> *> (attribute); 342 343 if (t == 0) 344 throw Iex::TypeExc ("Unexpected attribute type."); 345 346 return t; 347} 348 349 350template <class T> 351const TypedAttribute<T> * 352TypedAttribute<T>::cast (const Attribute *attribute) 353{ 354 const TypedAttribute<T> *t = 355 dynamic_cast <const TypedAttribute<T> *> (attribute); 356 357 if (t == 0) 358 throw Iex::TypeExc ("Unexpected attribute type."); 359 360 return t; 361} 362 363 364template <class T> 365inline TypedAttribute<T> & 366TypedAttribute<T>::cast (Attribute &attribute) 367{ 368 return *cast (&attribute); 369} 370 371 372template <class T> 373inline const TypedAttribute<T> & 374TypedAttribute<T>::cast (const Attribute &attribute) 375{ 376 return *cast (&attribute); 377} 378 379 380template <class T> 381inline void 382TypedAttribute<T>::registerAttributeType () 383{ 384 Attribute::registerAttributeType (staticTypeName(), makeNewAttribute); 385} 386 387 388template <class T> 389inline void 390TypedAttribute<T>::unRegisterAttributeType () 391{ 392 Attribute::unRegisterAttributeType (staticTypeName()); 393} 394 395 396} // namespace Imf 397 398#if defined(OPENEXR_DLL) && defined(_MSC_VER) 399 // Tell MS VC++ to disable "non dll-interface class used as base 400 // for dll-interface class" and "no suitable definition provided 401 // for explicit template" 402 #pragma warning (disable : 4275 4661) 403 404 #if defined (ILMIMF_EXPORTS) 405 #define IMF_EXPIMP_TEMPLATE 406 #else 407 #define IMF_EXPIMP_TEMPLATE extern 408 #endif 409 410 IMF_EXPIMP_TEMPLATE template class Imf::TypedAttribute<float>; 411 IMF_EXPIMP_TEMPLATE template class Imf::TypedAttribute<double>; 412 413 #pragma warning(default : 4251) 414 #undef EXTERN_TEMPLATE 415#endif 416 417// Metrowerks compiler wants the .cpp file inlined, too 418#ifdef __MWERKS__ 419#include <ImfAttribute.cpp> 420#endif 421 422#endif 423