/** * 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; }