Panda3D
|
00001 // Filename: streamWrapper.I 00002 // Created by: drose (11Nov08) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 00016 //////////////////////////////////////////////////////////////////// 00017 // Function: StreamWrapperBase::Constructor 00018 // Access: Protected 00019 // Description: 00020 //////////////////////////////////////////////////////////////////// 00021 INLINE StreamWrapperBase:: 00022 StreamWrapperBase() { 00023 #ifdef SIMPLE_THREADS 00024 _lock_flag = false; 00025 #endif 00026 } 00027 00028 //////////////////////////////////////////////////////////////////// 00029 // Function: StreamWrapperBase::acquire 00030 // Access: Published 00031 // Description: Acquires the internal lock. 00032 // 00033 // User code should call this to take temporary 00034 // possession of the stream and perform direct I/O 00035 // operations on it, for instance to make several 00036 // sequential atomic reads. You may not call any of the 00037 // StreamWrapper methods while the lock is held, other 00038 // than release(). 00039 // 00040 // Use with extreme caution! This is a very low-level, 00041 // non-recursive lock. You must call acquire() only 00042 // once, and you must later call release() exactly once. 00043 // Failing to do so may result in a hard deadlock with 00044 // no available debugging features. 00045 //////////////////////////////////////////////////////////////////// 00046 INLINE void StreamWrapperBase:: 00047 acquire() { 00048 _lock.acquire(); 00049 #ifdef SIMPLE_THREADS 00050 while (_lock_flag) { 00051 thread_yield(); 00052 } 00053 _lock_flag = true; 00054 #endif 00055 } 00056 00057 //////////////////////////////////////////////////////////////////// 00058 // Function: StreamWrapperBase::release 00059 // Access: Published 00060 // Description: Releases the internal lock. Must be called exactly 00061 // once following a call to acquire(). See the cautions 00062 // with acquire(). 00063 //////////////////////////////////////////////////////////////////// 00064 INLINE void StreamWrapperBase:: 00065 release() { 00066 #ifdef SIMPLE_THREADS 00067 assert(_lock_flag); 00068 _lock_flag = false; 00069 #endif 00070 _lock.release(); 00071 } 00072 00073 //////////////////////////////////////////////////////////////////// 00074 // Function: IStreamWrapper::Constructor 00075 // Access: Public 00076 // Description: 00077 //////////////////////////////////////////////////////////////////// 00078 INLINE IStreamWrapper:: 00079 IStreamWrapper(istream *stream, bool owns_pointer) : 00080 _istream(stream), 00081 _owns_pointer(owns_pointer) 00082 { 00083 } 00084 00085 //////////////////////////////////////////////////////////////////// 00086 // Function: IStreamWrapper::Constructor 00087 // Access: Published 00088 // Description: 00089 //////////////////////////////////////////////////////////////////// 00090 INLINE IStreamWrapper:: 00091 IStreamWrapper(istream &stream) : 00092 _istream(&stream), 00093 _owns_pointer(false) 00094 { 00095 } 00096 00097 //////////////////////////////////////////////////////////////////// 00098 // Function: IStreamWrapper::get_istream 00099 // Access: Published 00100 // Description: Returns the istream this object is wrapping. 00101 //////////////////////////////////////////////////////////////////// 00102 INLINE istream *IStreamWrapper:: 00103 get_istream() const { 00104 return _istream; 00105 } 00106 00107 //////////////////////////////////////////////////////////////////// 00108 // Function: IStreamWrapper::get 00109 // Access: Public 00110 // Description: Atomically reads a single character from the stream. 00111 //////////////////////////////////////////////////////////////////// 00112 INLINE int IStreamWrapper:: 00113 get() { 00114 int result; 00115 acquire(); 00116 result = _istream->get(); 00117 release(); 00118 return result; 00119 } 00120 00121 00122 //////////////////////////////////////////////////////////////////// 00123 // Function: OStreamWrapper::Constructor 00124 // Access: Public 00125 // Description: 00126 //////////////////////////////////////////////////////////////////// 00127 INLINE OStreamWrapper:: 00128 OStreamWrapper(ostream *stream, bool owns_pointer, bool stringstream_hack) : 00129 _ostream(stream), 00130 _owns_pointer(owns_pointer), 00131 _stringstream_hack(stringstream_hack) 00132 { 00133 } 00134 00135 //////////////////////////////////////////////////////////////////// 00136 // Function: OStreamWrapper::Constructor 00137 // Access: Published 00138 // Description: 00139 //////////////////////////////////////////////////////////////////// 00140 INLINE OStreamWrapper:: 00141 OStreamWrapper(ostream &stream) : 00142 _ostream(&stream), 00143 _owns_pointer(false), 00144 _stringstream_hack(false) 00145 { 00146 } 00147 00148 //////////////////////////////////////////////////////////////////// 00149 // Function: OStreamWrapper::get_ostream 00150 // Access: Published 00151 // Description: Returns the ostream this object is wrapping. 00152 //////////////////////////////////////////////////////////////////// 00153 INLINE ostream *OStreamWrapper:: 00154 get_ostream() const { 00155 return _ostream; 00156 } 00157 00158 //////////////////////////////////////////////////////////////////// 00159 // Function: OStreamWrapper::put 00160 // Access: Public 00161 // Description: Atomically writes a single character to the stream. 00162 // Returns true on success, false on failure. 00163 //////////////////////////////////////////////////////////////////// 00164 INLINE bool OStreamWrapper:: 00165 put(char c) { 00166 bool success; 00167 acquire(); 00168 _ostream->put(c); 00169 success = !_ostream->bad(); 00170 release(); 00171 return success; 00172 } 00173 00174 //////////////////////////////////////////////////////////////////// 00175 // Function: StreamWrapper::Constructor 00176 // Access: Public 00177 // Description: 00178 //////////////////////////////////////////////////////////////////// 00179 INLINE StreamWrapper:: 00180 StreamWrapper(iostream *stream, bool owns_pointer, bool stringstream_hack) : 00181 IStreamWrapper(stream, false), 00182 OStreamWrapper(stream, false, stringstream_hack), 00183 _iostream(stream), 00184 _owns_pointer(owns_pointer) 00185 { 00186 } 00187 00188 //////////////////////////////////////////////////////////////////// 00189 // Function: StreamWrapper::Constructor 00190 // Access: Published 00191 // Description: 00192 //////////////////////////////////////////////////////////////////// 00193 INLINE StreamWrapper:: 00194 StreamWrapper(iostream &stream) : 00195 IStreamWrapper(&stream, false), 00196 OStreamWrapper(&stream, false), 00197 _iostream(&stream), 00198 _owns_pointer(false) 00199 { 00200 } 00201 00202 //////////////////////////////////////////////////////////////////// 00203 // Function: StreamWrapper::get_iostream 00204 // Access: Published 00205 // Description: Returns the iostream this object is wrapping. 00206 //////////////////////////////////////////////////////////////////// 00207 INLINE iostream *StreamWrapper:: 00208 get_iostream() const { 00209 return _iostream; 00210 }