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