Panda3D
|
00001 // Filename: streamWrapper.h 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 #ifndef STREAMWRAPPER_H 00016 #define STREAMWRAPPER_H 00017 00018 #include "dtoolbase.h" 00019 #include "mutexImpl.h" 00020 00021 //////////////////////////////////////////////////////////////////// 00022 // Class : StreamWrapperBase 00023 // Description : The base class for both IStreamWrapper and 00024 // OStreamWrapper, this provides the common locking 00025 // interface. 00026 //////////////////////////////////////////////////////////////////// 00027 class EXPCL_DTOOLCONFIG StreamWrapperBase { 00028 protected: 00029 INLINE StreamWrapperBase(); 00030 00031 PUBLISHED: 00032 INLINE void acquire(); 00033 INLINE void release(); 00034 00035 private: 00036 MutexImpl _lock; 00037 #ifdef SIMPLE_THREADS 00038 // In the SIMPLE_THREADS case, we need to use a bool flag, because 00039 // MutexImpl defines to nothing in this case--but we still need to 00040 // achieve a form of locking, since I/O operations can cause the 00041 // thread to swap without warning. 00042 bool _lock_flag; 00043 #endif 00044 }; 00045 00046 //////////////////////////////////////////////////////////////////// 00047 // Class : IStreamWrapper 00048 // Description : This class provides a locking wrapper around an 00049 // arbitrary istream pointer. A thread may use this 00050 // class to perform an atomic seek/read/gcount 00051 // operation. 00052 //////////////////////////////////////////////////////////////////// 00053 class EXPCL_DTOOLCONFIG IStreamWrapper : virtual public StreamWrapperBase { 00054 public: 00055 INLINE IStreamWrapper(istream *stream, bool owns_pointer); 00056 PUBLISHED: 00057 INLINE IStreamWrapper(istream &stream); 00058 ~IStreamWrapper(); 00059 00060 INLINE istream *get_istream() const; 00061 00062 public: 00063 void read(char *buffer, streamsize num_bytes); 00064 void read(char *buffer, streamsize num_bytes, streamsize &read_bytes); 00065 void read(char *buffer, streamsize num_bytes, streamsize &read_bytes, bool &eof); 00066 void seek_read(streamsize pos, char *buffer, streamsize num_bytes, streamsize &read_bytes, bool &eof); 00067 INLINE int get(); 00068 streamsize seek_gpos_eof(); 00069 00070 private: 00071 istream *_istream; 00072 bool _owns_pointer; 00073 }; 00074 00075 //////////////////////////////////////////////////////////////////// 00076 // Class : OStreamWrapper 00077 // Description : This class provides a locking wrapper around an 00078 // arbitrary ostream pointer. A thread may use this 00079 // class to perform an atomic seek/write operation. 00080 //////////////////////////////////////////////////////////////////// 00081 class EXPCL_DTOOLCONFIG OStreamWrapper : virtual public StreamWrapperBase { 00082 public: 00083 INLINE OStreamWrapper(ostream *stream, bool owns_pointer, bool stringstream_hack = false); 00084 PUBLISHED: 00085 INLINE OStreamWrapper(ostream &stream); 00086 ~OStreamWrapper(); 00087 00088 INLINE ostream *get_ostream() const; 00089 00090 public: 00091 void write(const char *buffer, streamsize num_bytes); 00092 void write(const char *buffer, streamsize num_bytes, bool &fail); 00093 void seek_write(streamsize pos, const char *buffer, streamsize num_bytes, bool &fail); 00094 void seek_eof_write(const char *buffer, streamsize num_bytes, bool &fail); 00095 INLINE bool put(char c); 00096 streamsize seek_ppos_eof(); 00097 00098 private: 00099 ostream *_ostream; 00100 bool _owns_pointer; 00101 00102 // This flag is necessary to work around a weird quirk in the MSVS 00103 // C++ runtime library: an empty stringstream cannot successfully 00104 // seekp(0), until some data has been written to the stream. When 00105 // this flag is set true, we know we have a possibly-empty 00106 // stringstream, so we allow seekp(0) to fail silently, knowing that 00107 // there's no harm in this case. 00108 bool _stringstream_hack; 00109 }; 00110 00111 //////////////////////////////////////////////////////////////////// 00112 // Class : StreamWrapper 00113 // Description : This class provides a locking wrapper around a 00114 // combination ostream/istream pointer. 00115 //////////////////////////////////////////////////////////////////// 00116 class EXPCL_DTOOLCONFIG StreamWrapper : public IStreamWrapper, public OStreamWrapper { 00117 public: 00118 INLINE StreamWrapper(iostream *stream, bool owns_pointer, bool stringstream_hack = false); 00119 PUBLISHED: 00120 INLINE StreamWrapper(iostream &stream); 00121 ~StreamWrapper(); 00122 00123 INLINE iostream *get_iostream() const; 00124 00125 private: 00126 iostream *_iostream; 00127 bool _owns_pointer; 00128 }; 00129 00130 #include "streamWrapper.I" 00131 00132 #endif