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