libassa  3.5.1
xdrIOBuffer.cpp
Go to the documentation of this file.
1 // -*- c++ -*-
2 //------------------------------------------------------------------------------
3 // xdrIOBuffer.cpp
4 //------------------------------------------------------------------------------
5 // Copyright (C) 1997-2002,2005 Vladislav Grinchenko
6 //
7 // This library is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Library General Public
9 // License as published by the Free Software Foundation; either
10 // version 2 of the License, or (at your option) any later version.
11 //------------------------------------------------------------------------------
12 // Created: 04/11/2000
13 //------------------------------------------------------------------------------
14 #include <string.h>
15 #include <errno.h>
16 
17 #include "assa/MemDump.h"
18 #include "assa/xdrIOBuffer.h"
19 #include "assa/XDRHack.h"
20 
21 
22 namespace ASSA {
23 
24 Socket&
26 {
27  trace_with_mask("Socket >> xdrIOBuffer", XDRBUFTRACE);
28 
29  DL((XDRBUFTRACE,"Buffer Initially:\n"));
30  b_.dump ();
31 
32  if (b_.m_state != xdrIOBuffer::waiting) {
33  EL((ASSAERR,"Wrong state: %s\n", b_.get_state ().c_str ()));
34  return s_;
35  }
36  int expected = b_.m_sz - b_.size ();
37 
38  DL((XDRBUFTRACE,"Bytes expected: %d\n",expected));
39  DL((XDRBUFTRACE,"Bytes in Socket buffer(s): %d\n", s_.getBytesAvail ()));
40  int ret;
41 
42  if ((ret = s_.read (b_.m_ptr, expected)) <= 0)
43  {
44 #if defined(WIN32)
45  if (WSAGetLastError () != WSAEWOULDBLOCK) {
46  WSASetLastError (0);
47  EL((ASSAERR,"Socket::read() error!\n"));
49  }
50 #else
51  if (errno != EWOULDBLOCK) {
52  EL((ASSAERR,"Socket::read() error!\n"));
54  }
55 #endif
56  else {
57  EL((ASSAERR,"Socket::read() error! \n"));
58  }
59  return s_;
60  }
61  b_.m_ptr += ret;
62 
63  DL((XDRBUFTRACE,"Received %d bytes\n", ret));
64  b_.dump ();
65 
66  if (b_.m_sz == b_.size ()) { // at the end
67  DL((XDRBUFTRACE,"Complete message is in the buffer!\n"));
69  b_.m_ptr = b_.m_buf; // rewind m_ptr for parsing stage
70  b_.dump ();
71  }
72  return s_;
73 }
74 } // end namespace ASSA
75 
76 using namespace ASSA;
77 
79 xdrIOBuffer (u_int sz_)
80  : m_sz (sz_),
81  m_state (waiting)
82 {
83  trace_with_mask("xdrIOBuffer::xdrIOBuffer", XDRBUFTRACE);
84 
85  m_buf = new char[sz_];
86  m_ptr = m_buf;
87  memset (m_buf, 0, m_sz);
88  DL((XDRBUF,"Allocated xdrIOBuffer [%d]\n",m_sz));
89  dump ();
90 }
91 
93 ~xdrIOBuffer ()
94 {
95  trace_with_mask("xdrIOBuffer::~xdrIOBuffer", XDRBUFTRACE);
96 
97  DL((XDRBUFTRACE,"xdrIOBuffer->this = 0x%x\n", long(this)));
98  delete [] m_buf;
99 }
100 
103 {
104  trace_with_mask("xdrIOBuffer::operator=()", XDRBUFTRACE);
105 
106  delete [] m_buf;
107  copy (rhs_);
108  return *this;
109 }
110 
111 void
113 copy (const xdrIOBuffer& rhs_)
114 {
115  trace_with_mask("xdrIOBuffer::copy", XDRBUFTRACE);
116 
117  m_sz = rhs_.m_sz;
118  m_buf = new char[m_sz];
119  memcpy (m_buf, rhs_.m_buf, m_sz);
120  m_ptr = m_buf + (rhs_.size ());
121  m_state = rhs_.m_state;
122 }
123 
124 xdrIOBuffer&
126 operator>>(int& n_)
127 {
128  trace_with_mask("xdrIOBuffer::operator>>(int)", XDRBUFTRACE);
129 
130  if (m_state != xmitted) {
131  EL((ASSAERR,"Wrong state: %s\n", get_state ().c_str () ));
132  return *this;
133  }
134  int val;
135  int unit_sz = sizeof (int);
136  memcpy ((char*) &val, m_ptr, unit_sz);
137  m_ptr += unit_sz;
138 
139  n_ = (int) ntohl (val);
140 
141  if (size () == m_sz)
142  m_state = parsed;
143  return *this;
144 }
145 
146 xdrIOBuffer&
148 operator>>(std::string& s_)
149 {
150  trace_with_mask("xdrIOBuffer::operator>>(string)", XDRBUFTRACE);
151 
152  if (m_state != xmitted) {
153  EL((ASSAERR,"Wrong state: %s\n", get_state ().c_str () ));
154  return *this;
155  }
158  s_ = "";
159  u_long len = (u_long) *m_ptr;
160  char* cptr = m_ptr + 4;
161 
162  while (len--) {
163  s_ += *cptr++;
164  }
165  m_ptr += Socket::xdr_length (s_);
166 
167  if (size () == m_sz) {
168  m_state = parsed;
169  }
170  return *this;
171 }
172 
173 xdrIOBuffer&
175 operator>>(float& n_)
176 {
177  trace_with_mask("xdrIOBuffer::operator>>(float)", XDRBUFTRACE);
178 
179  if (m_state != xmitted) {
180  EL((ASSAERR,"Wrong state: %s\n", get_state ().c_str () ));
181  return *this;
182  }
183  float val;
184  int unit_sz = sizeof (float);
185  memcpy ((char*) &val, m_ptr, unit_sz);
186  m_ptr += unit_sz;
187 
188  XDR xdrs;
189  xdrmem_create (&xdrs, (caddr_t) &val, unit_sz, XDR_DECODE);
190  xdr_float (&xdrs, &n_);
191  xdr_destroy (&xdrs);
192 
193  if (size () == m_sz)
194  m_state = parsed;
195  return *this;
196 }
197 
198 void
200 {
201  trace_with_mask("xdrIOBuffer::reset", XDRBUFTRACE);
202 
203  m_ptr = m_buf;
204  memset (m_buf, 0, m_sz);
205  m_state = waiting;
206 }
207 
208 string
210 get_state () const
211 {
212  string msg;
213  switch (m_state)
214  {
215  case xdrIOBuffer::waiting: msg = "waiting"; break;
216  case xdrIOBuffer::xmitted: msg = "xmitted"; break;
217  case xdrIOBuffer::parsed: msg = "parsed"; break;
218  case xdrIOBuffer::error: msg = "error"; break;
219  }
220  return msg;
221 }
222 
223 void
225 dump () const
226 {
227  trace_with_mask("xdrIOBuffer::dump", XDRBUFTRACE);
228 
229  DL((XDRBUFTRACE,"xdrIOBuffer->this = 0x%x\n", long(this) ));
230  DL((XDRBUFTRACE,"\n\n" \
231  "\tm_buf ........: 0x%x \n" \
232  "\tm_sz .........: %d \n" \
233  "\tm_ptr ........: 0x%x \n" \
234  "\tbytes left ...: %d \n" \
235  "\tm_state ......: %s \n\n",
236  long (m_buf), m_sz, long (m_ptr),(m_sz - size ()),
237  get_state ().c_str ()));
238 
239  if (m_ptr != m_buf) {
240  MemDump image (m_buf, size ());
241  DL((XDRBUFTRACE,"Bytes in buffer so far:\n\n%s\n\n",
242  image.getMemDump () ));
243  }
244  else if (m_ptr == m_buf && m_state == xmitted) {
245  MemDump image (m_buf, (m_sz));
246  DL((XDRBUFTRACE,"Complete buffer:\n\n%s\n\n",
247  image.getMemDump () ));
248  }
249  else {
250  DL((XDRBUFTRACE,"Empty buffer\n" ));
251  }
252 }
253 
#define EL(X)
A macro for writing error message to the Logger.
Definition: Logger.h:285
#define DL(X)
A macro for writing debug message to the Logger.
Definition: Logger.h:273
#define trace_with_mask(s, m)
trace_with_mask() is used to trace function call chain in C++ program.
Definition: Logger.h:437
unsigned long u_long
Definition: Logger_Impl.h:41
unsigned int u_int
Definition: Logger_Impl.h:40
A Hex/Ascii memory dump of similar to od(1) UNIX utility.
XDRHack provides XDR definitions for systems that have them missing.
const char * getMemDump() const
Obtain a pointer to the dump image (null-terminated char string).
Definition: MemDump.h:94
static size_t xdr_length(const std::string &s_)
Give the true length of the XDR-encoded STL string.
Definition: Socket.h:343
virtual int read(char *buf_, const u_int size_)
Read expected number of bytes from the socket.
Definition: Socket.h:551
int getBytesAvail(void) const
Return number of bytes available in socket receive buffer.
Definition: Socket.cpp:48
void copy(const xdrIOBuffer &)
Copy object from argument.
xdrIOBuffer(u_int len_)
Constructor.
Definition: xdrIOBuffer.cpp:79
void reset()
Clear up the internal buffer and reset state to waiting.
friend Socket & operator>>(Socket &src_, xdrIOBuffer &dest_)
Read raw data from Socket nonblocking and store into internal buffer.
Definition: xdrIOBuffer.cpp:25
int m_sz
Buffer size and maximum expected size.
Definition: xdrIOBuffer.h:140
char * m_ptr
Pointer for next I/O operation into the buffer
Definition: xdrIOBuffer.h:143
int size() const
Return number of bytes in xdrIOBuffer.
Definition: xdrIOBuffer.h:171
~xdrIOBuffer()
Destructor.
Definition: xdrIOBuffer.cpp:93
state_t m_state
Object state.
Definition: xdrIOBuffer.h:146
char * m_buf
Buffer.
Definition: xdrIOBuffer.h:137
string get_state() const
Give verbal interpretation of object's state.
xdrIOBuffer & operator=(const xdrIOBuffer &rhs_)
Assign operator.
void dump() const
Dump object's internal state to the log file.
Definition: Acceptor.h:40
@ XDRBUF
Class xdrIOBuffer messages
Definition: LogMask.h:43
@ ASSAERR
ASSA and system errors
Definition: LogMask.h:34
@ XDRBUFTRACE
Extended xdrIOBuffer messages
Definition: LogMask.h:44
Socket & operator>>(Socket &s_, CharInBuffer &b_)
Regardless of the delimeter size, which can be >1, add the character received to the buffer and compa...
This class allows to read XDR-encoded data from Socket stream asynchronously and then read from it as...