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