1 // -*- c++ -*-
2 //------------------------------------------------------------------------------
3 // xdrIOBuffer.h
4 //------------------------------------------------------------------------------
5 // Copyright (c) 2000,2005 by 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/03/2000
13 //------------------------------------------------------------------------------
14
15 #ifndef XDR_IO_BUFFER_H
16 #define XDR_IO_BUFFER_H
17
18 #include "assa/Assure.h"
19 #include "assa/Socket.h"
20 #include "assa/IPv4Socket.h"
21
22 #include <string>
23
24 namespace ASSA {
25
26 /** @file xdrIOBuffer.h
27 *
28 * This class allows to read XDR-encoded data from Socket stream asynchronously
29 * and then read from it as if from a stream of intermixed strings, integers
30 * and floats. Data are XDR-decoded on a fly.
31 *
32 * Testing xdrIOBuffer object in conditional statement will produce
33 * false if:
34 *
35 * - Not entire buffer has been read yet.
36 * - Socket stream exceptional condition occured.
37 *
38 * Thus, data accumulation and data decoding functions are separated.
39 *
40 * Initially, buffer is in waiting state. In this state,
41 * xdrIOBuffer object waits for bytes from the Socket stream.
42 *
43 * When buffer object becomes full, the state is switched to
44 * xmitted. Now, an application code can read data
45 * from the buffer. The data will be XDR-decoded.
46 *
47 * xdrIOBuffer object yields TRUE in conditional statements only
48 * in xmitted state. In other words, buffer is TRUE if
49 * it is full, and FALSE otherwise.
50 *
51 * xdrIOBuffer can be used only once. You cannot "rewind", and therefore
52 * reuse it.
53 */
54
55 class xdrIOBuffer
56 {
57 public:
58 /** @enum state_t
59 */
60 enum state_t {
61 waiting,
62 xmitted,
63 parsed,
64 error
65 };
66
67 /** Constructor.
68 */
69 xdrIOBuffer (u_int len_);
70
71 /** Destructor.
72 */
73 ~xdrIOBuffer ();
74
75 /** Copy constructor
76 */
77 xdrIOBuffer (const xdrIOBuffer& rhs_);
78
79 /** Assign operator.
80 */
81 xdrIOBuffer& operator= (const xdrIOBuffer& rhs_);
82
83 /** Read raw data from Socket nonblocking and
84 * store into internal buffer.
85 */
86 friend Socket& operator>>(Socket& src_, xdrIOBuffer& dest_);
87
88 /** Read and XDR-decode STL string from the buffer.
89 */
90 xdrIOBuffer& operator>>(std::string&);
91
92 /** Read and XDR-decode an integer from the buffer.
93 */
94 xdrIOBuffer& operator>>(int&);
95
96 /** Read and XDR-decode a float from the buffer.
97 */
98 xdrIOBuffer& operator>>(float&);
99
100 /** Convertion to void* (for testing where bool is required).
101 */
102 operator void*() const;
103
104 /** Give verbal interpretation of object's state.
105 */
106 string get_state () const;
107
108 /** Return number of bytes in xdrIOBuffer. In <b>waiting</b>
109 state it's bytes transmitted so far. In <b>xmitted</b> state,
110 number of bytes left to decode.
111 */
112 int size () const;
113
114 /** Return buffer (maximum expected/allowable) size.
115 */
116 int buffer_size () const;
117
118 /** Return pointer to the first byte of xdrIOBuffer.
119 */
120 const char* str () const;
121
122 /** Clear up the internal buffer and reset state to
123 <b>waiting</b>.
124 */
125 void reset ();
126
127 /** Dump object's internal state to the log file
128 */
129 void dump () const;
130
131 protected:
132 /// Copy object from argument
133 void copy (const xdrIOBuffer&);
134
135 private:
136 /// Buffer
137 char* m_buf;
138
139 /// Buffer size and maximum expected size
140 int m_sz;
141
142 /// Pointer for next I/O operation into the buffer
143 char* m_ptr;
144
145 /// Object state
146 state_t m_state;
147 };
148
149 inline
150 xdrIOBuffer::
xdrIOBuffer(const xdrIOBuffer & rhs_)151 xdrIOBuffer (const xdrIOBuffer& rhs_)
152 {
153 trace_with_mask("xdrIOBuffer::xdrIOBuffer(xdrIOBuffer&)", XDRBUFTRACE);
154
155 copy (rhs_);
156 }
157
158 inline
159 xdrIOBuffer::
160 operator void*() const
161 {
162 trace_with_mask("xdrIOBuffer::opt void*()", XDRBUFTRACE);
163
164 return (m_state == waiting || m_state == parsed)
165 ? (void *)0 // bad state
166 : (void *)(-1); // good state
167 }
168
169 inline int
170 xdrIOBuffer::
size()171 size () const
172 {
173 return (m_ptr - m_buf);
174 }
175
176 inline int
177 xdrIOBuffer::
buffer_size()178 buffer_size () const
179 {
180 return (m_sz);
181 }
182
183 inline const char*
184 xdrIOBuffer::
str()185 str () const
186 {
187 return ((const char*) m_buf);
188 }
189
190 } // end namespace ASSA
191
192 #endif /* XDR_IO_BUFFER_H */
193