Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/downloader/identityStreamBuf.cxx

Go to the documentation of this file.
00001 // Filename: identityStreamBuf.cxx
00002 // Created by:  drose (09Oct02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "identityStreamBuf.h"
00020 
00021 // This module is not compiled if OpenSSL is not available.
00022 #ifdef HAVE_SSL
00023 
00024 #ifndef HAVE_STREAMSIZE
00025 // Some compilers (notably SGI) don't define this for us
00026 typedef int streamsize;
00027 #endif /* HAVE_STREAMSIZE */
00028 
00029 ////////////////////////////////////////////////////////////////////
00030 //     Function: IdentityStreamBuf::Constructor
00031 //       Access: Public
00032 //  Description:
00033 ////////////////////////////////////////////////////////////////////
00034 IdentityStreamBuf::
00035 IdentityStreamBuf() {
00036   _has_content_length = true;
00037   _bytes_remaining = 0;
00038 
00039 #ifdef HAVE_IOSTREAM
00040   char *buf = new char[4096];
00041   char *ebuf = buf + 4096;
00042   setg(buf, ebuf, ebuf);
00043   setp(buf, ebuf);
00044 
00045 #else
00046   allocate();
00047   setg(base(), ebuf(), ebuf());
00048   setp(base(), ebuf());
00049 #endif
00050 }
00051 
00052 ////////////////////////////////////////////////////////////////////
00053 //     Function: IdentityStreamBuf::Destructor
00054 //       Access: Public, Virtual
00055 //  Description:
00056 ////////////////////////////////////////////////////////////////////
00057 IdentityStreamBuf::
00058 ~IdentityStreamBuf() {
00059   close_read();
00060 }
00061 
00062 ////////////////////////////////////////////////////////////////////
00063 //     Function: IdentityStreamBuf::open_read
00064 //       Access: Public
00065 //  Description: If the document pointer is non-NULL, it will be
00066 //               updated with the length of the file as it is derived
00067 //               from the identity encoding.
00068 ////////////////////////////////////////////////////////////////////
00069 void IdentityStreamBuf::
00070 open_read(BioStreamPtr *source, HTTPChannel *doc, 
00071           bool has_content_length, size_t content_length) {
00072   _source = source;
00073   _doc = doc;
00074   _has_content_length = has_content_length;
00075   _bytes_remaining = content_length;
00076 
00077   if (_doc != (HTTPChannel *)NULL) {
00078     _read_index = doc->_read_index;
00079   }
00080 }
00081 
00082 ////////////////////////////////////////////////////////////////////
00083 //     Function: IdentityStreamBuf::close_read
00084 //       Access: Public
00085 //  Description:
00086 ////////////////////////////////////////////////////////////////////
00087 void IdentityStreamBuf::
00088 close_read() {
00089   _source.clear();
00090 }
00091 
00092 ////////////////////////////////////////////////////////////////////
00093 //     Function: IdentityStreamBuf::underflow
00094 //       Access: Protected, Virtual
00095 //  Description: Called by the system istream implementation when its
00096 //               internal buffer needs more characters.
00097 ////////////////////////////////////////////////////////////////////
00098 int IdentityStreamBuf::
00099 underflow() {
00100   // Sometimes underflow() is called even if the buffer is not empty.
00101   if (gptr() >= egptr()) {
00102     size_t buffer_size = egptr() - eback();
00103     gbump(-(int)buffer_size);
00104 
00105     size_t num_bytes = buffer_size;
00106     size_t read_count = read_chars(gptr(), buffer_size);
00107 
00108     if (read_count != num_bytes) {
00109       // Oops, we didn't read what we thought we would.
00110       if (read_count == 0) {
00111         gbump(num_bytes);
00112         return EOF;
00113       }
00114 
00115       // Slide what we did read to the top of the buffer.
00116       nassertr(read_count < num_bytes, EOF);
00117       size_t delta = num_bytes - read_count;
00118       memmove(gptr() + delta, gptr(), read_count);
00119       gbump(delta);
00120     }
00121   }
00122 
00123   return (unsigned char)*gptr();
00124 }
00125 
00126 
00127 ////////////////////////////////////////////////////////////////////
00128 //     Function: IdentityStreamBuf::read_chars
00129 //       Access: Private
00130 //  Description: Gets some characters from the source stream.
00131 ////////////////////////////////////////////////////////////////////
00132 size_t IdentityStreamBuf::
00133 read_chars(char *start, size_t length) {
00134   size_t read_count = 0;
00135 
00136   if (!_has_content_length) {
00137     // If we have no restrictions on content length, read till end of
00138     // file.
00139     (*_source)->read(start, length);
00140     read_count = (*_source)->gcount();
00141   
00142     if (read_count == 0) {
00143       if ((*_source)->is_closed()) {
00144         // socket closed; we're done.
00145         if (_doc != (HTTPChannel *)NULL && _read_index == _doc->_read_index) {
00146           _doc->finished_body(false);
00147         }
00148       }
00149       return 0;
00150     }
00151 
00152   } else {
00153     // Extract some of the bytes remaining in the chunk.
00154 
00155     if (_bytes_remaining != 0) {
00156       length = min(length, _bytes_remaining);
00157       (*_source)->read(start, length);
00158       read_count = (*_source)->gcount();
00159       _bytes_remaining -= read_count;
00160   
00161       if (read_count == 0) {
00162         if ((*_source)->is_closed()) {
00163           // socket closed unexpectedly; problem.
00164           if (_doc != (HTTPChannel *)NULL && _read_index == _doc->_read_index) {
00165             _doc->_state = HTTPChannel::S_failure;
00166           }
00167         }
00168         return 0;
00169       }
00170     }
00171       
00172     if (_bytes_remaining == 0) {
00173       // We're done.
00174       if (_doc != (HTTPChannel *)NULL && _read_index == _doc->_read_index) {
00175         _doc->finished_body(false);
00176       }
00177     }
00178   }
00179 
00180   return read_count;
00181 }
00182 
00183 #endif  // HAVE_SSL

Generated on Fri May 2 00:36:51 2003 for Panda by doxygen1.3