libassa 3.5.0
|
00001 // -*- c++ -*- 00002 //------------------------------------------------------------------------------ 00003 // Streambuf.cpp 00004 //------------------------------------------------------------------------------ 00005 // Copyright (c) 1999 by Vladislav Grinchenko 00006 // 00007 // This library is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU Library General Public 00009 // License as published by the Free Software Foundation; either 00010 // version 2 of the License, or (at your option) any later version. 00011 // 00012 //------------------------------------------------------------------------------ 00013 // Created: 12/02/99 00014 //------------------------------------------------------------------------------ 00015 00016 #include "assa/Streambuf.h" 00017 #include "assa/MemDump.h" 00018 00019 using namespace ASSA; 00020 00021 void 00022 io_ptrs:: 00023 dump () const 00024 { 00025 #ifdef LOG_PACKET 00026 trace_with_mask("io_ptrs::dump",STRMBUF); 00027 int len; 00028 00029 DL((STRMBUF,"---Ptr------:---Val---\n")); 00030 DL((STRMBUF,"m_read_base.: 0x%x\n", (u_long)m_read_base)); 00031 DL((STRMBUF,"m_read_ptr..: 0x%x\n", (u_long)m_read_ptr )); 00032 DL((STRMBUF,"m_read_end..: 0x%x\n", (u_long)m_read_end )); 00033 00034 if (m_read_ptr && (len = m_read_end - m_read_ptr) > 0) { 00035 MemDump get_area (m_read_ptr, len); 00036 DL((STRMBUF,"\n%s\n", get_area.getMemDump ())); 00037 } 00038 00039 DL((STRMBUF,"m_write_base: 0x%x\n", (u_long)m_write_base)); 00040 DL((STRMBUF,"m_write_ptr.: 0x%x\n", (u_long)m_write_ptr )); 00041 DL((STRMBUF,"m_write_end.: 0x%x\n", (u_long)m_write_end )); 00042 00043 if (m_write_base && (len = m_write_ptr - m_write_base) > 0) { 00044 MemDump put_area (m_write_base, len); 00045 DL((STRMBUF,"%s\n", put_area.getMemDump ())); 00046 } 00047 00048 DL((STRMBUF,"m_buf_base..: 0x%x\n", (u_long)m_buf_base )); 00049 DL((STRMBUF,"m_buf_end...: 0x%x\n", (u_long)m_buf_end )); 00050 DL((STRMBUF,"------------:---------\n"); 00051 00052 #endif 00053 } 00054 00055 int 00056 Streambuf:: 00057 snextc () 00058 { 00059 trace_with_mask("Streambuf::snextc",STRMBUFTRACE); 00060 00061 if (m_read_ptr >= m_read_end && underflow () == EOF) { 00062 return EOF; 00063 } 00064 return m_read_ptr++, sgetc (); 00065 } 00066 00067 void 00068 Streambuf:: 00069 setg (char* gbeg_, char* gnext_, char* gend_) 00070 { 00071 trace_with_mask("Streambuf::setg",STRMBUFTRACE); 00072 00073 m_read_base = gbeg_; 00074 m_read_ptr = gnext_; 00075 m_read_end = gend_; 00076 } 00077 00078 void 00079 Streambuf:: 00080 setb (char* b_, char* eb_, int del_) 00081 { 00082 trace_with_mask("Streambuf::setb",STRMBUFTRACE); 00083 00084 if (m_buf_base && !(m_flags & USER_BUF)) 00085 delete m_buf_base; 00086 00087 m_buf_base = b_; 00088 m_buf_end = eb_; 00089 00090 if (del_) 00091 m_flags &= ~ USER_BUF; // clear bit 00092 else 00093 m_flags |= USER_BUF; // set bit 00094 00095 dump (); 00096 } 00097 00098 Streambuf* 00099 Streambuf:: 00100 setbuf (char* p_, int len_) 00101 { 00102 trace_with_mask("Streambuf::setb",STRMBUFTRACE); 00103 00104 if (sync () == EOF) // Flush out all pending bytes before 00105 return NULL; // resetting buffer. Also, first time around, 00106 // calling sync() suppose to set put area 00107 // pointers. 00108 00109 if (p_ == NULL || len_ == 0) { 00110 DL((STRMBUF,"Unbuffered IO set.\n")); 00111 unbuffered (1); 00112 // We do it from doalloc instead - vlg 00113 // setb (m_shortbuf, m_shortbuf+1, 0); 00114 } 00115 else { 00116 DL((STRMBUF,"Buffered IO set.\n")); 00117 unbuffered (0); 00118 setb (p_, p_ + len_, 0); 00119 } 00120 setp (0, 0); 00121 setg (0, 0, 0); 00122 00123 return this; 00124 } 00125 00126 int 00127 Streambuf:: 00128 xsgetn (char* data_, int len_) 00129 { 00130 trace_with_mask("Streambuf::xsgetn",STRMBUFTRACE); 00131 00132 /* 00133 Get area is empty and nothing is on the socket. 00134 */ 00135 int count = m_read_end - m_read_ptr; // Bytes in Get area 00136 00137 if (count == 0 && underflow () == EOF) { 00138 DL((STRMBUFTRACE,"returning %d. count: %d\n", EOF)); 00139 return EOF; 00140 } 00141 count = m_read_end - m_read_ptr; // Adjusted bytes in Get area 00142 00143 DL((STRMBUFTRACE,"Adjusted bytes in Get Area: %d\n",count)); 00144 00145 if (count > len_) { 00146 count = len_; 00147 } 00148 00149 if (count <= 0) { 00150 count = 0; // Peer closed connection 00151 } 00152 else if (count > 20) { 00153 memcpy (data_, m_read_ptr, count); 00154 m_read_ptr += count; 00155 } 00156 else { 00157 char* s = data_; 00158 char* p = m_read_ptr; 00159 int i = count; 00160 while (i-- > 0) { 00161 *s++ = *p++; 00162 } 00163 m_read_ptr = p; 00164 } 00165 DL((STRMBUFTRACE,"Transferred %d bytes to user-space buffer\n", count)); 00166 00167 return (count); 00168 } 00169 00170 int 00171 Streambuf:: 00172 uflow () 00173 { 00174 trace_with_mask("Streambuf::uflow",STRMBUFTRACE); 00175 00176 if (underflow () == EOF) 00177 return EOF; 00178 dump (); 00179 return *(unsigned char *) m_read_ptr++; 00180 } 00181 00182 int 00183 Streambuf:: 00184 xsputn (const char* data_, int len_) 00185 { 00186 trace_with_mask("Streambuf::xsputn",STRMBUFTRACE); 00187 00188 const char* s = data_; 00189 int more = len_; 00190 if (more <= 0) { 00191 return 0; 00192 } 00193 00194 for (;;) { 00195 int count = m_write_end - m_write_ptr; // Space available 00196 00197 if (count > 0) { 00198 00199 if (count > more) // Enough buffer space 00200 count = more; 00201 00202 if (count > 20) { 00203 memcpy (m_write_ptr, s, count); 00204 s += count; 00205 m_write_ptr += count; 00206 } 00207 else if (count <= 0) { 00208 count = 0; 00209 } 00210 else { 00211 char* p = m_write_ptr; 00212 int i; 00213 00214 for (i=count; --i >= 0;) { 00215 *p++ = *s++; 00216 } 00217 m_write_ptr = p; 00218 } 00219 more -= count; 00220 } // if (count>0) 00221 00222 if (more == 0 || overflow ((unsigned char) *s++) == EOF) { 00223 break; 00224 } 00225 more--; 00226 00227 } // for (;;) 00228 00229 return (len_ - more); 00230 } 00231 00232 00233 int 00234 Streambuf::doallocate () 00235 { 00236 trace_with_mask("Streambuf::doallocate",STRMBUFTRACE); 00237 00238 char* buf; 00239 buf = new char [1024]; 00240 if (buf == NULL) { 00241 return EOF; 00242 } 00243 setb (buf, buf+1024, 1); 00244 00245 return 1; 00246 } 00247