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