Home | History | Annotate | Download | only in IlmImf
      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