00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <iostream>
00017
00018 #include "assa/Socket.h"
00019 #include "assa/Socketbuf.h"
00020 #include "assa/MemDump.h"
00021
00022 using namespace ASSA;
00023
00024 Socketbuf::
00025 Socketbuf (Socket* s_)
00026 : m_s (s_)
00027 {
00028 trace_with_mask("Socketbuf::Socketbuf",STRMBUFTRACE);
00029
00030 unbuffered (0);
00031 }
00032
00033 int
00034 Socketbuf::
00035 sync ()
00036 {
00037 trace_with_mask("Socketbuf::sync",STRMBUFTRACE);
00038 return flush_output ();
00039 }
00040
00041 int
00042 Socketbuf::
00043 showmanyc ()
00044 {
00045 trace_with_mask("Socketbuf::showmanyc",STRMBUFTRACE);
00046 return m_s->getBytesAvail ();
00047 }
00048
00049 void
00050 Socketbuf::
00051 xput_char (char c_)
00052 {
00053 trace_with_mask("Socketbuf::xput_char",STRMBUFTRACE);
00054 *pptr() = c_;
00055 pbump (1);
00056 }
00057
00058 Socketbuf::
00059 ~Socketbuf ()
00060 {
00061 trace_with_mask("Socketbuf::~Socketbuf",STRMBUFTRACE);
00062 overflow (EOF);
00063 }
00064
00065 int
00066 Socketbuf::
00067 sys_read (char* b_, int len_)
00068 {
00069 trace_with_mask("Socketbuf::sys_read",STRMBUFTRACE);
00070
00071 int ret = ::recv (m_s->getHandler (), b_, len_, 0);
00072
00073 DL((STRMBUFTRACE,"Tried to read %d bytes from fd=%d\n",
00074 len_, m_s->getHandler ()));
00075 DL((STRMBUFTRACE,"::recv() returned %d\n", ret));
00076
00077 if (ret == -1) {
00078 DL((STRMBUFTRACE,"::recv() error: %d (%s)\n",
00079 errno, strerror (get_errno ())));
00080 }
00081 return (ret);
00082 }
00083
00084 int
00085 Socketbuf::
00086 sys_write (char* b_, int len_)
00087 {
00088 trace_with_mask("Socketbuf::sys_write",STRMBUFTRACE);
00089
00090 int ret = ::send (m_s->getHandler (), b_, len_, 0);
00091
00092 DL((STRMBUFTRACE,"Tried to write %d bytes to fd=%d\n",
00093 len_, m_s->getHandler ()));
00094 DL((STRMBUFTRACE,"::send() returned %d\n", ret));
00095
00096 if (ret == -1) {
00097 DL((STRMBUFTRACE,"::send() error: %d\n",errno));
00098 }
00099
00100 return (ret);
00101 }
00102
00103 int
00104 Socketbuf::
00105 underflow ()
00106 {
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 trace_with_mask("Socketbuf::underflow",STRMBUFTRACE);
00118
00119 if (gptr () < egptr ())
00120 {
00121 return *(unsigned char*) gptr ();
00122 }
00123
00124 if (base () == 0 &&
00125 doallocate () == EOF)
00126 {
00127 return EOF;
00128 }
00129
00130 int bufsz = unbuffered () ? 1 : MAXTCPFRAMESZ;
00131
00132
00133
00134
00135
00136 int rval = sys_read (base (), bufsz);
00137
00138 DL((STRMBUF,"Socketbuf::sys_read() returned %d bytes\n", rval));
00139
00140 if (rval == EOF)
00141 {
00142 if (get_errno () != EWOULDBLOCK) {
00143 m_flags |= EOF_SEEN;
00144 }
00145 return EOF;
00146 }
00147
00148 DL((STRMBUF,"Having read %d bytes from socket\n",rval));
00149 MemDump::dump_to_log (STRMBUF, "Data received:", base (), rval);
00150
00151
00152
00153 setg (base (), base (), base () + rval);
00154
00155 dump ();
00156
00157 return (*(unsigned char*) gptr ());
00158 }
00159
00160 int
00161 Socketbuf::
00162 overflow (int c_)
00163 {
00164 trace_with_mask("Socketbuf::overflow",STRMBUFTRACE);
00165
00166
00167
00168
00169 if (c_ == EOF)
00170 return flush_output ();
00171
00172 if (pbase () == 0 && doallocate () == EOF)
00173 return EOF;
00174
00175 if (pptr () >= epptr() && flush_output () == EOF)
00176 return EOF;
00177
00178 xput_char (c_);
00179
00180 dump ();
00181
00182 if ((unbuffered () || pptr () >= epptr ()) && flush_output () == EOF)
00183 return EOF;
00184
00185 dump ();
00186
00187 return c_;
00188 }
00189
00190 int
00191 Socketbuf::
00192 flush_output ()
00193 {
00194 trace_with_mask("Socketbuf::flush_output",STRMBUFTRACE);
00195
00196 if (pptr () <= pbase ()) {
00197 return 0;
00198 }
00199
00200 int requested;
00201 int xmitted;
00202
00203 requested = pptr () - pbase ();
00204
00205 if ((xmitted = sys_write (pbase (), requested)) < 0) {
00206 return EOF;
00207 }
00208
00209 if (unbuffered ()) {
00210 setp (pbase (), epptr ());
00211 return 0;
00212 }
00213
00214 requested -= xmitted;
00215 setp (pbase (), pbase () + MAXTCPFRAMESZ);
00216 pbump (requested);
00217
00218 if (requested > 0) {
00219 ::memmove (pbase (), pbase () + xmitted, requested);
00220 }
00221
00222 return 0;
00223 }
00224
00225 int
00226 Socketbuf::doallocate ()
00227 {
00228 trace_with_mask("Socketbuf::doallocate",STRMBUFTRACE);
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 if (m_buf_base)
00246 return 0;
00247
00248 if ( ! (m_flags & UNBUFFERED) ) {
00249 DL((STRMBUF,"Buffered IO - allocating %d bytes\n",
00250 2 * MAXTCPFRAMESZ));
00251 char* buf = new char [2 * MAXTCPFRAMESZ];
00252
00253 setg (buf, buf + MAXTCPFRAMESZ, buf + MAXTCPFRAMESZ);
00254 setb (buf, buf + MAXTCPFRAMESZ, 1);
00255
00256 buf += MAXTCPFRAMESZ;
00257 setp (buf, buf+MAXTCPFRAMESZ);
00258 }
00259 else {
00260 DL((STRMBUF,"Unbuffered IO - same 1 byte array\n"));
00261 setb (m_shortbuf, m_shortbuf+1, 0);
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 setg (m_shortbuf, m_shortbuf+1, m_shortbuf+1);
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 setp (m_shortbuf, m_shortbuf+1);
00292 }
00293 dump ();
00294 return 1;
00295 }
00296
00297