00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "identityStreamBuf.h"
00016
00017
00018 #ifdef HAVE_OPENSSL
00019
00020 #ifndef HAVE_STREAMSIZE
00021
00022 typedef int streamsize;
00023 #endif
00024
00025
00026
00027
00028
00029
00030 IdentityStreamBuf::
00031 IdentityStreamBuf() {
00032 _has_content_length = true;
00033 _bytes_remaining = 0;
00034 _wanted_nonblocking = false;
00035 _read_state = ISocketStream::RS_initial;
00036
00037 #ifdef PHAVE_IOSTREAM
00038 _buffer = (char *)PANDA_MALLOC_ARRAY(4096);
00039 char *ebuf = _buffer + 4096;
00040 setg(_buffer, ebuf, ebuf);
00041 setp(_buffer, ebuf);
00042
00043 #else
00044 allocate();
00045 setg(base(), ebuf(), ebuf());
00046 setp(base(), ebuf());
00047 #endif
00048 }
00049
00050
00051
00052
00053
00054
00055 IdentityStreamBuf::
00056 ~IdentityStreamBuf() {
00057 close_read();
00058 #ifdef PHAVE_IOSTREAM
00059 PANDA_FREE_ARRAY(_buffer);
00060 #endif
00061 }
00062
00063
00064
00065
00066
00067
00068
00069
00070 void IdentityStreamBuf::
00071 open_read(BioStreamPtr *source, HTTPChannel *doc,
00072 bool has_content_length, size_t content_length) {
00073 _source = source;
00074 _has_content_length = has_content_length;
00075 _wanted_nonblocking = doc->_wanted_nonblocking;
00076 _bytes_remaining = content_length;
00077 _read_state = ISocketStream::RS_reading;
00078 }
00079
00080
00081
00082
00083
00084
00085 void IdentityStreamBuf::
00086 close_read() {
00087 _source.clear();
00088 }
00089
00090
00091
00092
00093
00094
00095
00096 int IdentityStreamBuf::
00097 underflow() {
00098
00099 if (gptr() >= egptr()) {
00100 size_t buffer_size = egptr() - eback();
00101 gbump(-(int)buffer_size);
00102
00103 size_t num_bytes = buffer_size;
00104 size_t read_count = read_chars(gptr(), buffer_size);
00105
00106 if (read_count != num_bytes) {
00107
00108 if (read_count == 0) {
00109 gbump(num_bytes);
00110 return EOF;
00111 }
00112
00113
00114 nassertr(read_count < num_bytes, EOF);
00115 size_t delta = num_bytes - read_count;
00116 memmove(gptr() + delta, gptr(), read_count);
00117 gbump(delta);
00118 }
00119 }
00120
00121 return (unsigned char)*gptr();
00122 }
00123
00124
00125
00126
00127
00128
00129
00130 size_t IdentityStreamBuf::
00131 read_chars(char *start, size_t length) {
00132 size_t read_count = 0;
00133
00134 if (!_has_content_length) {
00135
00136
00137 (*_source)->read(start, length);
00138 read_count = (*_source)->gcount();
00139
00140 if (!_wanted_nonblocking) {
00141 while (read_count == 0 && !(*_source)->is_closed()) {
00142
00143 thread_yield();
00144 (*_source)->read(start, length);
00145 read_count = (*_source)->gcount();
00146 }
00147 }
00148
00149 if (read_count == 0) {
00150 if ((*_source)->is_closed()) {
00151
00152 _read_state = ISocketStream::RS_complete;
00153 }
00154 return 0;
00155 }
00156
00157 } else {
00158
00159
00160
00161 if (_bytes_remaining != 0) {
00162 length = min(length, _bytes_remaining);
00163 (*_source)->read(start, length);
00164 read_count = (*_source)->gcount();
00165 if (!_wanted_nonblocking) {
00166 while (read_count == 0 && !(*_source)->is_closed()) {
00167
00168 thread_yield();
00169 (*_source)->read(start, length);
00170 read_count = (*_source)->gcount();
00171 }
00172 }
00173 nassertr(read_count <= _bytes_remaining, 0);
00174 _bytes_remaining -= read_count;
00175
00176 if (read_count == 0) {
00177 if ((*_source)->is_closed()) {
00178
00179 _read_state = ISocketStream::RS_error;
00180 }
00181 return 0;
00182 }
00183 }
00184
00185 if (_bytes_remaining == 0) {
00186
00187 _read_state = ISocketStream::RS_complete;
00188 }
00189 }
00190
00191 return read_count;
00192 }
00193
00194 #endif // HAVE_OPENSSL