Panda3D
socketStream.h
1 // Filename: socketStream.h
2 // Created by: drose (15Oct02)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #ifndef SOCKETSTREAM_H
16 #define SOCKETSTREAM_H
17 
18 #include "pandabase.h"
19 #include "trueClock.h"
20 #include "config_express.h" // for collect_tcp
21 #include "datagram.h"
22 #include "pdeque.h"
23 #include "typedReferenceCount.h"
24 #include "pointerTo.h"
25 
26 // At the present, this module is not compiled if OpenSSL is not
27 // available, since the only current use for it is to implement
28 // OpenSSL-defined constructs (like ISocketStream).
29 
30 #ifdef HAVE_OPENSSL
31 
32 class HTTPChannel;
33 
34 ////////////////////////////////////////////////////////////////////
35 // Class : SSReader
36 // Description : An internal class for reading from a socket stream.
37 // This serves as a base class for both ISocketStream
38 // and SocketStream; its purpose is to minimize
39 // redundant code between them. Do not use it directly.
40 ////////////////////////////////////////////////////////////////////
41 class EXPCL_PANDAEXPRESS SSReader {
42 public:
43  SSReader(istream *stream);
44  virtual ~SSReader();
45 
46 PUBLISHED:
47  INLINE bool receive_datagram(Datagram &dg);
48 
49  virtual bool is_closed() = 0;
50  virtual void close() = 0;
51 
52  INLINE void set_tcp_header_size(int tcp_header_size);
53  INLINE int get_tcp_header_size() const;
54 
55 private:
56  bool do_receive_datagram(Datagram &dg);
57 
58  istream *_istream;
59  size_t _data_expected;
60  string _data_so_far;
61  int _tcp_header_size;
62 
63 #ifdef SIMULATE_NETWORK_DELAY
64 PUBLISHED:
65  void start_delay(double min_delay, double max_delay);
66  void stop_delay();
67 
68 private:
69  void delay_datagram(const Datagram &datagram);
70  bool get_delayed(Datagram &datagram);
71 
72  class DelayedDatagram {
73  public:
74  double _reveal_time;
75  Datagram _datagram;
76  };
77 
78  typedef pdeque<DelayedDatagram> Delayed;
79  Delayed _delayed;
80  bool _delay_active;
81  double _min_delay, _delay_variance;
82 
83 #endif // SIMULATE_NETWORK_DELAY
84 };
85 
86 ////////////////////////////////////////////////////////////////////
87 // Class : SSWriter
88 // Description : An internal class for writing to a socket stream.
89 // This serves as a base class for both OSocketStream
90 // and SocketStream; its purpose is to minimize
91 // redundant code between them. Do not use it directly.
92 ////////////////////////////////////////////////////////////////////
93 class EXPCL_PANDAEXPRESS SSWriter {
94 public:
95  SSWriter(ostream *stream);
96  virtual ~SSWriter();
97 
98 PUBLISHED:
99  bool send_datagram(const Datagram &dg);
100 
101  virtual bool is_closed() = 0;
102  virtual void close() = 0;
103 
104  INLINE void set_collect_tcp(bool collect_tcp);
105  INLINE bool get_collect_tcp() const;
106  INLINE void set_collect_tcp_interval(double interval);
107  INLINE double get_collect_tcp_interval() const;
108 
109  INLINE void set_tcp_header_size(int tcp_header_size);
110  INLINE int get_tcp_header_size() const;
111 
112  INLINE bool consider_flush();
113  INLINE bool flush();
114 
115 private:
116  ostream *_ostream;
117  bool _collect_tcp;
118  double _collect_tcp_interval;
119  double _queued_data_start;
120  int _tcp_header_size;
121 };
122 
123 ////////////////////////////////////////////////////////////////////
124 // Class : ISocketStream
125 // Description : This is a base class for istreams implemented in
126 // Panda that read from a (possibly non-blocking)
127 // socket. It adds is_closed(), which can be called
128 // after an eof condition to check whether the socket
129 // has been closed, or whether more data may be
130 // available later.
131 ////////////////////////////////////////////////////////////////////
132 class EXPCL_PANDAEXPRESS ISocketStream : public istream, public SSReader {
133 public:
134  INLINE ISocketStream(streambuf *buf);
135  virtual ~ISocketStream();
136 
137 PUBLISHED:
138  enum ReadState {
139  RS_initial,
140  RS_reading,
141  RS_complete,
142  RS_error,
143  };
144 
145  virtual bool is_closed() = 0;
146  virtual void close() = 0;
147  virtual ReadState get_read_state() = 0;
148 
149 protected:
150  HTTPChannel *_channel;
151 
152 private:
153  friend class HTTPChannel;
154 };
155 
156 ////////////////////////////////////////////////////////////////////
157 // Class : OSocketStream
158 // Description : A base class for ostreams that write to a (possibly
159 // non-blocking) socket. It adds is_closed(), which can
160 // be called after any write operation fails to check
161 // whether the socket has been closed, or whether more
162 // data may be sent later.
163 ////////////////////////////////////////////////////////////////////
164 class EXPCL_PANDAEXPRESS OSocketStream : public ostream, public SSWriter {
165 public:
166  INLINE OSocketStream(streambuf *buf);
167 
168 PUBLISHED:
169  virtual bool is_closed() = 0;
170  virtual void close() = 0;
171 
172  INLINE bool flush();
173 };
174 
175 ////////////////////////////////////////////////////////////////////
176 // Class : SocketStream
177 // Description : A base class for iostreams that read and write to a
178 // (possibly non-blocking) socket.
179 ////////////////////////////////////////////////////////////////////
180 class EXPCL_PANDAEXPRESS SocketStream : public iostream, public SSReader, public SSWriter {
181 public:
182  INLINE SocketStream(streambuf *buf);
183 
184 PUBLISHED:
185  virtual bool is_closed() = 0;
186  virtual void close() = 0;
187 
188  INLINE void set_tcp_header_size(int tcp_header_size);
189  INLINE int get_tcp_header_size() const;
190 
191  INLINE bool flush();
192 };
193 
194 
195 #include "socketStream.I"
196 
197 #endif // HAVE_OPENSSL
198 
199 
200 #endif
201 
202 
This is our own Panda specialization on the default STL deque.
Definition: pdeque.h:38
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43