libassa 3.5.0
|
00001 // -*- c++ -*- 00002 //------------------------------------------------------------------------------ 00003 // xdrIOBuffer.cpp 00004 //------------------------------------------------------------------------------ 00005 // Copyright (C) 1997-2002,2005 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 // Created: 04/11/2000 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 ()) { // at the end 00067 DL((XDRBUFTRACE,"Complete message is in the buffer!\n")); 00068 b_.m_state = xdrIOBuffer::xmitted; 00069 b_.m_ptr = b_.m_buf; // rewind m_ptr for parsing stage 00070 b_.dump (); 00071 } 00072 return s_; 00073 } 00074 } // end namespace ASSA 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