ImfAttribute.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. //
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. // Copyright (c) Contributors to the OpenEXR Project.
  4. //
  5. #ifndef INCLUDED_IMF_ATTRIBUTE_H
  6. #define INCLUDED_IMF_ATTRIBUTE_H
  7. //-----------------------------------------------------------------------------
  8. //
  9. // class Attribute
  10. //
  11. //-----------------------------------------------------------------------------
  12. #include "ImfForward.h"
  13. #include "ImfIO.h"
  14. #include "ImfXdr.h"
  15. #include "IexBaseExc.h"
  16. #include <typeinfo>
  17. #include <cstring>
  18. #if defined(_MSC_VER)
  19. // suppress warning about non-exported base classes
  20. #pragma warning (push)
  21. #pragma warning (disable : 4251)
  22. #pragma warning (disable : 4275)
  23. #endif
  24. OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
  25. class IMF_EXPORT_TYPE Attribute
  26. {
  27. public:
  28. //---------------------------
  29. // Constructor and destructor
  30. //---------------------------
  31. IMF_EXPORT Attribute ();
  32. IMF_EXPORT virtual ~Attribute ();
  33. //-------------------------------
  34. // Get this attribute's type name
  35. //-------------------------------
  36. virtual const char * typeName () const = 0;
  37. //------------------------------
  38. // Make a copy of this attribute
  39. //------------------------------
  40. virtual Attribute * copy () const = 0;
  41. //----------------------------------------
  42. // Type-specific attribute I/O and copying
  43. //----------------------------------------
  44. virtual void writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
  45. int version) const = 0;
  46. virtual void readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
  47. int size,
  48. int version) = 0;
  49. virtual void copyValueFrom (const Attribute &other) = 0;
  50. //------------------
  51. // Attribute factory
  52. //------------------
  53. IMF_EXPORT static Attribute * newAttribute (const char typeName[]);
  54. //-----------------------------------------------------------
  55. // Test if a given attribute type has already been registered
  56. //-----------------------------------------------------------
  57. IMF_EXPORT static bool knownType (const char typeName[]);
  58. protected:
  59. //--------------------------------------------------
  60. // Register an attribute type so that newAttribute()
  61. // knows how to make objects of this type.
  62. //--------------------------------------------------
  63. IMF_EXPORT
  64. static void registerAttributeType (const char typeName[],
  65. Attribute *(*newAttribute)());
  66. //------------------------------------------------------
  67. // Un-register an attribute type so that newAttribute()
  68. // no longer knows how to make objects of this type (for
  69. // debugging only).
  70. //------------------------------------------------------
  71. IMF_EXPORT
  72. static void unRegisterAttributeType (const char typeName[]);
  73. };
  74. //-------------------------------------------------
  75. // Class template for attributes of a specific type
  76. //-------------------------------------------------
  77. template <class T>
  78. class IMF_EXPORT_TEMPLATE_TYPE TypedAttribute: public Attribute
  79. {
  80. public:
  81. //------------------------------------------------------------
  82. // Constructors and destructor: default behavior. This assumes
  83. // that the type T is copyable/assignable/moveable.
  84. //------------------------------------------------------------
  85. TypedAttribute () = default;
  86. TypedAttribute (const T &value);
  87. TypedAttribute (const TypedAttribute<T> &other) = default;
  88. TypedAttribute (TypedAttribute<T> &&other) = default;
  89. //NB: if we use a default destructor, it wreaks havoc with where the vtable and such end up
  90. //at least under mingw+windows, and since we are providing extern template instantiations
  91. //this will be pretty trim and should reduce code bloat
  92. virtual ~TypedAttribute ();
  93. TypedAttribute& operator = (const TypedAttribute<T>& other) = default;
  94. TypedAttribute& operator = (TypedAttribute<T>&& other) = default;
  95. //--------------------------------
  96. // Access to the attribute's value
  97. //--------------------------------
  98. T & value ();
  99. const T &value () const;
  100. //--------------------------------
  101. // Get this attribute's type name.
  102. //--------------------------------
  103. virtual const char * typeName () const;
  104. //---------------------------------------------------------
  105. // Static version of typeName()
  106. // This function must be specialized for each value type T.
  107. //---------------------------------------------------------
  108. static const char * staticTypeName ();
  109. //---------------------
  110. // Make a new attribute
  111. //---------------------
  112. static Attribute * makeNewAttribute ();
  113. //------------------------------
  114. // Make a copy of this attribute
  115. //------------------------------
  116. virtual Attribute * copy () const;
  117. //-----------------------------------------------------------------
  118. // Type-specific attribute I/O and copying.
  119. // Depending on type T, these functions may have to be specialized.
  120. //-----------------------------------------------------------------
  121. virtual void writeValueTo (
  122. OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
  123. int version) const;
  124. virtual void readValueFrom (
  125. OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
  126. int size,
  127. int version);
  128. virtual void copyValueFrom (const Attribute &other);
  129. //------------------------------------------------------------
  130. // Dynamic casts that throw exceptions instead of returning 0.
  131. //------------------------------------------------------------
  132. static TypedAttribute * cast (Attribute *attribute);
  133. static const TypedAttribute * cast (const Attribute *attribute);
  134. static TypedAttribute & cast (Attribute &attribute);
  135. static const TypedAttribute & cast (const Attribute &attribute);
  136. //---------------------------------------------------------------
  137. // Register this attribute type so that Attribute::newAttribute()
  138. // knows how to make objects of this type.
  139. //
  140. // Note that this function is not thread-safe because it modifies
  141. // a global variable in the IlmIlm library. A thread in a multi-
  142. // threaded program may call registerAttributeType() only when no
  143. // other thread is accessing any functions or classes in the
  144. // OpenEXR library.
  145. //
  146. //---------------------------------------------------------------
  147. static void registerAttributeType ();
  148. //-----------------------------------------------------
  149. // Un-register this attribute type (for debugging only)
  150. //-----------------------------------------------------
  151. static void unRegisterAttributeType ();
  152. private:
  153. T _value;
  154. };
  155. //------------------------------------
  156. // Implementation of TypedAttribute<T>
  157. //------------------------------------
  158. template <class T>
  159. TypedAttribute<T>::TypedAttribute (const T & value):
  160. Attribute (),
  161. _value (value)
  162. {
  163. // empty
  164. }
  165. template <class T>
  166. TypedAttribute<T>::~TypedAttribute ()
  167. {
  168. // empty
  169. }
  170. template <class T>
  171. inline T &
  172. TypedAttribute<T>::value ()
  173. {
  174. return _value;
  175. }
  176. template <class T>
  177. inline const T &
  178. TypedAttribute<T>::value () const
  179. {
  180. return _value;
  181. }
  182. template <class T>
  183. const char *
  184. TypedAttribute<T>::typeName () const
  185. {
  186. return staticTypeName();
  187. }
  188. template <class T>
  189. Attribute *
  190. TypedAttribute<T>::makeNewAttribute ()
  191. {
  192. return new TypedAttribute<T>();
  193. }
  194. template <class T>
  195. Attribute *
  196. TypedAttribute<T>::copy () const
  197. {
  198. Attribute * attribute = new TypedAttribute<T>();
  199. attribute->copyValueFrom (*this);
  200. return attribute;
  201. }
  202. template <class T>
  203. void
  204. TypedAttribute<T>::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
  205. int version) const
  206. {
  207. OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, _value);
  208. }
  209. template <class T>
  210. void
  211. TypedAttribute<T>::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
  212. int size,
  213. int version)
  214. {
  215. OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, _value);
  216. }
  217. template <class T>
  218. void
  219. TypedAttribute<T>::copyValueFrom (const Attribute &other)
  220. {
  221. _value = cast(other)._value;
  222. }
  223. template <class T>
  224. TypedAttribute<T> *
  225. TypedAttribute<T>::cast (Attribute *attribute)
  226. {
  227. TypedAttribute<T> *t =
  228. dynamic_cast <TypedAttribute<T> *> (attribute);
  229. if (t == 0)
  230. throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type.");
  231. return t;
  232. }
  233. template <class T>
  234. const TypedAttribute<T> *
  235. TypedAttribute<T>::cast (const Attribute *attribute)
  236. {
  237. const TypedAttribute<T> *t =
  238. dynamic_cast <const TypedAttribute<T> *> (attribute);
  239. if (t == 0)
  240. throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type.");
  241. return t;
  242. }
  243. template <class T>
  244. inline TypedAttribute<T> &
  245. TypedAttribute<T>::cast (Attribute &attribute)
  246. {
  247. return *cast (&attribute);
  248. }
  249. template <class T>
  250. inline const TypedAttribute<T> &
  251. TypedAttribute<T>::cast (const Attribute &attribute)
  252. {
  253. return *cast (&attribute);
  254. }
  255. template <class T>
  256. inline void
  257. TypedAttribute<T>::registerAttributeType ()
  258. {
  259. Attribute::registerAttributeType (staticTypeName(), makeNewAttribute);
  260. }
  261. template <class T>
  262. inline void
  263. TypedAttribute<T>::unRegisterAttributeType ()
  264. {
  265. Attribute::unRegisterAttributeType (staticTypeName());
  266. }
  267. OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
  268. #if defined(_MSC_VER)
  269. #pragma warning (pop)
  270. #endif
  271. #endif