historical/toontown-classic.git/panda/include/streamWrapper.I
2024-01-16 11:20:27 -06:00

198 lines
3.9 KiB
Text

/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file streamWrapper.I
* @author drose
* @date 2008-11-11
*/
/**
*
*/
INLINE StreamWrapperBase::
StreamWrapperBase() {
#ifdef SIMPLE_THREADS
_lock_flag = false;
#endif
}
/**
* Acquires the internal lock.
*
* User code should call this to take temporary possession of the stream and
* perform direct I/O operations on it, for instance to make several
* sequential atomic reads. You may not call any of the StreamWrapper methods
* while the lock is held, other than release().
*
* Use with extreme caution! This is a very low-level, non-recursive lock.
* You must call acquire() only once, and you must later call release()
* exactly once. Failing to do so may result in a hard deadlock with no
* available debugging features.
*/
INLINE void StreamWrapperBase::
acquire() {
_lock.lock();
#ifdef SIMPLE_THREADS
while (_lock_flag) {
thread_yield();
}
_lock_flag = true;
#endif
}
/**
* Releases the internal lock. Must be called exactly once following a call
* to acquire(). See the cautions with acquire().
*/
INLINE void StreamWrapperBase::
release() {
#ifdef SIMPLE_THREADS
assert(_lock_flag);
_lock_flag = false;
#endif
_lock.unlock();
}
/**
* Increments the reference count. Only has impact if the class that manages
* this StreamWrapper's lifetime (eg. Multifile) respects it.
*/
INLINE void StreamWrapperBase::
ref() const {
AtomicAdjust::inc(_ref_count);
}
/**
* Decrements the reference count. Only has impact if the class that manages
* this StreamWrapper's lifetime (eg. Multifile) respects it.
*/
INLINE bool StreamWrapperBase::
unref() const {
return AtomicAdjust::dec(_ref_count);
}
/**
*
*/
INLINE IStreamWrapper::
IStreamWrapper(std::istream *stream, bool owns_pointer) :
_istream(stream),
_owns_pointer(owns_pointer)
{
}
/**
*
*/
INLINE IStreamWrapper::
IStreamWrapper(std::istream &stream) :
_istream(&stream),
_owns_pointer(false)
{
}
/**
* Returns the istream this object is wrapping.
*/
INLINE std::istream *IStreamWrapper::
get_istream() const {
return _istream;
}
/**
* Atomically reads a single character from the stream.
*/
INLINE int IStreamWrapper::
get() {
int result;
acquire();
result = _istream->get();
release();
return result;
}
/**
*
*/
INLINE OStreamWrapper::
OStreamWrapper(std::ostream *stream, bool owns_pointer, bool stringstream_hack) :
_ostream(stream),
_owns_pointer(owns_pointer)
#ifdef WIN32_VC
, _stringstream_hack(stringstream_hack)
#endif
{
}
/**
*
*/
INLINE OStreamWrapper::
OStreamWrapper(std::ostream &stream) :
_ostream(&stream),
_owns_pointer(false)
#ifdef WIN32_VC
, _stringstream_hack(false)
#endif
{
}
/**
* Returns the ostream this object is wrapping.
*/
INLINE std::ostream *OStreamWrapper::
get_ostream() const {
return _ostream;
}
/**
* Atomically writes a single character to the stream. Returns true on
* success, false on failure.
*/
INLINE bool OStreamWrapper::
put(char c) {
bool success;
acquire();
_ostream->put(c);
success = !_ostream->bad();
release();
return success;
}
/**
*
*/
INLINE StreamWrapper::
StreamWrapper(std::iostream *stream, bool owns_pointer, bool stringstream_hack) :
IStreamWrapper(stream, false),
OStreamWrapper(stream, false, stringstream_hack),
_iostream(stream),
_owns_pointer(owns_pointer)
{
}
/**
*
*/
INLINE StreamWrapper::
StreamWrapper(std::iostream &stream) :
IStreamWrapper(&stream, false),
OStreamWrapper(&stream, false),
_iostream(&stream),
_owns_pointer(false)
{
}
/**
* Returns the iostream this object is wrapping.
*/
INLINE std::iostream *StreamWrapper::
get_iostream() const {
return _iostream;
}