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