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