ImfStdIO.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  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.67
  32. //
  33. ///////////////////////////////////////////////////////////////////////////
  34. //-----------------------------------------------------------------------------
  35. //
  36. // Low-level file input and output for OpenEXR
  37. // based on C++ standard iostreams.
  38. //
  39. //-----------------------------------------------------------------------------
  40. #include <ImfStdIO.h>
  41. #include "Iex.h"
  42. #include <errno.h>
  43. #ifdef _MSC_VER
  44. # define VC_EXTRALEAN
  45. # include <Windows.h>
  46. # include <string.h>
  47. #endif
  48. using namespace std;
  49. #include "ImfNamespace.h"
  50. OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
  51. namespace {
  52. #ifdef _MSC_VER
  53. std::wstring WidenFilename (const char *filename)
  54. {
  55. std::wstring ret;
  56. int fnlen = static_cast<int>( strlen(filename) );
  57. int len = MultiByteToWideChar(CP_UTF8, 0, filename, fnlen, NULL, 0 );
  58. if (len > 0)
  59. {
  60. ret.resize(len);
  61. MultiByteToWideChar(CP_UTF8, 0, filename, fnlen, &ret[0], len);
  62. }
  63. return ret;
  64. }
  65. #endif
  66. void
  67. clearError ()
  68. {
  69. errno = 0;
  70. }
  71. bool
  72. checkError (istream &is, streamsize expected = 0)
  73. {
  74. if (!is)
  75. {
  76. if (errno)
  77. IEX_NAMESPACE::throwErrnoExc();
  78. if (is.gcount() < expected)
  79. {
  80. THROW (IEX_NAMESPACE::InputExc, "Early end of file: read " << is.gcount()
  81. << " out of " << expected << " requested bytes.");
  82. }
  83. return false;
  84. }
  85. return true;
  86. }
  87. void
  88. checkError (ostream &os)
  89. {
  90. if (!os)
  91. {
  92. if (errno)
  93. IEX_NAMESPACE::throwErrnoExc();
  94. throw IEX_NAMESPACE::ErrnoExc ("File output failed.");
  95. }
  96. }
  97. } // namespace
  98. StdIFStream::StdIFStream (const char fileName[]):
  99. OPENEXR_IMF_INTERNAL_NAMESPACE::IStream (fileName),
  100. _is (new ifstream (
  101. #ifdef _MSC_VER
  102. WidenFilename(fileName).c_str(),
  103. #else
  104. fileName,
  105. #endif
  106. ios_base::binary)),
  107. _deleteStream (true)
  108. {
  109. if (!*_is)
  110. {
  111. delete _is;
  112. IEX_NAMESPACE::throwErrnoExc();
  113. }
  114. }
  115. StdIFStream::StdIFStream (ifstream &is, const char fileName[]):
  116. OPENEXR_IMF_INTERNAL_NAMESPACE::IStream (fileName),
  117. _is (&is),
  118. _deleteStream (false)
  119. {
  120. // empty
  121. }
  122. StdIFStream::~StdIFStream ()
  123. {
  124. if (_deleteStream)
  125. delete _is;
  126. }
  127. bool
  128. StdIFStream::read (char c[/*n*/], int n)
  129. {
  130. if (!*_is)
  131. throw IEX_NAMESPACE::InputExc ("Unexpected end of file.");
  132. clearError();
  133. _is->read (c, n);
  134. return checkError (*_is, n);
  135. }
  136. Int64
  137. StdIFStream::tellg ()
  138. {
  139. return std::streamoff (_is->tellg());
  140. }
  141. void
  142. StdIFStream::seekg (Int64 pos)
  143. {
  144. _is->seekg (pos);
  145. checkError (*_is);
  146. }
  147. void
  148. StdIFStream::clear ()
  149. {
  150. _is->clear();
  151. }
  152. StdOFStream::StdOFStream (const char fileName[]):
  153. OPENEXR_IMF_INTERNAL_NAMESPACE::OStream (fileName),
  154. _os (new ofstream (
  155. #ifdef _MSC_VER
  156. WidenFilename(fileName).c_str(),
  157. #else
  158. fileName,
  159. #endif
  160. ios_base::binary)),
  161. _deleteStream (true)
  162. {
  163. if (!*_os)
  164. {
  165. delete _os;
  166. IEX_NAMESPACE::throwErrnoExc();
  167. }
  168. }
  169. StdOFStream::StdOFStream (ofstream &os, const char fileName[]):
  170. OPENEXR_IMF_INTERNAL_NAMESPACE::OStream (fileName),
  171. _os (&os),
  172. _deleteStream (false)
  173. {
  174. // empty
  175. }
  176. StdOFStream::~StdOFStream ()
  177. {
  178. if (_deleteStream)
  179. delete _os;
  180. }
  181. void
  182. StdOFStream::write (const char c[/*n*/], int n)
  183. {
  184. clearError();
  185. _os->write (c, n);
  186. checkError (*_os);
  187. }
  188. Int64
  189. StdOFStream::tellp ()
  190. {
  191. return std::streamoff (_os->tellp());
  192. }
  193. void
  194. StdOFStream::seekp (Int64 pos)
  195. {
  196. _os->seekp (pos);
  197. checkError (*_os);
  198. }
  199. StdOSStream::StdOSStream (): OPENEXR_IMF_INTERNAL_NAMESPACE::OStream ("(string)")
  200. {
  201. // empty
  202. }
  203. void
  204. StdOSStream::write (const char c[/*n*/], int n)
  205. {
  206. clearError();
  207. _os.write (c, n);
  208. checkError (_os);
  209. }
  210. Int64
  211. StdOSStream::tellp ()
  212. {
  213. return std::streamoff (_os.tellp());
  214. }
  215. void
  216. StdOSStream::seekp (Int64 pos)
  217. {
  218. _os.seekp (pos);
  219. checkError (_os);
  220. }
  221. OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT