00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <string.h>
00015 #include <errno.h>
00016
00017 #include "assa/MemDump.h"
00018 #include "assa/xdrIOBuffer.h"
00019 #include "assa/XDRHack.h"
00020
00021
00022 namespace ASSA {
00023
00024 Socket&
00025 operator>>(Socket& s_, xdrIOBuffer& b_)
00026 {
00027 trace_with_mask("Socket >> xdrIOBuffer", XDRBUFTRACE);
00028
00029 DL((XDRBUFTRACE,"Buffer Initially:\n"));
00030 b_.dump ();
00031
00032 if (b_.m_state != xdrIOBuffer::waiting) {
00033 EL((ASSAERR,"Wrong state: %s\n", b_.get_state ().c_str ()));
00034 return s_;
00035 }
00036 int expected = b_.m_sz - b_.size ();
00037
00038 DL((XDRBUFTRACE,"Bytes expected: %d\n",expected));
00039 DL((XDRBUFTRACE,"Bytes in Socket buffer(s): %d\n", s_.getBytesAvail ()));
00040 int ret;
00041
00042 if ((ret = s_.read (b_.m_ptr, expected)) <= 0)
00043 {
00044 #if defined(WIN32)
00045 if (WSAGetLastError () != WSAEWOULDBLOCK) {
00046 WSASetLastError (0);
00047 EL((ASSAERR,"Socket::read() error!\n"));
00048 b_.m_state = xdrIOBuffer::error;
00049 }
00050 #else
00051 if (errno != EWOULDBLOCK) {
00052 EL((ASSAERR,"Socket::read() error!\n"));
00053 b_.m_state = xdrIOBuffer::error;
00054 }
00055 #endif
00056 else {
00057 EL((ASSAERR,"Socket::read() error! \n"));
00058 }
00059 return s_;
00060 }
00061 b_.m_ptr += ret;
00062
00063 DL((XDRBUFTRACE,"Received %d bytes\n", ret));
00064 b_.dump ();
00065
00066 if (b_.m_sz == b_.size ()) {
00067 DL((XDRBUFTRACE,"Complete message is in the buffer!\n"));
00068 b_.m_state = xdrIOBuffer::xmitted;
00069 b_.m_ptr = b_.m_buf;
00070 b_.dump ();
00071 }
00072 return s_;
00073 }
00074 }
00075
00076 using namespace ASSA;
00077
00078 xdrIOBuffer::
00079 xdrIOBuffer (u_int sz_)
00080 : m_sz (sz_),
00081 m_state (waiting)
00082 {
00083 trace_with_mask("xdrIOBuffer::xdrIOBuffer", XDRBUFTRACE);
00084
00085 m_buf = new char[sz_];
00086 m_ptr = m_buf;
00087 memset (m_buf, 0, m_sz);
00088 DL((XDRBUF,"Allocated xdrIOBuffer [%d]\n",m_sz));
00089 dump ();
00090 }
00091
00092 xdrIOBuffer::
00093 ~xdrIOBuffer ()
00094 {
00095 trace_with_mask("xdrIOBuffer::~xdrIOBuffer", XDRBUFTRACE);
00096
00097 DL((XDRBUFTRACE,"xdrIOBuffer->this = 0x%x\n", long(this)));
00098 delete [] m_buf;
00099 }
00100
00101 xdrIOBuffer&
00102 xdrIOBuffer::operator= (const xdrIOBuffer& rhs_)
00103 {
00104 trace_with_mask("xdrIOBuffer::operator=()", XDRBUFTRACE);
00105
00106 delete [] m_buf;
00107 copy (rhs_);
00108 return *this;
00109 }
00110
00111 void
00112 xdrIOBuffer::
00113 copy (const xdrIOBuffer& rhs_)
00114 {
00115 trace_with_mask("xdrIOBuffer::copy", XDRBUFTRACE);
00116
00117 m_sz = rhs_.m_sz;
00118 m_buf = new char[m_sz];
00119 memcpy (m_buf, rhs_.m_buf, m_sz);
00120 m_ptr = m_buf + (rhs_.size ());
00121 m_state = rhs_.m_state;
00122 }
00123
00124 xdrIOBuffer&
00125 xdrIOBuffer::
00126 operator>>(int& n_)
00127 {
00128 trace_with_mask("xdrIOBuffer::operator>>(int)", XDRBUFTRACE);
00129
00130 if (m_state != xmitted) {
00131 EL((ASSAERR,"Wrong state: %s\n", get_state ().c_str () ));
00132 return *this;
00133 }
00134 int val;
00135 int unit_sz = sizeof (int);
00136 memcpy ((char*) &val, m_ptr, unit_sz);
00137 m_ptr += unit_sz;
00138
00139 n_ = (int) ntohl (val);
00140
00141 if (size () == m_sz)
00142 m_state = parsed;
00143 return *this;
00144 }
00145
00146 xdrIOBuffer&
00147 xdrIOBuffer::
00148 operator>>(std::string& s_)
00149 {
00150 trace_with_mask("xdrIOBuffer::operator>>(string)", XDRBUFTRACE);
00151
00152 if (m_state != xmitted) {
00153 EL((ASSAERR,"Wrong state: %s\n", get_state ().c_str () ));
00154 return *this;
00155 }
00158 s_ = "";
00159 u_long len = (u_long) *m_ptr;
00160 char* cptr = m_ptr + 4;
00161
00162 while (len--) {
00163 s_ += *cptr++;
00164 }
00165 m_ptr += Socket::xdr_length (s_);
00166
00167 if (size () == m_sz) {
00168 m_state = parsed;
00169 }
00170 return *this;
00171 }
00172
00173 xdrIOBuffer&
00174 xdrIOBuffer::
00175 operator>>(float& n_)
00176 {
00177 trace_with_mask("xdrIOBuffer::operator>>(float)", XDRBUFTRACE);
00178
00179 if (m_state != xmitted) {
00180 EL((ASSAERR,"Wrong state: %s\n", get_state ().c_str () ));
00181 return *this;
00182 }
00183 float val;
00184 int unit_sz = sizeof (float);
00185 memcpy ((char*) &val, m_ptr, unit_sz);
00186 m_ptr += unit_sz;
00187
00188 XDR xdrs;
00189 xdrmem_create (&xdrs, (caddr_t) &val, unit_sz, XDR_DECODE);
00190 xdr_float (&xdrs, &n_);
00191 xdr_destroy (&xdrs);
00192
00193 if (size () == m_sz)
00194 m_state = parsed;
00195 return *this;
00196 }
00197
00198 void
00199 xdrIOBuffer::reset ()
00200 {
00201 trace_with_mask("xdrIOBuffer::reset", XDRBUFTRACE);
00202
00203 m_ptr = m_buf;
00204 memset (m_buf, 0, m_sz);
00205 m_state = waiting;
00206 }
00207
00208 string
00209 xdrIOBuffer::
00210 get_state () const
00211 {
00212 string msg;
00213 switch (m_state)
00214 {
00215 case xdrIOBuffer::waiting: msg = "waiting"; break;
00216 case xdrIOBuffer::xmitted: msg = "xmitted"; break;
00217 case xdrIOBuffer::parsed: msg = "parsed"; break;
00218 case xdrIOBuffer::error: msg = "error"; break;
00219 }
00220 return msg;
00221 }
00222
00223 void
00224 xdrIOBuffer::
00225 dump () const
00226 {
00227 trace_with_mask("xdrIOBuffer::dump", XDRBUFTRACE);
00228
00229 DL((XDRBUFTRACE,"xdrIOBuffer->this = 0x%x\n", long(this) ));
00230 DL((XDRBUFTRACE,"\n\n" \
00231 "\tm_buf ........: 0x%x \n" \
00232 "\tm_sz .........: %d \n" \
00233 "\tm_ptr ........: 0x%x \n" \
00234 "\tbytes left ...: %d \n" \
00235 "\tm_state ......: %s \n\n",
00236 long (m_buf), m_sz, long (m_ptr),(m_sz - size ()),
00237 get_state ().c_str ()));
00238
00239 if (m_ptr != m_buf) {
00240 MemDump image (m_buf, size ());
00241 DL((XDRBUFTRACE,"Bytes in buffer so far:\n\n%s\n\n",
00242 image.getMemDump () ));
00243 }
00244 else if (m_ptr == m_buf && m_state == xmitted) {
00245 MemDump image (m_buf, (m_sz));
00246 DL((XDRBUFTRACE,"Complete buffer:\n\n%s\n\n",
00247 image.getMemDump () ));
00248 }
00249 else {
00250 DL((XDRBUFTRACE,"Empty buffer\n" ));
00251 }
00252 }
00253