Panda3D
 All Classes Functions Variables Enumerations
streamWrapper.cxx
1 // Filename: streamWrapper.cxx
2 // Created by: drose (11Nov08)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "streamWrapper.h"
16 
17 ////////////////////////////////////////////////////////////////////
18 // Function: IStreamWrapper::Destructor
19 // Access: Published
20 // Description:
21 ////////////////////////////////////////////////////////////////////
22 IStreamWrapper::
23 ~IStreamWrapper() {
24  if (_owns_pointer) {
25  // For some reason--compiler bug in gcc 3.2?--explicitly deleting
26  // the stream pointer does not call the appropriate global delete
27  // function; instead apparently calling the system delete
28  // function. So we call the delete function by hand instead.
29 #if !defined(WIN32_VC) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
30  _istream->~istream();
31  (*global_operator_delete)(_istream);
32 #else
33  delete _istream;
34 #endif
35  }
36 }
37 
38 ////////////////////////////////////////////////////////////////////
39 // Function: IStreamWrapper::read
40 // Access: Public
41 // Description: Atomically reads a number of bytes from the stream,
42 // without error detection. If fewer bytes than
43 // requested are read, quietly fills the remaining bytes
44 // with 0.
45 ////////////////////////////////////////////////////////////////////
47 read(char *buffer, streamsize num_bytes) {
48  acquire();
49  _istream->clear();
50  _istream->read(buffer, num_bytes);
51  streamsize read_bytes = _istream->gcount();
52  while (read_bytes < num_bytes) {
53  // Fewer bytes than expected were read. Maybe more will be
54  // coming later.
55  release();
56  thread_yield();
57  acquire();
58 
59  _istream->read(buffer + read_bytes, num_bytes - read_bytes);
60  streamsize this_read_bytes = _istream->gcount();
61  assert(this_read_bytes <= num_bytes - read_bytes);
62  read_bytes += this_read_bytes;
63 
64  if (this_read_bytes == 0) {
65  // No, don't expect any more.
66  memset(buffer + read_bytes, 0, num_bytes - read_bytes);
67  break;
68  }
69  }
70  assert(read_bytes <= num_bytes);
71  release();
72 }
73 
74 ////////////////////////////////////////////////////////////////////
75 // Function: IStreamWrapper::read
76 // Access: Public
77 // Description: Atomically reads a number of bytes from the stream.
78 // Returns the number of bytes actually read.
79 ////////////////////////////////////////////////////////////////////
81 read(char *buffer, streamsize num_bytes, streamsize &read_bytes) {
82  acquire();
83  _istream->clear();
84  _istream->read(buffer, num_bytes);
85  read_bytes = _istream->gcount();
86  assert(read_bytes <= num_bytes);
87  release();
88 }
89 
90 ////////////////////////////////////////////////////////////////////
91 // Function: IStreamWrapper::read
92 // Access: Public
93 // Description: Atomically reads a number of bytes from the stream.
94 // Returns the number of bytes actually read, and
95 // whether an eof condition was detected by the
96 // operation.
97 ////////////////////////////////////////////////////////////////////
99 read(char *buffer, streamsize num_bytes, streamsize &read_bytes, bool &eof) {
100  acquire();
101  _istream->clear();
102  _istream->read(buffer, num_bytes);
103  read_bytes = _istream->gcount();
104  assert(read_bytes <= num_bytes);
105  eof = _istream->eof() || _istream->fail();
106  release();
107 }
108 
109 ////////////////////////////////////////////////////////////////////
110 // Function: IStreamWrapper::seek_read
111 // Access: Public
112 // Description: Atomically seeks to a particular offset from the
113 // beginning of the file, and reads a number of bytes
114 // from the stream. Returns the number of bytes
115 // actually read, and whether an eof condition was
116 // detected by the operation.
117 ////////////////////////////////////////////////////////////////////
118 void IStreamWrapper::
119 seek_read(streamsize pos, char *buffer, streamsize num_bytes,
120  streamsize &read_bytes, bool &eof) {
121  acquire();
122  _istream->clear();
123  _istream->seekg(pos);
124  _istream->read(buffer, num_bytes);
125  read_bytes = _istream->gcount();
126  assert(read_bytes <= num_bytes);
127  eof = _istream->eof() || _istream->fail();
128  release();
129 }
130 
131 ////////////////////////////////////////////////////////////////////
132 // Function: IStreamWrapper::seek_gpos_eof
133 // Access: Public
134 // Description: Atomically seeks to EOF and returns the gpos there;
135 // that is, returns the file size. Note that the EOF
136 // might have been moved in another thread by the time
137 // this method returns.
138 ////////////////////////////////////////////////////////////////////
139 streamsize IStreamWrapper::
141  streamsize pos;
142  acquire();
143  _istream->seekg(0, ios::end);
144  pos = _istream->tellg();
145  release();
146 
147  return pos;
148 }
149 
150 ////////////////////////////////////////////////////////////////////
151 // Function: OStreamWrapper::Destructor
152 // Access: Published
153 // Description:
154 ////////////////////////////////////////////////////////////////////
155 OStreamWrapper::
156 ~OStreamWrapper() {
157  if (_owns_pointer) {
158  // For some reason--compiler bug in gcc 3.2?--explicitly deleting
159  // the stream pointer does not call the appropriate global delete
160  // function; instead apparently calling the system delete
161  // function. So we call the delete function by hand instead.
162 #if !defined(WIN32_VC) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
163  _ostream->~ostream();
164  (*global_operator_delete)(_ostream);
165 #else
166  delete _ostream;
167 #endif
168  }
169 }
170 
171 ////////////////////////////////////////////////////////////////////
172 // Function: OStreamWrapper::write
173 // Access: Public
174 // Description: Atomically writes a number of bytes to the stream,
175 // without error detection.
176 ////////////////////////////////////////////////////////////////////
177 void OStreamWrapper::
178 write(const char *buffer, streamsize num_bytes) {
179  acquire();
180  _ostream->write(buffer, num_bytes);
181  release();
182 }
183 
184 ////////////////////////////////////////////////////////////////////
185 // Function: OStreamWrapper::read
186 // Access: Public
187 // Description: Atomically writes a number of bytes to the stream.
188 // Returns whether a failure condition was detected by
189 // the operation.
190 ////////////////////////////////////////////////////////////////////
191 void OStreamWrapper::
192 write(const char *buffer, streamsize num_bytes, bool &fail) {
193  acquire();
194  _ostream->clear();
195  _ostream->write(buffer, num_bytes);
196  fail = _ostream->fail();
197  release();
198 }
199 
200 ////////////////////////////////////////////////////////////////////
201 // Function: OStreamWrapper::seek_write
202 // Access: Public
203 // Description: Atomically seeks to a particular offset from the
204 // beginning of the file, and writes a number of bytes
205 // to the stream. Returns whether a failure condition
206 // was detected by the operation.
207 ////////////////////////////////////////////////////////////////////
208 void OStreamWrapper::
209 seek_write(streamsize pos, const char *buffer, streamsize num_bytes,
210  bool &fail) {
211  acquire();
212  _ostream->clear();
213  _ostream->seekp(pos);
214 
215 #ifdef WIN32_VC
216  if (_ostream->fail() && _stringstream_hack && pos == 0) {
217  // Ignore an unsuccessful attempt to seekp(0) if
218  // _stringstream_hack is true.
219  _ostream->clear();
220  }
221 #endif // WIN32_VC
222 
223  _ostream->write(buffer, num_bytes);
224  fail = _ostream->fail();
225  release();
226 }
227 
228 ////////////////////////////////////////////////////////////////////
229 // Function: OStreamWrapper::seek_eof_write
230 // Access: Public
231 // Description: Atomically seeks to the end of the file, and writes a
232 // number of bytes to the stream. Returns whether a
233 // failure condition was detected by the operation.
234 ////////////////////////////////////////////////////////////////////
235 void OStreamWrapper::
236 seek_eof_write(const char *buffer, streamsize num_bytes, bool &fail) {
237  acquire();
238  _ostream->clear();
239  _ostream->seekp(0, ios::end);
240 
241 #ifdef WIN32_VC
242  if (_ostream->fail() && _stringstream_hack) {
243  // Ignore an unsuccessful attempt to seekp(0) if
244  // _stringstream_hack is true.
245  _ostream->clear();
246  }
247 #endif // WIN32_VC
248 
249  _ostream->write(buffer, num_bytes);
250  fail = _ostream->fail();
251  release();
252 }
253 
254 ////////////////////////////////////////////////////////////////////
255 // Function: OStreamWrapper::seek_ppos_eof
256 // Access: Public
257 // Description: Atomically seeks to EOF and returns the ppos there;
258 // that is, returns the file size. Note that the EOF
259 // might have been moved in another thread by the time
260 // this method returns.
261 ////////////////////////////////////////////////////////////////////
262 streamsize OStreamWrapper::
264  streamsize pos;
265  acquire();
266  _ostream->seekp(0, ios::end);
267 
268 #ifdef WIN32_VC
269  if (_ostream->fail() && _stringstream_hack) {
270  // Ignore an unsuccessful attempt to seekp(0) if
271  // _stringstream_hack is true.
272  _ostream->clear();
273  release();
274  return 0;
275  }
276 #endif // WIN32_VC
277 
278  pos = _ostream->tellp();
279  release();
280 
281  return pos;
282 }
283 
284 ////////////////////////////////////////////////////////////////////
285 // Function: StreamWrapper::Destructor
286 // Access: Published
287 // Description:
288 ////////////////////////////////////////////////////////////////////
289 StreamWrapper::
290 ~StreamWrapper() {
291  if (_owns_pointer) {
292  // For some reason--compiler bug in gcc 3.2?--explicitly deleting
293  // the stream pointer does not call the appropriate global delete
294  // function; instead apparently calling the system delete
295  // function. So we call the delete function by hand instead.
296 #if !defined(WIN32_VC) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
297  _iostream->~iostream();
298  (*global_operator_delete)(_iostream);
299 #else
300  delete _iostream;
301 #endif
302  }
303 }
void seek_write(streamsize pos, const char *buffer, streamsize num_bytes, bool &fail)
Atomically seeks to a particular offset from the beginning of the file, and writes a number of bytes ...
void seek_eof_write(const char *buffer, streamsize num_bytes, bool &fail)
Atomically seeks to the end of the file, and writes a number of bytes to the stream.
void write(const char *buffer, streamsize num_bytes)
Atomically writes a number of bytes to the stream, without error detection.
void seek_read(streamsize pos, char *buffer, streamsize num_bytes, streamsize &read_bytes, bool &eof)
Atomically seeks to a particular offset from the beginning of the file, and reads a number of bytes f...
void release()
Releases the internal lock.
Definition: streamWrapper.I:65
streamsize seek_gpos_eof()
Atomically seeks to EOF and returns the gpos there; that is, returns the file size.
streamsize seek_ppos_eof()
Atomically seeks to EOF and returns the ppos there; that is, returns the file size.
void read(char *buffer, streamsize num_bytes)
Atomically reads a number of bytes from the stream, without error detection.
void acquire()
Acquires the internal lock.
Definition: streamWrapper.I:47