Panda3D
|
00001 // Filename: socketStream.h 00002 // Created by: drose (15Oct02) 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 SOCKETSTREAM_H 00016 #define SOCKETSTREAM_H 00017 00018 #include "pandabase.h" 00019 #include "trueClock.h" 00020 #include "config_express.h" // for collect_tcp 00021 #include "datagram.h" 00022 #include "pdeque.h" 00023 #include "typedReferenceCount.h" 00024 #include "pointerTo.h" 00025 00026 // At the present, this module is not compiled if OpenSSL is not 00027 // available, since the only current use for it is to implement 00028 // OpenSSL-defined constructs (like ISocketStream). 00029 00030 #ifdef HAVE_OPENSSL 00031 00032 class HTTPChannel; 00033 00034 //////////////////////////////////////////////////////////////////// 00035 // Class : SSReader 00036 // Description : An internal class for reading from a socket stream. 00037 // This serves as a base class for both ISocketStream 00038 // and SocketStream; its purpose is to minimize 00039 // redundant code between them. Do not use it directly. 00040 //////////////////////////////////////////////////////////////////// 00041 class EXPCL_PANDAEXPRESS SSReader { 00042 public: 00043 SSReader(istream *stream); 00044 virtual ~SSReader(); 00045 00046 PUBLISHED: 00047 INLINE bool receive_datagram(Datagram &dg); 00048 00049 virtual bool is_closed() = 0; 00050 virtual void close() = 0; 00051 00052 INLINE void set_tcp_header_size(int tcp_header_size); 00053 INLINE int get_tcp_header_size() const; 00054 00055 private: 00056 bool do_receive_datagram(Datagram &dg); 00057 00058 istream *_istream; 00059 size_t _data_expected; 00060 string _data_so_far; 00061 int _tcp_header_size; 00062 00063 #ifdef SIMULATE_NETWORK_DELAY 00064 PUBLISHED: 00065 void start_delay(double min_delay, double max_delay); 00066 void stop_delay(); 00067 00068 private: 00069 void delay_datagram(const Datagram &datagram); 00070 bool get_delayed(Datagram &datagram); 00071 00072 class DelayedDatagram { 00073 public: 00074 double _reveal_time; 00075 Datagram _datagram; 00076 }; 00077 00078 typedef pdeque<DelayedDatagram> Delayed; 00079 Delayed _delayed; 00080 bool _delay_active; 00081 double _min_delay, _delay_variance; 00082 00083 #endif // SIMULATE_NETWORK_DELAY 00084 }; 00085 00086 //////////////////////////////////////////////////////////////////// 00087 // Class : SSWriter 00088 // Description : An internal class for writing to a socket stream. 00089 // This serves as a base class for both OSocketStream 00090 // and SocketStream; its purpose is to minimize 00091 // redundant code between them. Do not use it directly. 00092 //////////////////////////////////////////////////////////////////// 00093 class EXPCL_PANDAEXPRESS SSWriter { 00094 public: 00095 SSWriter(ostream *stream); 00096 virtual ~SSWriter(); 00097 00098 PUBLISHED: 00099 bool send_datagram(const Datagram &dg); 00100 00101 virtual bool is_closed() = 0; 00102 virtual void close() = 0; 00103 00104 INLINE void set_collect_tcp(bool collect_tcp); 00105 INLINE bool get_collect_tcp() const; 00106 INLINE void set_collect_tcp_interval(double interval); 00107 INLINE double get_collect_tcp_interval() const; 00108 00109 INLINE void set_tcp_header_size(int tcp_header_size); 00110 INLINE int get_tcp_header_size() const; 00111 00112 INLINE bool consider_flush(); 00113 INLINE bool flush(); 00114 00115 private: 00116 ostream *_ostream; 00117 bool _collect_tcp; 00118 double _collect_tcp_interval; 00119 double _queued_data_start; 00120 int _tcp_header_size; 00121 }; 00122 00123 //////////////////////////////////////////////////////////////////// 00124 // Class : ISocketStream 00125 // Description : This is a base class for istreams implemented in 00126 // Panda that read from a (possibly non-blocking) 00127 // socket. It adds is_closed(), which can be called 00128 // after an eof condition to check whether the socket 00129 // has been closed, or whether more data may be 00130 // available later. 00131 //////////////////////////////////////////////////////////////////// 00132 class EXPCL_PANDAEXPRESS ISocketStream : public istream, public SSReader { 00133 public: 00134 INLINE ISocketStream(streambuf *buf); 00135 virtual ~ISocketStream(); 00136 00137 PUBLISHED: 00138 enum ReadState { 00139 RS_initial, 00140 RS_reading, 00141 RS_complete, 00142 RS_error, 00143 }; 00144 00145 virtual bool is_closed() = 0; 00146 virtual void close() = 0; 00147 virtual ReadState get_read_state() = 0; 00148 00149 protected: 00150 HTTPChannel *_channel; 00151 00152 private: 00153 friend class HTTPChannel; 00154 }; 00155 00156 //////////////////////////////////////////////////////////////////// 00157 // Class : OSocketStream 00158 // Description : A base class for ostreams that write to a (possibly 00159 // non-blocking) socket. It adds is_closed(), which can 00160 // be called after any write operation fails to check 00161 // whether the socket has been closed, or whether more 00162 // data may be sent later. 00163 //////////////////////////////////////////////////////////////////// 00164 class EXPCL_PANDAEXPRESS OSocketStream : public ostream, public SSWriter { 00165 public: 00166 INLINE OSocketStream(streambuf *buf); 00167 00168 PUBLISHED: 00169 virtual bool is_closed() = 0; 00170 virtual void close() = 0; 00171 00172 INLINE bool flush(); 00173 }; 00174 00175 //////////////////////////////////////////////////////////////////// 00176 // Class : SocketStream 00177 // Description : A base class for iostreams that read and write to a 00178 // (possibly non-blocking) socket. 00179 //////////////////////////////////////////////////////////////////// 00180 class EXPCL_PANDAEXPRESS SocketStream : public iostream, public SSReader, public SSWriter { 00181 public: 00182 INLINE SocketStream(streambuf *buf); 00183 00184 PUBLISHED: 00185 virtual bool is_closed() = 0; 00186 virtual void close() = 0; 00187 00188 INLINE void set_tcp_header_size(int tcp_header_size); 00189 INLINE int get_tcp_header_size() const; 00190 00191 INLINE bool flush(); 00192 }; 00193 00194 00195 #include "socketStream.I" 00196 00197 #endif // HAVE_OPENSSL 00198 00199 00200 #endif 00201 00202