Panda3D
streamWrapper.h
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.h
10  * @author drose
11  * @date 2008-11-11
12  */
13 
14 #ifndef STREAMWRAPPER_H
15 #define STREAMWRAPPER_H
16 
17 #include "dtoolbase.h"
18 #include "mutexImpl.h"
19 #include "atomicAdjust.h"
20 
21 /**
22  * The base class for both IStreamWrapper and OStreamWrapper, this provides
23  * the common locking interface.
24  */
25 class EXPCL_DTOOL_PRC StreamWrapperBase {
26 protected:
27  INLINE StreamWrapperBase();
28  INLINE StreamWrapperBase(const StreamWrapperBase &copy) = delete;
29 
30 PUBLISHED:
31  INLINE void acquire();
32  INLINE void release();
33 
34 public:
35  INLINE void ref() const;
36  INLINE bool unref() const;
37 
38 private:
39  MutexImpl _lock;
40 
41  // This isn't really designed as a reference counted class, but it is useful
42  // to treat it as one when dealing with substreams created by Multifile.
43  mutable AtomicAdjust::Integer _ref_count = 1;
44 
45 #ifdef SIMPLE_THREADS
46  // In the SIMPLE_THREADS case, we need to use a bool flag, because MutexImpl
47  // defines to nothing in this case--but we still need to achieve a form of
48  // locking, since IO operations can cause the thread to swap without
49  // warning.
50  bool _lock_flag;
51 #endif
52 };
53 
54 /**
55  * This class provides a locking wrapper around an arbitrary istream pointer.
56  * A thread may use this class to perform an atomic seek/read/gcount
57  * operation.
58  */
59 class EXPCL_DTOOL_PRC IStreamWrapper : virtual public StreamWrapperBase {
60 public:
61  INLINE IStreamWrapper(std::istream *stream, bool owns_pointer);
62 PUBLISHED:
63  INLINE explicit IStreamWrapper(std::istream &stream);
64  ~IStreamWrapper();
65 
66  INLINE std::istream *get_istream() const;
67  MAKE_PROPERTY(std::istream, get_istream);
68 
69 public:
70  void read(char *buffer, std::streamsize num_bytes);
71  void read(char *buffer, std::streamsize num_bytes, std::streamsize &read_bytes);
72  void read(char *buffer, std::streamsize num_bytes, std::streamsize &read_bytes, bool &eof);
73  void seek_read(std::streamsize pos, char *buffer, std::streamsize num_bytes, std::streamsize &read_bytes, bool &eof);
74  INLINE int get();
75  std::streamsize seek_gpos_eof();
76 
77 private:
78  std::istream *_istream;
79  bool _owns_pointer;
80 };
81 
82 /**
83  * This class provides a locking wrapper around an arbitrary ostream pointer.
84  * A thread may use this class to perform an atomic seek/write operation.
85  */
86 class EXPCL_DTOOL_PRC OStreamWrapper : virtual public StreamWrapperBase {
87 public:
88  INLINE OStreamWrapper(std::ostream *stream, bool owns_pointer, bool stringstream_hack = false);
89 PUBLISHED:
90  INLINE explicit OStreamWrapper(std::ostream &stream);
91  ~OStreamWrapper();
92 
93  INLINE std::ostream *get_ostream() const;
94  MAKE_PROPERTY(std::ostream, get_ostream);
95 
96 public:
97  void write(const char *buffer, std::streamsize num_bytes);
98  void write(const char *buffer, std::streamsize num_bytes, bool &fail);
99  void seek_write(std::streamsize pos, const char *buffer, std::streamsize num_bytes, bool &fail);
100  void seek_eof_write(const char *buffer, std::streamsize num_bytes, bool &fail);
101  INLINE bool put(char c);
102  std::streamsize seek_ppos_eof();
103 
104 private:
105  std::ostream *_ostream;
106  bool _owns_pointer;
107 
108  // This flag is necessary to work around a weird quirk in the MSVS C++
109  // runtime library: an empty stringstream cannot successfully seekp(0),
110  // until some data has been written to the stream. When this flag is set
111  // true, we know we have a possibly-empty stringstream, so we allow seekp(0)
112  // to fail silently, knowing that there's no harm in this case.
113 #ifdef WIN32_VC
114  bool _stringstream_hack;
115 #endif
116 };
117 
118 /**
119  * This class provides a locking wrapper around a combination ostream/istream
120  * pointer.
121  */
122 class EXPCL_DTOOL_PRC StreamWrapper : public IStreamWrapper, public OStreamWrapper {
123 public:
124  INLINE StreamWrapper(std::iostream *stream, bool owns_pointer, bool stringstream_hack = false);
125 PUBLISHED:
126  INLINE explicit StreamWrapper(std::iostream &stream);
127  ~StreamWrapper();
128 
129  INLINE std::iostream *get_iostream() const;
130  MAKE_PROPERTY(std::iostream, get_iostream);
131 
132 private:
133  std::iostream *_iostream;
134  bool _owns_pointer;
135 };
136 
137 #include "streamWrapper.I"
138 
139 #endif
IStreamWrapper
This class provides a locking wrapper around an arbitrary istream pointer.
Definition: streamWrapper.h:59
StreamWrapper
This class provides a locking wrapper around a combination ostream/istream pointer.
Definition: streamWrapper.h:122
OStreamWrapper
This class provides a locking wrapper around an arbitrary ostream pointer.
Definition: streamWrapper.h:86
mutexImpl.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
streamWrapper.I
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
StreamWrapperBase
The base class for both IStreamWrapper and OStreamWrapper, this provides the common locking interface...
Definition: streamWrapper.h:25
atomicAdjust.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
dtoolbase.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
MutexDummyImpl
A fake mutex implementation for single-threaded applications that don't need any synchronization cont...
Definition: mutexDummyImpl.h:24