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
This class provides a locking wrapper around a combination ostream/istream pointer.
This class provides a locking wrapper around an arbitrary istream pointer.
Definition: streamWrapper.h:59
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A fake mutex implementation for single-threaded applications that don't need any synchronization cont...
This class provides a locking wrapper around an arbitrary ostream pointer.
Definition: streamWrapper.h:86
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The base class for both IStreamWrapper and OStreamWrapper, this provides the common locking interface...
Definition: streamWrapper.h:25