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