28 _wanted_nonblocking =
false;
29 _read_state = ISocketStream::RS_initial;
32 _buffer = (
char *)PANDA_MALLOC_ARRAY(4096);
33 char *ebuf = _buffer + 4096;
34 setg(_buffer, ebuf, ebuf);
39 setg(base(), ebuf(), ebuf());
51 PANDA_FREE_ARRAY(_buffer);
59 void ChunkedStreamBuf::
60 open_read(BioStreamPtr *source, HTTPChannel *doc) {
62 nassertv(!_source.is_null());
65 _wanted_nonblocking = doc->_wanted_nonblocking;
66 _read_state = ISocketStream::RS_reading;
69 if (_doc !=
nullptr) {
70 _read_index = doc->_read_index;
71 _doc->_transfer_file_size = 0;
72 _doc->_got_transfer_file_size =
true;
83 void ChunkedStreamBuf::
92 int ChunkedStreamBuf::
95 if (gptr() >= egptr()) {
96 size_t buffer_size = egptr() - eback();
97 gbump(-(
int)buffer_size);
99 size_t num_bytes = buffer_size;
100 size_t read_count = read_chars(gptr(), buffer_size);
102 if (read_count != num_bytes) {
104 if (read_count == 0) {
110 nassertr(read_count < num_bytes, EOF);
111 size_t delta = num_bytes - read_count;
112 memmove(gptr() + delta, gptr(), read_count);
117 return (
unsigned char)*gptr();
124 size_t ChunkedStreamBuf::
125 read_chars(
char *start,
size_t length) {
127 nassertr(!_source.is_null(), 0);
132 if (_chunk_remaining != 0) {
134 length = std::min(length, _chunk_remaining);
135 (*_source)->read(start, length);
136 size_t read_count = (*_source)->gcount();
137 if (!_wanted_nonblocking) {
138 while (read_count == 0 && !(*_source)->is_closed()) {
141 (*_source)->read(start, length);
142 read_count = (*_source)->gcount();
145 _chunk_remaining -= read_count;
147 if (read_count == 0 && (*_source)->is_closed()) {
149 _read_state = ISocketStream::RS_error;
157 bool got_line = http_getline(line);
158 while (got_line && line.empty()) {
162 got_line = http_getline(line);
166 if ((*_source)->is_closed()) {
168 _read_state = ISocketStream::RS_error;
171 if (!_wanted_nonblocking) {
179 size_t chunk_size = (size_t)strtol(line.c_str(),
nullptr, 16);
180 if (downloader_cat.is_spam()) {
181 downloader_cat.spam()
182 <<
"Got chunk of size " << chunk_size <<
" bytes.\n";
185 if (chunk_size == 0) {
188 if (_doc !=
nullptr && _read_index == _doc->_read_index) {
189 _doc->_file_size = _doc->_transfer_file_size;
190 _doc->_got_file_size =
true;
192 _read_state = ISocketStream::RS_complete;
196 if (_doc !=
nullptr && _read_index == _doc->_read_index) {
197 _doc->_transfer_file_size += chunk_size;
200 _chunk_remaining = chunk_size;
214 bool ChunkedStreamBuf::
215 http_getline(std::string &str) {
216 nassertr(!_source.is_null(),
false);
217 int ch = (*_source)->get();
218 while (!(*_source)->eof() && !(*_source)->fail()) {
222 str = _working_getline;
223 _working_getline = std::string();
227 size_t p = str.length();
228 while (p > 0 && isspace(str[p - 1])) {
231 str = str.substr(0, p);
241 _working_getline += (char)ch;
243 ch = (*_source)->get();
249 #endif // HAVE_OPENSSL PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.